diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc index 8c1166ce79..9924da359d 100644 --- a/src/tint/transform/builtin_polyfill.cc +++ b/src/tint/transform/builtin_polyfill.cc @@ -745,18 +745,52 @@ struct BuiltinPolyfill::State { } auto name = b.Symbols().New(is_div ? "tint_div" : "tint_mod"); - auto* use_one = b.Equal(rhs, ScalarOrVector(width, 0_a)); + + auto* rhs_is_zero = b.Equal(rhs, ScalarOrVector(width, 0_a)); + if (lhs_ty->is_signed_integer_scalar_or_vector()) { const auto bits = lhs_el_ty->Size() * 8; auto min_int = AInt(AInt::kLowestValue >> (AInt::kNumBits - bits)); const ast::Expression* lhs_is_min = b.Equal(lhs, ScalarOrVector(width, min_int)); const ast::Expression* rhs_is_minus_one = b.Equal(rhs, ScalarOrVector(width, -1_a)); - // use_one = use_one | ((lhs == MIN_INT) & (rhs == -1)) - use_one = b.Or(use_one, b.And(lhs_is_min, rhs_is_minus_one)); - } - auto* select = b.Call("select", rhs, ScalarOrVector(width, 1_a), use_one); + // use_one = rhs_is_zero | ((lhs == MIN_INT) & (rhs == -1)) + auto* use_one = b.Or(rhs_is_zero, b.And(lhs_is_min, rhs_is_minus_one)); + + // Special handling for mod in case either operand is negative, as negative operands + // for % is undefined behaviour for most backends (HLSL, MSL, GLSL, SPIR-V). + if (!is_div) { + const char* rhs_or_one = "rhs_or_one"; + body.Push(b.Decl(b.Let( + rhs_or_one, b.Call("select", rhs, ScalarOrVector(width, 1_a), use_one)))); + + // Is either operand negative? + // (lhs | rhs) & (1<<31) + auto sign_bit_mask = ScalarOrVector(width, u32(1 << (bits - 1))); + auto* lhs_or_rhs = CastScalarOrVector(width, b.Or(lhs, rhs_or_one)); + auto* lhs_or_rhs_is_neg = + b.NotEqual(b.And(lhs_or_rhs, sign_bit_mask), ScalarOrVector(width, 0_u)); + + // lhs - trunc(lhs / rhs) * rhs (note: integral division truncates) + auto* slow_mod = b.Sub(lhs, b.Mul(b.Div(lhs, rhs_or_one), rhs_or_one)); + + // lhs % rhs + auto* fast_mod = b.Mod(lhs, rhs_or_one); + + auto* use_slow = b.Call("any", lhs_or_rhs_is_neg); + + body.Push(b.If(use_slow, b.Block(b.Return(slow_mod)), + b.Else(b.Block(b.Return(fast_mod))))); + + } else { + auto* rhs_or_one = b.Call("select", rhs, ScalarOrVector(width, 1_a), use_one); + body.Push(b.Return(is_div ? b.Div(lhs, rhs_or_one) : b.Mod(lhs, rhs_or_one))); + } + + } else { + auto* rhs_or_one = b.Call("select", rhs, ScalarOrVector(width, 1_a), rhs_is_zero); + body.Push(b.Return(is_div ? b.Div(lhs, rhs_or_one) : b.Mod(lhs, rhs_or_one))); + } - body.Push(b.Return(is_div ? b.Div(lhs, select) : b.Mod(lhs, select))); b.Func(name, utils::Vector{ b.Param("lhs", T(lhs_ty)), @@ -808,6 +842,14 @@ struct BuiltinPolyfill::State { } return b.Call(b.ty.vec(width), value); } + + template + const ast::Expression* CastScalarOrVector(uint32_t width, const ast::Expression* e) { + if (width == 1) { + return b.Call(b.ty.Of(), e); + } + return b.Call(b.ty.vec(width), e); + } }; BuiltinPolyfill::BuiltinPolyfill() = default; diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc index 2a7f684021..65365bbb77 100644 --- a/src/tint/transform/builtin_polyfill_test.cc +++ b/src/tint/transform/builtin_polyfill_test.cc @@ -2073,7 +2073,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : i32, rhs : i32) -> i32 { - return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); + let rhs_or_one = select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))); + if (any(((u32((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2121,7 +2126,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : i32, rhs : i32) -> i32 { - return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); + let rhs_or_one = select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))); + if (any(((u32((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2169,7 +2179,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : i32, rhs : i32) -> i32 { - return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); + let rhs_or_one = select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1)))); + if (any(((u32((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2363,7 +2378,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : vec3, rhs : i32) -> vec3 { let r = vec3(rhs); - return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); + let rhs_or_one = select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))); + if (any(((vec3((lhs | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2413,7 +2433,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : vec3, rhs : i32) -> vec3 { let r = vec3(rhs); - return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); + let rhs_or_one = select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))); + if (any(((vec3((lhs | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2463,7 +2488,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : vec3, rhs : i32) -> vec3 { let r = vec3(rhs); - return (lhs % select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); + let rhs_or_one = select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1))))); + if (any(((vec3((lhs | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { @@ -2563,7 +2593,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : i32, rhs : vec3) -> vec3 { let l = vec3(lhs); - return (l % select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1)))))); + let rhs_or_one = select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))); + if (any(((vec3((l | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } fn f() { @@ -2613,7 +2648,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : i32, rhs : vec3) -> vec3 { let l = vec3(lhs); - return (l % select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1)))))); + let rhs_or_one = select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1))))); + if (any(((vec3((l | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } fn f() { @@ -2711,7 +2751,12 @@ fn f() { auto* expect = R"( fn tint_mod(lhs : vec3, rhs : vec3) -> vec3 { - return (lhs % select(rhs, vec3(1), ((rhs == vec3(0)) | ((lhs == vec3(-2147483648)) & (rhs == vec3(-1)))))); + let rhs_or_one = select(rhs, vec3(1), ((rhs == vec3(0)) | ((lhs == vec3(-2147483648)) & (rhs == vec3(-1))))); + if (any(((vec3((lhs | rhs_or_one)) & vec3(2147483648u)) != vec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } fn f() { diff --git a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.dxc.hlsl index 84546915fc..68305a9757 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.fxc.hlsl index 84546915fc..68305a9757 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.glsl index 70e79ddd0f..47c1572a2b 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.msl index 15c78158c1..dd155b17b3 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.spvasm index 8e25954968..89a507ffa9 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 25 +; Bound: 46 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,32 +10,62 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %1 = OpTypeFunction %int %int %int - %8 = OpConstantNull %int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %10 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %13 = OpConstantNull %int %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %29 = OpConstantNull %uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %19 = OpTypeFunction %void + %40 = OpTypeFunction %void %int_2 = OpConstant %int 2 %tint_mod = OpFunction %int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %int %6 = OpLabel - %9 = OpIEqual %bool %rhs %8 - %12 = OpIEqual %bool %lhs %int_n2147483648 - %14 = OpIEqual %bool %rhs %int_n1 - %15 = OpLogicalAnd %bool %12 %14 - %16 = OpLogicalOr %bool %9 %15 - %7 = OpSelect %int %16 %int_1 %rhs - %18 = OpSRem %int %lhs %7 - OpReturnValue %18 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %10 +%tint_return_value = OpVariable %_ptr_Function_int Function %13 + %15 = OpIEqual %bool %rhs %13 + %17 = OpIEqual %bool %lhs %int_n2147483648 + %19 = OpIEqual %bool %rhs %int_n1 + %20 = OpLogicalAnd %bool %17 %19 + %21 = OpLogicalOr %bool %15 %20 + %14 = OpSelect %int %21 %int_1 %rhs + %26 = OpBitwiseOr %int %lhs %14 + %24 = OpBitcast %uint %26 + %28 = OpBitwiseAnd %uint %24 %uint_2147483648 + %30 = OpINotEqual %bool %28 %29 + OpSelectionMerge %31 None + OpBranchConditional %30 %32 %33 + %32 = OpLabel + OpStore %tint_return_flag %true + %35 = OpSDiv %int %lhs %14 + %36 = OpIMul %int %35 %14 + %37 = OpISub %int %lhs %36 + OpStore %tint_return_value %37 + OpBranch %31 + %33 = OpLabel + OpStore %tint_return_flag %true + %38 = OpSRem %int %lhs %14 + OpStore %tint_return_value %38 + OpBranch %31 + %31 = OpLabel + %39 = OpLoad %int %tint_return_value + OpReturnValue %39 OpFunctionEnd - %f = OpFunction %void None %19 - %22 = OpLabel - %24 = OpFunctionCall %int %tint_mod %int_1 %int_2 + %f = OpFunction %void None %40 + %43 = OpLabel + %45 = OpFunctionCall %int %tint_mod %int_1 %int_2 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.dxc.hlsl index 6fc93b7e92..831298d61e 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.fxc.hlsl index 6fc93b7e92..831298d61e 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.glsl index f9117fb4b3..ab6b883925 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(int lhs, ivec3 rhs) { ivec3 l = ivec3(lhs); - return (l % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((l | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.msl index 9b89ade458..17b2370e0c 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int lhs, int3 rhs) { int3 const l = int3(lhs); - return (l % select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((l | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(l) - as_type(as_type((as_type((l / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (l % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.spvasm index bb4919507a..749734c9a1 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 34 +; Bound: 57 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,41 +10,74 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %int %v3int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_4 = OpConstant %int 4 %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %32 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %55 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %lhs %lhs %lhs - %11 = OpIEqual %v3bool %rhs %10 - %16 = OpIEqual %v3bool %8 %15 - %19 = OpIEqual %v3bool %rhs %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %rhs - %24 = OpSRem %v3int %8 %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %lhs %lhs %lhs + %17 = OpIEqual %v3bool %rhs %14 + %21 = OpIEqual %v3bool %15 %20 + %24 = OpIEqual %v3bool %rhs %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %rhs + %33 = OpBitwiseOr %v3int %15 %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %15 %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %15 %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %15 %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %33 = OpFunctionCall %v3int %tint_mod %int_4 %32 + %f = OpFunction %void None %48 + %51 = OpLabel + %56 = OpFunctionCall %v3int %tint_mod %int_4 %55 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 3e147af81d..3604e81335 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 3e147af81d..3604e81335 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.glsl index 5564275d6c..987c55453f 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(ivec3 lhs, int rhs) { ivec3 r = ivec3(rhs); - return (lhs % mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.msl index 9a30326165..097d4d9fd4 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int rhs) { int3 const r = int3(rhs); - return (lhs % select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1)))))); + int3 const rhs_or_one = select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.spvasm index 6ec533fa3e..52fbedbbeb 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 34 +; Bound: 57 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,41 +10,74 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %54 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %rhs %rhs %rhs - %11 = OpIEqual %v3bool %8 %10 - %16 = OpIEqual %v3bool %lhs %15 - %19 = OpIEqual %v3bool %8 %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %8 - %24 = OpSRem %v3int %lhs %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %rhs %rhs %rhs + %17 = OpIEqual %v3bool %15 %14 + %21 = OpIEqual %v3bool %lhs %20 + %24 = OpIEqual %v3bool %15 %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %15 + %33 = OpBitwiseOr %v3int %lhs %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %lhs %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %lhs %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %lhs %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %33 = OpFunctionCall %v3int %tint_mod %31 %int_4 + %f = OpFunction %void None %48 + %51 = OpLabel + %56 = OpFunctionCall %v3int %tint_mod %54 %int_4 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.dxc.hlsl index c12408d50b..2050f5beef 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.fxc.hlsl index c12408d50b..2050f5beef 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.glsl index 36bb83c9dc..1e34296c77 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es ivec3 tint_mod(ivec3 lhs, ivec3 rhs) { - return (lhs % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.msl index 770ab3f534..6e6c7258c1 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.spvasm index 9ef43ed064..92536c9cab 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 36 +; Bound: 59 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,43 +10,76 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %v3int - %9 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %19 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %22 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %34 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %36 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %24 = OpTypeFunction %void + %47 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %53 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 %int_5 = OpConstant %int 5 %int_6 = OpConstant %int 6 - %34 = OpConstantComposite %v3int %int_4 %int_5 %int_6 + %57 = OpConstantComposite %v3int %int_4 %int_5 %int_6 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %10 = OpIEqual %v3bool %rhs %9 - %15 = OpIEqual %v3bool %lhs %14 - %18 = OpIEqual %v3bool %rhs %17 - %19 = OpLogicalAnd %v3bool %15 %18 - %20 = OpLogicalOr %v3bool %10 %19 - %8 = OpSelect %v3int %20 %22 %rhs - %23 = OpSRem %v3int %lhs %8 - OpReturnValue %23 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %16 = OpIEqual %v3bool %rhs %14 + %20 = OpIEqual %v3bool %lhs %19 + %23 = OpIEqual %v3bool %rhs %22 + %24 = OpLogicalAnd %v3bool %20 %23 + %25 = OpLogicalOr %v3bool %16 %24 + %15 = OpSelect %v3int %25 %27 %rhs + %32 = OpBitwiseOr %v3int %lhs %15 + %29 = OpBitcast %v3uint %32 + %35 = OpBitwiseAnd %v3uint %29 %34 + %37 = OpINotEqual %v3bool %35 %36 + %28 = OpAny %bool %37 + OpSelectionMerge %38 None + OpBranchConditional %28 %39 %40 + %39 = OpLabel + OpStore %tint_return_flag %true + %42 = OpSDiv %v3int %lhs %15 + %43 = OpIMul %v3int %42 %15 + %44 = OpISub %v3int %lhs %43 + OpStore %tint_return_value %44 + OpBranch %38 + %40 = OpLabel + OpStore %tint_return_flag %true + %45 = OpSRem %v3int %lhs %15 + OpStore %tint_return_value %45 + OpBranch %38 + %38 = OpLabel + %46 = OpLoad %v3int %tint_return_value + OpReturnValue %46 OpFunctionEnd - %f = OpFunction %void None %24 - %27 = OpLabel - %35 = OpFunctionCall %v3int %tint_mod %30 %34 + %f = OpFunction %void None %47 + %50 = OpLabel + %58 = OpFunctionCall %v3int %tint_mod %53 %57 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl index a5f5597b34..1ea277f3a5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl index a5f5597b34..1ea277f3a5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl index ddb6a6b810..b2f5da8a54 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl index 8d879ce523..2aeeffb3f5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm index f6041166bd..5963a80b16 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 24 +; Bound: 45 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,31 +10,61 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %1 = OpTypeFunction %int %int %int - %8 = OpConstantNull %int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %10 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %13 = OpConstantNull %int %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %29 = OpConstantNull %uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %19 = OpTypeFunction %void + %40 = OpTypeFunction %void %tint_mod = OpFunction %int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %int %6 = OpLabel - %9 = OpIEqual %bool %rhs %8 - %12 = OpIEqual %bool %lhs %int_n2147483648 - %14 = OpIEqual %bool %rhs %int_n1 - %15 = OpLogicalAnd %bool %12 %14 - %16 = OpLogicalOr %bool %9 %15 - %7 = OpSelect %int %16 %int_1 %rhs - %18 = OpSRem %int %lhs %7 - OpReturnValue %18 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %10 +%tint_return_value = OpVariable %_ptr_Function_int Function %13 + %15 = OpIEqual %bool %rhs %13 + %17 = OpIEqual %bool %lhs %int_n2147483648 + %19 = OpIEqual %bool %rhs %int_n1 + %20 = OpLogicalAnd %bool %17 %19 + %21 = OpLogicalOr %bool %15 %20 + %14 = OpSelect %int %21 %int_1 %rhs + %26 = OpBitwiseOr %int %lhs %14 + %24 = OpBitcast %uint %26 + %28 = OpBitwiseAnd %uint %24 %uint_2147483648 + %30 = OpINotEqual %bool %28 %29 + OpSelectionMerge %31 None + OpBranchConditional %30 %32 %33 + %32 = OpLabel + OpStore %tint_return_flag %true + %35 = OpSDiv %int %lhs %14 + %36 = OpIMul %int %35 %14 + %37 = OpISub %int %lhs %36 + OpStore %tint_return_value %37 + OpBranch %31 + %33 = OpLabel + OpStore %tint_return_flag %true + %38 = OpSRem %int %lhs %14 + OpStore %tint_return_value %38 + OpBranch %31 + %31 = OpLabel + %39 = OpLoad %int %tint_return_value + OpReturnValue %39 OpFunctionEnd - %f = OpFunction %void None %19 - %22 = OpLabel - %23 = OpFunctionCall %int %tint_mod %int_1 %8 + %f = OpFunction %void None %40 + %43 = OpLabel + %44 = OpFunctionCall %int %tint_mod %int_1 %13 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl index f199262055..285985afd7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl index f199262055..285985afd7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl index 412aedf276..14f1a4ec32 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(int lhs, ivec3 rhs) { ivec3 l = ivec3(lhs); - return (l % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((l | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl index 49b1bee619..cfbccf8b1c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int lhs, int3 rhs) { int3 const l = int3(lhs); - return (l % select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((l | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(l) - as_type(as_type((as_type((l / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (l % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm index 1c8946398d..11dd73e8cf 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 34 +; Bound: 57 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,41 +10,74 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %int %v3int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_4 = OpConstant %int 4 - %30 = OpConstantNull %int + %53 = OpConstantNull %int %int_2 = OpConstant %int 2 - %32 = OpConstantComposite %v3int %30 %int_2 %30 + %55 = OpConstantComposite %v3int %53 %int_2 %53 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %lhs %lhs %lhs - %11 = OpIEqual %v3bool %rhs %10 - %16 = OpIEqual %v3bool %8 %15 - %19 = OpIEqual %v3bool %rhs %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %rhs - %24 = OpSRem %v3int %8 %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %lhs %lhs %lhs + %17 = OpIEqual %v3bool %rhs %14 + %21 = OpIEqual %v3bool %15 %20 + %24 = OpIEqual %v3bool %rhs %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %rhs + %33 = OpBitwiseOr %v3int %15 %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %15 %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %15 %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %15 %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %33 = OpFunctionCall %v3int %tint_mod %int_4 %32 + %f = OpFunction %void None %48 + %51 = OpLabel + %56 = OpFunctionCall %v3int %tint_mod %int_4 %55 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 418539b3c3..d5938f9972 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 418539b3c3..d5938f9972 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl index 788c7fee9c..579b7559c2 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(ivec3 lhs, int rhs) { ivec3 r = ivec3(rhs); - return (lhs % mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl index a3b8e521d1..95c9959b53 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int rhs) { int3 const r = int3(rhs); - return (lhs % select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1)))))); + int3 const rhs_or_one = select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm index 4f001ca36e..e88004d5e2 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 34 +; Bound: 57 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,41 +10,74 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %32 = OpConstantNull %int + %54 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %55 = OpConstantNull %int %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %rhs %rhs %rhs - %11 = OpIEqual %v3bool %8 %10 - %16 = OpIEqual %v3bool %lhs %15 - %19 = OpIEqual %v3bool %8 %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %8 - %24 = OpSRem %v3int %lhs %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %rhs %rhs %rhs + %17 = OpIEqual %v3bool %15 %14 + %21 = OpIEqual %v3bool %lhs %20 + %24 = OpIEqual %v3bool %15 %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %15 + %33 = OpBitwiseOr %v3int %lhs %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %lhs %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %lhs %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %lhs %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %33 = OpFunctionCall %v3int %tint_mod %31 %32 + %f = OpFunction %void None %48 + %51 = OpLabel + %56 = OpFunctionCall %v3int %tint_mod %54 %55 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl index f5613073b2..61a695f8ce 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl index f5613073b2..61a695f8ce 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl index e1da39494e..c24178a1a0 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es ivec3 tint_mod(ivec3 lhs, ivec3 rhs) { - return (lhs % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl index cc6b827ef4..aceb594b1d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm index 3672562ec1..30bd04a805 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 35 +; Bound: 58 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,42 +10,75 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %v3int - %9 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %19 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %22 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %34 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %36 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %24 = OpTypeFunction %void + %47 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %31 = OpConstantNull %int + %53 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %54 = OpConstantNull %int %int_5 = OpConstant %int 5 - %33 = OpConstantComposite %v3int %31 %int_5 %31 + %56 = OpConstantComposite %v3int %54 %int_5 %54 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %10 = OpIEqual %v3bool %rhs %9 - %15 = OpIEqual %v3bool %lhs %14 - %18 = OpIEqual %v3bool %rhs %17 - %19 = OpLogicalAnd %v3bool %15 %18 - %20 = OpLogicalOr %v3bool %10 %19 - %8 = OpSelect %v3int %20 %22 %rhs - %23 = OpSRem %v3int %lhs %8 - OpReturnValue %23 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %16 = OpIEqual %v3bool %rhs %14 + %20 = OpIEqual %v3bool %lhs %19 + %23 = OpIEqual %v3bool %rhs %22 + %24 = OpLogicalAnd %v3bool %20 %23 + %25 = OpLogicalOr %v3bool %16 %24 + %15 = OpSelect %v3int %25 %27 %rhs + %32 = OpBitwiseOr %v3int %lhs %15 + %29 = OpBitcast %v3uint %32 + %35 = OpBitwiseAnd %v3uint %29 %34 + %37 = OpINotEqual %v3bool %35 %36 + %28 = OpAny %bool %37 + OpSelectionMerge %38 None + OpBranchConditional %28 %39 %40 + %39 = OpLabel + OpStore %tint_return_flag %true + %42 = OpSDiv %v3int %lhs %15 + %43 = OpIMul %v3int %42 %15 + %44 = OpISub %v3int %lhs %43 + OpStore %tint_return_value %44 + OpBranch %38 + %40 = OpLabel + OpStore %tint_return_flag %true + %45 = OpSRem %v3int %lhs %15 + OpStore %tint_return_value %45 + OpBranch %38 + %38 = OpLabel + %46 = OpLoad %v3int %tint_return_value + OpReturnValue %46 OpFunctionEnd - %f = OpFunction %void None %24 - %27 = OpLabel - %34 = OpFunctionCall %v3int %tint_mod %30 %33 + %f = OpFunction %void None %47 + %50 = OpLabel + %57 = OpFunctionCall %v3int %tint_mod %53 %56 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl index ee8f7775f0..ed1bd8a633 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl index ee8f7775f0..ed1bd8a633 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl index 7edd1670aa..c68ce313ac 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl index 8bd7973ff8..98ad24edc4 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm index 44f6beacda..e63496497f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 31 +; Bound: 51 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,42 +10,71 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %1 = OpTypeFunction %int %int %int - %8 = OpConstantNull %int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %10 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %13 = OpConstantNull %int %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %29 = OpConstantNull %uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %19 = OpTypeFunction %void -%_ptr_Function_int = OpTypePointer Function %int + %40 = OpTypeFunction %void %tint_mod = OpFunction %int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %int %6 = OpLabel - %9 = OpIEqual %bool %rhs %8 - %12 = OpIEqual %bool %lhs %int_n2147483648 - %14 = OpIEqual %bool %rhs %int_n1 - %15 = OpLogicalAnd %bool %12 %14 - %16 = OpLogicalOr %bool %9 %15 - %7 = OpSelect %int %16 %int_1 %rhs - %18 = OpSRem %int %lhs %7 - OpReturnValue %18 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %10 +%tint_return_value = OpVariable %_ptr_Function_int Function %13 + %15 = OpIEqual %bool %rhs %13 + %17 = OpIEqual %bool %lhs %int_n2147483648 + %19 = OpIEqual %bool %rhs %int_n1 + %20 = OpLogicalAnd %bool %17 %19 + %21 = OpLogicalOr %bool %15 %20 + %14 = OpSelect %int %21 %int_1 %rhs + %26 = OpBitwiseOr %int %lhs %14 + %24 = OpBitcast %uint %26 + %28 = OpBitwiseAnd %uint %24 %uint_2147483648 + %30 = OpINotEqual %bool %28 %29 + OpSelectionMerge %31 None + OpBranchConditional %30 %32 %33 + %32 = OpLabel + OpStore %tint_return_flag %true + %35 = OpSDiv %int %lhs %14 + %36 = OpIMul %int %35 %14 + %37 = OpISub %int %lhs %36 + OpStore %tint_return_value %37 + OpBranch %31 + %33 = OpLabel + OpStore %tint_return_flag %true + %38 = OpSRem %int %lhs %14 + OpStore %tint_return_value %38 + OpBranch %31 + %31 = OpLabel + %39 = OpLoad %int %tint_return_value + OpReturnValue %39 OpFunctionEnd - %f = OpFunction %void None %19 - %22 = OpLabel - %a = OpVariable %_ptr_Function_int Function %8 - %b = OpVariable %_ptr_Function_int Function %8 + %f = OpFunction %void None %40 + %43 = OpLabel + %a = OpVariable %_ptr_Function_int Function %13 + %b = OpVariable %_ptr_Function_int Function %13 OpStore %a %int_1 - OpStore %b %8 - %27 = OpLoad %int %a - %28 = OpLoad %int %b - %29 = OpLoad %int %b - %30 = OpIAdd %int %28 %29 - %26 = OpFunctionCall %int %tint_mod %27 %30 + OpStore %b %13 + %47 = OpLoad %int %a + %48 = OpLoad %int %b + %49 = OpLoad %int %b + %50 = OpIAdd %int %48 %49 + %46 = OpFunctionCall %int %tint_mod %47 %50 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl index 7186ef9aa6..9c23d5f6ae 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl index 7186ef9aa6..9c23d5f6ae 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl index e2aa4af88a..0a57a091fa 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(int lhs, ivec3 rhs) { ivec3 l = ivec3(lhs); - return (l % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((l | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl index 2a01a507c1..d18c7c05d5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int lhs, int3 rhs) { int3 const l = int3(lhs); - return (l % select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((l | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(l) - as_type(as_type((as_type((l / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (l % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm index d1c773263f..18b6fdd61c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 42 +; Bound: 64 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,53 +10,85 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %int %v3int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %32 = OpConstantNull %int + %55 = OpConstantNull %int %int_2 = OpConstant %int 2 - %34 = OpConstantComposite %v3int %32 %int_2 %32 -%_ptr_Function_v3int = OpTypePointer Function %v3int + %57 = OpConstantComposite %v3int %55 %int_2 %55 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %lhs %lhs %lhs - %11 = OpIEqual %v3bool %rhs %10 - %16 = OpIEqual %v3bool %8 %15 - %19 = OpIEqual %v3bool %rhs %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %rhs - %24 = OpSRem %v3int %8 %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %lhs %lhs %lhs + %17 = OpIEqual %v3bool %rhs %14 + %21 = OpIEqual %v3bool %15 %20 + %24 = OpIEqual %v3bool %rhs %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %rhs + %33 = OpBitwiseOr %v3int %15 %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %15 %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %15 %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %15 %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %a = OpVariable %_ptr_Function_int Function %32 - %b = OpVariable %_ptr_Function_v3int Function %10 + %f = OpFunction %void None %48 + %51 = OpLabel + %a = OpVariable %_ptr_Function_int Function %55 + %b = OpVariable %_ptr_Function_v3int Function %14 OpStore %a %int_4 - OpStore %b %34 - %38 = OpLoad %int %a - %39 = OpLoad %v3int %b - %40 = OpLoad %v3int %b - %41 = OpIAdd %v3int %39 %40 - %37 = OpFunctionCall %v3int %tint_mod %38 %41 + OpStore %b %57 + %60 = OpLoad %int %a + %61 = OpLoad %v3int %b + %62 = OpLoad %v3int %b + %63 = OpIAdd %v3int %61 %62 + %59 = OpFunctionCall %v3int %tint_mod %60 %63 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 8eebf875fa..91f50c2abe 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 8eebf875fa..91f50c2abe 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl index 8d0fbcc9d7..1b929ace4e 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(ivec3 lhs, int rhs) { ivec3 r = ivec3(rhs); - return (lhs % mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl index ccd2c1e384..984ae600e0 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int rhs) { int3 const r = int3(rhs); - return (lhs % select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1)))))); + int3 const rhs_or_one = select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm index cdc8bfca69..80e55aeb82 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 42 +; Bound: 64 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,53 +10,85 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %34 = OpConstantNull %int + %54 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %56 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %rhs %rhs %rhs - %11 = OpIEqual %v3bool %8 %10 - %16 = OpIEqual %v3bool %lhs %15 - %19 = OpIEqual %v3bool %8 %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %8 - %24 = OpSRem %v3int %lhs %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %rhs %rhs %rhs + %17 = OpIEqual %v3bool %15 %14 + %21 = OpIEqual %v3bool %lhs %20 + %24 = OpIEqual %v3bool %15 %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %15 + %33 = OpBitwiseOr %v3int %lhs %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %lhs %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %lhs %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %lhs %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %10 - %b = OpVariable %_ptr_Function_int Function %34 - OpStore %a %31 - OpStore %b %34 - %38 = OpLoad %v3int %a - %39 = OpLoad %int %b - %40 = OpLoad %int %b - %41 = OpIAdd %int %39 %40 - %37 = OpFunctionCall %v3int %tint_mod %38 %41 + %f = OpFunction %void None %48 + %51 = OpLabel + %a = OpVariable %_ptr_Function_v3int Function %14 + %b = OpVariable %_ptr_Function_int Function %56 + OpStore %a %54 + OpStore %b %56 + %60 = OpLoad %v3int %a + %61 = OpLoad %int %b + %62 = OpLoad %int %b + %63 = OpIAdd %int %61 %62 + %59 = OpFunctionCall %v3int %tint_mod %60 %63 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl index 6b63195902..d68cef6740 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl index 6b63195902..d68cef6740 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl index fab324117c..533cb4f834 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es ivec3 tint_mod(ivec3 lhs, ivec3 rhs) { - return (lhs % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl index 46862681b3..4ef0a4aa01 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm index fad367d31e..1c69618b6b 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 42 +; Bound: 64 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,53 +10,85 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %v3int - %9 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %19 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %22 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %34 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %36 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %24 = OpTypeFunction %void + %47 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %33 = OpConstantNull %int + %53 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %55 = OpConstantNull %int %int_5 = OpConstant %int 5 - %35 = OpConstantComposite %v3int %33 %int_5 %33 + %57 = OpConstantComposite %v3int %55 %int_5 %55 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %10 = OpIEqual %v3bool %rhs %9 - %15 = OpIEqual %v3bool %lhs %14 - %18 = OpIEqual %v3bool %rhs %17 - %19 = OpLogicalAnd %v3bool %15 %18 - %20 = OpLogicalOr %v3bool %10 %19 - %8 = OpSelect %v3int %20 %22 %rhs - %23 = OpSRem %v3int %lhs %8 - OpReturnValue %23 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %16 = OpIEqual %v3bool %rhs %14 + %20 = OpIEqual %v3bool %lhs %19 + %23 = OpIEqual %v3bool %rhs %22 + %24 = OpLogicalAnd %v3bool %20 %23 + %25 = OpLogicalOr %v3bool %16 %24 + %15 = OpSelect %v3int %25 %27 %rhs + %32 = OpBitwiseOr %v3int %lhs %15 + %29 = OpBitcast %v3uint %32 + %35 = OpBitwiseAnd %v3uint %29 %34 + %37 = OpINotEqual %v3bool %35 %36 + %28 = OpAny %bool %37 + OpSelectionMerge %38 None + OpBranchConditional %28 %39 %40 + %39 = OpLabel + OpStore %tint_return_flag %true + %42 = OpSDiv %v3int %lhs %15 + %43 = OpIMul %v3int %42 %15 + %44 = OpISub %v3int %lhs %43 + OpStore %tint_return_value %44 + OpBranch %38 + %40 = OpLabel + OpStore %tint_return_flag %true + %45 = OpSRem %v3int %lhs %15 + OpStore %tint_return_value %45 + OpBranch %38 + %38 = OpLabel + %46 = OpLoad %v3int %tint_return_value + OpReturnValue %46 OpFunctionEnd - %f = OpFunction %void None %24 - %27 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %9 - OpStore %a %30 - OpStore %b %35 - %38 = OpLoad %v3int %a - %39 = OpLoad %v3int %b - %40 = OpLoad %v3int %b - %41 = OpIAdd %v3int %39 %40 - %37 = OpFunctionCall %v3int %tint_mod %38 %41 + %f = OpFunction %void None %47 + %50 = OpLabel + %a = OpVariable %_ptr_Function_v3int Function %14 + %b = OpVariable %_ptr_Function_v3int Function %14 + OpStore %a %53 + OpStore %b %57 + %60 = OpLoad %v3int %a + %61 = OpLoad %v3int %b + %62 = OpLoad %v3int %b + %63 = OpIAdd %v3int %61 %62 + %59 = OpFunctionCall %v3int %tint_mod %60 %63 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl index dcafd63729..3972cffb57 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl index dcafd63729..3972cffb57 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl index ddb6a6b810..b2f5da8a54 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl index 56de74d16b..0dcf578aed 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm index 7d444d39f7..deb7e72b17 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 29 +; Bound: 49 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,40 +10,69 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %1 = OpTypeFunction %int %int %int - %8 = OpConstantNull %int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %10 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %13 = OpConstantNull %int %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %29 = OpConstantNull %uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %19 = OpTypeFunction %void -%_ptr_Function_int = OpTypePointer Function %int + %40 = OpTypeFunction %void %tint_mod = OpFunction %int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %int %6 = OpLabel - %9 = OpIEqual %bool %rhs %8 - %12 = OpIEqual %bool %lhs %int_n2147483648 - %14 = OpIEqual %bool %rhs %int_n1 - %15 = OpLogicalAnd %bool %12 %14 - %16 = OpLogicalOr %bool %9 %15 - %7 = OpSelect %int %16 %int_1 %rhs - %18 = OpSRem %int %lhs %7 - OpReturnValue %18 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %10 +%tint_return_value = OpVariable %_ptr_Function_int Function %13 + %15 = OpIEqual %bool %rhs %13 + %17 = OpIEqual %bool %lhs %int_n2147483648 + %19 = OpIEqual %bool %rhs %int_n1 + %20 = OpLogicalAnd %bool %17 %19 + %21 = OpLogicalOr %bool %15 %20 + %14 = OpSelect %int %21 %int_1 %rhs + %26 = OpBitwiseOr %int %lhs %14 + %24 = OpBitcast %uint %26 + %28 = OpBitwiseAnd %uint %24 %uint_2147483648 + %30 = OpINotEqual %bool %28 %29 + OpSelectionMerge %31 None + OpBranchConditional %30 %32 %33 + %32 = OpLabel + OpStore %tint_return_flag %true + %35 = OpSDiv %int %lhs %14 + %36 = OpIMul %int %35 %14 + %37 = OpISub %int %lhs %36 + OpStore %tint_return_value %37 + OpBranch %31 + %33 = OpLabel + OpStore %tint_return_flag %true + %38 = OpSRem %int %lhs %14 + OpStore %tint_return_value %38 + OpBranch %31 + %31 = OpLabel + %39 = OpLoad %int %tint_return_value + OpReturnValue %39 OpFunctionEnd - %f = OpFunction %void None %19 - %22 = OpLabel - %a = OpVariable %_ptr_Function_int Function %8 - %b = OpVariable %_ptr_Function_int Function %8 + %f = OpFunction %void None %40 + %43 = OpLabel + %a = OpVariable %_ptr_Function_int Function %13 + %b = OpVariable %_ptr_Function_int Function %13 OpStore %a %int_1 - OpStore %b %8 - %27 = OpLoad %int %a - %28 = OpLoad %int %b - %26 = OpFunctionCall %int %tint_mod %27 %28 + OpStore %b %13 + %47 = OpLoad %int %a + %48 = OpLoad %int %b + %46 = OpFunctionCall %int %tint_mod %47 %48 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl index 4c97839e39..73eb99aefd 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl index 4c97839e39..73eb99aefd 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int lhs, int3 rhs) { const int3 l = int3((lhs).xxx); - return (l % (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((l | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl index 412aedf276..14f1a4ec32 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(int lhs, ivec3 rhs) { ivec3 l = ivec3(lhs); - return (l % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(l, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((l | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (l - ((l / rhs_or_one) * rhs_or_one)); + } else { + return (l % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl index 143e92e409..90a14f7406 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int lhs, int3 rhs) { int3 const l = int3(lhs); - return (l % select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((l == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((l | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(l) - as_type(as_type((as_type((l / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (l % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm index 402ae071ea..b386e2b989 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 40 +; Bound: 62 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,51 +10,83 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %int %v3int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %32 = OpConstantNull %int + %55 = OpConstantNull %int %int_2 = OpConstant %int 2 - %34 = OpConstantComposite %v3int %32 %int_2 %32 -%_ptr_Function_v3int = OpTypePointer Function %v3int + %57 = OpConstantComposite %v3int %55 %int_2 %55 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %lhs %lhs %lhs - %11 = OpIEqual %v3bool %rhs %10 - %16 = OpIEqual %v3bool %8 %15 - %19 = OpIEqual %v3bool %rhs %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %rhs - %24 = OpSRem %v3int %8 %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %lhs %lhs %lhs + %17 = OpIEqual %v3bool %rhs %14 + %21 = OpIEqual %v3bool %15 %20 + %24 = OpIEqual %v3bool %rhs %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %rhs + %33 = OpBitwiseOr %v3int %15 %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %15 %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %15 %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %15 %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %a = OpVariable %_ptr_Function_int Function %32 - %b = OpVariable %_ptr_Function_v3int Function %10 + %f = OpFunction %void None %48 + %51 = OpLabel + %a = OpVariable %_ptr_Function_int Function %55 + %b = OpVariable %_ptr_Function_v3int Function %14 OpStore %a %int_4 - OpStore %b %34 - %38 = OpLoad %int %a - %39 = OpLoad %v3int %b - %37 = OpFunctionCall %v3int %tint_mod %38 %39 + OpStore %b %57 + %60 = OpLoad %int %a + %61 = OpLoad %v3int %b + %59 = OpFunctionCall %v3int %tint_mod %60 %61 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl index fc3af835ea..7985138ee7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl index fc3af835ea..7985138ee7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,6 +1,11 @@ int3 tint_mod(int3 lhs, int rhs) { const int3 r = int3((rhs).xxx); - return (lhs % (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); + const int3 rhs_or_one = (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl index 788c7fee9c..579b7559c2 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl @@ -2,7 +2,12 @@ ivec3 tint_mod(ivec3 lhs, int rhs) { ivec3 r = ivec3(rhs); - return (lhs % mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(r, ivec3(1), bvec3(uvec3(equal(r, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(r, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl index e84bf2fb88..b3041b703e 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl @@ -3,7 +3,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int rhs) { int3 const r = int3(rhs); - return (lhs % select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1)))))); + int3 const rhs_or_one = select(r, int3(1), ((r == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (r == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm index ff197fa0e5..3e128f9068 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 40 +; Bound: 62 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,51 +10,83 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %int - %10 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %20 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %23 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %35 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %37 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %25 = OpTypeFunction %void + %48 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %34 = OpConstantNull %int + %54 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %56 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %int %7 = OpLabel - %8 = OpCompositeConstruct %v3int %rhs %rhs %rhs - %11 = OpIEqual %v3bool %8 %10 - %16 = OpIEqual %v3bool %lhs %15 - %19 = OpIEqual %v3bool %8 %18 - %20 = OpLogicalAnd %v3bool %16 %19 - %21 = OpLogicalOr %v3bool %11 %20 - %9 = OpSelect %v3int %21 %23 %8 - %24 = OpSRem %v3int %lhs %9 - OpReturnValue %24 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %15 = OpCompositeConstruct %v3int %rhs %rhs %rhs + %17 = OpIEqual %v3bool %15 %14 + %21 = OpIEqual %v3bool %lhs %20 + %24 = OpIEqual %v3bool %15 %23 + %25 = OpLogicalAnd %v3bool %21 %24 + %26 = OpLogicalOr %v3bool %17 %25 + %16 = OpSelect %v3int %26 %28 %15 + %33 = OpBitwiseOr %v3int %lhs %16 + %30 = OpBitcast %v3uint %33 + %36 = OpBitwiseAnd %v3uint %30 %35 + %38 = OpINotEqual %v3bool %36 %37 + %29 = OpAny %bool %38 + OpSelectionMerge %39 None + OpBranchConditional %29 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %v3int %lhs %16 + %44 = OpIMul %v3int %43 %16 + %45 = OpISub %v3int %lhs %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %v3int %lhs %16 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %v3int %tint_return_value + OpReturnValue %47 OpFunctionEnd - %f = OpFunction %void None %25 - %28 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %10 - %b = OpVariable %_ptr_Function_int Function %34 - OpStore %a %31 - OpStore %b %34 - %38 = OpLoad %v3int %a - %39 = OpLoad %int %b - %37 = OpFunctionCall %v3int %tint_mod %38 %39 + %f = OpFunction %void None %48 + %51 = OpLabel + %a = OpVariable %_ptr_Function_v3int Function %14 + %b = OpVariable %_ptr_Function_int Function %56 + OpStore %a %54 + OpStore %b %56 + %60 = OpLoad %v3int %a + %61 = OpLoad %int %b + %59 = OpFunctionCall %v3int %tint_mod %60 %61 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl index 6369536021..669e78ce7d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl index 6369536021..669e78ce7d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,5 +1,10 @@ int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); + const int3 rhs_or_one = (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs); + if (any(((uint3((lhs | rhs_or_one)) & (2147483648u).xxx) != (0u).xxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } [numthreads(1, 1, 1)] diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl index e1da39494e..c24178a1a0 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl @@ -1,7 +1,12 @@ #version 310 es ivec3 tint_mod(ivec3 lhs, ivec3 rhs) { - return (lhs % mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1)))))))); + ivec3 rhs_or_one = mix(rhs, ivec3(1), bvec3(uvec3(equal(rhs, ivec3(0))) | uvec3(bvec3(uvec3(equal(lhs, ivec3(-2147483648))) & uvec3(equal(rhs, ivec3(-1))))))); + if (any(notEqual((uvec3((lhs | rhs_or_one)) & uvec3(2147483648u)), uvec3(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl index 847e9f6adb..165c7f28bf 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl @@ -2,7 +2,12 @@ using namespace metal; int3 tint_mod(int3 lhs, int3 rhs) { - return (lhs % select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); + int3 const rhs_or_one = select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1))))); + if (any(((uint3((lhs | rhs_or_one)) & uint3(2147483648u)) != uint3(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } kernel void f() { diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm index e7b09d1839..ebca6fa80b 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 40 +; Bound: 62 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,51 +10,83 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %f "f" OpName %a "a" OpName %b "b" %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 %1 = OpTypeFunction %v3int %v3int %v3int - %9 = OpConstantNull %v3int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %11 = OpConstantNull %bool +%_ptr_Function_v3int = OpTypePointer Function %v3int + %14 = OpConstantNull %v3int %v3bool = OpTypeVector %bool 3 %int_n2147483648 = OpConstant %int -2147483648 - %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %19 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %22 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%uint_2147483648 = OpConstant %uint 2147483648 + %34 = OpConstantComposite %v3uint %uint_2147483648 %uint_2147483648 %uint_2147483648 + %36 = OpConstantNull %v3uint + %true = OpConstantTrue %bool %void = OpTypeVoid - %24 = OpTypeFunction %void + %47 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %33 = OpConstantNull %int + %53 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %55 = OpConstantNull %int %int_5 = OpConstant %int 5 - %35 = OpConstantComposite %v3int %33 %int_5 %33 + %57 = OpConstantComposite %v3int %55 %int_5 %55 %tint_mod = OpFunction %v3int None %1 %lhs = OpFunctionParameter %v3int %rhs = OpFunctionParameter %v3int %7 = OpLabel - %10 = OpIEqual %v3bool %rhs %9 - %15 = OpIEqual %v3bool %lhs %14 - %18 = OpIEqual %v3bool %rhs %17 - %19 = OpLogicalAnd %v3bool %15 %18 - %20 = OpLogicalOr %v3bool %10 %19 - %8 = OpSelect %v3int %20 %22 %rhs - %23 = OpSRem %v3int %lhs %8 - OpReturnValue %23 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %11 +%tint_return_value = OpVariable %_ptr_Function_v3int Function %14 + %16 = OpIEqual %v3bool %rhs %14 + %20 = OpIEqual %v3bool %lhs %19 + %23 = OpIEqual %v3bool %rhs %22 + %24 = OpLogicalAnd %v3bool %20 %23 + %25 = OpLogicalOr %v3bool %16 %24 + %15 = OpSelect %v3int %25 %27 %rhs + %32 = OpBitwiseOr %v3int %lhs %15 + %29 = OpBitcast %v3uint %32 + %35 = OpBitwiseAnd %v3uint %29 %34 + %37 = OpINotEqual %v3bool %35 %36 + %28 = OpAny %bool %37 + OpSelectionMerge %38 None + OpBranchConditional %28 %39 %40 + %39 = OpLabel + OpStore %tint_return_flag %true + %42 = OpSDiv %v3int %lhs %15 + %43 = OpIMul %v3int %42 %15 + %44 = OpISub %v3int %lhs %43 + OpStore %tint_return_value %44 + OpBranch %38 + %40 = OpLabel + OpStore %tint_return_flag %true + %45 = OpSRem %v3int %lhs %15 + OpStore %tint_return_value %45 + OpBranch %38 + %38 = OpLabel + %46 = OpLoad %v3int %tint_return_value + OpReturnValue %46 OpFunctionEnd - %f = OpFunction %void None %24 - %27 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %9 - OpStore %a %30 - OpStore %b %35 - %38 = OpLoad %v3int %a - %39 = OpLoad %v3int %b - %37 = OpFunctionCall %v3int %tint_mod %38 %39 + %f = OpFunction %void None %47 + %50 = OpLabel + %a = OpVariable %_ptr_Function_v3int Function %14 + %b = OpVariable %_ptr_Function_v3int Function %14 + OpStore %a %53 + OpStore %b %57 + %60 = OpLoad %v3int %a + %61 = OpLoad %v3int %b + %59 = OpFunctionCall %v3int %tint_mod %60 %61 OpReturn OpFunctionEnd 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 e1f2af52c9..ab7448db45 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 @@ -11,7 +11,12 @@ int tint_div(int lhs, int rhs) { } int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo(int maybe_zero) { diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl index e1f2af52c9..ab7448db45 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 @@ -11,7 +11,12 @@ int tint_div(int lhs, int rhs) { } int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo(int maybe_zero) { diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.glsl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.glsl index 61509234e0..4fdb12838f 100644 --- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.glsl @@ -16,7 +16,12 @@ int tint_div(int lhs, int rhs) { } int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo(int maybe_zero) { diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl index 0a9040112f..36a30d4c6f 100644 --- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl @@ -6,7 +6,12 @@ int tint_div(int lhs, int rhs) { } int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } void foo(int maybe_zero) { diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.spvasm b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.spvasm index 9393c9ad0a..6764152fa7 100644 --- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 62 +; Bound: 83 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -16,6 +16,8 @@ OpName %tint_mod "tint_mod" OpName %lhs_0 "lhs" OpName %rhs_0 "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %foo "foo" OpName %maybe_zero "maybe_zero" %int = OpTypeInt 32 1 @@ -33,7 +35,14 @@ %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 - %40 = OpTypeFunction %void %int +%_ptr_Function_bool = OpTypePointer Function %bool + %35 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %50 = OpConstantNull %uint + %true = OpConstantTrue %bool + %61 = OpTypeFunction %void %int %unused_entry_point = OpFunction %void None %9 %12 = OpLabel OpReturn @@ -55,43 +64,64 @@ %lhs_0 = OpFunctionParameter %int %rhs_0 = OpFunctionParameter %int %32 = OpLabel - %34 = OpIEqual %bool %rhs_0 %4 - %35 = OpIEqual %bool %lhs_0 %int_n2147483648 - %36 = OpIEqual %bool %rhs_0 %int_n1 - %37 = OpLogicalAnd %bool %35 %36 - %38 = OpLogicalOr %bool %34 %37 - %33 = OpSelect %int %38 %int_1 %rhs_0 - %39 = OpSRem %int %lhs_0 %33 - OpReturnValue %39 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %35 +%tint_return_value = OpVariable %_ptr_Function_int Function %4 + %39 = OpIEqual %bool %rhs_0 %4 + %40 = OpIEqual %bool %lhs_0 %int_n2147483648 + %41 = OpIEqual %bool %rhs_0 %int_n1 + %42 = OpLogicalAnd %bool %40 %41 + %43 = OpLogicalOr %bool %39 %42 + %38 = OpSelect %int %43 %int_1 %rhs_0 + %47 = OpBitwiseOr %int %lhs_0 %38 + %45 = OpBitcast %uint %47 + %49 = OpBitwiseAnd %uint %45 %uint_2147483648 + %51 = OpINotEqual %bool %49 %50 + OpSelectionMerge %52 None + OpBranchConditional %51 %53 %54 + %53 = OpLabel + OpStore %tint_return_flag %true + %56 = OpSDiv %int %lhs_0 %38 + %57 = OpIMul %int %56 %38 + %58 = OpISub %int %lhs_0 %57 + OpStore %tint_return_value %58 + OpBranch %52 + %54 = OpLabel + OpStore %tint_return_flag %true + %59 = OpSRem %int %lhs_0 %38 + OpStore %tint_return_value %59 + OpBranch %52 + %52 = OpLabel + %60 = OpLoad %int %tint_return_value + OpReturnValue %60 OpFunctionEnd - %foo = OpFunction %void None %40 + %foo = OpFunction %void None %61 %maybe_zero = OpFunctionParameter %int - %43 = OpLabel - %45 = OpLoad %int %a - %44 = OpFunctionCall %int %tint_div %45 %4 - OpStore %a %44 - %47 = OpLoad %int %a - %46 = OpFunctionCall %int %tint_mod %47 %4 - OpStore %a %46 - %49 = OpLoad %int %a - %48 = OpFunctionCall %int %tint_div %49 %maybe_zero - OpStore %a %48 - %51 = OpLoad %int %a - %50 = OpFunctionCall %int %tint_mod %51 %maybe_zero - OpStore %a %50 - %52 = OpLoad %float %b - %53 = OpFDiv %float %52 %8 - OpStore %b %53 - %54 = OpLoad %float %b - %55 = OpFRem %float %54 %8 - OpStore %b %55 - %56 = OpLoad %float %b - %57 = OpConvertSToF %float %maybe_zero - %58 = OpFDiv %float %56 %57 - OpStore %b %58 - %59 = OpLoad %float %b - %60 = OpConvertSToF %float %maybe_zero - %61 = OpFRem %float %59 %60 - OpStore %b %61 + %64 = OpLabel + %66 = OpLoad %int %a + %65 = OpFunctionCall %int %tint_div %66 %4 + OpStore %a %65 + %68 = OpLoad %int %a + %67 = OpFunctionCall %int %tint_mod %68 %4 + OpStore %a %67 + %70 = OpLoad %int %a + %69 = OpFunctionCall %int %tint_div %70 %maybe_zero + OpStore %a %69 + %72 = OpLoad %int %a + %71 = OpFunctionCall %int %tint_mod %72 %maybe_zero + OpStore %a %71 + %73 = OpLoad %float %b + %74 = OpFDiv %float %73 %8 + OpStore %b %74 + %75 = OpLoad %float %b + %76 = OpFRem %float %75 %8 + OpStore %b %76 + %77 = OpLoad %float %b + %78 = OpConvertSToF %float %maybe_zero + %79 = OpFDiv %float %77 %78 + OpStore %b %79 + %80 = OpLoad %float %b + %81 = OpConvertSToF %float %maybe_zero + %82 = OpFRem %float %80 %81 + OpStore %b %82 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.dxc.hlsl index f7bac0aedd..40a04199e4 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.dxc.hlsl @@ -6,7 +6,12 @@ void unused_entry_point() { RWByteAddressBuffer v : register(u0, space0); int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.fxc.hlsl index f7bac0aedd..40a04199e4 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.fxc.hlsl @@ -6,7 +6,12 @@ void unused_entry_point() { RWByteAddressBuffer v : register(u0, space0); int tint_mod(int lhs, int rhs) { - return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); + const int rhs_or_one = (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl index f84aaf67a9..1b27070db0 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl @@ -13,7 +13,12 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; int tint_mod(int lhs, int rhs) { - return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); + int rhs_or_one = (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs); + if (((uint((lhs | rhs_or_one)) & 2147483648u) != 0u)) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl index e8cc90c3c4..42772eec7a 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl @@ -6,7 +6,12 @@ struct S { }; int tint_mod(int lhs, int rhs) { - return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); + int const rhs_or_one = select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1)))); + if (any(((uint((lhs | rhs_or_one)) & 2147483648u) != 0u))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } void foo(device S* const tint_symbol_1) { diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.spvasm b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.spvasm index ab4da25163..5df8f971b8 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 37 +; Bound: 57 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -16,6 +16,8 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -30,12 +32,18 @@ %void = OpTypeVoid %6 = OpTypeFunction %void %10 = OpTypeFunction %int %int %int - %16 = OpConstantNull %int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %18 = OpConstantNull %bool +%_ptr_Function_int = OpTypePointer Function %int + %21 = OpConstantNull %int %int_n2147483648 = OpConstant %int -2147483648 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 %uint = OpTypeInt 32 0 +%uint_2147483648 = OpConstant %uint 2147483648 + %37 = OpConstantNull %uint + %true = OpConstantTrue %bool %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int %int_2 = OpConstant %int 2 @@ -47,21 +55,42 @@ %lhs = OpFunctionParameter %int %rhs = OpFunctionParameter %int %14 = OpLabel - %17 = OpIEqual %bool %rhs %16 - %20 = OpIEqual %bool %lhs %int_n2147483648 - %22 = OpIEqual %bool %rhs %int_n1 - %23 = OpLogicalAnd %bool %20 %22 - %24 = OpLogicalOr %bool %17 %23 - %15 = OpSelect %int %24 %int_1 %rhs - %26 = OpSRem %int %lhs %15 - OpReturnValue %26 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %18 +%tint_return_value = OpVariable %_ptr_Function_int Function %21 + %23 = OpIEqual %bool %rhs %21 + %25 = OpIEqual %bool %lhs %int_n2147483648 + %27 = OpIEqual %bool %rhs %int_n1 + %28 = OpLogicalAnd %bool %25 %27 + %29 = OpLogicalOr %bool %23 %28 + %22 = OpSelect %int %29 %int_1 %rhs + %34 = OpBitwiseOr %int %lhs %22 + %32 = OpBitcast %uint %34 + %36 = OpBitwiseAnd %uint %32 %uint_2147483648 + %38 = OpINotEqual %bool %36 %37 + OpSelectionMerge %39 None + OpBranchConditional %38 %40 %41 + %40 = OpLabel + OpStore %tint_return_flag %true + %43 = OpSDiv %int %lhs %22 + %44 = OpIMul %int %43 %22 + %45 = OpISub %int %lhs %44 + OpStore %tint_return_value %45 + OpBranch %39 + %41 = OpLabel + OpStore %tint_return_flag %true + %46 = OpSRem %int %lhs %22 + OpStore %tint_return_value %46 + OpBranch %39 + %39 = OpLabel + %47 = OpLoad %int %tint_return_value + OpReturnValue %47 OpFunctionEnd %foo = OpFunction %void None %6 - %28 = OpLabel - %33 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - %34 = OpLoad %int %33 - %29 = OpFunctionCall %int %tint_mod %34 %int_2 - %36 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - OpStore %36 %29 + %49 = OpLabel + %53 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 + %54 = OpLoad %int %53 + %50 = OpFunctionCall %int %tint_mod %54 %int_2 + %56 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 + OpStore %56 %50 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.dxc.hlsl index a6095f4453..ea807538e4 100644 --- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.dxc.hlsl @@ -7,7 +7,12 @@ RWByteAddressBuffer v : register(u0, space0); int4 tint_mod(int4 lhs, int rhs) { const int4 r = int4((rhs).xxxx); - return (lhs % (((r == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (r == (-1).xxxx))) ? (1).xxxx : r)); + const int4 rhs_or_one = (((r == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (r == (-1).xxxx))) ? (1).xxxx : r); + if (any(((uint4((lhs | rhs_or_one)) & (2147483648u).xxxx) != (0u).xxxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.fxc.hlsl index a6095f4453..ea807538e4 100644 --- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.fxc.hlsl @@ -7,7 +7,12 @@ RWByteAddressBuffer v : register(u0, space0); int4 tint_mod(int4 lhs, int rhs) { const int4 r = int4((rhs).xxxx); - return (lhs % (((r == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (r == (-1).xxxx))) ? (1).xxxx : r)); + const int4 rhs_or_one = (((r == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (r == (-1).xxxx))) ? (1).xxxx : r); + if (any(((uint4((lhs | rhs_or_one)) & (2147483648u).xxxx) != (0u).xxxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.glsl b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.glsl index 5609858b2b..b650cfb145 100644 --- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.glsl @@ -14,7 +14,12 @@ layout(binding = 0, std430) buffer v_block_ssbo { ivec4 tint_mod(ivec4 lhs, int rhs) { ivec4 r = ivec4(rhs); - return (lhs % mix(r, ivec4(1), bvec4(uvec4(equal(r, ivec4(0))) | uvec4(bvec4(uvec4(equal(lhs, ivec4(-2147483648))) & uvec4(equal(r, ivec4(-1)))))))); + ivec4 rhs_or_one = mix(r, ivec4(1), bvec4(uvec4(equal(r, ivec4(0))) | uvec4(bvec4(uvec4(equal(lhs, ivec4(-2147483648))) & uvec4(equal(r, ivec4(-1))))))); + if (any(notEqual((uvec4((lhs | rhs_or_one)) & uvec4(2147483648u)), uvec4(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl index 7a065fd5cf..e0a82ebd81 100644 --- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl @@ -7,7 +7,12 @@ struct S { int4 tint_mod(int4 lhs, int rhs) { int4 const r = int4(rhs); - return (lhs % select(r, int4(1), ((r == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (r == int4(-1)))))); + int4 const rhs_or_one = select(r, int4(1), ((r == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (r == int4(-1))))); + if (any(((uint4((lhs | rhs_or_one)) & uint4(2147483648u)) != uint4(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } void foo(device S* const tint_symbol_1) { diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.spvasm b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.spvasm index da13a297e8..52b59dde7b 100644 --- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 43 +; Bound: 65 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -16,6 +16,8 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -31,16 +33,24 @@ %void = OpTypeVoid %7 = OpTypeFunction %void %11 = OpTypeFunction %v4int %v4int %int - %18 = OpConstantNull %v4int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %19 = OpConstantNull %bool +%_ptr_Function_v4int = OpTypePointer Function %v4int + %22 = OpConstantNull %v4int %v4bool = OpTypeVector %bool 4 %int_n2147483648 = OpConstant %int -2147483648 - %23 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648 + %28 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %26 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1 + %31 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %31 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 + %36 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 +%uint_2147483648 = OpConstant %uint 2147483648 + %43 = OpConstantComposite %v4uint %uint_2147483648 %uint_2147483648 %uint_2147483648 %uint_2147483648 + %45 = OpConstantNull %v4uint + %true = OpConstantTrue %bool %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int %int_2 = OpConstant %int 2 @@ -52,22 +62,44 @@ %lhs = OpFunctionParameter %v4int %rhs = OpFunctionParameter %int %15 = OpLabel - %16 = OpCompositeConstruct %v4int %rhs %rhs %rhs %rhs - %19 = OpIEqual %v4bool %16 %18 - %24 = OpIEqual %v4bool %lhs %23 - %27 = OpIEqual %v4bool %16 %26 - %28 = OpLogicalAnd %v4bool %24 %27 - %29 = OpLogicalOr %v4bool %19 %28 - %17 = OpSelect %v4int %29 %31 %16 - %32 = OpSRem %v4int %lhs %17 - OpReturnValue %32 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %19 +%tint_return_value = OpVariable %_ptr_Function_v4int Function %22 + %23 = OpCompositeConstruct %v4int %rhs %rhs %rhs %rhs + %25 = OpIEqual %v4bool %23 %22 + %29 = OpIEqual %v4bool %lhs %28 + %32 = OpIEqual %v4bool %23 %31 + %33 = OpLogicalAnd %v4bool %29 %32 + %34 = OpLogicalOr %v4bool %25 %33 + %24 = OpSelect %v4int %34 %36 %23 + %41 = OpBitwiseOr %v4int %lhs %24 + %38 = OpBitcast %v4uint %41 + %44 = OpBitwiseAnd %v4uint %38 %43 + %46 = OpINotEqual %v4bool %44 %45 + %37 = OpAny %bool %46 + OpSelectionMerge %47 None + OpBranchConditional %37 %48 %49 + %48 = OpLabel + OpStore %tint_return_flag %true + %51 = OpSDiv %v4int %lhs %24 + %52 = OpIMul %v4int %51 %24 + %53 = OpISub %v4int %lhs %52 + OpStore %tint_return_value %53 + OpBranch %47 + %49 = OpLabel + OpStore %tint_return_flag %true + %54 = OpSRem %v4int %lhs %24 + OpStore %tint_return_value %54 + OpBranch %47 + %47 = OpLabel + %55 = OpLoad %v4int %tint_return_value + OpReturnValue %55 OpFunctionEnd %foo = OpFunction %void None %7 - %34 = OpLabel - %39 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %40 = OpLoad %v4int %39 - %35 = OpFunctionCall %v4int %tint_mod %40 %int_2 - %42 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - OpStore %42 %35 + %57 = OpLabel + %61 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + %62 = OpLoad %v4int %61 + %58 = OpFunctionCall %v4int %tint_mod %62 %int_2 + %64 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + OpStore %64 %58 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.dxc.hlsl index 8a5eb1a9c5..051500d31f 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.dxc.hlsl @@ -6,7 +6,12 @@ void unused_entry_point() { RWByteAddressBuffer v : register(u0, space0); int4 tint_mod(int4 lhs, int4 rhs) { - return (lhs % (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); + const int4 rhs_or_one = (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs); + if (any(((uint4((lhs | rhs_or_one)) & (2147483648u).xxxx) != (0u).xxxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.fxc.hlsl index 8a5eb1a9c5..051500d31f 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.fxc.hlsl @@ -6,7 +6,12 @@ void unused_entry_point() { RWByteAddressBuffer v : register(u0, space0); int4 tint_mod(int4 lhs, int4 rhs) { - return (lhs % (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); + const int4 rhs_or_one = (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs); + if (any(((uint4((lhs | rhs_or_one)) & (2147483648u).xxxx) != (0u).xxxx))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl index 192c38d11a..b7ed4cce48 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl @@ -13,7 +13,12 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; ivec4 tint_mod(ivec4 lhs, ivec4 rhs) { - return (lhs % mix(rhs, ivec4(1), bvec4(uvec4(equal(rhs, ivec4(0))) | uvec4(bvec4(uvec4(equal(lhs, ivec4(-2147483648))) & uvec4(equal(rhs, ivec4(-1)))))))); + ivec4 rhs_or_one = mix(rhs, ivec4(1), bvec4(uvec4(equal(rhs, ivec4(0))) | uvec4(bvec4(uvec4(equal(lhs, ivec4(-2147483648))) & uvec4(equal(rhs, ivec4(-1))))))); + if (any(notEqual((uvec4((lhs | rhs_or_one)) & uvec4(2147483648u)), uvec4(0u)))) { + return (lhs - ((lhs / rhs_or_one) * rhs_or_one)); + } else { + return (lhs % rhs_or_one); + } } void foo() { diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl index cb90ef8c19..fc613339ac 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl @@ -6,7 +6,12 @@ struct S { }; int4 tint_mod(int4 lhs, int4 rhs) { - return (lhs % select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1)))))); + int4 const rhs_or_one = select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1))))); + if (any(((uint4((lhs | rhs_or_one)) & uint4(2147483648u)) != uint4(0u)))) { + return as_type((as_type(lhs) - as_type(as_type((as_type((lhs / rhs_or_one)) * as_type(rhs_or_one)))))); + } else { + return (lhs % rhs_or_one); + } } void foo(device S* const tint_symbol_1) { diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.spvasm b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.spvasm index 70e392143c..3ac6525e08 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 43 +; Bound: 65 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -16,6 +16,8 @@ OpName %tint_mod "tint_mod" OpName %lhs "lhs" OpName %rhs "rhs" + OpName %tint_return_flag "tint_return_flag" + OpName %tint_return_value "tint_return_value" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -31,20 +33,28 @@ %void = OpTypeVoid %7 = OpTypeFunction %void %11 = OpTypeFunction %v4int %v4int %v4int - %17 = OpConstantNull %v4int %bool = OpTypeBool +%_ptr_Function_bool = OpTypePointer Function %bool + %19 = OpConstantNull %bool +%_ptr_Function_v4int = OpTypePointer Function %v4int + %22 = OpConstantNull %v4int %v4bool = OpTypeVector %bool 4 %int_n2147483648 = OpConstant %int -2147483648 - %22 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648 + %27 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n1 = OpConstant %int -1 - %25 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1 + %30 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 - %30 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 + %35 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %uint = OpTypeInt 32 0 + %v4uint = OpTypeVector %uint 4 +%uint_2147483648 = OpConstant %uint 2147483648 + %42 = OpConstantComposite %v4uint %uint_2147483648 %uint_2147483648 %uint_2147483648 %uint_2147483648 + %44 = OpConstantNull %v4uint + %true = OpConstantTrue %bool %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int %int_2 = OpConstant %int 2 - %41 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 + %63 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 %unused_entry_point = OpFunction %void None %7 %10 = OpLabel OpReturn @@ -53,21 +63,43 @@ %lhs = OpFunctionParameter %v4int %rhs = OpFunctionParameter %v4int %15 = OpLabel - %18 = OpIEqual %v4bool %rhs %17 - %23 = OpIEqual %v4bool %lhs %22 - %26 = OpIEqual %v4bool %rhs %25 - %27 = OpLogicalAnd %v4bool %23 %26 - %28 = OpLogicalOr %v4bool %18 %27 - %16 = OpSelect %v4int %28 %30 %rhs - %31 = OpSRem %v4int %lhs %16 - OpReturnValue %31 +%tint_return_flag = OpVariable %_ptr_Function_bool Function %19 +%tint_return_value = OpVariable %_ptr_Function_v4int Function %22 + %24 = OpIEqual %v4bool %rhs %22 + %28 = OpIEqual %v4bool %lhs %27 + %31 = OpIEqual %v4bool %rhs %30 + %32 = OpLogicalAnd %v4bool %28 %31 + %33 = OpLogicalOr %v4bool %24 %32 + %23 = OpSelect %v4int %33 %35 %rhs + %40 = OpBitwiseOr %v4int %lhs %23 + %37 = OpBitcast %v4uint %40 + %43 = OpBitwiseAnd %v4uint %37 %42 + %45 = OpINotEqual %v4bool %43 %44 + %36 = OpAny %bool %45 + OpSelectionMerge %46 None + OpBranchConditional %36 %47 %48 + %47 = OpLabel + OpStore %tint_return_flag %true + %50 = OpSDiv %v4int %lhs %23 + %51 = OpIMul %v4int %50 %23 + %52 = OpISub %v4int %lhs %51 + OpStore %tint_return_value %52 + OpBranch %46 + %48 = OpLabel + OpStore %tint_return_flag %true + %53 = OpSRem %v4int %lhs %23 + OpStore %tint_return_value %53 + OpBranch %46 + %46 = OpLabel + %54 = OpLoad %v4int %tint_return_value + OpReturnValue %54 OpFunctionEnd %foo = OpFunction %void None %7 - %33 = OpLabel - %38 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %39 = OpLoad %v4int %38 - %34 = OpFunctionCall %v4int %tint_mod %39 %41 - %42 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - OpStore %42 %34 + %56 = OpLabel + %60 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + %61 = OpLoad %v4int %60 + %57 = OpFunctionCall %v4int %tint_mod %61 %63 + %64 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + OpStore %64 %57 OpReturn OpFunctionEnd diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt index 1f33c92a00..ae85de9e0e 100644 --- a/webgpu-cts/expectations.txt +++ b/webgpu-cts/expectations.txt @@ -407,18 +407,6 @@ crbug.com/dawn/0000 webgpu:api,validation,buffer,mapping:mapAsync,state,mappingP crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="2d" [ Failure ] crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="_undef_" [ Failure ] crbug.com/dawn/0000 webgpu:api,validation,encoding,encoder_state:pass_end_invalid_order:* [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize="_undef_" [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize=2 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize=3 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize=4 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_rw";vectorize="_undef_" [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_rw";vectorize=2 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_rw";vectorize=3 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_rw";vectorize=4 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="uniform";vectorize="_undef_" [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="uniform";vectorize=2 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="uniform";vectorize=3 [ Failure ] -crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="uniform";vectorize=4 [ Failure ] crbug.com/dawn/0000 [ monterey ] webgpu:web_platform,canvas,configure:alpha_mode:* [ Failure ] crbug.com/dawn/0000 [ monterey ] webgpu:web_platform,canvas,configure:defaults:* [ Failure ] crbug.com/dawn/0000 [ monterey ] webgpu:web_platform,canvas,configure:device:* [ Failure ]