diff --git a/src/tint/number.h b/src/tint/number.h index 0558c8f77a..c116ddf56f 100644 --- a/src/tint/number.h +++ b/src/tint/number.h @@ -124,6 +124,9 @@ struct Number : NumberBase> { /// type is the underlying type of the Number using type = T; + /// Number of bits in the number. + static constexpr size_t kNumBits = sizeof(T) * 8; + /// Highest finite representable value of this type. static constexpr type kHighestValue = std::numeric_limits::max(); @@ -187,6 +190,9 @@ struct Number : NumberBase> /// C++ does not have a native float16 type, so we use a 32-bit float instead. using type = float; + /// Number of bits in the number. + static constexpr size_t kNumBits = 16; + /// Highest finite representable value of this type. static constexpr type kHighestValue = 65504.0f; // 2¹⁵ × (1 + 1023/1024) diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index 2f5b5e0200..3d1f40e389 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -3267,6 +3267,14 @@ class ProgramBuilder { //! @cond Doxygen_Suppress // Various template specializations for ProgramBuilder::TypesBuilder::CToAST. template <> +struct ProgramBuilder::TypesBuilder::CToAST { + static const ast::Type* get(const ProgramBuilder::TypesBuilder*) { return nullptr; } +}; +template <> +struct ProgramBuilder::TypesBuilder::CToAST { + static const ast::Type* get(const ProgramBuilder::TypesBuilder*) { return nullptr; } +}; +template <> struct ProgramBuilder::TypesBuilder::CToAST { static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->i32(); } }; diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc index 17fcc20411..4dfc1495f0 100644 --- a/src/tint/transform/builtin_polyfill.cc +++ b/src/tint/transform/builtin_polyfill.cc @@ -14,6 +14,8 @@ #include "src/tint/transform/builtin_polyfill.h" +#include +#include #include #include @@ -29,6 +31,9 @@ TINT_INSTANTIATE_TYPEINFO(tint::transform::BuiltinPolyfill::Config); namespace tint::transform { +/// BinaryOpSignature is tuple of a binary op, LHS type and RHS type +using BinaryOpSignature = std::tuple; + /// PIMPL state for the transform struct BuiltinPolyfill::State { /// Constructor @@ -36,15 +41,6 @@ struct BuiltinPolyfill::State { /// @param p the builtins to polyfill State(CloneContext& c, Builtins p) : ctx(c), polyfill(p) {} - /// The clone context - CloneContext& ctx; - /// The builtins to polyfill - Builtins polyfill; - /// The destination program builder - ProgramBuilder& b = *ctx.dst; - /// The source clone context - const sem::Info& sem = ctx.src->Sem(); - /// Builds the polyfill function for the `acosh` builtin /// @param ty the parameter and return type for the function /// @return the polyfill function name @@ -563,6 +559,63 @@ struct BuiltinPolyfill::State { return name; } + /// Builds the polyfill function for a divide or modulo operator with integer scalar or vector + /// operands. + /// @param sig the signature of the binary operator + /// @return the polyfill function name + Symbol int_div_mod(const BinaryOpSignature& sig) { + const auto op = std::get<0>(sig); + const auto* lhs_ty = std::get<1>(sig); + const auto* rhs_ty = std::get<2>(sig); + const bool is_div = op == ast::BinaryOp::kDivide; + + uint32_t lhs_width = 1; + uint32_t rhs_width = 1; + const auto* lhs_el_ty = sem::Type::ElementOf(lhs_ty, &lhs_width); + const auto* rhs_el_ty = sem::Type::ElementOf(rhs_ty, &rhs_width); + + const uint32_t width = std::max(lhs_width, rhs_width); + + const char* lhs = "lhs"; + const char* rhs = "rhs"; + + utils::Vector body; + + if (lhs_width < width) { + // lhs is scalar, rhs is vector. Convert lhs to vector. + body.Push(b.Decl(b.Let("l", b.vec(T(lhs_el_ty), width, b.Expr(lhs))))); + lhs = "l"; + } + if (rhs_width < width) { + // lhs is vector, rhs is scalar. Convert rhs to vector. + body.Push(b.Decl(b.Let("r", b.vec(T(rhs_el_ty), width, b.Expr(rhs))))); + rhs = "r"; + } + + auto name = b.Symbols().New(is_div ? "tint_div" : "tint_mod"); + auto* use_one = b.Equal(rhs, ScalarOrVector(width, 0_a)); + if (lhs_ty->is_signed_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); + + 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)), + b.Param("rhs", T(rhs_ty)), + }, + width == 1 ? T(lhs_ty) : b.ty.vec(T(lhs_el_ty), width), // return type + std::move(body)); + + return name; + } + /// Builds the polyfill function for the `saturate` builtin /// @param ty the parameter and return type for the function /// @return the polyfill function name @@ -625,6 +678,15 @@ struct BuiltinPolyfill::State { } private: + /// The clone context + CloneContext& ctx; + /// The builtins to polyfill + Builtins polyfill; + /// The destination program builder + ProgramBuilder& b = *ctx.dst; + /// The source clone context + const sem::Info& sem = ctx.src->Sem(); + /// @returns the AST type for the given sem type const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); } @@ -659,13 +721,14 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src, return SkipTransform; } - auto& builtins = cfg->builtins; + auto& polyfill = cfg->builtins; utils::Hashmap builtin_polyfills; + utils::Hashmap binary_op_polyfills; ProgramBuilder b; CloneContext ctx{&b, src, /* auto_clone_symbols */ true}; - State s{ctx, builtins}; + State s{ctx, polyfill}; bool made_changes = false; for (auto* node : src->ASTNodes().Objects()) { @@ -679,84 +742,84 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src, if (!builtin) { continue; } - Symbol polyfill; + Symbol fn; switch (builtin->Type()) { case sem::BuiltinType::kAcosh: - if (builtins.acosh != Level::kNone) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.acosh != Level::kNone) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.acosh(builtin->ReturnType()); }); } break; case sem::BuiltinType::kAsinh: - if (builtins.asinh) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.asinh) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.asinh(builtin->ReturnType()); }); } break; case sem::BuiltinType::kAtanh: - if (builtins.atanh != Level::kNone) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.atanh != Level::kNone) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.atanh(builtin->ReturnType()); }); } break; case sem::BuiltinType::kClamp: - if (builtins.clamp_int) { + if (polyfill.clamp_int) { auto& sig = builtin->Signature(); if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) { - polyfill = builtin_polyfills.GetOrCreate( + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.clampInteger(builtin->ReturnType()); }); } } break; case sem::BuiltinType::kCountLeadingZeros: - if (builtins.count_leading_zeros) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.count_leading_zeros) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.countLeadingZeros(builtin->ReturnType()); }); } break; case sem::BuiltinType::kCountTrailingZeros: - if (builtins.count_trailing_zeros) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.count_trailing_zeros) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.countTrailingZeros(builtin->ReturnType()); }); } break; case sem::BuiltinType::kExtractBits: - if (builtins.extract_bits != Level::kNone) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.extract_bits != Level::kNone) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.extractBits(builtin->ReturnType()); }); } break; case sem::BuiltinType::kFirstLeadingBit: - if (builtins.first_leading_bit) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.first_leading_bit) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); }); } break; case sem::BuiltinType::kFirstTrailingBit: - if (builtins.first_trailing_bit) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.first_trailing_bit) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); }); } break; case sem::BuiltinType::kInsertBits: - if (builtins.insert_bits != Level::kNone) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.insert_bits != Level::kNone) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.insertBits(builtin->ReturnType()); }); } break; case sem::BuiltinType::kSaturate: - if (builtins.saturate) { - polyfill = builtin_polyfills.GetOrCreate( + if (polyfill.saturate) { + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.saturate(builtin->ReturnType()); }); } break; case sem::BuiltinType::kTextureSampleBaseClampToEdge: - if (builtins.texture_sample_base_clamp_to_edge_2d_f32) { + if (polyfill.texture_sample_base_clamp_to_edge_2d_f32) { auto& sig = builtin->Signature(); auto* tex = sig.Parameter(sem::ParameterUsage::kTexture); if (auto* stex = tex->Type()->As()) { if (stex->type()->Is()) { - polyfill = builtin_polyfills.GetOrCreate(builtin, [&] { + fn = builtin_polyfills.GetOrCreate(builtin, [&] { return s.textureSampleBaseClampToEdge_2d_f32(); }); } @@ -764,9 +827,9 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src, } break; case sem::BuiltinType::kQuantizeToF16: - if (builtins.quantize_to_vec_f16) { + if (polyfill.quantize_to_vec_f16) { if (auto* vec = builtin->ReturnType()->As()) { - polyfill = builtin_polyfills.GetOrCreate( + fn = builtin_polyfills.GetOrCreate( builtin, [&] { return s.quantizeToF16(vec); }); } } @@ -776,16 +839,16 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src, break; } - if (polyfill.IsValid()) { - auto* replacement = s.b.Call(polyfill, ctx.Clone(call->Declaration()->args)); + if (fn.IsValid()) { + auto* replacement = b.Call(fn, ctx.Clone(call->Declaration()->args)); ctx.Replace(call->Declaration(), replacement); made_changes = true; } } else if (auto* bin_op = node->As()) { switch (bin_op->op) { case ast::BinaryOp::kShiftLeft: - case ast::BinaryOp::kShiftRight: - if (builtins.bitshift_modulo) { + case ast::BinaryOp::kShiftRight: { + if (polyfill.bitshift_modulo) { auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef(); auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef(); auto* lhs_el_ty = sem::Type::DeepestElementOf(lhs_ty); @@ -798,6 +861,24 @@ Transform::ApplyResult BuiltinPolyfill::Apply(const Program* src, made_changes = true; } break; + } + case ast::BinaryOp::kDivide: + case ast::BinaryOp::kModulo: { + if (polyfill.int_div_mod) { + auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef(); + if (lhs_ty->is_integer_scalar_or_vector()) { + auto* rhs_ty = src->TypeOf(bin_op->rhs)->UnwrapRef(); + BinaryOpSignature sig{bin_op->op, lhs_ty, rhs_ty}; + auto fn = binary_op_polyfills.GetOrCreate( + sig, [&] { return s.int_div_mod(sig); }); + auto* lhs = ctx.Clone(bin_op->lhs); + auto* rhs = ctx.Clone(bin_op->rhs); + ctx.Replace(bin_op, b.Call(fn, lhs, rhs)); + made_changes = true; + } + } + break; + } default: break; } diff --git a/src/tint/transform/builtin_polyfill.h b/src/tint/transform/builtin_polyfill.h index 7083aa7f23..f9eb029949 100644 --- a/src/tint/transform/builtin_polyfill.h +++ b/src/tint/transform/builtin_polyfill.h @@ -63,6 +63,9 @@ class BuiltinPolyfill final : public Castable { bool first_trailing_bit = false; /// Should `insertBits()` be polyfilled? Level insert_bits = Level::kNone; + /// Should integer scalar / vector divides and modulos be polyfilled to avoid DBZ and + /// integer overflows? + bool int_div_mod = false; /// Should `saturate()` be polyfilled? bool saturate = false; /// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d textures? diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc index 1e380d482d..b7671676a9 100644 --- a/src/tint/transform/builtin_polyfill_test.cc +++ b/src/tint/transform/builtin_polyfill_test.cc @@ -1920,6 +1920,775 @@ fn f() { EXPECT_EQ(expect, str(got)); } +//////////////////////////////////////////////////////////////////////////////// +// int_div_mod +//////////////////////////////////////////////////////////////////////////////// +DataMap polyfillIntDivMod() { + BuiltinPolyfill::Builtins builtins; + builtins.int_div_mod = true; + DataMap data; + data.Add(builtins); + return data; +} + +TEST_F(BuiltinPolyfillTest, ShouldRunIntDiv) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i / v; +} +)"; + + EXPECT_FALSE(ShouldRun(src)); + EXPECT_TRUE(ShouldRun(src, polyfillIntDivMod())); +} + +TEST_F(BuiltinPolyfillTest, ShouldRunIntMod) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i % v; +} +)"; + + EXPECT_FALSE(ShouldRun(src)); + EXPECT_TRUE(ShouldRun(src, polyfillIntDivMod())); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_ai_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20 / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : i32, rhs : i32) -> i32 { + return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_div(20, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_ai_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20 % v; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : i32, rhs : i32) -> i32 { + return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(20, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_i32_ai) { + auto* src = R"( +fn f() { + let v = 10i; + let x = v / 20; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : i32, rhs : i32) -> i32 { + return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_div(v, 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_i32_ai) { + auto* src = R"( +fn f() { + let v = 10i; + let x = v % 20; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : i32, rhs : i32) -> i32 { + return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(v, 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_i32_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : i32, rhs : i32) -> i32 { + return (lhs / select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_div(20i, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_i32_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i % v; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : i32, rhs : i32) -> i32 { + return (lhs % select(rhs, 1, ((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(20i, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_ai_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20 / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : u32, rhs : u32) -> u32 { + return (lhs / select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_div(20, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_ai_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20 % v; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : u32, rhs : u32) -> u32 { + return (lhs % select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_mod(20, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_u32_ai) { + auto* src = R"( +fn f() { + let v = 10u; + let x = v / 20; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : u32, rhs : u32) -> u32 { + return (lhs / select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_div(v, 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_u32_ai) { + auto* src = R"( +fn f() { + let v = 10u; + let x = v % 20; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : u32, rhs : u32) -> u32 { + return (lhs % select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_mod(v, 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_u32_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20u / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : u32, rhs : u32) -> u32 { + return (lhs / select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_div(20u, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_u32_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20u % v; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : u32, rhs : u32) -> u32 { + return (lhs % select(rhs, 1, (rhs == 0))); +} + +fn f() { + let v = 10u; + let x = tint_mod(20u, v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_ai_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20) / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : i32) -> vec3 { + let r = vec3(rhs); + return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(vec3(20), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_ai_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20) % v; +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(vec3(20), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_ai) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(v) / 20; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : i32) -> vec3 { + let r = vec3(rhs); + return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(vec3(v), 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_ai) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(v) % 20; +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(vec3(v), 20); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20i) / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : i32) -> vec3 { + let r = vec3(rhs); + return (lhs / select(r, vec3(1), ((r == vec3(0)) | ((lhs == vec3(-2147483648)) & (r == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(vec3(20i), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20i) % v; +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(vec3(20i), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_u32_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = vec3(20u) / v; +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : u32) -> vec3 { + let r = vec3(rhs); + return (lhs / select(r, vec3(1), (r == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_div(vec3(20u), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_u32_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = vec3(20u) % v; +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : vec3, rhs : u32) -> vec3 { + let r = vec3(rhs); + return (lhs % select(r, vec3(1), (r == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_mod(vec3(20u), v); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_ai_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20 / vec3(v); +} +)"; + + auto* expect = R"( +fn tint_div(lhs : i32, rhs : vec3) -> vec3 { + let l = vec3(lhs); + return (l / select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(20, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_ai_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20 % vec3(v); +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(20, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_i32_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i / vec3(v); +} +)"; + + auto* expect = R"( +fn tint_div(lhs : i32, rhs : vec3) -> vec3 { + let l = vec3(lhs); + return (l / select(rhs, vec3(1), ((rhs == vec3(0)) | ((l == vec3(-2147483648)) & (rhs == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(20i, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_i32_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = 20i % vec3(v); +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(20i, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_u32_vec3_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20u / vec3(v); +} +)"; + + auto* expect = R"( +fn tint_div(lhs : u32, rhs : vec3) -> vec3 { + let l = vec3(lhs); + return (l / select(rhs, vec3(1), (rhs == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_div(20u, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_u32_vec3_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = 20u % vec3(v); +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : u32, rhs : vec3) -> vec3 { + let l = vec3(lhs); + return (l % select(rhs, vec3(1), (rhs == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_mod(20u, vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_i32_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20i) / vec3(v); +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : vec3) -> vec3 { + return (lhs / select(rhs, vec3(1), ((rhs == vec3(0)) | ((lhs == vec3(-2147483648)) & (rhs == vec3(-1)))))); +} + +fn f() { + let v = 10i; + let x = tint_div(vec3(20i), vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_i32_vec3_i32) { + auto* src = R"( +fn f() { + let v = 10i; + let x = vec3(20i) % vec3(v); +} +)"; + + 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)))))); +} + +fn f() { + let v = 10i; + let x = tint_mod(vec3(20i), vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntDiv_vec3_u32_vec3_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = vec3(20u) / vec3(v); +} +)"; + + auto* expect = R"( +fn tint_div(lhs : vec3, rhs : vec3) -> vec3 { + return (lhs / select(rhs, vec3(1), (rhs == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_div(vec3(20u), vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + +TEST_F(BuiltinPolyfillTest, IntMod_vec3_u32_vec3_u32) { + auto* src = R"( +fn f() { + let v = 10u; + let x = vec3(20u) % vec3(v); +} +)"; + + auto* expect = R"( +fn tint_mod(lhs : vec3, rhs : vec3) -> vec3 { + return (lhs % select(rhs, vec3(1), (rhs == vec3(0)))); +} + +fn f() { + let v = 10u; + let x = tint_mod(vec3(20u), vec3(v)); +} +)"; + + auto got = Run(src, polyfillIntDivMod()); + + EXPECT_EQ(expect, str(got)); +} + //////////////////////////////////////////////////////////////////////////////// // saturate //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index 29136cbe09..b8140b9de8 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc @@ -182,6 +182,9 @@ SanitizedResult Sanitize(const Program* in, manager.Add(); + // ExpandCompoundAssignment must come before BuiltinPolyfill + manager.Add(); + { // Builtin polyfills transform::BuiltinPolyfill::Builtins polyfills; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; @@ -193,6 +196,7 @@ SanitizedResult Sanitize(const Program* in, polyfills.first_leading_bit = true; polyfills.first_trailing_bit = true; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; + polyfills.int_div_mod = true; polyfills.saturate = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; data.Add(polyfills); @@ -214,7 +218,6 @@ SanitizedResult Sanitize(const Program* in, manager.Add(); } manager.Add(); - manager.Add(); manager.Add(); manager.Add(); diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index a7c3f00514..3eb3358d20 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -157,6 +157,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { manager.Add(); + // ExpandCompoundAssignment must come before BuiltinPolyfill + manager.Add(); + { // Builtin polyfills transform::BuiltinPolyfill::Builtins polyfills; polyfills.acosh = transform::BuiltinPolyfill::Level::kFull; @@ -172,6 +175,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { polyfills.first_leading_bit = true; polyfills.first_trailing_bit = true; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kFull; + polyfills.int_div_mod = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; data.Add(polyfills); manager.Add(); @@ -211,7 +215,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { // assumes that num_workgroups builtins only appear as struct members and are // only accessed directly via member accessors. manager.Add(); - manager.Add(); manager.Add(); manager.Add(); manager.Add(); @@ -661,117 +664,6 @@ bool GeneratorImpl::EmitAssign(const ast::AssignmentStatement* stmt) { return true; } -bool GeneratorImpl::EmitExpressionOrOneIfZero(std::ostream& out, const ast::Expression* expr) { - // For constants, replace literal 0 with 1. - if (const auto* val = builder_.Sem().Get(expr)->ConstantValue()) { - if (!val->AnyZero()) { - return EmitExpression(out, expr); - } - - auto* ty = val->Type(); - - if (ty->IsAnyOf()) { - return EmitValue(out, ty, 1); - } - - if (auto* vec = ty->As()) { - auto* elem_ty = vec->type(); - - if (!EmitType(out, ty, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) { - return false; - } - - out << "("; - for (size_t i = 0; i < vec->Width(); ++i) { - if (i != 0) { - out << ", "; - } - auto s = val->Index(i)->As(); - if (!EmitValue(out, elem_ty, (s == 0) ? 1 : static_cast(s))) { - return false; - } - } - out << ")"; - return true; - } - - TINT_ICE(Writer, diagnostics_) - << "EmitExpressionOrOneIfZero expects integer scalar or vector"; - return false; - } - - auto* ty = TypeOf(expr)->UnwrapRef(); - - // For non-constants, we need to emit runtime code to check if the value is 0, - // and return 1 in that case. - std::string zero; - { - std::ostringstream ss; - EmitValue(ss, ty, 0); - zero = ss.str(); - } - std::string one; - { - std::ostringstream ss; - EmitValue(ss, ty, 1); - one = ss.str(); - } - - // For identifiers, no need for a function call as it's fine to evaluate - // `expr` more than once. - if (expr->Is()) { - out << "("; - if (!EmitExpression(out, expr)) { - return false; - } - out << " == " << zero << " ? " << one << " : "; - if (!EmitExpression(out, expr)) { - return false; - } - out << ")"; - return true; - } - - // For non-identifier expressions, call a function to make sure `expr` is only - // evaluated once. - auto name = utils::GetOrCreate(value_or_one_if_zero_, ty, [&]() -> std::string { - // Example: - // int4 tint_value_or_one_if_zero_int4(int4 value) { - // return value == 0 ? 0 : value; - // } - std::string ty_name; - { - std::ostringstream ss; - if (!EmitType(ss, ty, tint::ast::AddressSpace::kUndefined, ast::Access::kUndefined, - "")) { - return ""; - } - ty_name = ss.str(); - } - - std::string fn = UniqueIdentifier("value_or_one_if_zero_" + ty_name); - line(&helpers_) << ty_name << " " << fn << "(" << ty_name << " value) {"; - { - ScopedIndent si(&helpers_); - line(&helpers_) << "return value == " << zero << " ? " << one << " : value;"; - } - line(&helpers_) << "}"; - line(&helpers_); - return fn; - }); - - if (name.empty()) { - return false; - } - - out << name << "("; - if (!EmitExpression(out, expr)) { - return false; - } - out << ")"; - return true; -} - bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* expr) { if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) { auto name = UniqueIdentifier(kTempNamePrefix); @@ -892,21 +784,9 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, const ast::BinaryExpression* e break; case ast::BinaryOp::kDivide: out << "/"; - // BUG(crbug.com/tint/1083): Integer divide/modulo by zero is a FXC - // compile error, and undefined behavior in WGSL. - if (TypeOf(expr->rhs)->UnwrapRef()->is_integer_scalar_or_vector()) { - out << " "; - return EmitExpressionOrOneIfZero(out, expr->rhs); - } break; case ast::BinaryOp::kModulo: out << "%"; - // BUG(crbug.com/tint/1083): Integer divide/modulo by zero is a FXC - // compile error, and undefined behavior in WGSL. - if (TypeOf(expr->rhs)->UnwrapRef()->is_integer_scalar_or_vector()) { - out << " "; - return EmitExpressionOrOneIfZero(out, expr->rhs); - } break; case ast::BinaryOp::kNone: diagnostics_.add_error(diag::System::Writer, "missing binary operation type"); diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h index eca773404e..16b824b483 100644 --- a/src/tint/writer/hlsl/generator_impl.h +++ b/src/tint/writer/hlsl/generator_impl.h @@ -93,12 +93,6 @@ class GeneratorImpl : public TextGenerator { /// @param stmt the statement to emit /// @returns true if the statement was emitted successfully bool EmitAssign(const ast::AssignmentStatement* stmt); - /// Emits code such that if `expr` is zero, it emits one, else `expr`. - /// Used to avoid divide-by-zeros by substituting constant zeros with ones. - /// @param out the output of the expression stream - /// @param expr the expression - /// @returns true if the expression was emitted, false otherwise - bool EmitExpressionOrOneIfZero(std::ostream& out, const ast::Expression* expr); /// Handles generating a binary expression /// @param out the output of the expression stream /// @param expr the binary expression diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc index 1163078020..6e2b3c7aa6 100644 --- a/src/tint/writer/hlsl/generator_impl_binary_test.cc +++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc @@ -653,295 +653,5 @@ foo((tint_tmp), (tint_tmp_1), (tint_tmp_2)); )"); } -namespace HlslGeneratorDivMod { - -struct Params { - enum class Type { Div, Mod }; - Type type; -}; - -struct HlslGeneratorDivModTest : TestParamHelper { - std::string Token() { return GetParam().type == Params::Type::Div ? "/" : "%"; } - - template - auto Op(Args... args) { - return GetParam().type == Params::Type::Div ? Div(std::forward(args)...) - : Mod(std::forward(args)...); - } -}; - -INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest, - HlslGeneratorDivModTest, - testing::Values(Params{Params::Type::Div}, Params{Params::Type::Mod})); - -TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_i32) { - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.i32())), - Decl(Let("r", Op("a", 0_i))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn() { - int a = 0; - const int r = (a )" + Token() + - R"( 1); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_u32) { - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.u32())), - Decl(Let("r", Op("a", 0_u))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn() { - uint a = 0u; - const uint r = (a )" + Token() + - R"( 1u); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_vec_i32) { - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", vec4(100_i, 100_i, 100_i, 100_i))), - Decl(Let("r", Op("a", vec4(50_i, 0_i, 25_i, 0_i)))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn() { - int4 a = (100).xxxx; - const int4 r = (a )" + Token() + - R"( int4(50, 1, 25, 1)); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_scalar_i32) { - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", vec4(100_i, 100_i, 100_i, 100_i))), - Decl(Let("r", Op("a", 0_i))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn() { - int4 a = (100).xxxx; - const int4 r = (a )" + Token() + - R"( 1); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_i32) { - Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.i32())), - Decl(Let("r", Op("a", "b"))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn(int b) { - int a = 0; - const int r = (a )" + Token() + - R"( (b == 0 ? 1 : b)); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_u32) { - Func("fn", utils::Vector{Param("b", ty.u32())}, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.u32())), - Decl(Let("r", Op("a", "b"))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn(uint b) { - uint a = 0u; - const uint r = (a )" + Token() + - R"( (b == 0u ? 1u : b)); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_vec_i32) { - Func("fn", utils::Vector{Param("b", ty.vec3())}, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.vec3())), - Decl(Let("r", Op("a", "b"))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn(int3 b) { - int3 a = int3(0, 0, 0); - const int3 r = (a )" + Token() + - R"( (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByIdentifier_vec_by_scalar_i32) { - Func("fn", utils::Vector{Param("b", ty.i32())}, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.vec3())), - Decl(Let("r", Op("a", "b"))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(void fn(int b) { - int3 a = int3(0, 0, 0); - const int3 r = (a )" + Token() + - R"( (b == 0 ? 1 : b)); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_i32) { - Func("zero", utils::Empty, ty.i32(), - utils::Vector{ - Return(Expr(0_i)), - }); - - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.i32())), - Decl(Let("r", Op("a", Call("zero")))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; -} - -int zero() { - return 0; -} - -void fn() { - int a = 0; - const int r = (a )" + Token() + - R"( value_or_one_if_zero_int(zero())); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_u32) { - Func("zero", utils::Empty, ty.u32(), - utils::Vector{ - Return(Expr(0_u)), - }); - - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.u32())), - Decl(Let("r", Op("a", Call("zero")))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; -} - -uint zero() { - return 0u; -} - -void fn() { - uint a = 0u; - const uint r = (a )" + Token() + - R"( value_or_one_if_zero_uint(zero())); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_vec_i32) { - Func("zero", utils::Empty, ty.vec3(), - utils::Vector{ - Return(vec3(0_i, 0_i, 0_i)), - }); - - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.vec3())), - Decl(Let("r", Op("a", Call("zero")))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; -} - -int3 zero() { - return (0).xxx; -} - -void fn() { - int3 a = int3(0, 0, 0); - const int3 r = (a )" + Token() + - R"( value_or_one_if_zero_int3(zero())); -} -)"); -} - -TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_scalar_i32) { - Func("zero", utils::Empty, ty.i32(), - utils::Vector{ - Return(0_i), - }); - - Func("fn", utils::Empty, ty.void_(), - utils::Vector{ - Decl(Var("a", ty.vec3())), - Decl(Let("r", Op("a", Call("zero")))), - }); - - GeneratorImpl& gen = Build(); - - ASSERT_TRUE(gen.Generate()); - EXPECT_EQ(gen.result(), R"(int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; -} - -int zero() { - return 0; -} - -void fn() { - int3 a = int3(0, 0, 0); - const int3 r = (a )" + Token() + - R"( value_or_one_if_zero_int(zero())); -} -)"); -} -} // namespace HlslGeneratorDivMod - } // namespace } // namespace tint::writer::hlsl diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc index 88578dff6a..351a6d411e 100644 --- a/src/tint/writer/msl/generator_impl.cc +++ b/src/tint/writer/msl/generator_impl.cc @@ -167,6 +167,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { manager.Add(); + // ExpandCompoundAssignment must come before BuiltinPolyfill + manager.Add(); + { // Builtin polyfills transform::BuiltinPolyfill::Builtins polyfills; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; @@ -177,6 +180,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { polyfills.first_leading_bit = true; polyfills.first_trailing_bit = true; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; + polyfills.int_div_mod = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; data.Add(polyfills); manager.Add(); @@ -224,7 +228,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { manager.Add(); } manager.Add(); - manager.Add(); manager.Add(); manager.Add(); diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc index 30dd186001..18c751179c 100644 --- a/src/tint/writer/spirv/generator_impl.cc +++ b/src/tint/writer/spirv/generator_impl.cc @@ -48,6 +48,9 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { manager.Add(); + // ExpandCompoundAssignment must come before BuiltinPolyfill + manager.Add(); + { // Builtin polyfills transform::BuiltinPolyfill::Builtins polyfills; polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck; @@ -60,6 +63,7 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { polyfills.first_leading_bit = true; polyfills.first_trailing_bit = true; polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; + polyfills.int_div_mod = true; polyfills.saturate = true; polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true; polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741 @@ -80,7 +84,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) { manager.Add(); } manager.Add(); - manager.Add(); manager.Add(); manager.Add(); // Required for arrayLength() manager.Add(); diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl index f37fc2baec..7f89b55301 100644 --- a/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl @@ -1,5 +1,9 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } void marg8uintin() { @@ -32,9 +36,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex4D(uint gridSize, uint index) { - uint z_1 = (gridSize / value_or_one_if_zero_uint((index * index))); - uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); - uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); + uint z_1 = tint_div(gridSize, (index * index)); + uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(z_1, y_1, y_1); } diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl index f37fc2baec..7f89b55301 100644 --- a/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl @@ -1,5 +1,9 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } void marg8uintin() { @@ -32,9 +36,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex4D(uint gridSize, uint index) { - uint z_1 = (gridSize / value_or_one_if_zero_uint((index * index))); - uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); - uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); + uint z_1 = tint_div(gridSize, (index * index)); + uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(z_1, y_1, y_1); } diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.msl b/test/tint/bug/chromium/1273230.wgsl.expected.msl index 1e627d7253..15000e6755 100644 --- a/test/tint/bug/chromium/1273230.wgsl.expected.msl +++ b/test/tint/bug/chromium/1273230.wgsl.expected.msl @@ -14,6 +14,14 @@ struct tint_array { T elements[N]; }; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + void marg8uintin() { } @@ -81,9 +89,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex4D(uint gridSize, uint index) { - uint z_1 = (gridSize / (index * index)); - uint y_1 = ((gridSize - ((gridSize * gridSize) * z_1)) / gridSize); - uint x_1 = (index % gridSize); + uint z_1 = tint_div(gridSize, (index * index)); + uint y_1 = tint_div((gridSize - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(z_1, y_1, y_1); } diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.spvasm b/test/tint/bug/chromium/1273230.wgsl.expected.spvasm index 110100a60f..2e6650348d 100644 --- a/test/tint/bug/chromium/1273230.wgsl.expected.spvasm +++ b/test/tint/bug/chromium/1273230.wgsl.expected.spvasm @@ -1,10 +1,10 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 275 +; Bound: 290 ; Schema: 0 OpCapability Shader - %69 = OpExtInstImport "GLSL.std.450" + %86 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1 OpExecutionMode %main_count LocalSize 128 1 1 @@ -47,6 +47,12 @@ OpMemberName %Dbg 10 "value_f32_2" OpMemberName %Dbg 11 "value_f32_3" OpName %dbg "dbg" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" + OpName %tint_mod "tint_mod" + OpName %lhs_0 "lhs" + OpName %rhs_0 "rhs" OpName %marg8uintin "marg8uintin" OpName %toVoxelPos "toVoxelPos" OpName %position "position" @@ -171,291 +177,310 @@ %dbg_block = OpTypeStruct %Dbg %_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block %dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer + %32 = OpTypeFunction %uint %uint %uint + %38 = OpConstantNull %uint + %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 %void = OpTypeVoid - %32 = OpTypeFunction %void - %36 = OpTypeFunction %v3float %v3float + %50 = OpTypeFunction %void + %54 = OpTypeFunction %v3float %v3float %uint_0 = OpConstant %uint 0 %uint_4 = OpConstant %uint 4 %_ptr_Uniform_float = OpTypePointer Uniform %float - %uint_1 = OpConstant %uint 1 %uint_2 = OpConstant %uint 2 %_ptr_Function_v3float = OpTypePointer Function %v3float - %54 = OpConstantNull %v3float + %71 = OpConstantNull %v3float %uint_5 = OpConstant %uint 5 %_ptr_Function_float = OpTypePointer Function %float - %79 = OpConstantNull %float + %96 = OpConstantNull %float %_ptr_Uniform_uint = OpTypePointer Uniform %uint - %116 = OpTypeFunction %uint %uint %v3float + %133 = OpTypeFunction %uint %uint %v3float %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %124 = OpConstantNull %v3uint + %141 = OpConstantNull %v3uint %_ptr_Function_uint = OpTypePointer Function %uint - %137 = OpTypeFunction %v3uint %uint %uint - %145 = OpConstantNull %uint - %158 = OpTypeFunction %v3float %uint + %154 = OpTypeFunction %v3uint %uint %uint + %174 = OpTypeFunction %v3float %uint %uint_3 = OpConstant %uint 3 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint - %190 = OpConstantNull %int + %206 = OpConstantNull %int %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int %_ptr_Function_int = OpTypePointer Function %int - %206 = OpTypeFunction %void %v3uint - %bool = OpTypeBool + %222 = OpTypeFunction %void %v3uint %float_3 = OpConstant %float 3 %int_1 = OpConstant %int 1 -%marg8uintin = OpFunction %void None %32 - %35 = OpLabel + %tint_div = OpFunction %uint None %32 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %36 = OpLabel + %39 = OpIEqual %bool %rhs %38 + %37 = OpSelect %uint %39 %uint_1 %rhs + %42 = OpUDiv %uint %lhs %37 + OpReturnValue %42 + OpFunctionEnd + %tint_mod = OpFunction %uint None %32 + %lhs_0 = OpFunctionParameter %uint + %rhs_0 = OpFunctionParameter %uint + %46 = OpLabel + %48 = OpIEqual %bool %rhs_0 %38 + %47 = OpSelect %uint %48 %uint_1 %rhs_0 + %49 = OpUMod %uint %lhs_0 %47 + OpReturnValue %49 + OpFunctionEnd +%marg8uintin = OpFunction %void None %50 + %53 = OpLabel OpReturn OpFunctionEnd - %toVoxelPos = OpFunction %v3float None %36 + %toVoxelPos = OpFunction %v3float None %54 %position = OpFunctionParameter %v3float - %39 = OpLabel - %bbMin = OpVariable %_ptr_Function_v3float Function %54 - %bbMax = OpVariable %_ptr_Function_v3float Function %54 - %bbSize = OpVariable %_ptr_Function_v3float Function %54 - %cubeSize = OpVariable %_ptr_Function_float Function %79 - %gridSize = OpVariable %_ptr_Function_float Function %79 - %gx = OpVariable %_ptr_Function_float Function %79 - %gy = OpVariable %_ptr_Function_float Function %79 - %gz = OpVariable %_ptr_Function_float Function %79 - %43 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 - %44 = OpLoad %float %43 - %46 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 - %47 = OpLoad %float %46 - %49 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 - %50 = OpLoad %float %49 - %51 = OpCompositeConstruct %v3float %44 %47 %50 - OpStore %bbMin %51 - %56 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0 - %57 = OpLoad %float %56 - %58 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1 - %59 = OpLoad %float %58 - %60 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2 - %61 = OpLoad %float %60 - %62 = OpCompositeConstruct %v3float %57 %59 %61 - OpStore %bbMax %62 - %64 = OpLoad %v3float %bbMin - %65 = OpLoad %v3float %bbMin - %66 = OpFSub %v3float %64 %65 - OpStore %bbSize %66 - %72 = OpAccessChain %_ptr_Function_float %bbMax %uint_0 - %73 = OpLoad %float %72 - %74 = OpAccessChain %_ptr_Function_float %bbMax %uint_1 - %75 = OpLoad %float %74 - %70 = OpExtInst %float %69 NMax %73 %75 - %76 = OpAccessChain %_ptr_Function_float %bbSize %uint_2 - %77 = OpLoad %float %76 - %68 = OpExtInst %float %69 NMax %70 %77 - OpStore %cubeSize %68 - %82 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %83 = OpLoad %uint %82 - %80 = OpConvertUToF %float %83 - OpStore %gridSize %80 - %85 = OpLoad %float %cubeSize - %86 = OpCompositeExtract %float %position 0 - %87 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 - %88 = OpLoad %float %87 - %89 = OpFSub %float %86 %88 - %90 = OpFMul %float %85 %89 - %91 = OpLoad %float %cubeSize - %92 = OpFDiv %float %90 %91 - OpStore %gx %92 - %94 = OpLoad %float %gx - %95 = OpCompositeExtract %float %position 1 - %96 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 - %97 = OpLoad %float %96 - %98 = OpFSub %float %95 %97 - %99 = OpFMul %float %94 %98 - %100 = OpLoad %float %gridSize - %101 = OpFDiv %float %99 %100 - OpStore %gy %101 - %103 = OpLoad %float %gridSize - %104 = OpCompositeExtract %float %position 2 - %105 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 - %106 = OpLoad %float %105 - %107 = OpFSub %float %104 %106 - %108 = OpFMul %float %103 %107 - %109 = OpLoad %float %gridSize - %110 = OpFDiv %float %108 %109 - OpStore %gz %110 - %112 = OpLoad %float %gz - %113 = OpLoad %float %gz - %114 = OpLoad %float %gz - %115 = OpCompositeConstruct %v3float %112 %113 %114 - OpReturnValue %115 + %57 = OpLabel + %bbMin = OpVariable %_ptr_Function_v3float Function %71 + %bbMax = OpVariable %_ptr_Function_v3float Function %71 + %bbSize = OpVariable %_ptr_Function_v3float Function %71 + %cubeSize = OpVariable %_ptr_Function_float Function %96 + %gridSize = OpVariable %_ptr_Function_float Function %96 + %gx = OpVariable %_ptr_Function_float Function %96 + %gy = OpVariable %_ptr_Function_float Function %96 + %gz = OpVariable %_ptr_Function_float Function %96 + %61 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 + %62 = OpLoad %float %61 + %63 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 + %64 = OpLoad %float %63 + %66 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 + %67 = OpLoad %float %66 + %68 = OpCompositeConstruct %v3float %62 %64 %67 + OpStore %bbMin %68 + %73 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0 + %74 = OpLoad %float %73 + %75 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1 + %76 = OpLoad %float %75 + %77 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2 + %78 = OpLoad %float %77 + %79 = OpCompositeConstruct %v3float %74 %76 %78 + OpStore %bbMax %79 + %81 = OpLoad %v3float %bbMin + %82 = OpLoad %v3float %bbMin + %83 = OpFSub %v3float %81 %82 + OpStore %bbSize %83 + %89 = OpAccessChain %_ptr_Function_float %bbMax %uint_0 + %90 = OpLoad %float %89 + %91 = OpAccessChain %_ptr_Function_float %bbMax %uint_1 + %92 = OpLoad %float %91 + %87 = OpExtInst %float %86 NMax %90 %92 + %93 = OpAccessChain %_ptr_Function_float %bbSize %uint_2 + %94 = OpLoad %float %93 + %85 = OpExtInst %float %86 NMax %87 %94 + OpStore %cubeSize %85 + %99 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %100 = OpLoad %uint %99 + %97 = OpConvertUToF %float %100 + OpStore %gridSize %97 + %102 = OpLoad %float %cubeSize + %103 = OpCompositeExtract %float %position 0 + %104 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 + %105 = OpLoad %float %104 + %106 = OpFSub %float %103 %105 + %107 = OpFMul %float %102 %106 + %108 = OpLoad %float %cubeSize + %109 = OpFDiv %float %107 %108 + OpStore %gx %109 + %111 = OpLoad %float %gx + %112 = OpCompositeExtract %float %position 1 + %113 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 + %114 = OpLoad %float %113 + %115 = OpFSub %float %112 %114 + %116 = OpFMul %float %111 %115 + %117 = OpLoad %float %gridSize + %118 = OpFDiv %float %116 %117 + OpStore %gy %118 + %120 = OpLoad %float %gridSize + %121 = OpCompositeExtract %float %position 2 + %122 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 + %123 = OpLoad %float %122 + %124 = OpFSub %float %121 %123 + %125 = OpFMul %float %120 %124 + %126 = OpLoad %float %gridSize + %127 = OpFDiv %float %125 %126 + OpStore %gz %127 + %129 = OpLoad %float %gz + %130 = OpLoad %float %gz + %131 = OpLoad %float %gz + %132 = OpCompositeConstruct %v3float %129 %130 %131 + OpReturnValue %132 OpFunctionEnd - %toIndex1D = OpFunction %uint None %116 + %toIndex1D = OpFunction %uint None %133 %gridSize_0 = OpFunctionParameter %uint %voxelPos = OpFunctionParameter %v3float - %120 = OpLabel - %icoord = OpVariable %_ptr_Function_v3uint Function %124 - %121 = OpConvertFToU %v3uint %voxelPos - OpStore %icoord %121 - %126 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 - %127 = OpLoad %uint %126 - %128 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 - %129 = OpLoad %uint %128 - %130 = OpIMul %uint %gridSize_0 %129 - %131 = OpIAdd %uint %127 %130 - %132 = OpIMul %uint %gridSize_0 %gridSize_0 - %133 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 - %134 = OpLoad %uint %133 - %135 = OpIMul %uint %132 %134 - %136 = OpIAdd %uint %131 %135 - OpReturnValue %136 + %137 = OpLabel + %icoord = OpVariable %_ptr_Function_v3uint Function %141 + %138 = OpConvertFToU %v3uint %voxelPos + OpStore %icoord %138 + %143 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 + %144 = OpLoad %uint %143 + %145 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 + %146 = OpLoad %uint %145 + %147 = OpIMul %uint %gridSize_0 %146 + %148 = OpIAdd %uint %144 %147 + %149 = OpIMul %uint %gridSize_0 %gridSize_0 + %150 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 + %151 = OpLoad %uint %150 + %152 = OpIMul %uint %149 %151 + %153 = OpIAdd %uint %148 %152 + OpReturnValue %153 OpFunctionEnd - %toIndex4D = OpFunction %v3uint None %137 + %toIndex4D = OpFunction %v3uint None %154 %gridSize_1 = OpFunctionParameter %uint %index = OpFunctionParameter %uint - %141 = OpLabel - %z = OpVariable %_ptr_Function_uint Function %145 - %y = OpVariable %_ptr_Function_uint Function %145 - %x = OpVariable %_ptr_Function_uint Function %145 - %142 = OpIMul %uint %index %index - %143 = OpUDiv %uint %gridSize_1 %142 - OpStore %z %143 - %146 = OpIMul %uint %gridSize_1 %gridSize_1 - %147 = OpLoad %uint %z - %148 = OpIMul %uint %146 %147 - %149 = OpISub %uint %gridSize_1 %148 - %150 = OpUDiv %uint %149 %gridSize_1 - OpStore %y %150 - %152 = OpUMod %uint %index %gridSize_1 - OpStore %x %152 - %154 = OpLoad %uint %z - %155 = OpLoad %uint %y - %156 = OpLoad %uint %y - %157 = OpCompositeConstruct %v3uint %154 %155 %156 - OpReturnValue %157 + %158 = OpLabel + %z = OpVariable %_ptr_Function_uint Function %38 + %y = OpVariable %_ptr_Function_uint Function %38 + %x = OpVariable %_ptr_Function_uint Function %38 + %160 = OpIMul %uint %index %index + %159 = OpFunctionCall %uint %tint_div %gridSize_1 %160 + OpStore %z %159 + %163 = OpIMul %uint %gridSize_1 %gridSize_1 + %164 = OpLoad %uint %z + %165 = OpIMul %uint %163 %164 + %166 = OpISub %uint %gridSize_1 %165 + %162 = OpFunctionCall %uint %tint_div %166 %gridSize_1 + OpStore %y %162 + %168 = OpFunctionCall %uint %tint_mod %index %gridSize_1 + OpStore %x %168 + %170 = OpLoad %uint %z + %171 = OpLoad %uint %y + %172 = OpLoad %uint %y + %173 = OpCompositeConstruct %v3uint %170 %171 %172 + OpReturnValue %173 OpFunctionEnd -%loadPosition = OpFunction %v3float None %158 +%loadPosition = OpFunction %v3float None %174 %vertexIndex = OpFunctionParameter %uint - %161 = OpLabel - %position_0 = OpVariable %_ptr_Function_v3float Function %54 - %163 = OpIMul %uint %uint_3 %vertexIndex - %164 = OpIAdd %uint %163 %145 - %166 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %164 - %167 = OpLoad %float %166 - %168 = OpIMul %uint %uint_3 %vertexIndex - %169 = OpIAdd %uint %168 %uint_1 - %170 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %169 - %171 = OpLoad %float %170 - %172 = OpIMul %uint %uint_3 %vertexIndex - %173 = OpIAdd %uint %172 %uint_2 - %174 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %173 - %175 = OpLoad %float %174 - %176 = OpCompositeConstruct %v3float %167 %171 %175 - OpStore %position_0 %176 - %178 = OpLoad %v3float %position_0 - OpReturnValue %178 + %177 = OpLabel + %position_0 = OpVariable %_ptr_Function_v3float Function %71 + %179 = OpIMul %uint %uint_3 %vertexIndex + %180 = OpIAdd %uint %179 %38 + %182 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %180 + %183 = OpLoad %float %182 + %184 = OpIMul %uint %uint_3 %vertexIndex + %185 = OpIAdd %uint %184 %uint_1 + %186 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %185 + %187 = OpLoad %float %186 + %188 = OpIMul %uint %uint_3 %vertexIndex + %189 = OpIAdd %uint %188 %uint_2 + %190 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %189 + %191 = OpLoad %float %190 + %192 = OpCompositeConstruct %v3float %183 %187 %191 + OpStore %position_0 %192 + %194 = OpLoad %v3float %position_0 + OpReturnValue %194 OpFunctionEnd - %doIgnore = OpFunction %void None %32 - %180 = OpLabel - %g43 = OpVariable %_ptr_Function_uint Function %145 - %kj6 = OpVariable %_ptr_Function_uint Function %145 - %b53 = OpVariable %_ptr_Function_uint Function %145 - %rwg = OpVariable %_ptr_Function_uint Function %145 - %rb5 = OpVariable %_ptr_Function_float Function %79 - %g55 = OpVariable %_ptr_Function_int Function %190 - %181 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %182 = OpLoad %uint %181 - OpStore %g43 %182 - %185 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 - %186 = OpLoad %uint %185 - OpStore %kj6 %186 - %192 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %190 - %188 = OpAtomicLoad %uint %192 %uint_1 %uint_0 - OpStore %b53 %188 - %194 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %190 - %195 = OpLoad %uint %194 - OpStore %rwg %195 - %197 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %190 - %198 = OpLoad %float %197 - OpStore %rb5 %198 - %203 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %190 - %200 = OpAtomicLoad %int %203 %uint_1 %uint_0 - OpStore %g55 %200 + %doIgnore = OpFunction %void None %50 + %196 = OpLabel + %g43 = OpVariable %_ptr_Function_uint Function %38 + %kj6 = OpVariable %_ptr_Function_uint Function %38 + %b53 = OpVariable %_ptr_Function_uint Function %38 + %rwg = OpVariable %_ptr_Function_uint Function %38 + %rb5 = OpVariable %_ptr_Function_float Function %96 + %g55 = OpVariable %_ptr_Function_int Function %206 + %197 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 + %198 = OpLoad %uint %197 + OpStore %g43 %198 + %201 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 + %202 = OpLoad %uint %201 + OpStore %kj6 %202 + %208 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %206 + %204 = OpAtomicLoad %uint %208 %uint_1 %uint_0 + OpStore %b53 %204 + %210 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %206 + %211 = OpLoad %uint %210 + OpStore %rwg %211 + %213 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %206 + %214 = OpLoad %float %213 + OpStore %rb5 %214 + %219 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %206 + %216 = OpAtomicLoad %int %219 %uint_1 %uint_0 + OpStore %g55 %216 OpReturn OpFunctionEnd -%main_count_inner = OpFunction %void None %206 +%main_count_inner = OpFunction %void None %222 %GlobalInvocationID = OpFunctionParameter %v3uint - %209 = OpLabel -%triangleIndex = OpVariable %_ptr_Function_uint Function %145 - %i0 = OpVariable %_ptr_Function_uint Function %145 - %i1 = OpVariable %_ptr_Function_uint Function %145 - %i2 = OpVariable %_ptr_Function_uint Function %145 - %p0 = OpVariable %_ptr_Function_v3float Function %54 - %p1 = OpVariable %_ptr_Function_v3float Function %54 - %p2 = OpVariable %_ptr_Function_v3float Function %54 - %254 = OpVariable %_ptr_Function_v3float Function %54 - %center = OpVariable %_ptr_Function_v3float Function %54 - %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %54 - %lIndex = OpVariable %_ptr_Function_uint Function %145 -%triangleOffset = OpVariable %_ptr_Function_int Function %190 - %210 = OpCompositeExtract %uint %GlobalInvocationID 0 - OpStore %triangleIndex %210 - %212 = OpLoad %uint %triangleIndex - %213 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %214 = OpLoad %uint %213 - %215 = OpUGreaterThanEqual %bool %212 %214 - OpSelectionMerge %217 None - OpBranchConditional %215 %218 %217 - %218 = OpLabel - OpReturn - %217 = OpLabel - %219 = OpFunctionCall %void %doIgnore - %220 = OpLoad %uint %triangleIndex - %221 = OpIMul %uint %uint_3 %220 - %222 = OpIAdd %uint %221 %145 - %223 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %222 - %224 = OpLoad %uint %223 - OpStore %i0 %224 - %226 = OpLoad %uint %i0 - %227 = OpIMul %uint %uint_3 %226 - %228 = OpIAdd %uint %227 %uint_1 - %229 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %228 + %225 = OpLabel +%triangleIndex = OpVariable %_ptr_Function_uint Function %38 + %i0 = OpVariable %_ptr_Function_uint Function %38 + %i1 = OpVariable %_ptr_Function_uint Function %38 + %i2 = OpVariable %_ptr_Function_uint Function %38 + %p0 = OpVariable %_ptr_Function_v3float Function %71 + %p1 = OpVariable %_ptr_Function_v3float Function %71 + %p2 = OpVariable %_ptr_Function_v3float Function %71 + %269 = OpVariable %_ptr_Function_v3float Function %71 + %center = OpVariable %_ptr_Function_v3float Function %71 + %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %71 + %lIndex = OpVariable %_ptr_Function_uint Function %38 +%triangleOffset = OpVariable %_ptr_Function_int Function %206 + %226 = OpCompositeExtract %uint %GlobalInvocationID 0 + OpStore %triangleIndex %226 + %228 = OpLoad %uint %triangleIndex + %229 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %230 = OpLoad %uint %229 - OpStore %i1 %230 - %232 = OpLoad %uint %i0 - %233 = OpIMul %uint %uint_3 %232 - %234 = OpIAdd %uint %233 %uint_2 - %235 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %234 - %236 = OpLoad %uint %235 - OpStore %i2 %236 - %239 = OpLoad %uint %i0 - %238 = OpFunctionCall %v3float %loadPosition %239 - OpStore %p0 %238 - %242 = OpLoad %uint %i0 - %241 = OpFunctionCall %v3float %loadPosition %242 - OpStore %p1 %241 - %245 = OpLoad %uint %i2 - %244 = OpFunctionCall %v3float %loadPosition %245 - OpStore %p2 %244 - %247 = OpLoad %v3float %p0 - %248 = OpLoad %v3float %p2 - %249 = OpFAdd %v3float %247 %248 - %250 = OpLoad %v3float %p1 - %251 = OpFAdd %v3float %249 %250 - %255 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 - %253 = OpFDiv %v3float %251 %255 - OpStore %center %253 - %258 = OpLoad %v3float %p1 - %257 = OpFunctionCall %v3float %toVoxelPos %258 - OpStore %voxelPos_0 %257 - %261 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %262 = OpLoad %uint %261 - %263 = OpLoad %v3float %p0 - %260 = OpFunctionCall %uint %toIndex1D %262 %263 - OpStore %lIndex %260 - %267 = OpLoad %uint %i1 - %268 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %267 - %265 = OpAtomicIAdd %int %268 %uint_1 %uint_0 %int_1 - OpStore %triangleOffset %265 + %231 = OpUGreaterThanEqual %bool %228 %230 + OpSelectionMerge %232 None + OpBranchConditional %231 %233 %232 + %233 = OpLabel + OpReturn + %232 = OpLabel + %234 = OpFunctionCall %void %doIgnore + %235 = OpLoad %uint %triangleIndex + %236 = OpIMul %uint %uint_3 %235 + %237 = OpIAdd %uint %236 %38 + %238 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %237 + %239 = OpLoad %uint %238 + OpStore %i0 %239 + %241 = OpLoad %uint %i0 + %242 = OpIMul %uint %uint_3 %241 + %243 = OpIAdd %uint %242 %uint_1 + %244 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %243 + %245 = OpLoad %uint %244 + OpStore %i1 %245 + %247 = OpLoad %uint %i0 + %248 = OpIMul %uint %uint_3 %247 + %249 = OpIAdd %uint %248 %uint_2 + %250 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %249 + %251 = OpLoad %uint %250 + OpStore %i2 %251 + %254 = OpLoad %uint %i0 + %253 = OpFunctionCall %v3float %loadPosition %254 + OpStore %p0 %253 + %257 = OpLoad %uint %i0 + %256 = OpFunctionCall %v3float %loadPosition %257 + OpStore %p1 %256 + %260 = OpLoad %uint %i2 + %259 = OpFunctionCall %v3float %loadPosition %260 + OpStore %p2 %259 + %262 = OpLoad %v3float %p0 + %263 = OpLoad %v3float %p2 + %264 = OpFAdd %v3float %262 %263 + %265 = OpLoad %v3float %p1 + %266 = OpFAdd %v3float %264 %265 + %270 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 + %268 = OpFDiv %v3float %266 %270 + OpStore %center %268 + %273 = OpLoad %v3float %p1 + %272 = OpFunctionCall %v3float %toVoxelPos %273 + OpStore %voxelPos_0 %272 + %276 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %277 = OpLoad %uint %276 + %278 = OpLoad %v3float %p0 + %275 = OpFunctionCall %uint %toIndex1D %277 %278 + OpStore %lIndex %275 + %282 = OpLoad %uint %i1 + %283 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %282 + %280 = OpAtomicIAdd %int %283 %uint_1 %uint_0 %int_1 + OpStore %triangleOffset %280 OpReturn OpFunctionEnd - %main_count = OpFunction %void None %32 - %272 = OpLabel - %274 = OpLoad %v3uint %GlobalInvocationID_1 - %273 = OpFunctionCall %void %main_count_inner %274 + %main_count = OpFunction %void None %50 + %287 = OpLabel + %289 = OpLoad %v3uint %GlobalInvocationID_1 + %288 = OpFunctionCall %void %main_count_inner %289 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/1083.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1083.wgsl.expected.dxc.hlsl index a1dedc8079..2ce1859cec 100644 --- a/test/tint/bug/tint/1083.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/tint/1083.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int c = (a / (b == 0 ? 1 : b)); + const int c = tint_div(a, b); return; } diff --git a/test/tint/bug/tint/1083.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1083.wgsl.expected.fxc.hlsl index a1dedc8079..2ce1859cec 100644 --- a/test/tint/bug/tint/1083.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/tint/1083.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int c = (a / (b == 0 ? 1 : b)); + const int c = tint_div(a, b); return; } diff --git a/test/tint/bug/tint/1083.wgsl.expected.glsl b/test/tint/bug/tint/1083.wgsl.expected.glsl index 0054f12abe..28c473ff21 100644 --- a/test/tint/bug/tint/1083.wgsl.expected.glsl +++ b/test/tint/bug/tint/1083.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void f() { int a = 1; int b = 0; - int c = (a / b); + int c = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/bug/tint/1083.wgsl.expected.msl b/test/tint/bug/tint/1083.wgsl.expected.msl index 08beb2b6ee..0a3dd4195a 100644 --- a/test/tint/bug/tint/1083.wgsl.expected.msl +++ b/test/tint/bug/tint/1083.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int const a = 1; int const b = 0; - int const c = (a / b); + int const c = tint_div(a, b); return; } diff --git a/test/tint/bug/tint/1083.wgsl.expected.spvasm b/test/tint/bug/tint/1083.wgsl.expected.spvasm index fa188bd8fe..162cf507bb 100644 --- a/test/tint/bug/tint/1083.wgsl.expected.spvasm +++ b/test/tint/bug/tint/1083.wgsl.expected.spvasm @@ -1,20 +1,40 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 24 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 - %7 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpSDiv %int %int_1 %7 + %void = OpTypeVoid + %19 = OpTypeFunction %void + %tint_div = 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 = OpSDiv %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %23 = OpFunctionCall %int %tint_div %int_1 %8 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl index 978093c5d2..6a0326e702 100644 --- a/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl @@ -1,5 +1,9 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } cbuffer cbuffer_uniforms : register(b0, space0) { @@ -29,9 +33,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex3D(uint gridSize, uint index) { - uint z_1 = (index / value_or_one_if_zero_uint((gridSize * gridSize))); - uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); - uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); + uint z_1 = tint_div(index, (gridSize * gridSize)); + uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(x_1, y_1, z_1); } diff --git a/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl index 978093c5d2..6a0326e702 100644 --- a/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl @@ -1,5 +1,9 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } cbuffer cbuffer_uniforms : register(b0, space0) { @@ -29,9 +33,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex3D(uint gridSize, uint index) { - uint z_1 = (index / value_or_one_if_zero_uint((gridSize * gridSize))); - uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / (gridSize == 0u ? 1u : gridSize)); - uint x_1 = (index % (gridSize == 0u ? 1u : gridSize)); + uint z_1 = tint_div(index, (gridSize * gridSize)); + uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(x_1, y_1, z_1); } diff --git a/test/tint/bug/tint/1113.wgsl.expected.msl b/test/tint/bug/tint/1113.wgsl.expected.msl index bf546c194a..0ab0884b2f 100644 --- a/test/tint/bug/tint/1113.wgsl.expected.msl +++ b/test/tint/bug/tint/1113.wgsl.expected.msl @@ -14,6 +14,14 @@ struct tint_array { T elements[N]; }; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + struct Uniforms { /* 0x0000 */ uint numTriangles; /* 0x0004 */ uint gridSize; @@ -78,9 +86,9 @@ uint toIndex1D(uint gridSize, float3 voxelPos) { } uint3 toIndex3D(uint gridSize, uint index) { - uint z_1 = (index / (gridSize * gridSize)); - uint y_1 = ((index - ((gridSize * gridSize) * z_1)) / gridSize); - uint x_1 = (index % gridSize); + uint z_1 = tint_div(index, (gridSize * gridSize)); + uint y_1 = tint_div((index - ((gridSize * gridSize) * z_1)), gridSize); + uint x_1 = tint_mod(index, gridSize); return uint3(x_1, y_1, z_1); } diff --git a/test/tint/bug/tint/1113.wgsl.expected.spvasm b/test/tint/bug/tint/1113.wgsl.expected.spvasm index ae2be84b18..f1eee0ccab 100644 --- a/test/tint/bug/tint/1113.wgsl.expected.spvasm +++ b/test/tint/bug/tint/1113.wgsl.expected.spvasm @@ -1,10 +1,10 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 404 +; Bound: 419 ; Schema: 0 OpCapability Shader - %67 = OpExtInstImport "GLSL.std.450" + %84 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %main_count "main_count" %GlobalInvocationID_1 OpEntryPoint GLCompute %main_create_lut "main_create_lut" %GlobalInvocationID_2 @@ -53,6 +53,12 @@ OpMemberName %Dbg 10 "value_f32_2" OpMemberName %Dbg 11 "value_f32_3" OpName %dbg "dbg" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" + OpName %tint_mod "tint_mod" + OpName %lhs_0 "lhs" + OpName %rhs_0 "rhs" OpName %toVoxelPos "toVoxelPos" OpName %position "position" OpName %bbMin "bbMin" @@ -201,452 +207,471 @@ %dbg_block = OpTypeStruct %Dbg %_ptr_StorageBuffer_dbg_block = OpTypePointer StorageBuffer %dbg_block %dbg = OpVariable %_ptr_StorageBuffer_dbg_block StorageBuffer - %34 = OpTypeFunction %v3float %v3float + %34 = OpTypeFunction %uint %uint %uint + %40 = OpConstantNull %uint + %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 + %52 = OpTypeFunction %v3float %v3float %uint_0 = OpConstant %uint 0 %uint_4 = OpConstant %uint 4 %_ptr_Uniform_float = OpTypePointer Uniform %float - %uint_1 = OpConstant %uint 1 %uint_2 = OpConstant %uint 2 %_ptr_Function_v3float = OpTypePointer Function %v3float - %52 = OpConstantNull %v3float + %69 = OpConstantNull %v3float %uint_5 = OpConstant %uint 5 %_ptr_Function_float = OpTypePointer Function %float - %77 = OpConstantNull %float + %94 = OpConstantNull %float %_ptr_Uniform_uint = OpTypePointer Uniform %uint - %114 = OpTypeFunction %uint %uint %v3float + %131 = OpTypeFunction %uint %uint %v3float %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %122 = OpConstantNull %v3uint + %139 = OpConstantNull %v3uint %_ptr_Function_uint = OpTypePointer Function %uint - %135 = OpTypeFunction %v3uint %uint %uint - %143 = OpConstantNull %uint - %156 = OpTypeFunction %v3float %uint + %152 = OpTypeFunction %v3uint %uint %uint + %172 = OpTypeFunction %v3float %uint %uint_3 = OpConstant %uint 3 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %void = OpTypeVoid - %177 = OpTypeFunction %void + %193 = OpTypeFunction %void %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint - %190 = OpConstantNull %int + %206 = OpConstantNull %int %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int %_ptr_Function_int = OpTypePointer Function %int - %206 = OpTypeFunction %void %v3uint - %bool = OpTypeBool + %222 = OpTypeFunction %void %v3uint %float_3 = OpConstant %float 3 %uint_8 = OpConstant %uint 8 %uint_9 = OpConstant %uint 9 %uint_10 = OpConstant %uint 10 %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 - %toVoxelPos = OpFunction %v3float None %34 - %position = OpFunctionParameter %v3float - %37 = OpLabel - %bbMin = OpVariable %_ptr_Function_v3float Function %52 - %bbMax = OpVariable %_ptr_Function_v3float Function %52 - %bbSize = OpVariable %_ptr_Function_v3float Function %52 - %cubeSize = OpVariable %_ptr_Function_float Function %77 - %gridSize = OpVariable %_ptr_Function_float Function %77 - %gx = OpVariable %_ptr_Function_float Function %77 - %gy = OpVariable %_ptr_Function_float Function %77 - %gz = OpVariable %_ptr_Function_float Function %77 - %41 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 - %42 = OpLoad %float %41 - %44 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 - %45 = OpLoad %float %44 - %47 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 - %48 = OpLoad %float %47 - %49 = OpCompositeConstruct %v3float %42 %45 %48 - OpStore %bbMin %49 - %54 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0 - %55 = OpLoad %float %54 - %56 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1 - %57 = OpLoad %float %56 - %58 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2 - %59 = OpLoad %float %58 - %60 = OpCompositeConstruct %v3float %55 %57 %59 - OpStore %bbMax %60 - %62 = OpLoad %v3float %bbMax - %63 = OpLoad %v3float %bbMin - %64 = OpFSub %v3float %62 %63 - OpStore %bbSize %64 - %70 = OpAccessChain %_ptr_Function_float %bbSize %uint_0 - %71 = OpLoad %float %70 - %72 = OpAccessChain %_ptr_Function_float %bbSize %uint_1 - %73 = OpLoad %float %72 - %68 = OpExtInst %float %67 NMax %71 %73 - %74 = OpAccessChain %_ptr_Function_float %bbSize %uint_2 - %75 = OpLoad %float %74 - %66 = OpExtInst %float %67 NMax %68 %75 - OpStore %cubeSize %66 - %80 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %81 = OpLoad %uint %80 - %78 = OpConvertUToF %float %81 - OpStore %gridSize %78 - %83 = OpLoad %float %gridSize - %84 = OpCompositeExtract %float %position 0 - %85 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 - %86 = OpLoad %float %85 - %87 = OpFSub %float %84 %86 - %88 = OpFMul %float %83 %87 - %89 = OpLoad %float %cubeSize - %90 = OpFDiv %float %88 %89 - OpStore %gx %90 - %92 = OpLoad %float %gridSize - %93 = OpCompositeExtract %float %position 1 - %94 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 - %95 = OpLoad %float %94 - %96 = OpFSub %float %93 %95 - %97 = OpFMul %float %92 %96 - %98 = OpLoad %float %cubeSize - %99 = OpFDiv %float %97 %98 - OpStore %gy %99 - %101 = OpLoad %float %gridSize - %102 = OpCompositeExtract %float %position 2 - %103 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 - %104 = OpLoad %float %103 - %105 = OpFSub %float %102 %104 - %106 = OpFMul %float %101 %105 - %107 = OpLoad %float %cubeSize - %108 = OpFDiv %float %106 %107 - OpStore %gz %108 - %110 = OpLoad %float %gx - %111 = OpLoad %float %gy - %112 = OpLoad %float %gz - %113 = OpCompositeConstruct %v3float %110 %111 %112 - OpReturnValue %113 + %tint_div = OpFunction %uint None %34 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %38 = OpLabel + %41 = OpIEqual %bool %rhs %40 + %39 = OpSelect %uint %41 %uint_1 %rhs + %44 = OpUDiv %uint %lhs %39 + OpReturnValue %44 OpFunctionEnd - %toIndex1D = OpFunction %uint None %114 + %tint_mod = OpFunction %uint None %34 + %lhs_0 = OpFunctionParameter %uint + %rhs_0 = OpFunctionParameter %uint + %48 = OpLabel + %50 = OpIEqual %bool %rhs_0 %40 + %49 = OpSelect %uint %50 %uint_1 %rhs_0 + %51 = OpUMod %uint %lhs_0 %49 + OpReturnValue %51 + OpFunctionEnd + %toVoxelPos = OpFunction %v3float None %52 + %position = OpFunctionParameter %v3float + %55 = OpLabel + %bbMin = OpVariable %_ptr_Function_v3float Function %69 + %bbMax = OpVariable %_ptr_Function_v3float Function %69 + %bbSize = OpVariable %_ptr_Function_v3float Function %69 + %cubeSize = OpVariable %_ptr_Function_float Function %94 + %gridSize = OpVariable %_ptr_Function_float Function %94 + %gx = OpVariable %_ptr_Function_float Function %94 + %gy = OpVariable %_ptr_Function_float Function %94 + %gz = OpVariable %_ptr_Function_float Function %94 + %59 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 + %60 = OpLoad %float %59 + %61 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 + %62 = OpLoad %float %61 + %64 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 + %65 = OpLoad %float %64 + %66 = OpCompositeConstruct %v3float %60 %62 %65 + OpStore %bbMin %66 + %71 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_0 + %72 = OpLoad %float %71 + %73 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_1 + %74 = OpLoad %float %73 + %75 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_5 %uint_2 + %76 = OpLoad %float %75 + %77 = OpCompositeConstruct %v3float %72 %74 %76 + OpStore %bbMax %77 + %79 = OpLoad %v3float %bbMax + %80 = OpLoad %v3float %bbMin + %81 = OpFSub %v3float %79 %80 + OpStore %bbSize %81 + %87 = OpAccessChain %_ptr_Function_float %bbSize %uint_0 + %88 = OpLoad %float %87 + %89 = OpAccessChain %_ptr_Function_float %bbSize %uint_1 + %90 = OpLoad %float %89 + %85 = OpExtInst %float %84 NMax %88 %90 + %91 = OpAccessChain %_ptr_Function_float %bbSize %uint_2 + %92 = OpLoad %float %91 + %83 = OpExtInst %float %84 NMax %85 %92 + OpStore %cubeSize %83 + %97 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %98 = OpLoad %uint %97 + %95 = OpConvertUToF %float %98 + OpStore %gridSize %95 + %100 = OpLoad %float %gridSize + %101 = OpCompositeExtract %float %position 0 + %102 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_0 + %103 = OpLoad %float %102 + %104 = OpFSub %float %101 %103 + %105 = OpFMul %float %100 %104 + %106 = OpLoad %float %cubeSize + %107 = OpFDiv %float %105 %106 + OpStore %gx %107 + %109 = OpLoad %float %gridSize + %110 = OpCompositeExtract %float %position 1 + %111 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_1 + %112 = OpLoad %float %111 + %113 = OpFSub %float %110 %112 + %114 = OpFMul %float %109 %113 + %115 = OpLoad %float %cubeSize + %116 = OpFDiv %float %114 %115 + OpStore %gy %116 + %118 = OpLoad %float %gridSize + %119 = OpCompositeExtract %float %position 2 + %120 = OpAccessChain %_ptr_Uniform_float %uniforms %uint_0 %uint_4 %uint_2 + %121 = OpLoad %float %120 + %122 = OpFSub %float %119 %121 + %123 = OpFMul %float %118 %122 + %124 = OpLoad %float %cubeSize + %125 = OpFDiv %float %123 %124 + OpStore %gz %125 + %127 = OpLoad %float %gx + %128 = OpLoad %float %gy + %129 = OpLoad %float %gz + %130 = OpCompositeConstruct %v3float %127 %128 %129 + OpReturnValue %130 + OpFunctionEnd + %toIndex1D = OpFunction %uint None %131 %gridSize_0 = OpFunctionParameter %uint %voxelPos = OpFunctionParameter %v3float - %118 = OpLabel - %icoord = OpVariable %_ptr_Function_v3uint Function %122 - %119 = OpConvertFToU %v3uint %voxelPos - OpStore %icoord %119 - %124 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 - %125 = OpLoad %uint %124 - %126 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 - %127 = OpLoad %uint %126 - %128 = OpIMul %uint %gridSize_0 %127 - %129 = OpIAdd %uint %125 %128 - %130 = OpIMul %uint %gridSize_0 %gridSize_0 - %131 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 - %132 = OpLoad %uint %131 - %133 = OpIMul %uint %130 %132 - %134 = OpIAdd %uint %129 %133 - OpReturnValue %134 + %135 = OpLabel + %icoord = OpVariable %_ptr_Function_v3uint Function %139 + %136 = OpConvertFToU %v3uint %voxelPos + OpStore %icoord %136 + %141 = OpAccessChain %_ptr_Function_uint %icoord %uint_0 + %142 = OpLoad %uint %141 + %143 = OpAccessChain %_ptr_Function_uint %icoord %uint_1 + %144 = OpLoad %uint %143 + %145 = OpIMul %uint %gridSize_0 %144 + %146 = OpIAdd %uint %142 %145 + %147 = OpIMul %uint %gridSize_0 %gridSize_0 + %148 = OpAccessChain %_ptr_Function_uint %icoord %uint_2 + %149 = OpLoad %uint %148 + %150 = OpIMul %uint %147 %149 + %151 = OpIAdd %uint %146 %150 + OpReturnValue %151 OpFunctionEnd - %toIndex3D = OpFunction %v3uint None %135 + %toIndex3D = OpFunction %v3uint None %152 %gridSize_1 = OpFunctionParameter %uint %index = OpFunctionParameter %uint - %139 = OpLabel - %z = OpVariable %_ptr_Function_uint Function %143 - %y = OpVariable %_ptr_Function_uint Function %143 - %x = OpVariable %_ptr_Function_uint Function %143 - %140 = OpIMul %uint %gridSize_1 %gridSize_1 - %141 = OpUDiv %uint %index %140 - OpStore %z %141 - %144 = OpIMul %uint %gridSize_1 %gridSize_1 - %145 = OpLoad %uint %z - %146 = OpIMul %uint %144 %145 - %147 = OpISub %uint %index %146 - %148 = OpUDiv %uint %147 %gridSize_1 - OpStore %y %148 - %150 = OpUMod %uint %index %gridSize_1 - OpStore %x %150 - %152 = OpLoad %uint %x - %153 = OpLoad %uint %y - %154 = OpLoad %uint %z - %155 = OpCompositeConstruct %v3uint %152 %153 %154 - OpReturnValue %155 + %156 = OpLabel + %z = OpVariable %_ptr_Function_uint Function %40 + %y = OpVariable %_ptr_Function_uint Function %40 + %x = OpVariable %_ptr_Function_uint Function %40 + %158 = OpIMul %uint %gridSize_1 %gridSize_1 + %157 = OpFunctionCall %uint %tint_div %index %158 + OpStore %z %157 + %161 = OpIMul %uint %gridSize_1 %gridSize_1 + %162 = OpLoad %uint %z + %163 = OpIMul %uint %161 %162 + %164 = OpISub %uint %index %163 + %160 = OpFunctionCall %uint %tint_div %164 %gridSize_1 + OpStore %y %160 + %166 = OpFunctionCall %uint %tint_mod %index %gridSize_1 + OpStore %x %166 + %168 = OpLoad %uint %x + %169 = OpLoad %uint %y + %170 = OpLoad %uint %z + %171 = OpCompositeConstruct %v3uint %168 %169 %170 + OpReturnValue %171 OpFunctionEnd -%loadPosition = OpFunction %v3float None %156 +%loadPosition = OpFunction %v3float None %172 %vertexIndex = OpFunctionParameter %uint - %159 = OpLabel - %position_0 = OpVariable %_ptr_Function_v3float Function %52 - %161 = OpIMul %uint %uint_3 %vertexIndex - %162 = OpIAdd %uint %161 %143 - %164 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %162 - %165 = OpLoad %float %164 - %166 = OpIMul %uint %uint_3 %vertexIndex - %167 = OpIAdd %uint %166 %uint_1 - %168 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %167 - %169 = OpLoad %float %168 - %170 = OpIMul %uint %uint_3 %vertexIndex - %171 = OpIAdd %uint %170 %uint_2 - %172 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %171 - %173 = OpLoad %float %172 - %174 = OpCompositeConstruct %v3float %165 %169 %173 - OpStore %position_0 %174 - %176 = OpLoad %v3float %position_0 - OpReturnValue %176 + %175 = OpLabel + %position_0 = OpVariable %_ptr_Function_v3float Function %69 + %177 = OpIMul %uint %uint_3 %vertexIndex + %178 = OpIAdd %uint %177 %40 + %180 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %178 + %181 = OpLoad %float %180 + %182 = OpIMul %uint %uint_3 %vertexIndex + %183 = OpIAdd %uint %182 %uint_1 + %184 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %183 + %185 = OpLoad %float %184 + %186 = OpIMul %uint %uint_3 %vertexIndex + %187 = OpIAdd %uint %186 %uint_2 + %188 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %187 + %189 = OpLoad %float %188 + %190 = OpCompositeConstruct %v3float %181 %185 %189 + OpStore %position_0 %190 + %192 = OpLoad %v3float %position_0 + OpReturnValue %192 OpFunctionEnd - %doIgnore = OpFunction %void None %177 - %180 = OpLabel - %g42 = OpVariable %_ptr_Function_uint Function %143 - %kj6 = OpVariable %_ptr_Function_uint Function %143 - %b53 = OpVariable %_ptr_Function_uint Function %143 - %rwg = OpVariable %_ptr_Function_uint Function %143 - %rb5 = OpVariable %_ptr_Function_float Function %77 - %g55 = OpVariable %_ptr_Function_int Function %190 - %181 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %182 = OpLoad %uint %181 - OpStore %g42 %182 - %185 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 - %186 = OpLoad %uint %185 - OpStore %kj6 %186 - %192 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %190 - %188 = OpAtomicLoad %uint %192 %uint_1 %uint_0 - OpStore %b53 %188 - %194 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %190 - %195 = OpLoad %uint %194 - OpStore %rwg %195 - %197 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %190 - %198 = OpLoad %float %197 - OpStore %rb5 %198 - %203 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %190 - %200 = OpAtomicLoad %int %203 %uint_1 %uint_0 - OpStore %g55 %200 + %doIgnore = OpFunction %void None %193 + %196 = OpLabel + %g42 = OpVariable %_ptr_Function_uint Function %40 + %kj6 = OpVariable %_ptr_Function_uint Function %40 + %b53 = OpVariable %_ptr_Function_uint Function %40 + %rwg = OpVariable %_ptr_Function_uint Function %40 + %rb5 = OpVariable %_ptr_Function_float Function %94 + %g55 = OpVariable %_ptr_Function_int Function %206 + %197 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 + %198 = OpLoad %uint %197 + OpStore %g42 %198 + %201 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_5 + %202 = OpLoad %uint %201 + OpStore %kj6 %202 + %208 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %206 + %204 = OpAtomicLoad %uint %208 %uint_1 %uint_0 + OpStore %b53 %204 + %210 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %206 + %211 = OpLoad %uint %210 + OpStore %rwg %211 + %213 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %206 + %214 = OpLoad %float %213 + OpStore %rb5 %214 + %219 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %206 + %216 = OpAtomicLoad %int %219 %uint_1 %uint_0 + OpStore %g55 %216 OpReturn OpFunctionEnd -%main_count_inner = OpFunction %void None %206 +%main_count_inner = OpFunction %void None %222 %GlobalInvocationID = OpFunctionParameter %v3uint - %209 = OpLabel -%triangleIndex = OpVariable %_ptr_Function_uint Function %143 - %i0 = OpVariable %_ptr_Function_uint Function %143 - %i1 = OpVariable %_ptr_Function_uint Function %143 - %i2 = OpVariable %_ptr_Function_uint Function %143 - %p0 = OpVariable %_ptr_Function_v3float Function %52 - %p1 = OpVariable %_ptr_Function_v3float Function %52 - %p2 = OpVariable %_ptr_Function_v3float Function %52 - %254 = OpVariable %_ptr_Function_v3float Function %52 - %center = OpVariable %_ptr_Function_v3float Function %52 - %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %52 - %voxelIndex = OpVariable %_ptr_Function_uint Function %143 - %acefg = OpVariable %_ptr_Function_uint Function %143 - %210 = OpCompositeExtract %uint %GlobalInvocationID 0 - OpStore %triangleIndex %210 - %212 = OpLoad %uint %triangleIndex - %213 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %214 = OpLoad %uint %213 - %215 = OpUGreaterThanEqual %bool %212 %214 - OpSelectionMerge %217 None - OpBranchConditional %215 %218 %217 - %218 = OpLabel - OpReturn - %217 = OpLabel - %219 = OpFunctionCall %void %doIgnore - %220 = OpLoad %uint %triangleIndex - %221 = OpIMul %uint %uint_3 %220 - %222 = OpIAdd %uint %221 %143 - %223 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %222 - %224 = OpLoad %uint %223 - OpStore %i0 %224 - %226 = OpLoad %uint %triangleIndex - %227 = OpIMul %uint %uint_3 %226 - %228 = OpIAdd %uint %227 %uint_1 - %229 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %228 + %225 = OpLabel +%triangleIndex = OpVariable %_ptr_Function_uint Function %40 + %i0 = OpVariable %_ptr_Function_uint Function %40 + %i1 = OpVariable %_ptr_Function_uint Function %40 + %i2 = OpVariable %_ptr_Function_uint Function %40 + %p0 = OpVariable %_ptr_Function_v3float Function %69 + %p1 = OpVariable %_ptr_Function_v3float Function %69 + %p2 = OpVariable %_ptr_Function_v3float Function %69 + %269 = OpVariable %_ptr_Function_v3float Function %69 + %center = OpVariable %_ptr_Function_v3float Function %69 + %voxelPos_0 = OpVariable %_ptr_Function_v3float Function %69 + %voxelIndex = OpVariable %_ptr_Function_uint Function %40 + %acefg = OpVariable %_ptr_Function_uint Function %40 + %226 = OpCompositeExtract %uint %GlobalInvocationID 0 + OpStore %triangleIndex %226 + %228 = OpLoad %uint %triangleIndex + %229 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 %230 = OpLoad %uint %229 - OpStore %i1 %230 - %232 = OpLoad %uint %triangleIndex - %233 = OpIMul %uint %uint_3 %232 - %234 = OpIAdd %uint %233 %uint_2 - %235 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %234 - %236 = OpLoad %uint %235 - OpStore %i2 %236 - %239 = OpLoad %uint %i0 - %238 = OpFunctionCall %v3float %loadPosition %239 - OpStore %p0 %238 - %242 = OpLoad %uint %i1 - %241 = OpFunctionCall %v3float %loadPosition %242 - OpStore %p1 %241 - %245 = OpLoad %uint %i2 - %244 = OpFunctionCall %v3float %loadPosition %245 - OpStore %p2 %244 - %247 = OpLoad %v3float %p0 - %248 = OpLoad %v3float %p1 - %249 = OpFAdd %v3float %247 %248 - %250 = OpLoad %v3float %p2 - %251 = OpFAdd %v3float %249 %250 - %255 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 - %253 = OpFDiv %v3float %251 %255 - OpStore %center %253 - %258 = OpLoad %v3float %center - %257 = OpFunctionCall %v3float %toVoxelPos %258 - OpStore %voxelPos_0 %257 - %261 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %262 = OpLoad %uint %261 - %263 = OpLoad %v3float %voxelPos_0 - %260 = OpFunctionCall %uint %toIndex1D %262 %263 - OpStore %voxelIndex %260 - %267 = OpLoad %uint %voxelIndex - %268 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %267 - %265 = OpAtomicIAdd %uint %268 %uint_1 %uint_0 %uint_1 - OpStore %acefg %265 - %270 = OpLoad %uint %triangleIndex - %271 = OpIEqual %bool %270 %143 - OpSelectionMerge %272 None - OpBranchConditional %271 %273 %272 - %273 = OpLabel - %274 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_4 - %275 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %276 = OpLoad %uint %275 - OpStore %274 %276 - %278 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_8 - %279 = OpAccessChain %_ptr_Function_float %center %uint_0 - %280 = OpLoad %float %279 - OpStore %278 %280 - %282 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_9 - %283 = OpAccessChain %_ptr_Function_float %center %uint_1 - %284 = OpLoad %float %283 - OpStore %282 %284 - %286 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_10 - %287 = OpAccessChain %_ptr_Function_float %center %uint_2 - %288 = OpLoad %float %287 - OpStore %286 %288 - OpBranch %272 - %272 = OpLabel + %231 = OpUGreaterThanEqual %bool %228 %230 + OpSelectionMerge %232 None + OpBranchConditional %231 %233 %232 + %233 = OpLabel + OpReturn + %232 = OpLabel + %234 = OpFunctionCall %void %doIgnore + %235 = OpLoad %uint %triangleIndex + %236 = OpIMul %uint %uint_3 %235 + %237 = OpIAdd %uint %236 %40 + %238 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %237 + %239 = OpLoad %uint %238 + OpStore %i0 %239 + %241 = OpLoad %uint %triangleIndex + %242 = OpIMul %uint %uint_3 %241 + %243 = OpIAdd %uint %242 %uint_1 + %244 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %243 + %245 = OpLoad %uint %244 + OpStore %i1 %245 + %247 = OpLoad %uint %triangleIndex + %248 = OpIMul %uint %uint_3 %247 + %249 = OpIAdd %uint %248 %uint_2 + %250 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %249 + %251 = OpLoad %uint %250 + OpStore %i2 %251 + %254 = OpLoad %uint %i0 + %253 = OpFunctionCall %v3float %loadPosition %254 + OpStore %p0 %253 + %257 = OpLoad %uint %i1 + %256 = OpFunctionCall %v3float %loadPosition %257 + OpStore %p1 %256 + %260 = OpLoad %uint %i2 + %259 = OpFunctionCall %v3float %loadPosition %260 + OpStore %p2 %259 + %262 = OpLoad %v3float %p0 + %263 = OpLoad %v3float %p1 + %264 = OpFAdd %v3float %262 %263 + %265 = OpLoad %v3float %p2 + %266 = OpFAdd %v3float %264 %265 + %270 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 + %268 = OpFDiv %v3float %266 %270 + OpStore %center %268 + %273 = OpLoad %v3float %center + %272 = OpFunctionCall %v3float %toVoxelPos %273 + OpStore %voxelPos_0 %272 + %276 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %277 = OpLoad %uint %276 + %278 = OpLoad %v3float %voxelPos_0 + %275 = OpFunctionCall %uint %toIndex1D %277 %278 + OpStore %voxelIndex %275 + %282 = OpLoad %uint %voxelIndex + %283 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %282 + %280 = OpAtomicIAdd %uint %283 %uint_1 %uint_0 %uint_1 + OpStore %acefg %280 + %285 = OpLoad %uint %triangleIndex + %286 = OpIEqual %bool %285 %40 + OpSelectionMerge %287 None + OpBranchConditional %286 %288 %287 + %288 = OpLabel + %289 = OpAccessChain %_ptr_StorageBuffer_uint %dbg %uint_0 %uint_4 + %290 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %291 = OpLoad %uint %290 + OpStore %289 %291 + %293 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_8 + %294 = OpAccessChain %_ptr_Function_float %center %uint_0 + %295 = OpLoad %float %294 + OpStore %293 %295 + %297 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_9 + %298 = OpAccessChain %_ptr_Function_float %center %uint_1 + %299 = OpLoad %float %298 + OpStore %297 %299 + %301 = OpAccessChain %_ptr_StorageBuffer_float %dbg %uint_0 %uint_10 + %302 = OpAccessChain %_ptr_Function_float %center %uint_2 + %303 = OpLoad %float %302 + OpStore %301 %303 + OpBranch %287 + %287 = OpLabel OpReturn OpFunctionEnd - %main_count = OpFunction %void None %177 - %290 = OpLabel - %292 = OpLoad %v3uint %GlobalInvocationID_1 - %291 = OpFunctionCall %void %main_count_inner %292 + %main_count = OpFunction %void None %193 + %305 = OpLabel + %307 = OpLoad %v3uint %GlobalInvocationID_1 + %306 = OpFunctionCall %void %main_count_inner %307 OpReturn OpFunctionEnd -%main_create_lut_inner = OpFunction %void None %206 +%main_create_lut_inner = OpFunction %void None %222 %GlobalInvocationID_0 = OpFunctionParameter %v3uint - %295 = OpLabel -%voxelIndex_0 = OpVariable %_ptr_Function_uint Function %143 - %maxVoxels = OpVariable %_ptr_Function_uint Function %143 -%numTriangles = OpVariable %_ptr_Function_uint Function %143 - %offset = OpVariable %_ptr_Function_int Function %190 - %296 = OpCompositeExtract %uint %GlobalInvocationID_0 0 - OpStore %voxelIndex_0 %296 - %298 = OpFunctionCall %void %doIgnore - %299 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %300 = OpLoad %uint %299 - %301 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %302 = OpLoad %uint %301 - %303 = OpIMul %uint %300 %302 - %304 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %305 = OpLoad %uint %304 - %306 = OpIMul %uint %303 %305 - OpStore %maxVoxels %306 - %308 = OpLoad %uint %voxelIndex_0 - %309 = OpLoad %uint %maxVoxels - %310 = OpUGreaterThanEqual %bool %308 %309 - OpSelectionMerge %311 None - OpBranchConditional %310 %312 %311 - %312 = OpLabel + %310 = OpLabel +%voxelIndex_0 = OpVariable %_ptr_Function_uint Function %40 + %maxVoxels = OpVariable %_ptr_Function_uint Function %40 +%numTriangles = OpVariable %_ptr_Function_uint Function %40 + %offset = OpVariable %_ptr_Function_int Function %206 + %311 = OpCompositeExtract %uint %GlobalInvocationID_0 0 + OpStore %voxelIndex_0 %311 + %313 = OpFunctionCall %void %doIgnore + %314 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %315 = OpLoad %uint %314 + %316 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %317 = OpLoad %uint %316 + %318 = OpIMul %uint %315 %317 + %319 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %320 = OpLoad %uint %319 + %321 = OpIMul %uint %318 %320 + OpStore %maxVoxels %321 + %323 = OpLoad %uint %voxelIndex_0 + %324 = OpLoad %uint %maxVoxels + %325 = OpUGreaterThanEqual %bool %323 %324 + OpSelectionMerge %326 None + OpBranchConditional %325 %327 %326 + %327 = OpLabel OpReturn - %311 = OpLabel - %315 = OpLoad %uint %voxelIndex_0 - %316 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %315 - %313 = OpAtomicLoad %uint %316 %uint_1 %uint_0 - OpStore %numTriangles %313 + %326 = OpLabel + %330 = OpLoad %uint %voxelIndex_0 + %331 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %330 + %328 = OpAtomicLoad %uint %331 %uint_1 %uint_0 + OpStore %numTriangles %328 OpStore %offset %int_n1 - %320 = OpLoad %uint %numTriangles - %321 = OpUGreaterThan %bool %320 %143 - OpSelectionMerge %322 None - OpBranchConditional %321 %323 %322 - %323 = OpLabel - %326 = OpAccessChain %_ptr_StorageBuffer_uint_0 %dbg %uint_0 %uint_0 - %327 = OpLoad %uint %numTriangles - %324 = OpAtomicIAdd %uint %326 %uint_1 %uint_0 %327 - %328 = OpBitcast %int %324 - OpStore %offset %328 - OpBranch %322 - %322 = OpLabel - %331 = OpLoad %uint %voxelIndex_0 - %332 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %331 - %333 = OpLoad %int %offset - OpAtomicStore %332 %uint_1 %uint_0 %333 + %335 = OpLoad %uint %numTriangles + %336 = OpUGreaterThan %bool %335 %40 + OpSelectionMerge %337 None + OpBranchConditional %336 %338 %337 + %338 = OpLabel + %341 = OpAccessChain %_ptr_StorageBuffer_uint_0 %dbg %uint_0 %uint_0 + %342 = OpLoad %uint %numTriangles + %339 = OpAtomicIAdd %uint %341 %uint_1 %uint_0 %342 + %343 = OpBitcast %int %339 + OpStore %offset %343 + OpBranch %337 + %337 = OpLabel + %346 = OpLoad %uint %voxelIndex_0 + %347 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %346 + %348 = OpLoad %int %offset + OpAtomicStore %347 %uint_1 %uint_0 %348 OpReturn OpFunctionEnd -%main_create_lut = OpFunction %void None %177 - %335 = OpLabel - %337 = OpLoad %v3uint %GlobalInvocationID_2 - %336 = OpFunctionCall %void %main_create_lut_inner %337 +%main_create_lut = OpFunction %void None %193 + %350 = OpLabel + %352 = OpLoad %v3uint %GlobalInvocationID_2 + %351 = OpFunctionCall %void %main_create_lut_inner %352 OpReturn OpFunctionEnd -%main_sort_triangles_inner = OpFunction %void None %206 +%main_sort_triangles_inner = OpFunction %void None %222 %GlobalInvocationID_4 = OpFunctionParameter %v3uint - %340 = OpLabel -%triangleIndex_0 = OpVariable %_ptr_Function_uint Function %143 - %i0_0 = OpVariable %_ptr_Function_uint Function %143 - %i1_0 = OpVariable %_ptr_Function_uint Function %143 - %i2_0 = OpVariable %_ptr_Function_uint Function %143 - %p0_0 = OpVariable %_ptr_Function_v3float Function %52 - %p1_0 = OpVariable %_ptr_Function_v3float Function %52 - %p2_0 = OpVariable %_ptr_Function_v3float Function %52 - %383 = OpVariable %_ptr_Function_v3float Function %52 - %center_0 = OpVariable %_ptr_Function_v3float Function %52 - %voxelPos_1 = OpVariable %_ptr_Function_v3float Function %52 -%voxelIndex_1 = OpVariable %_ptr_Function_uint Function %143 -%triangleOffset = OpVariable %_ptr_Function_int Function %190 - %341 = OpCompositeExtract %uint %GlobalInvocationID_4 0 - OpStore %triangleIndex_0 %341 - %343 = OpFunctionCall %void %doIgnore - %344 = OpLoad %uint %triangleIndex_0 - %345 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %346 = OpLoad %uint %345 - %347 = OpUGreaterThanEqual %bool %344 %346 - OpSelectionMerge %348 None - OpBranchConditional %347 %349 %348 - %349 = OpLabel + %355 = OpLabel +%triangleIndex_0 = OpVariable %_ptr_Function_uint Function %40 + %i0_0 = OpVariable %_ptr_Function_uint Function %40 + %i1_0 = OpVariable %_ptr_Function_uint Function %40 + %i2_0 = OpVariable %_ptr_Function_uint Function %40 + %p0_0 = OpVariable %_ptr_Function_v3float Function %69 + %p1_0 = OpVariable %_ptr_Function_v3float Function %69 + %p2_0 = OpVariable %_ptr_Function_v3float Function %69 + %398 = OpVariable %_ptr_Function_v3float Function %69 + %center_0 = OpVariable %_ptr_Function_v3float Function %69 + %voxelPos_1 = OpVariable %_ptr_Function_v3float Function %69 +%voxelIndex_1 = OpVariable %_ptr_Function_uint Function %40 +%triangleOffset = OpVariable %_ptr_Function_int Function %206 + %356 = OpCompositeExtract %uint %GlobalInvocationID_4 0 + OpStore %triangleIndex_0 %356 + %358 = OpFunctionCall %void %doIgnore + %359 = OpLoad %uint %triangleIndex_0 + %360 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 + %361 = OpLoad %uint %360 + %362 = OpUGreaterThanEqual %bool %359 %361 + OpSelectionMerge %363 None + OpBranchConditional %362 %364 %363 + %364 = OpLabel OpReturn - %348 = OpLabel - %350 = OpLoad %uint %triangleIndex_0 - %351 = OpIMul %uint %uint_3 %350 - %352 = OpIAdd %uint %351 %143 - %353 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %352 - %354 = OpLoad %uint %353 - OpStore %i0_0 %354 - %356 = OpLoad %uint %triangleIndex_0 - %357 = OpIMul %uint %uint_3 %356 - %358 = OpIAdd %uint %357 %uint_1 - %359 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %358 - %360 = OpLoad %uint %359 - OpStore %i1_0 %360 - %362 = OpLoad %uint %triangleIndex_0 - %363 = OpIMul %uint %uint_3 %362 - %364 = OpIAdd %uint %363 %uint_2 - %365 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %364 - %366 = OpLoad %uint %365 - OpStore %i2_0 %366 - %369 = OpLoad %uint %i0_0 - %368 = OpFunctionCall %v3float %loadPosition %369 - OpStore %p0_0 %368 - %372 = OpLoad %uint %i1_0 - %371 = OpFunctionCall %v3float %loadPosition %372 - OpStore %p1_0 %371 - %375 = OpLoad %uint %i2_0 - %374 = OpFunctionCall %v3float %loadPosition %375 - OpStore %p2_0 %374 - %377 = OpLoad %v3float %p0_0 - %378 = OpLoad %v3float %p1_0 - %379 = OpFAdd %v3float %377 %378 - %380 = OpLoad %v3float %p2_0 - %381 = OpFAdd %v3float %379 %380 - %384 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 - %382 = OpFDiv %v3float %381 %384 - OpStore %center_0 %382 - %387 = OpLoad %v3float %center_0 - %386 = OpFunctionCall %v3float %toVoxelPos %387 - OpStore %voxelPos_1 %386 - %390 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %391 = OpLoad %uint %390 - %392 = OpLoad %v3float %voxelPos_1 - %389 = OpFunctionCall %uint %toIndex1D %391 %392 - OpStore %voxelIndex_1 %389 - %396 = OpLoad %uint %voxelIndex_1 - %397 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %396 - %394 = OpAtomicIAdd %int %397 %uint_1 %uint_0 %int_1 - OpStore %triangleOffset %394 + %363 = OpLabel + %365 = OpLoad %uint %triangleIndex_0 + %366 = OpIMul %uint %uint_3 %365 + %367 = OpIAdd %uint %366 %40 + %368 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %367 + %369 = OpLoad %uint %368 + OpStore %i0_0 %369 + %371 = OpLoad %uint %triangleIndex_0 + %372 = OpIMul %uint %uint_3 %371 + %373 = OpIAdd %uint %372 %uint_1 + %374 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %373 + %375 = OpLoad %uint %374 + OpStore %i1_0 %375 + %377 = OpLoad %uint %triangleIndex_0 + %378 = OpIMul %uint %uint_3 %377 + %379 = OpIAdd %uint %378 %uint_2 + %380 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %379 + %381 = OpLoad %uint %380 + OpStore %i2_0 %381 + %384 = OpLoad %uint %i0_0 + %383 = OpFunctionCall %v3float %loadPosition %384 + OpStore %p0_0 %383 + %387 = OpLoad %uint %i1_0 + %386 = OpFunctionCall %v3float %loadPosition %387 + OpStore %p1_0 %386 + %390 = OpLoad %uint %i2_0 + %389 = OpFunctionCall %v3float %loadPosition %390 + OpStore %p2_0 %389 + %392 = OpLoad %v3float %p0_0 + %393 = OpLoad %v3float %p1_0 + %394 = OpFAdd %v3float %392 %393 + %395 = OpLoad %v3float %p2_0 + %396 = OpFAdd %v3float %394 %395 + %399 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3 + %397 = OpFDiv %v3float %396 %399 + OpStore %center_0 %397 + %402 = OpLoad %v3float %center_0 + %401 = OpFunctionCall %v3float %toVoxelPos %402 + OpStore %voxelPos_1 %401 + %405 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %406 = OpLoad %uint %405 + %407 = OpLoad %v3float %voxelPos_1 + %404 = OpFunctionCall %uint %toIndex1D %406 %407 + OpStore %voxelIndex_1 %404 + %411 = OpLoad %uint %voxelIndex_1 + %412 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %411 + %409 = OpAtomicIAdd %int %412 %uint_1 %uint_0 %int_1 + OpStore %triangleOffset %409 OpReturn OpFunctionEnd -%main_sort_triangles = OpFunction %void None %177 - %401 = OpLabel - %403 = OpLoad %v3uint %GlobalInvocationID_3 - %402 = OpFunctionCall %void %main_sort_triangles_inner %403 +%main_sort_triangles = OpFunction %void None %193 + %416 = OpLabel + %418 = OpLoad %v3uint %GlobalInvocationID_3 + %417 = OpFunctionCall %void %main_sort_triangles_inner %418 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/1520.spvasm.expected.dxc.hlsl b/test/tint/bug/tint/1520.spvasm.expected.dxc.hlsl index 211fd62802..e07e2fa318 100644 --- a/test/tint/bug/tint/1520.spvasm.expected.dxc.hlsl +++ b/test/tint/bug/tint/1520.spvasm.expected.dxc.hlsl @@ -1,5 +1,5 @@ -int4 value_or_one_if_zero_int4(int4 value) { - return value == int4(0, 0, 0, 0) ? int4(1, 1, 1, 1) : value; +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); } cbuffer cbuffer_x_4 : register(b0, space0) { @@ -25,7 +25,8 @@ bool test_int_S1_c0_b() { ok = true; x_41 = false; if (true) { - x_40 = all((((0).xxxx / value_or_one_if_zero_int4(int4(x_27, x_27, x_27, x_27))) == (0).xxxx)); + const int4 tint_symbol_3 = tint_div((0).xxxx, int4(x_27, x_27, x_27, x_27)); + x_40 = all((tint_symbol_3 == (0).xxxx)); x_41 = x_40; } ok = x_41; @@ -47,11 +48,11 @@ bool test_int_S1_c0_b() { ok = x_55; const int4 x_58 = (x_50 * (2).xxxx); val = x_58; - const int4 x_59 = (x_58 / (2).xxxx); + const int4 x_59 = tint_div(x_58, (2).xxxx); val = x_59; const int4 x_60 = (x_59 * (2).xxxx); val = x_60; - const int4 x_61 = (x_60 / (2).xxxx); + const int4 x_61 = tint_div(x_60, (2).xxxx); val = x_61; x_66 = false; if (x_55) { @@ -151,8 +152,8 @@ main_out main_inner(bool sk_Clockwise_param, float4 vcolor_S0_param) { sk_Clockwise = sk_Clockwise_param; vcolor_S0 = vcolor_S0_param; main_1(); - const main_out tint_symbol_5 = {sk_FragColor}; - return tint_symbol_5; + const main_out tint_symbol_6 = {sk_FragColor}; + return tint_symbol_6; } tint_symbol_2 main(tint_symbol_1 tint_symbol) { diff --git a/test/tint/bug/tint/1520.spvasm.expected.fxc.hlsl b/test/tint/bug/tint/1520.spvasm.expected.fxc.hlsl index 211fd62802..e07e2fa318 100644 --- a/test/tint/bug/tint/1520.spvasm.expected.fxc.hlsl +++ b/test/tint/bug/tint/1520.spvasm.expected.fxc.hlsl @@ -1,5 +1,5 @@ -int4 value_or_one_if_zero_int4(int4 value) { - return value == int4(0, 0, 0, 0) ? int4(1, 1, 1, 1) : value; +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); } cbuffer cbuffer_x_4 : register(b0, space0) { @@ -25,7 +25,8 @@ bool test_int_S1_c0_b() { ok = true; x_41 = false; if (true) { - x_40 = all((((0).xxxx / value_or_one_if_zero_int4(int4(x_27, x_27, x_27, x_27))) == (0).xxxx)); + const int4 tint_symbol_3 = tint_div((0).xxxx, int4(x_27, x_27, x_27, x_27)); + x_40 = all((tint_symbol_3 == (0).xxxx)); x_41 = x_40; } ok = x_41; @@ -47,11 +48,11 @@ bool test_int_S1_c0_b() { ok = x_55; const int4 x_58 = (x_50 * (2).xxxx); val = x_58; - const int4 x_59 = (x_58 / (2).xxxx); + const int4 x_59 = tint_div(x_58, (2).xxxx); val = x_59; const int4 x_60 = (x_59 * (2).xxxx); val = x_60; - const int4 x_61 = (x_60 / (2).xxxx); + const int4 x_61 = tint_div(x_60, (2).xxxx); val = x_61; x_66 = false; if (x_55) { @@ -151,8 +152,8 @@ main_out main_inner(bool sk_Clockwise_param, float4 vcolor_S0_param) { sk_Clockwise = sk_Clockwise_param; vcolor_S0 = vcolor_S0_param; main_1(); - const main_out tint_symbol_5 = {sk_FragColor}; - return tint_symbol_5; + const main_out tint_symbol_6 = {sk_FragColor}; + return tint_symbol_6; } tint_symbol_2 main(tint_symbol_1 tint_symbol) { diff --git a/test/tint/bug/tint/1520.spvasm.expected.glsl b/test/tint/bug/tint/1520.spvasm.expected.glsl index 74b44090c0..fbf2852b99 100644 --- a/test/tint/bug/tint/1520.spvasm.expected.glsl +++ b/test/tint/bug/tint/1520.spvasm.expected.glsl @@ -3,6 +3,10 @@ precision mediump float; layout(location = 0) in vec4 vcolor_S0_param_1; layout(location = 0) out vec4 sk_FragColor_1_1; +ivec4 tint_div(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)))))))); +} + struct UniformBuffer { uint pad; uint pad_1; @@ -40,7 +44,8 @@ bool test_int_S1_c0_b() { ok = true; x_41 = false; if (true) { - x_40 = all(equal((ivec4(0) / ivec4(x_27, x_27, x_27, x_27)), ivec4(0))); + ivec4 tint_symbol_1 = tint_div(ivec4(0), ivec4(x_27, x_27, x_27, x_27)); + x_40 = all(equal(tint_symbol_1, ivec4(0))); x_41 = x_40; } ok = x_41; @@ -62,11 +67,11 @@ bool test_int_S1_c0_b() { ok = x_55; ivec4 x_58 = (x_50 * ivec4(2)); val = x_58; - ivec4 x_59 = (x_58 / ivec4(2)); + ivec4 x_59 = tint_div(x_58, ivec4(2)); val = x_59; ivec4 x_60 = (x_59 * ivec4(2)); val = x_60; - ivec4 x_61 = (x_60 / ivec4(2)); + ivec4 x_61 = tint_div(x_60, ivec4(2)); val = x_61; x_66 = false; if (x_55) { @@ -159,8 +164,8 @@ main_out tint_symbol(bool sk_Clockwise_param, vec4 vcolor_S0_param) { sk_Clockwise = sk_Clockwise_param; vcolor_S0 = vcolor_S0_param; main_1(); - main_out tint_symbol_1 = main_out(sk_FragColor); - return tint_symbol_1; + main_out tint_symbol_2 = main_out(sk_FragColor); + return tint_symbol_2; } void main() { diff --git a/test/tint/bug/tint/1520.spvasm.expected.msl b/test/tint/bug/tint/1520.spvasm.expected.msl index d9ff17cfb6..b997052bfe 100644 --- a/test/tint/bug/tint/1520.spvasm.expected.msl +++ b/test/tint/bug/tint/1520.spvasm.expected.msl @@ -14,6 +14,10 @@ struct tint_array { T elements[N]; }; +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1)))))); +} + struct UniformBuffer { /* 0x0000 */ tint_array tint_pad; /* 0x0010 */ float unknownInput_S1_c0; @@ -23,7 +27,7 @@ struct UniformBuffer { /* 0x0040 */ float3x3 umatrix_S1; }; -bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { +bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_6) { int unknown = 0; bool ok = false; int4 val = 0; @@ -33,13 +37,14 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { bool x_55 = false; bool x_65 = false; bool x_66 = false; - float const x_26 = (*(tint_symbol_5)).unknownInput_S1_c0; + float const x_26 = (*(tint_symbol_6)).unknownInput_S1_c0; int const x_27 = int(x_26); unknown = x_27; ok = true; x_41 = false; if (true) { - x_40 = all(((int4(0) / int4(x_27, x_27, x_27, x_27)) == int4(0))); + int4 const tint_symbol_4 = tint_div(int4(0), int4(x_27, x_27, x_27, x_27)); + x_40 = all((tint_symbol_4 == int4(0))); x_41 = x_40; } ok = x_41; @@ -61,11 +66,11 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { ok = x_55; int4 const x_58 = as_type((as_type(x_50) * as_type(int4(2)))); val = x_58; - int4 const x_59 = (x_58 / int4(2)); + int4 const x_59 = tint_div(x_58, int4(2)); val = x_59; int4 const x_60 = as_type((as_type(x_59) * as_type(int4(2)))); val = x_60; - int4 const x_61 = (x_60 / int4(2)); + int4 const x_61 = tint_div(x_60, int4(2)); val = x_61; x_66 = false; if (x_55) { @@ -76,7 +81,7 @@ bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { return x_66; } -void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* const tint_symbol_7, thread float4* const tint_symbol_8) { +void main_1(thread float4* const tint_symbol_7, const constant UniformBuffer* const tint_symbol_8, thread float4* const tint_symbol_9) { float4 outputColor_S0 = 0.0f; float4 output_S1 = 0.0f; float x_8_unknown = 0.0f; @@ -91,9 +96,9 @@ void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* co bool x_111 = false; bool x_114 = false; bool x_115 = false; - float4 const x_72 = *(tint_symbol_6); + float4 const x_72 = *(tint_symbol_7); outputColor_S0 = x_72; - float const x_77 = (*(tint_symbol_7)).unknownInput_S1_c0; + float const x_77 = (*(tint_symbol_8)).unknownInput_S1_c0; x_8_unknown = x_77; x_9_ok = true; x_87 = false; @@ -134,19 +139,19 @@ void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* co x_9_ok = x_111; x_115 = false; if (x_111) { - x_114 = test_int_S1_c0_b(tint_symbol_7); + x_114 = test_int_S1_c0_b(tint_symbol_8); x_115 = x_114; } if (x_115) { - float4 const x_122 = (*(tint_symbol_7)).ucolorGreen_S1_c0; + float4 const x_122 = (*(tint_symbol_8)).ucolorGreen_S1_c0; x_116 = x_122; } else { - float4 const x_124 = (*(tint_symbol_7)).ucolorRed_S1_c0; + float4 const x_124 = (*(tint_symbol_8)).ucolorRed_S1_c0; x_116 = x_124; } float4 const x_125 = x_116; output_S1 = x_125; - *(tint_symbol_8) = x_125; + *(tint_symbol_9) = x_125; return; } @@ -162,19 +167,19 @@ struct tint_symbol_3 { float4 sk_FragColor_1 [[color(0)]]; }; -main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread float4* const tint_symbol_10, const constant UniformBuffer* const tint_symbol_11, thread float4* const tint_symbol_12) { - thread bool tint_symbol_9 = false; - tint_symbol_9 = sk_Clockwise_param; - *(tint_symbol_10) = vcolor_S0_param; - main_1(tint_symbol_10, tint_symbol_11, tint_symbol_12); - main_out const tint_symbol_4 = {.sk_FragColor_1=*(tint_symbol_12)}; - return tint_symbol_4; +main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread float4* const tint_symbol_11, const constant UniformBuffer* const tint_symbol_12, thread float4* const tint_symbol_13) { + thread bool tint_symbol_10 = false; + tint_symbol_10 = sk_Clockwise_param; + *(tint_symbol_11) = vcolor_S0_param; + main_1(tint_symbol_11, tint_symbol_12, tint_symbol_13); + main_out const tint_symbol_5 = {.sk_FragColor_1=*(tint_symbol_13)}; + return tint_symbol_5; } -fragment tint_symbol_3 tint_symbol(const constant UniformBuffer* tint_symbol_14 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) { - thread float4 tint_symbol_13 = 0.0f; - thread float4 tint_symbol_15 = 0.0f; - main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_symbol_13), tint_symbol_14, &(tint_symbol_15)); +fragment tint_symbol_3 tint_symbol(const constant UniformBuffer* tint_symbol_15 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) { + thread float4 tint_symbol_14 = 0.0f; + thread float4 tint_symbol_16 = 0.0f; + main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_symbol_14), tint_symbol_15, &(tint_symbol_16)); tint_symbol_3 wrapper_result = {}; wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1; return wrapper_result; diff --git a/test/tint/bug/tint/1520.spvasm.expected.spvasm b/test/tint/bug/tint/1520.spvasm.expected.spvasm index 5a7ff67a50..3a07adf01b 100644 --- a/test/tint/bug/tint/1520.spvasm.expected.spvasm +++ b/test/tint/bug/tint/1520.spvasm.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 177 +; Bound: 193 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -21,6 +21,9 @@ OpName %sk_FragColor "sk_FragColor" OpName %sk_Clockwise "sk_Clockwise" OpName %vcolor_S0 "vcolor_S0" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %test_int_S1_c0_b "test_int_S1_c0_b" OpName %unknown "unknown" OpName %ok "ok" @@ -89,122 +92,140 @@ %21 = OpConstantNull %bool %sk_Clockwise = OpVariable %_ptr_Private_bool Private %21 %vcolor_S0 = OpVariable %_ptr_Private_v4float Private %10 - %23 = OpTypeFunction %bool %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %29 = OpConstantNull %int -%_ptr_Function_bool = OpTypePointer Function %bool %v4int = OpTypeVector %int 4 + %23 = OpTypeFunction %v4int %v4int %v4int + %31 = OpConstantNull %v4int + %v4bool = OpTypeVector %bool 4 +%int_n2147483648 = OpConstant %int -2147483648 + %35 = OpConstantComposite %v4int %int_n2147483648 %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %38 = OpConstantComposite %v4int %int_n1 %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %43 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 + %45 = OpTypeFunction %bool +%_ptr_Function_int = OpTypePointer Function %int + %50 = OpConstantNull %int +%_ptr_Function_bool = OpTypePointer Function %bool %_ptr_Function_v4int = OpTypePointer Function %v4int - %35 = OpConstantNull %v4int %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float %true = OpConstantTrue %bool - %v4bool = OpTypeVector %bool 4 - %int_1 = OpConstant %int 1 - %60 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %int_2 = OpConstant %int 2 - %73 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 + %89 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 %void = OpTypeVoid - %86 = OpTypeFunction %void + %102 = OpTypeFunction %void %_ptr_Function_v4float = OpTypePointer Function %v4float %_ptr_Function_float = OpTypePointer Function %float - %95 = OpConstantNull %float + %111 = OpConstantNull %float %float_1 = OpConstant %float 1 - %120 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %136 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 %float_2 = OpConstant %float 2 - %133 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 + %149 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 %uint_2 = OpConstant %uint 2 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float %uint_1 = OpConstant %uint 1 %main_out = OpTypeStruct %v4float - %162 = OpTypeFunction %main_out %bool %v4float -%test_int_S1_c0_b = OpFunction %bool None %23 - %25 = OpLabel - %unknown = OpVariable %_ptr_Function_int Function %29 + %178 = OpTypeFunction %main_out %bool %v4float + %tint_div = OpFunction %v4int None %23 + %lhs = OpFunctionParameter %v4int + %rhs = OpFunctionParameter %v4int + %29 = OpLabel + %32 = OpIEqual %v4bool %rhs %31 + %36 = OpIEqual %v4bool %lhs %35 + %39 = OpIEqual %v4bool %rhs %38 + %40 = OpLogicalAnd %v4bool %36 %39 + %41 = OpLogicalOr %v4bool %32 %40 + %30 = OpSelect %v4int %41 %43 %rhs + %44 = OpSDiv %v4int %lhs %30 + OpReturnValue %44 + OpFunctionEnd +%test_int_S1_c0_b = OpFunction %bool None %45 + %47 = OpLabel + %unknown = OpVariable %_ptr_Function_int Function %50 %ok = OpVariable %_ptr_Function_bool Function %21 - %val = OpVariable %_ptr_Function_v4int Function %35 + %val = OpVariable %_ptr_Function_v4int Function %31 %x_40 = OpVariable %_ptr_Function_bool Function %21 %x_41 = OpVariable %_ptr_Function_bool Function %21 %x_54 = OpVariable %_ptr_Function_bool Function %21 %x_55 = OpVariable %_ptr_Function_bool Function %21 %x_65 = OpVariable %_ptr_Function_bool Function %21 %x_66 = OpVariable %_ptr_Function_bool Function %21 - %45 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 - %46 = OpLoad %float %45 - %47 = OpConvertFToS %int %46 - OpStore %unknown %47 + %64 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 + %65 = OpLoad %float %64 + %66 = OpConvertFToS %int %65 + OpStore %unknown %66 OpStore %ok %true OpStore %x_41 %21 - OpSelectionMerge %49 None - OpBranchConditional %true %50 %49 - %50 = OpLabel - %52 = OpCompositeConstruct %v4int %47 %47 %47 %47 - %53 = OpSDiv %v4int %35 %52 - %54 = OpIEqual %v4bool %53 %35 - %51 = OpAll %bool %54 - OpStore %x_40 %51 - %56 = OpLoad %bool %x_40 - OpStore %x_41 %56 - OpBranch %49 - %49 = OpLabel - %57 = OpLoad %bool %x_41 - OpStore %ok %57 - %58 = OpCompositeConstruct %v4int %47 %47 %47 %47 - OpStore %val %58 - %61 = OpIAdd %v4int %58 %60 - OpStore %val %61 - %62 = OpISub %v4int %61 %60 - OpStore %val %62 - %63 = OpIAdd %v4int %62 %60 - OpStore %val %63 - %64 = OpISub %v4int %63 %60 - OpStore %val %64 - OpStore %x_55 %21 - %65 = OpLoad %bool %x_41 - OpSelectionMerge %66 None - OpBranchConditional %65 %67 %66 - %67 = OpLabel - %69 = OpIEqual %v4bool %64 %58 - %68 = OpAll %bool %69 - OpStore %x_54 %68 - %70 = OpLoad %bool %x_54 - OpStore %x_55 %70 - OpBranch %66 - %66 = OpLabel - %71 = OpLoad %bool %x_55 - OpStore %ok %71 - %74 = OpIMul %v4int %64 %73 - OpStore %val %74 - %75 = OpSDiv %v4int %74 %73 - OpStore %val %75 - %76 = OpIMul %v4int %75 %73 + OpSelectionMerge %68 None + OpBranchConditional %true %69 %68 + %69 = OpLabel + %71 = OpCompositeConstruct %v4int %66 %66 %66 %66 + %70 = OpFunctionCall %v4int %tint_div %31 %71 + %73 = OpIEqual %v4bool %70 %31 + %72 = OpAll %bool %73 + OpStore %x_40 %72 + %74 = OpLoad %bool %x_40 + OpStore %x_41 %74 + OpBranch %68 + %68 = OpLabel + %75 = OpLoad %bool %x_41 + OpStore %ok %75 + %76 = OpCompositeConstruct %v4int %66 %66 %66 %66 OpStore %val %76 - %77 = OpSDiv %v4int %76 %73 + %77 = OpIAdd %v4int %76 %43 OpStore %val %77 + %78 = OpISub %v4int %77 %43 + OpStore %val %78 + %79 = OpIAdd %v4int %78 %43 + OpStore %val %79 + %80 = OpISub %v4int %79 %43 + OpStore %val %80 + OpStore %x_55 %21 + %81 = OpLoad %bool %x_41 + OpSelectionMerge %82 None + OpBranchConditional %81 %83 %82 + %83 = OpLabel + %85 = OpIEqual %v4bool %80 %76 + %84 = OpAll %bool %85 + OpStore %x_54 %84 + %86 = OpLoad %bool %x_54 + OpStore %x_55 %86 + OpBranch %82 + %82 = OpLabel + %87 = OpLoad %bool %x_55 + OpStore %ok %87 + %90 = OpIMul %v4int %80 %89 + OpStore %val %90 + %91 = OpFunctionCall %v4int %tint_div %90 %89 + OpStore %val %91 + %92 = OpIMul %v4int %91 %89 + OpStore %val %92 + %93 = OpFunctionCall %v4int %tint_div %92 %89 + OpStore %val %93 OpStore %x_66 %21 - %78 = OpLoad %bool %x_55 - OpSelectionMerge %79 None - OpBranchConditional %78 %80 %79 - %80 = OpLabel - %82 = OpIEqual %v4bool %77 %58 - %81 = OpAll %bool %82 - OpStore %x_65 %81 - %83 = OpLoad %bool %x_65 - OpStore %x_66 %83 - OpBranch %79 - %79 = OpLabel - %84 = OpLoad %bool %x_66 - OpStore %ok %84 - %85 = OpLoad %bool %x_66 - OpReturnValue %85 + %94 = OpLoad %bool %x_55 + OpSelectionMerge %95 None + OpBranchConditional %94 %96 %95 + %96 = OpLabel + %98 = OpIEqual %v4bool %93 %76 + %97 = OpAll %bool %98 + OpStore %x_65 %97 + %99 = OpLoad %bool %x_65 + OpStore %x_66 %99 + OpBranch %95 + %95 = OpLabel + %100 = OpLoad %bool %x_66 + OpStore %ok %100 + %101 = OpLoad %bool %x_66 + OpReturnValue %101 OpFunctionEnd - %main_1 = OpFunction %void None %86 - %89 = OpLabel + %main_1 = OpFunction %void None %102 + %105 = OpLabel %outputColor_S0 = OpVariable %_ptr_Function_v4float Function %10 %output_S1 = OpVariable %_ptr_Function_v4float Function %10 -%x_8_unknown = OpVariable %_ptr_Function_float Function %95 +%x_8_unknown = OpVariable %_ptr_Function_float Function %111 %x_9_ok = OpVariable %_ptr_Function_bool Function %21 %x_10_val = OpVariable %_ptr_Function_v4float Function %10 %x_116 = OpVariable %_ptr_Function_v4float Function %10 @@ -216,120 +237,120 @@ %x_111 = OpVariable %_ptr_Function_bool Function %21 %x_114 = OpVariable %_ptr_Function_bool Function %21 %x_115 = OpVariable %_ptr_Function_bool Function %21 - %107 = OpLoad %v4float %vcolor_S0 - OpStore %outputColor_S0 %107 - %108 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 - %109 = OpLoad %float %108 - OpStore %x_8_unknown %109 + %123 = OpLoad %v4float %vcolor_S0 + OpStore %outputColor_S0 %123 + %124 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 %uint_0 + %125 = OpLoad %float %124 + OpStore %x_8_unknown %125 OpStore %x_9_ok %true OpStore %x_87 %21 - OpSelectionMerge %110 None - OpBranchConditional %true %111 %110 - %111 = OpLabel - %113 = OpCompositeConstruct %v4float %109 %109 %109 %109 - %114 = OpFDiv %v4float %10 %113 - %115 = OpFOrdEqual %v4bool %114 %10 - %112 = OpAll %bool %115 - OpStore %x_86 %112 - %116 = OpLoad %bool %x_86 - OpStore %x_87 %116 - OpBranch %110 - %110 = OpLabel - %117 = OpLoad %bool %x_87 - OpStore %x_9_ok %117 - %118 = OpCompositeConstruct %v4float %109 %109 %109 %109 - OpStore %x_10_val %118 - %121 = OpFAdd %v4float %118 %120 - OpStore %x_10_val %121 - %122 = OpFSub %v4float %121 %120 - OpStore %x_10_val %122 - %123 = OpFAdd %v4float %122 %120 - OpStore %x_10_val %123 - %124 = OpFSub %v4float %123 %120 - OpStore %x_10_val %124 - OpStore %x_100 %21 - %125 = OpLoad %bool %x_87 OpSelectionMerge %126 None - OpBranchConditional %125 %127 %126 + OpBranchConditional %true %127 %126 %127 = OpLabel - %129 = OpFOrdEqual %v4bool %124 %118 - %128 = OpAll %bool %129 - OpStore %x_99 %128 - %130 = OpLoad %bool %x_99 - OpStore %x_100 %130 + %129 = OpCompositeConstruct %v4float %125 %125 %125 %125 + %130 = OpFDiv %v4float %10 %129 + %131 = OpFOrdEqual %v4bool %130 %10 + %128 = OpAll %bool %131 + OpStore %x_86 %128 + %132 = OpLoad %bool %x_86 + OpStore %x_87 %132 OpBranch %126 %126 = OpLabel - %131 = OpLoad %bool %x_100 - OpStore %x_9_ok %131 - %134 = OpFMul %v4float %124 %133 + %133 = OpLoad %bool %x_87 + OpStore %x_9_ok %133 + %134 = OpCompositeConstruct %v4float %125 %125 %125 %125 OpStore %x_10_val %134 - %135 = OpFDiv %v4float %134 %133 - OpStore %x_10_val %135 - %136 = OpFMul %v4float %135 %133 - OpStore %x_10_val %136 - %137 = OpFDiv %v4float %136 %133 + %137 = OpFAdd %v4float %134 %136 OpStore %x_10_val %137 + %138 = OpFSub %v4float %137 %136 + OpStore %x_10_val %138 + %139 = OpFAdd %v4float %138 %136 + OpStore %x_10_val %139 + %140 = OpFSub %v4float %139 %136 + OpStore %x_10_val %140 + OpStore %x_100 %21 + %141 = OpLoad %bool %x_87 + OpSelectionMerge %142 None + OpBranchConditional %141 %143 %142 + %143 = OpLabel + %145 = OpFOrdEqual %v4bool %140 %134 + %144 = OpAll %bool %145 + OpStore %x_99 %144 + %146 = OpLoad %bool %x_99 + OpStore %x_100 %146 + OpBranch %142 + %142 = OpLabel + %147 = OpLoad %bool %x_100 + OpStore %x_9_ok %147 + %150 = OpFMul %v4float %140 %149 + OpStore %x_10_val %150 + %151 = OpFDiv %v4float %150 %149 + OpStore %x_10_val %151 + %152 = OpFMul %v4float %151 %149 + OpStore %x_10_val %152 + %153 = OpFDiv %v4float %152 %149 + OpStore %x_10_val %153 OpStore %x_111 %21 - %138 = OpLoad %bool %x_100 - OpSelectionMerge %139 None - OpBranchConditional %138 %140 %139 - %140 = OpLabel - %142 = OpFOrdEqual %v4bool %137 %118 - %141 = OpAll %bool %142 - OpStore %x_110 %141 - %143 = OpLoad %bool %x_110 - OpStore %x_111 %143 - OpBranch %139 - %139 = OpLabel - %144 = OpLoad %bool %x_111 - OpStore %x_9_ok %144 + %154 = OpLoad %bool %x_100 + OpSelectionMerge %155 None + OpBranchConditional %154 %156 %155 + %156 = OpLabel + %158 = OpFOrdEqual %v4bool %153 %134 + %157 = OpAll %bool %158 + OpStore %x_110 %157 + %159 = OpLoad %bool %x_110 + OpStore %x_111 %159 + OpBranch %155 + %155 = OpLabel + %160 = OpLoad %bool %x_111 + OpStore %x_9_ok %160 OpStore %x_115 %21 - %145 = OpLoad %bool %x_111 - OpSelectionMerge %146 None - OpBranchConditional %145 %147 %146 - %147 = OpLabel - %148 = OpFunctionCall %bool %test_int_S1_c0_b - OpStore %x_114 %148 - %149 = OpLoad %bool %x_114 - OpStore %x_115 %149 - OpBranch %146 - %146 = OpLabel - %150 = OpLoad %bool %x_115 - OpSelectionMerge %151 None - OpBranchConditional %150 %152 %153 - %152 = OpLabel - %156 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_2 - %157 = OpLoad %v4float %156 - OpStore %x_116 %157 - OpBranch %151 - %153 = OpLabel - %159 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_1 - %160 = OpLoad %v4float %159 - OpStore %x_116 %160 - OpBranch %151 - %151 = OpLabel - %161 = OpLoad %v4float %x_116 - OpStore %output_S1 %161 - OpStore %sk_FragColor %161 + %161 = OpLoad %bool %x_111 + OpSelectionMerge %162 None + OpBranchConditional %161 %163 %162 + %163 = OpLabel + %164 = OpFunctionCall %bool %test_int_S1_c0_b + OpStore %x_114 %164 + %165 = OpLoad %bool %x_114 + OpStore %x_115 %165 + OpBranch %162 + %162 = OpLabel + %166 = OpLoad %bool %x_115 + OpSelectionMerge %167 None + OpBranchConditional %166 %168 %169 + %168 = OpLabel + %172 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_2 + %173 = OpLoad %v4float %172 + OpStore %x_116 %173 + OpBranch %167 + %169 = OpLabel + %175 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_0 %uint_1 + %176 = OpLoad %v4float %175 + OpStore %x_116 %176 + OpBranch %167 + %167 = OpLabel + %177 = OpLoad %v4float %x_116 + OpStore %output_S1 %177 + OpStore %sk_FragColor %177 OpReturn OpFunctionEnd - %main_inner = OpFunction %main_out None %162 + %main_inner = OpFunction %main_out None %178 %sk_Clockwise_param = OpFunctionParameter %bool %vcolor_S0_param = OpFunctionParameter %v4float - %167 = OpLabel + %183 = OpLabel OpStore %sk_Clockwise %sk_Clockwise_param OpStore %vcolor_S0 %vcolor_S0_param - %168 = OpFunctionCall %void %main_1 - %169 = OpLoad %v4float %sk_FragColor - %170 = OpCompositeConstruct %main_out %169 - OpReturnValue %170 + %184 = OpFunctionCall %void %main_1 + %185 = OpLoad %v4float %sk_FragColor + %186 = OpCompositeConstruct %main_out %185 + OpReturnValue %186 OpFunctionEnd - %main = OpFunction %void None %86 - %172 = OpLabel - %174 = OpLoad %bool %sk_Clockwise_param_1 - %175 = OpLoad %v4float %vcolor_S0_param_1 - %173 = OpFunctionCall %main_out %main_inner %174 %175 - %176 = OpCompositeExtract %v4float %173 0 - OpStore %sk_FragColor_1_1 %176 + %main = OpFunction %void None %102 + %188 = OpLabel + %190 = OpLoad %bool %sk_Clockwise_param_1 + %191 = OpLoad %v4float %vcolor_S0_param_1 + %189 = OpFunctionCall %main_out %main_inner %190 %191 + %192 = OpCompositeExtract %v4float %189 0 + OpStore %sk_FragColor_1_1 %192 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl index ea467eae49..708904c0ea 100644 --- a/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl @@ -1,3 +1,7 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + RWByteAddressBuffer b : register(u0, space0); [numthreads(1, 1, 1)] @@ -8,7 +12,8 @@ void main() { break; } const uint p_save = i; - if (((i % 2u) == 0u)) { + const uint tint_symbol = tint_mod(i, 2u); + if ((tint_symbol == 0u)) { { b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u))); i = (i + 1u); diff --git a/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl index ea467eae49..708904c0ea 100644 --- a/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl @@ -1,3 +1,7 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + RWByteAddressBuffer b : register(u0, space0); [numthreads(1, 1, 1)] @@ -8,7 +12,8 @@ void main() { break; } const uint p_save = i; - if (((i % 2u) == 0u)) { + const uint tint_symbol = tint_mod(i, 2u); + if ((tint_symbol == 0u)) { { b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u))); i = (i + 1u); diff --git a/test/tint/bug/tint/221.wgsl.expected.glsl b/test/tint/bug/tint/221.wgsl.expected.glsl index f00f6e238c..5f6890fed9 100644 --- a/test/tint/bug/tint/221.wgsl.expected.glsl +++ b/test/tint/bug/tint/221.wgsl.expected.glsl @@ -1,5 +1,9 @@ #version 310 es +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + struct Buf { uint count; uint data[50]; @@ -16,7 +20,8 @@ void tint_symbol() { break; } uint p_save = i; - if (((i % 2u) == 0u)) { + uint tint_symbol_1 = tint_mod(i, 2u); + if ((tint_symbol_1 == 0u)) { { b.inner.data[p_save] = (b.inner.data[p_save] * 2u); i = (i + 1u); diff --git a/test/tint/bug/tint/221.wgsl.expected.msl b/test/tint/bug/tint/221.wgsl.expected.msl index ad7d150b6b..7e30a1864e 100644 --- a/test/tint/bug/tint/221.wgsl.expected.msl +++ b/test/tint/bug/tint/221.wgsl.expected.msl @@ -14,28 +14,33 @@ struct tint_array { T elements[N]; }; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + struct Buf { /* 0x0000 */ uint count; /* 0x0004 */ tint_array data; }; -kernel void tint_symbol(device Buf* tint_symbol_1 [[buffer(0)]]) { +kernel void tint_symbol(device Buf* tint_symbol_2 [[buffer(0)]]) { uint i = 0u; while (true) { - if ((i >= (*(tint_symbol_1)).count)) { + if ((i >= (*(tint_symbol_2)).count)) { break; } uint const p_save = i; - if (((i % 2u) == 0u)) { + uint const tint_symbol_1 = tint_mod(i, 2u); + if ((tint_symbol_1 == 0u)) { { - (*(tint_symbol_1)).data[p_save] = ((*(tint_symbol_1)).data[p_save] * 2u); + (*(tint_symbol_2)).data[p_save] = ((*(tint_symbol_2)).data[p_save] * 2u); i = (i + 1u); } continue; } - (*(tint_symbol_1)).data[p_save] = 0u; + (*(tint_symbol_2)).data[p_save] = 0u; { - (*(tint_symbol_1)).data[p_save] = ((*(tint_symbol_1)).data[p_save] * 2u); + (*(tint_symbol_2)).data[p_save] = ((*(tint_symbol_2)).data[p_save] * 2u); i = (i + 1u); } } diff --git a/test/tint/bug/tint/221.wgsl.expected.spvasm b/test/tint/bug/tint/221.wgsl.expected.spvasm index 45ee7a76ea..335ac8a501 100644 --- a/test/tint/bug/tint/221.wgsl.expected.spvasm +++ b/test/tint/bug/tint/221.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 43 +; Bound: 51 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %Buf 0 "count" OpMemberName %Buf 1 "data" OpName %b "b" + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %main "main" OpName %i "i" OpDecorate %b_block Block @@ -29,55 +32,65 @@ %b_block = OpTypeStruct %Buf %_ptr_StorageBuffer_b_block = OpTypePointer StorageBuffer %b_block %b = OpVariable %_ptr_StorageBuffer_b_block StorageBuffer + %8 = OpTypeFunction %uint %uint %uint + %14 = OpConstantNull %uint + %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 %void = OpTypeVoid - %8 = OpTypeFunction %void - %12 = OpConstantNull %uint + %19 = OpTypeFunction %void %_ptr_Function_uint = OpTypePointer Function %uint %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint - %bool = OpTypeBool %uint_2 = OpConstant %uint 2 - %uint_1 = OpConstant %uint 1 - %main = OpFunction %void None %8 - %11 = OpLabel - %i = OpVariable %_ptr_Function_uint Function %12 - OpStore %i %12 - OpBranch %15 - %15 = OpLabel - OpLoopMerge %16 %17 None - OpBranch %18 - %18 = OpLabel - %19 = OpLoad %uint %i - %22 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_0 - %23 = OpLoad %uint %22 - %24 = OpUGreaterThanEqual %bool %19 %23 - OpSelectionMerge %26 None - OpBranchConditional %24 %27 %26 - %27 = OpLabel - OpBranch %16 - %26 = OpLabel - %28 = OpLoad %uint %i + %tint_mod = OpFunction %uint None %8 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %12 = OpLabel + %15 = OpIEqual %bool %rhs %14 + %13 = OpSelect %uint %15 %uint_1 %rhs + %18 = OpUMod %uint %lhs %13 + OpReturnValue %18 + OpFunctionEnd + %main = OpFunction %void None %19 + %22 = OpLabel + %i = OpVariable %_ptr_Function_uint Function %14 + OpStore %i %14 + OpBranch %25 + %25 = OpLabel + OpLoopMerge %26 %27 None + OpBranch %28 + %28 = OpLabel %29 = OpLoad %uint %i - %31 = OpUMod %uint %29 %uint_2 - %32 = OpIEqual %bool %31 %12 - OpSelectionMerge %33 None - OpBranchConditional %32 %34 %33 - %34 = OpLabel - OpBranch %17 - %33 = OpLabel - %36 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 - OpStore %36 %12 - OpBranch %17 - %17 = OpLabel - %37 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 - %38 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %28 - %39 = OpLoad %uint %38 - %40 = OpIMul %uint %39 %uint_2 - OpStore %37 %40 - %41 = OpLoad %uint %i - %42 = OpIAdd %uint %41 %uint_1 - OpStore %i %42 - OpBranch %15 - %16 = OpLabel + %32 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_0 + %33 = OpLoad %uint %32 + %34 = OpUGreaterThanEqual %bool %29 %33 + OpSelectionMerge %35 None + OpBranchConditional %34 %36 %35 + %36 = OpLabel + OpBranch %26 + %35 = OpLabel + %37 = OpLoad %uint %i + %39 = OpLoad %uint %i + %38 = OpFunctionCall %uint %tint_mod %39 %uint_2 + %41 = OpIEqual %bool %38 %14 + OpSelectionMerge %42 None + OpBranchConditional %41 %43 %42 + %43 = OpLabel + OpBranch %27 + %42 = OpLabel + %44 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37 + OpStore %44 %14 + OpBranch %27 + %27 = OpLabel + %45 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37 + %46 = OpAccessChain %_ptr_StorageBuffer_uint %b %uint_0 %uint_1 %37 + %47 = OpLoad %uint %46 + %48 = OpIMul %uint %47 %uint_2 + OpStore %45 %48 + %49 = OpLoad %uint %i + %50 = OpIAdd %uint %49 %uint_1 + OpStore %i %50 + OpBranch %25 + %26 = OpLabel OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl index eef4cd9673..a893add710 100644 --- a/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl @@ -1,3 +1,7 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + ByteAddressBuffer firstMatrix : register(t0, space0); ByteAddressBuffer secondMatrix : register(t1, space0); RWByteAddressBuffer resultMatrix : register(u2, space0); @@ -63,7 +67,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { const uint tileCol = (local_id.x * 4u); const uint globalRow = (global_id.y * 4u); const uint globalCol = (global_id.x * 4u); - const uint numTiles = (((uniforms[0].y - 1u) / 64u) + 1u); + const uint tint_symbol_2 = tint_div((uniforms[0].y - 1u), 64u); + const uint numTiles = (tint_symbol_2 + 1u); float acc[16] = (float[16])0; float ACached = 0.0f; float BCached[4] = (float[4])0; @@ -84,8 +89,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { const uint inputRow = (tileRow + innerRow); const uint inputCol = (tileColA + innerCol); - const float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); - mm_Asub[inputRow][inputCol] = tint_symbol_2; + const float tint_symbol_3 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); + mm_Asub[inputRow][inputCol] = tint_symbol_3; } } } @@ -96,8 +101,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { const uint inputRow = (tileRowB + innerRow); const uint inputCol = (tileCol + innerCol); - const float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); - mm_Bsub[innerCol][inputCol] = tint_symbol_3; + const float tint_symbol_4 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); + mm_Bsub[innerCol][inputCol] = tint_symbol_4; } } } diff --git a/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl index eef4cd9673..a893add710 100644 --- a/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl @@ -1,3 +1,7 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + ByteAddressBuffer firstMatrix : register(t0, space0); ByteAddressBuffer secondMatrix : register(t1, space0); RWByteAddressBuffer resultMatrix : register(u2, space0); @@ -63,7 +67,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { const uint tileCol = (local_id.x * 4u); const uint globalRow = (global_id.y * 4u); const uint globalCol = (global_id.x * 4u); - const uint numTiles = (((uniforms[0].y - 1u) / 64u) + 1u); + const uint tint_symbol_2 = tint_div((uniforms[0].y - 1u), 64u); + const uint numTiles = (tint_symbol_2 + 1u); float acc[16] = (float[16])0; float ACached = 0.0f; float BCached[4] = (float[4])0; @@ -84,8 +89,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { const uint inputRow = (tileRow + innerRow); const uint inputCol = (tileColA + innerCol); - const float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); - mm_Asub[inputRow][inputCol] = tint_symbol_2; + const float tint_symbol_3 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); + mm_Asub[inputRow][inputCol] = tint_symbol_3; } } } @@ -96,8 +101,8 @@ void main_inner(uint3 local_id, uint3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { const uint inputRow = (tileRowB + innerRow); const uint inputCol = (tileCol + innerCol); - const float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); - mm_Bsub[innerCol][inputCol] = tint_symbol_3; + const float tint_symbol_4 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); + mm_Bsub[innerCol][inputCol] = tint_symbol_4; } } } diff --git a/test/tint/bug/tint/914.wgsl.expected.glsl b/test/tint/bug/tint/914.wgsl.expected.glsl index 31c557b21d..2797131645 100644 --- a/test/tint/bug/tint/914.wgsl.expected.glsl +++ b/test/tint/bug/tint/914.wgsl.expected.glsl @@ -1,5 +1,9 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + struct Uniforms { uint dimAOuter; uint dimInner; @@ -74,7 +78,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) { uint tileCol = (local_id.x * 4u); uint globalRow = (global_id.y * 4u); uint globalCol = (global_id.x * 4u); - uint numTiles = (((uniforms.inner.dimInner - 1u) / 64u) + 1u); + uint tint_symbol_1 = tint_div((uniforms.inner.dimInner - 1u), 64u); + uint numTiles = (tint_symbol_1 + 1u); float acc[16] = float[16](0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); float ACached = 0.0f; float BCached[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f); @@ -95,8 +100,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { uint inputRow = (tileRow + innerRow); uint inputCol = (tileColA + innerCol); - float tint_symbol_1 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); - mm_Asub[inputRow][inputCol] = tint_symbol_1; + float tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol)); + mm_Asub[inputRow][inputCol] = tint_symbol_2; } } } @@ -107,8 +112,8 @@ void tint_symbol(uvec3 local_id, uvec3 global_id, uint local_invocation_index) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { uint inputRow = (tileRowB + innerRow); uint inputCol = (tileCol + innerCol); - float tint_symbol_2 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); - mm_Bsub[innerCol][inputCol] = tint_symbol_2; + float tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol)); + mm_Bsub[innerCol][inputCol] = tint_symbol_3; } } } diff --git a/test/tint/bug/tint/914.wgsl.expected.msl b/test/tint/bug/tint/914.wgsl.expected.msl index e1eaf8e53f..b7dec3396e 100644 --- a/test/tint/bug/tint/914.wgsl.expected.msl +++ b/test/tint/bug/tint/914.wgsl.expected.msl @@ -14,6 +14,10 @@ struct tint_array { T elements[N]; }; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + struct Uniforms { /* 0x0000 */ uint dimAOuter; /* 0x0004 */ uint dimInner; @@ -24,42 +28,43 @@ struct Matrix { /* 0x0000 */ tint_array numbers; }; -float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_3, const device Matrix* const tint_symbol_4) { - if (((row < (*(tint_symbol_3)).dimAOuter) && (col < (*(tint_symbol_3)).dimInner))) { - float const result = (*(tint_symbol_4)).numbers[((row * (*(tint_symbol_3)).dimInner) + col)]; +float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_4, const device Matrix* const tint_symbol_5) { + if (((row < (*(tint_symbol_4)).dimAOuter) && (col < (*(tint_symbol_4)).dimInner))) { + float const result = (*(tint_symbol_5)).numbers[((row * (*(tint_symbol_4)).dimInner) + col)]; return result; } return 0.0f; } -float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_5, const device Matrix* const tint_symbol_6) { - if (((row < (*(tint_symbol_5)).dimInner) && (col < (*(tint_symbol_5)).dimBOuter))) { - float const result = (*(tint_symbol_6)).numbers[((row * (*(tint_symbol_5)).dimBOuter) + col)]; +float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_6, const device Matrix* const tint_symbol_7) { + if (((row < (*(tint_symbol_6)).dimInner) && (col < (*(tint_symbol_6)).dimBOuter))) { + float const result = (*(tint_symbol_7)).numbers[((row * (*(tint_symbol_6)).dimBOuter) + col)]; return result; } return 0.0f; } -void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_7, device Matrix* const tint_symbol_8) { - if (((row < (*(tint_symbol_7)).dimAOuter) && (col < (*(tint_symbol_7)).dimBOuter))) { - uint const index = (col + (row * (*(tint_symbol_7)).dimBOuter)); - (*(tint_symbol_8)).numbers[index] = value; +void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_8, device Matrix* const tint_symbol_9) { + if (((row < (*(tint_symbol_8)).dimAOuter) && (col < (*(tint_symbol_8)).dimBOuter))) { + uint const index = (col + (row * (*(tint_symbol_8)).dimBOuter)); + (*(tint_symbol_9)).numbers[index] = value; } } -void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array, 64>* const tint_symbol_9, threadgroup tint_array, 64>* const tint_symbol_10, const constant Uniforms* const tint_symbol_11, const device Matrix* const tint_symbol_12, const device Matrix* const tint_symbol_13, device Matrix* const tint_symbol_14) { +void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array, 64>* const tint_symbol_10, threadgroup tint_array, 64>* const tint_symbol_11, const constant Uniforms* const tint_symbol_12, const device Matrix* const tint_symbol_13, const device Matrix* const tint_symbol_14, device Matrix* const tint_symbol_15) { for(uint idx = local_invocation_index; (idx < 4096u); idx = (idx + 256u)) { uint const i = (idx / 64u); uint const i_1 = (idx % 64u); - (*(tint_symbol_9))[i][i_1] = 0.0f; (*(tint_symbol_10))[i][i_1] = 0.0f; + (*(tint_symbol_11))[i][i_1] = 0.0f; } threadgroup_barrier(mem_flags::mem_threadgroup); uint const tileRow = (local_id[1] * 4u); uint const tileCol = (local_id[0] * 4u); uint const globalRow = (global_id[1] * 4u); uint const globalCol = (global_id[0] * 4u); - uint const numTiles = ((((*(tint_symbol_11)).dimInner - 1u) / 64u) + 1u); + uint const tint_symbol_1 = tint_div(((*(tint_symbol_12)).dimInner - 1u), 64u); + uint const numTiles = (tint_symbol_1 + 1u); tint_array acc = {}; float ACached = 0.0f; tint_array BCached = {}; @@ -75,25 +80,25 @@ void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_in for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) { uint const inputRow = (tileRow + innerRow); uint const inputCol = (tileColA + innerCol); - float const tint_symbol_1 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_11, tint_symbol_12); - (*(tint_symbol_9))[inputRow][inputCol] = tint_symbol_1; + float const tint_symbol_2 = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_12, tint_symbol_13); + (*(tint_symbol_10))[inputRow][inputCol] = tint_symbol_2; } } for(uint innerRow = 0u; (innerRow < RowPerThreadB); innerRow = (innerRow + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { uint const inputRow = (tileRowB + innerRow); uint const inputCol = (tileCol + innerCol); - float const tint_symbol_2 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_11, tint_symbol_13); - (*(tint_symbol_10))[innerCol][inputCol] = tint_symbol_2; + float const tint_symbol_3 = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_12, tint_symbol_14); + (*(tint_symbol_11))[innerCol][inputCol] = tint_symbol_3; } } threadgroup_barrier(mem_flags::mem_threadgroup); for(uint k = 0u; (k < 64u); k = (k + 1u)) { for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) { - BCached[inner] = (*(tint_symbol_10))[k][(tileCol + inner)]; + BCached[inner] = (*(tint_symbol_11))[k][(tileCol + inner)]; } for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) { - ACached = (*(tint_symbol_9))[(tileRow + innerRow)][k]; + ACached = (*(tint_symbol_10))[(tileRow + innerRow)][k]; for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { uint const index = ((innerRow * 4u) + innerCol); acc[index] = (acc[index] + (ACached * BCached[innerCol])); @@ -105,15 +110,15 @@ void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_in for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) { for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) { uint const index = ((innerRow * 4u) + innerCol); - mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_symbol_11, tint_symbol_14); + mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_symbol_12, tint_symbol_15); } } } -kernel void tint_symbol(const constant Uniforms* tint_symbol_17 [[buffer(0)]], const device Matrix* tint_symbol_18 [[buffer(2)]], const device Matrix* tint_symbol_19 [[buffer(3)]], device Matrix* tint_symbol_20 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) { - threadgroup tint_array, 64> tint_symbol_15; +kernel void tint_symbol(const constant Uniforms* tint_symbol_18 [[buffer(0)]], const device Matrix* tint_symbol_19 [[buffer(2)]], const device Matrix* tint_symbol_20 [[buffer(3)]], device Matrix* tint_symbol_21 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) { threadgroup tint_array, 64> tint_symbol_16; - tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_15), &(tint_symbol_16), tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20); + threadgroup tint_array, 64> tint_symbol_17; + tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_16), &(tint_symbol_17), tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21); return; } diff --git a/test/tint/bug/tint/914.wgsl.expected.spvasm b/test/tint/bug/tint/914.wgsl.expected.spvasm index f6ddfb7ea0..f7719e037f 100644 --- a/test/tint/bug/tint/914.wgsl.expected.spvasm +++ b/test/tint/bug/tint/914.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 389 +; Bound: 397 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -24,6 +24,9 @@ OpName %uniforms "uniforms" OpName %mm_Asub "mm_Asub" OpName %mm_Bsub "mm_Bsub" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %mm_readA "mm_readA" OpName %row "row" OpName %col "col" @@ -109,23 +112,24 @@ %_ptr_Workgroup__arr__arr_float_uint_64_uint_64 = OpTypePointer Workgroup %_arr__arr_float_uint_64_uint_64 %mm_Asub = OpVariable %_ptr_Workgroup__arr__arr_float_uint_64_uint_64 Workgroup %mm_Bsub = OpVariable %_ptr_Workgroup__arr__arr_float_uint_64_uint_64 Workgroup - %25 = OpTypeFunction %float %uint %uint + %25 = OpTypeFunction %uint %uint %uint + %31 = OpConstantNull %uint %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 + %36 = OpTypeFunction %float %uint %uint %_ptr_Function_bool = OpTypePointer Function %bool - %33 = OpConstantNull %bool + %43 = OpConstantNull %bool %_ptr_Function_float = OpTypePointer Function %float - %36 = OpConstantNull %float + %46 = OpConstantNull %float %uint_0 = OpConstant %uint 0 %_ptr_Uniform_uint = OpTypePointer Uniform %uint - %uint_1 = OpConstant %uint 1 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float %true = OpConstantTrue %bool %uint_2 = OpConstant %uint 2 %void = OpTypeVoid - %93 = OpTypeFunction %void %uint %uint %float - %116 = OpTypeFunction %void %v3uint %v3uint %uint + %102 = OpTypeFunction %void %uint %uint %float + %125 = OpTypeFunction %void %v3uint %v3uint %uint %_ptr_Function_uint = OpTypePointer Function %uint - %124 = OpConstantNull %uint %uint_4096 = OpConstant %uint 4096 %_ptr_Workgroup_float = OpTypePointer Workgroup %float %uint_256 = OpConstant %uint 256 @@ -134,523 +138,532 @@ %uint_16 = OpConstant %uint 16 %_arr_float_uint_16 = OpTypeArray %float %uint_16 %_ptr_Function__arr_float_uint_16 = OpTypePointer Function %_arr_float_uint_16 - %165 = OpConstantNull %_arr_float_uint_16 + %173 = OpConstantNull %_arr_float_uint_16 %_arr_float_uint_4 = OpTypeArray %float %uint_4 %_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4 - %170 = OpConstantNull %_arr_float_uint_4 - %382 = OpTypeFunction %void - %mm_readA = OpFunction %float None %25 + %178 = OpConstantNull %_arr_float_uint_4 + %390 = OpTypeFunction %void + %tint_div = OpFunction %uint None %25 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %29 = OpLabel + %32 = OpIEqual %bool %rhs %31 + %30 = OpSelect %uint %32 %uint_1 %rhs + %35 = OpUDiv %uint %lhs %30 + OpReturnValue %35 + OpFunctionEnd + %mm_readA = OpFunction %float None %36 %row = OpFunctionParameter %uint %col = OpFunctionParameter %uint - %29 = OpLabel -%tint_return_flag = OpVariable %_ptr_Function_bool Function %33 -%tint_return_value = OpVariable %_ptr_Function_float Function %36 - %39 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %40 = OpLoad %uint %39 - %41 = OpULessThan %bool %row %40 - OpSelectionMerge %42 None - OpBranchConditional %41 %43 %42 - %43 = OpLabel - %45 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %46 = OpLoad %uint %45 - %47 = OpULessThan %bool %col %46 - OpBranch %42 - %42 = OpLabel - %48 = OpPhi %bool %41 %29 %47 %43 - OpSelectionMerge %49 None - OpBranchConditional %48 %50 %49 - %50 = OpLabel - %51 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %52 = OpLoad %uint %51 - %53 = OpIMul %uint %row %52 - %54 = OpIAdd %uint %53 %col - %56 = OpAccessChain %_ptr_StorageBuffer_float %firstMatrix %uint_0 %54 - %57 = OpLoad %float %56 + %40 = OpLabel +%tint_return_flag = OpVariable %_ptr_Function_bool Function %43 +%tint_return_value = OpVariable %_ptr_Function_float Function %46 + %49 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 + %50 = OpLoad %uint %49 + %51 = OpULessThan %bool %row %50 + OpSelectionMerge %52 None + OpBranchConditional %51 %53 %52 + %53 = OpLabel + %54 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %55 = OpLoad %uint %54 + %56 = OpULessThan %bool %col %55 + OpBranch %52 + %52 = OpLabel + %57 = OpPhi %bool %51 %40 %56 %53 + OpSelectionMerge %58 None + OpBranchConditional %57 %59 %58 + %59 = OpLabel + %60 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %61 = OpLoad %uint %60 + %62 = OpIMul %uint %row %61 + %63 = OpIAdd %uint %62 %col + %65 = OpAccessChain %_ptr_StorageBuffer_float %firstMatrix %uint_0 %63 + %66 = OpLoad %float %65 OpStore %tint_return_flag %true - OpStore %tint_return_value %57 - OpBranch %49 - %49 = OpLabel - %60 = OpLoad %bool %tint_return_flag - %59 = OpLogicalNot %bool %60 - OpSelectionMerge %61 None - OpBranchConditional %59 %62 %61 - %62 = OpLabel + OpStore %tint_return_value %66 + OpBranch %58 + %58 = OpLabel + %69 = OpLoad %bool %tint_return_flag + %68 = OpLogicalNot %bool %69 + OpSelectionMerge %70 None + OpBranchConditional %68 %71 %70 + %71 = OpLabel OpStore %tint_return_flag %true - OpStore %tint_return_value %36 - OpBranch %61 - %61 = OpLabel - %63 = OpLoad %float %tint_return_value - OpReturnValue %63 + OpStore %tint_return_value %46 + OpBranch %70 + %70 = OpLabel + %72 = OpLoad %float %tint_return_value + OpReturnValue %72 OpFunctionEnd - %mm_readB = OpFunction %float None %25 + %mm_readB = OpFunction %float None %36 %row_0 = OpFunctionParameter %uint %col_0 = OpFunctionParameter %uint - %67 = OpLabel -%tint_return_flag_1 = OpVariable %_ptr_Function_bool Function %33 -%tint_return_value_1 = OpVariable %_ptr_Function_float Function %36 - %70 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %71 = OpLoad %uint %70 - %72 = OpULessThan %bool %row_0 %71 - OpSelectionMerge %73 None - OpBranchConditional %72 %74 %73 - %74 = OpLabel - %76 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 - %77 = OpLoad %uint %76 - %78 = OpULessThan %bool %col_0 %77 - OpBranch %73 - %73 = OpLabel - %79 = OpPhi %bool %72 %67 %78 %74 - OpSelectionMerge %80 None - OpBranchConditional %79 %81 %80 - %81 = OpLabel - %82 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 - %83 = OpLoad %uint %82 - %84 = OpIMul %uint %row_0 %83 - %85 = OpIAdd %uint %84 %col_0 - %86 = OpAccessChain %_ptr_StorageBuffer_float %secondMatrix %uint_0 %85 - %87 = OpLoad %float %86 - OpStore %tint_return_flag_1 %true - OpStore %tint_return_value_1 %87 - OpBranch %80 - %80 = OpLabel - %89 = OpLoad %bool %tint_return_flag_1 - %88 = OpLogicalNot %bool %89 - OpSelectionMerge %90 None - OpBranchConditional %88 %91 %90 - %91 = OpLabel - OpStore %tint_return_flag_1 %true - OpStore %tint_return_value_1 %36 - OpBranch %90 + %76 = OpLabel +%tint_return_flag_1 = OpVariable %_ptr_Function_bool Function %43 +%tint_return_value_1 = OpVariable %_ptr_Function_float Function %46 + %79 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %80 = OpLoad %uint %79 + %81 = OpULessThan %bool %row_0 %80 + OpSelectionMerge %82 None + OpBranchConditional %81 %83 %82 + %83 = OpLabel + %85 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 + %86 = OpLoad %uint %85 + %87 = OpULessThan %bool %col_0 %86 + OpBranch %82 + %82 = OpLabel + %88 = OpPhi %bool %81 %76 %87 %83 + OpSelectionMerge %89 None + OpBranchConditional %88 %90 %89 %90 = OpLabel - %92 = OpLoad %float %tint_return_value_1 - OpReturnValue %92 + %91 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 + %92 = OpLoad %uint %91 + %93 = OpIMul %uint %row_0 %92 + %94 = OpIAdd %uint %93 %col_0 + %95 = OpAccessChain %_ptr_StorageBuffer_float %secondMatrix %uint_0 %94 + %96 = OpLoad %float %95 + OpStore %tint_return_flag_1 %true + OpStore %tint_return_value_1 %96 + OpBranch %89 + %89 = OpLabel + %98 = OpLoad %bool %tint_return_flag_1 + %97 = OpLogicalNot %bool %98 + OpSelectionMerge %99 None + OpBranchConditional %97 %100 %99 + %100 = OpLabel + OpStore %tint_return_flag_1 %true + OpStore %tint_return_value_1 %46 + OpBranch %99 + %99 = OpLabel + %101 = OpLoad %float %tint_return_value_1 + OpReturnValue %101 OpFunctionEnd - %mm_write = OpFunction %void None %93 + %mm_write = OpFunction %void None %102 %row_1 = OpFunctionParameter %uint %col_1 = OpFunctionParameter %uint %value = OpFunctionParameter %float - %99 = OpLabel - %100 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 - %101 = OpLoad %uint %100 - %102 = OpULessThan %bool %row_1 %101 - OpSelectionMerge %103 None - OpBranchConditional %102 %104 %103 - %104 = OpLabel - %105 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 - %106 = OpLoad %uint %105 - %107 = OpULessThan %bool %col_1 %106 - OpBranch %103 - %103 = OpLabel - %108 = OpPhi %bool %102 %99 %107 %104 - OpSelectionMerge %109 None - OpBranchConditional %108 %110 %109 - %110 = OpLabel - %111 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 - %112 = OpLoad %uint %111 - %113 = OpIMul %uint %row_1 %112 - %114 = OpIAdd %uint %col_1 %113 - %115 = OpAccessChain %_ptr_StorageBuffer_float %resultMatrix %uint_0 %114 - OpStore %115 %value - OpBranch %109 - %109 = OpLabel + %108 = OpLabel + %109 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_0 + %110 = OpLoad %uint %109 + %111 = OpULessThan %bool %row_1 %110 + OpSelectionMerge %112 None + OpBranchConditional %111 %113 %112 + %113 = OpLabel + %114 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 + %115 = OpLoad %uint %114 + %116 = OpULessThan %bool %col_1 %115 + OpBranch %112 + %112 = OpLabel + %117 = OpPhi %bool %111 %108 %116 %113 + OpSelectionMerge %118 None + OpBranchConditional %117 %119 %118 + %119 = OpLabel + %120 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_2 + %121 = OpLoad %uint %120 + %122 = OpIMul %uint %row_1 %121 + %123 = OpIAdd %uint %col_1 %122 + %124 = OpAccessChain %_ptr_StorageBuffer_float %resultMatrix %uint_0 %123 + OpStore %124 %value + OpBranch %118 + %118 = OpLabel OpReturn OpFunctionEnd - %main_inner = OpFunction %void None %116 + %main_inner = OpFunction %void None %125 %local_id = OpFunctionParameter %v3uint %global_id = OpFunctionParameter %v3uint %local_invocation_index = OpFunctionParameter %uint - %121 = OpLabel - %idx = OpVariable %_ptr_Function_uint Function %124 - %acc = OpVariable %_ptr_Function__arr_float_uint_16 Function %165 - %ACached = OpVariable %_ptr_Function_float Function %36 - %BCached = OpVariable %_ptr_Function__arr_float_uint_4 Function %170 - %index = OpVariable %_ptr_Function_uint Function %124 - %t = OpVariable %_ptr_Function_uint Function %124 - %innerRow = OpVariable %_ptr_Function_uint Function %124 - %innerCol = OpVariable %_ptr_Function_uint Function %124 - %innerRow_0 = OpVariable %_ptr_Function_uint Function %124 - %innerCol_0 = OpVariable %_ptr_Function_uint Function %124 - %k = OpVariable %_ptr_Function_uint Function %124 - %inner = OpVariable %_ptr_Function_uint Function %124 - %innerRow_1 = OpVariable %_ptr_Function_uint Function %124 - %innerCol_1 = OpVariable %_ptr_Function_uint Function %124 - %innerRow_2 = OpVariable %_ptr_Function_uint Function %124 - %innerCol_2 = OpVariable %_ptr_Function_uint Function %124 + %130 = OpLabel + %idx = OpVariable %_ptr_Function_uint Function %31 + %acc = OpVariable %_ptr_Function__arr_float_uint_16 Function %173 + %ACached = OpVariable %_ptr_Function_float Function %46 + %BCached = OpVariable %_ptr_Function__arr_float_uint_4 Function %178 + %index = OpVariable %_ptr_Function_uint Function %31 + %t = OpVariable %_ptr_Function_uint Function %31 + %innerRow = OpVariable %_ptr_Function_uint Function %31 + %innerCol = OpVariable %_ptr_Function_uint Function %31 + %innerRow_0 = OpVariable %_ptr_Function_uint Function %31 + %innerCol_0 = OpVariable %_ptr_Function_uint Function %31 + %k = OpVariable %_ptr_Function_uint Function %31 + %inner = OpVariable %_ptr_Function_uint Function %31 + %innerRow_1 = OpVariable %_ptr_Function_uint Function %31 + %innerCol_1 = OpVariable %_ptr_Function_uint Function %31 + %innerRow_2 = OpVariable %_ptr_Function_uint Function %31 + %innerCol_2 = OpVariable %_ptr_Function_uint Function %31 OpStore %idx %local_invocation_index - OpBranch %125 - %125 = OpLabel - OpLoopMerge %126 %127 None - OpBranch %128 - %128 = OpLabel - %130 = OpLoad %uint %idx - %132 = OpULessThan %bool %130 %uint_4096 - %129 = OpLogicalNot %bool %132 - OpSelectionMerge %133 None - OpBranchConditional %129 %134 %133 - %134 = OpLabel - OpBranch %126 + OpBranch %133 %133 = OpLabel - %135 = OpLoad %uint %idx - %136 = OpUDiv %uint %135 %uint_64 - %137 = OpLoad %uint %idx - %138 = OpUMod %uint %137 %uint_64 - %140 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %136 %138 - OpStore %140 %36 - %141 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %136 %138 - OpStore %141 %36 - OpBranch %127 - %127 = OpLabel - %142 = OpLoad %uint %idx - %144 = OpIAdd %uint %142 %uint_256 - OpStore %idx %144 - OpBranch %125 - %126 = OpLabel + OpLoopMerge %134 %135 None + OpBranch %136 + %136 = OpLabel + %138 = OpLoad %uint %idx + %140 = OpULessThan %bool %138 %uint_4096 + %137 = OpLogicalNot %bool %140 + OpSelectionMerge %141 None + OpBranchConditional %137 %142 %141 + %142 = OpLabel + OpBranch %134 + %141 = OpLabel + %143 = OpLoad %uint %idx + %144 = OpUDiv %uint %143 %uint_64 + %145 = OpLoad %uint %idx + %146 = OpUMod %uint %145 %uint_64 + %148 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %144 %146 + OpStore %148 %46 + %149 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %144 %146 + OpStore %149 %46 + OpBranch %135 + %135 = OpLabel + %150 = OpLoad %uint %idx + %152 = OpIAdd %uint %150 %uint_256 + OpStore %idx %152 + OpBranch %133 + %134 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - %147 = OpCompositeExtract %uint %local_id 1 - %149 = OpIMul %uint %147 %uint_4 - %150 = OpCompositeExtract %uint %local_id 0 - %151 = OpIMul %uint %150 %uint_4 - %152 = OpCompositeExtract %uint %global_id 1 - %153 = OpIMul %uint %152 %uint_4 - %154 = OpCompositeExtract %uint %global_id 0 - %155 = OpIMul %uint %154 %uint_4 - %156 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 - %157 = OpLoad %uint %156 - %158 = OpISub %uint %157 %uint_1 - %159 = OpUDiv %uint %158 %uint_64 - %160 = OpIAdd %uint %159 %uint_1 - OpStore %index %124 - OpBranch %172 - %172 = OpLabel - OpLoopMerge %173 %174 None - OpBranch %175 - %175 = OpLabel - %177 = OpLoad %uint %index - %178 = OpULessThan %bool %177 %uint_16 - %176 = OpLogicalNot %bool %178 - OpSelectionMerge %179 None - OpBranchConditional %176 %180 %179 + %155 = OpCompositeExtract %uint %local_id 1 + %157 = OpIMul %uint %155 %uint_4 + %158 = OpCompositeExtract %uint %local_id 0 + %159 = OpIMul %uint %158 %uint_4 + %160 = OpCompositeExtract %uint %global_id 1 + %161 = OpIMul %uint %160 %uint_4 + %162 = OpCompositeExtract %uint %global_id 0 + %163 = OpIMul %uint %162 %uint_4 + %165 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_0 %uint_1 + %166 = OpLoad %uint %165 + %167 = OpISub %uint %166 %uint_1 + %164 = OpFunctionCall %uint %tint_div %167 %uint_64 + %168 = OpIAdd %uint %164 %uint_1 + OpStore %index %31 + OpBranch %180 %180 = OpLabel - OpBranch %173 - %179 = OpLabel - %181 = OpLoad %uint %index - %182 = OpAccessChain %_ptr_Function_float %acc %181 - OpStore %182 %36 - OpBranch %174 - %174 = OpLabel - %183 = OpLoad %uint %index - %184 = OpIAdd %uint %183 %uint_1 - OpStore %index %184 - OpBranch %172 - %173 = OpLabel - %185 = OpCompositeExtract %uint %local_id 0 - %186 = OpIMul %uint %185 %uint_4 - %187 = OpCompositeExtract %uint %local_id 1 - %188 = OpIMul %uint %187 %uint_4 - OpStore %t %124 - OpBranch %190 - %190 = OpLabel - OpLoopMerge %191 %192 None - OpBranch %193 - %193 = OpLabel - %195 = OpLoad %uint %t - %196 = OpULessThan %bool %195 %160 - %194 = OpLogicalNot %bool %196 - OpSelectionMerge %197 None - OpBranchConditional %194 %198 %197 + OpLoopMerge %181 %182 None + OpBranch %183 + %183 = OpLabel + %185 = OpLoad %uint %index + %186 = OpULessThan %bool %185 %uint_16 + %184 = OpLogicalNot %bool %186 + OpSelectionMerge %187 None + OpBranchConditional %184 %188 %187 + %188 = OpLabel + OpBranch %181 + %187 = OpLabel + %189 = OpLoad %uint %index + %190 = OpAccessChain %_ptr_Function_float %acc %189 + OpStore %190 %46 + OpBranch %182 + %182 = OpLabel + %191 = OpLoad %uint %index + %192 = OpIAdd %uint %191 %uint_1 + OpStore %index %192 + OpBranch %180 + %181 = OpLabel + %193 = OpCompositeExtract %uint %local_id 0 + %194 = OpIMul %uint %193 %uint_4 + %195 = OpCompositeExtract %uint %local_id 1 + %196 = OpIMul %uint %195 %uint_4 + OpStore %t %31 + OpBranch %198 %198 = OpLabel - OpBranch %191 - %197 = OpLabel - OpStore %innerRow %124 - OpBranch %200 - %200 = OpLabel - OpLoopMerge %201 %202 None - OpBranch %203 - %203 = OpLabel - %205 = OpLoad %uint %innerRow - %206 = OpULessThan %bool %205 %uint_4 - %204 = OpLogicalNot %bool %206 - OpSelectionMerge %207 None - OpBranchConditional %204 %208 %207 - %208 = OpLabel + OpLoopMerge %199 %200 None OpBranch %201 - %207 = OpLabel - OpStore %innerCol %124 + %201 = OpLabel + %203 = OpLoad %uint %t + %204 = OpULessThan %bool %203 %168 + %202 = OpLogicalNot %bool %204 + OpSelectionMerge %205 None + OpBranchConditional %202 %206 %205 + %206 = OpLabel + OpBranch %199 + %205 = OpLabel + OpStore %innerRow %31 + OpBranch %208 + %208 = OpLabel + OpLoopMerge %209 %210 None + OpBranch %211 + %211 = OpLabel + %213 = OpLoad %uint %innerRow + %214 = OpULessThan %bool %213 %uint_4 + %212 = OpLogicalNot %bool %214 + OpSelectionMerge %215 None + OpBranchConditional %212 %216 %215 + %216 = OpLabel + OpBranch %209 + %215 = OpLabel + OpStore %innerCol %31 + OpBranch %218 + %218 = OpLabel + OpLoopMerge %219 %220 None + OpBranch %221 + %221 = OpLabel + %223 = OpLoad %uint %innerCol + %224 = OpULessThan %bool %223 %uint_4 + %222 = OpLogicalNot %bool %224 + OpSelectionMerge %225 None + OpBranchConditional %222 %226 %225 + %226 = OpLabel + OpBranch %219 + %225 = OpLabel + %227 = OpLoad %uint %innerRow + %228 = OpIAdd %uint %157 %227 + %229 = OpLoad %uint %innerCol + %230 = OpIAdd %uint %194 %229 + %232 = OpLoad %uint %innerRow + %233 = OpIAdd %uint %161 %232 + %234 = OpLoad %uint %t + %235 = OpIMul %uint %234 %uint_64 + %236 = OpIAdd %uint %235 %230 + %231 = OpFunctionCall %float %mm_readA %233 %236 + %237 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %228 %230 + OpStore %237 %231 + OpBranch %220 + %220 = OpLabel + %238 = OpLoad %uint %innerCol + %239 = OpIAdd %uint %238 %uint_1 + OpStore %innerCol %239 + OpBranch %218 + %219 = OpLabel OpBranch %210 %210 = OpLabel - OpLoopMerge %211 %212 None - OpBranch %213 - %213 = OpLabel - %215 = OpLoad %uint %innerCol - %216 = OpULessThan %bool %215 %uint_4 - %214 = OpLogicalNot %bool %216 - OpSelectionMerge %217 None - OpBranchConditional %214 %218 %217 - %218 = OpLabel - OpBranch %211 - %217 = OpLabel - %219 = OpLoad %uint %innerRow - %220 = OpIAdd %uint %149 %219 - %221 = OpLoad %uint %innerCol - %222 = OpIAdd %uint %186 %221 - %224 = OpLoad %uint %innerRow - %225 = OpIAdd %uint %153 %224 - %226 = OpLoad %uint %t - %227 = OpIMul %uint %226 %uint_64 - %228 = OpIAdd %uint %227 %222 - %223 = OpFunctionCall %float %mm_readA %225 %228 - %229 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %220 %222 - OpStore %229 %223 - OpBranch %212 - %212 = OpLabel - %230 = OpLoad %uint %innerCol - %231 = OpIAdd %uint %230 %uint_1 - OpStore %innerCol %231 - OpBranch %210 - %211 = OpLabel - OpBranch %202 - %202 = OpLabel - %232 = OpLoad %uint %innerRow - %233 = OpIAdd %uint %232 %uint_1 - OpStore %innerRow %233 - OpBranch %200 - %201 = OpLabel - OpStore %innerRow_0 %124 - OpBranch %235 - %235 = OpLabel - OpLoopMerge %236 %237 None - OpBranch %238 - %238 = OpLabel - %240 = OpLoad %uint %innerRow_0 - %241 = OpULessThan %bool %240 %uint_4 - %239 = OpLogicalNot %bool %241 - OpSelectionMerge %242 None - OpBranchConditional %239 %243 %242 + %240 = OpLoad %uint %innerRow + %241 = OpIAdd %uint %240 %uint_1 + OpStore %innerRow %241 + OpBranch %208 + %209 = OpLabel + OpStore %innerRow_0 %31 + OpBranch %243 %243 = OpLabel - OpBranch %236 - %242 = OpLabel - OpStore %innerCol_0 %124 + OpLoopMerge %244 %245 None + OpBranch %246 + %246 = OpLabel + %248 = OpLoad %uint %innerRow_0 + %249 = OpULessThan %bool %248 %uint_4 + %247 = OpLogicalNot %bool %249 + OpSelectionMerge %250 None + OpBranchConditional %247 %251 %250 + %251 = OpLabel + OpBranch %244 + %250 = OpLabel + OpStore %innerCol_0 %31 + OpBranch %253 + %253 = OpLabel + OpLoopMerge %254 %255 None + OpBranch %256 + %256 = OpLabel + %258 = OpLoad %uint %innerCol_0 + %259 = OpULessThan %bool %258 %uint_4 + %257 = OpLogicalNot %bool %259 + OpSelectionMerge %260 None + OpBranchConditional %257 %261 %260 + %261 = OpLabel + OpBranch %254 + %260 = OpLabel + %262 = OpLoad %uint %innerRow_0 + %263 = OpIAdd %uint %196 %262 + %264 = OpLoad %uint %innerCol_0 + %265 = OpIAdd %uint %159 %264 + %267 = OpLoad %uint %t + %268 = OpIMul %uint %267 %uint_64 + %269 = OpIAdd %uint %268 %263 + %270 = OpLoad %uint %innerCol_0 + %271 = OpIAdd %uint %163 %270 + %266 = OpFunctionCall %float %mm_readB %269 %271 + %272 = OpLoad %uint %innerCol_0 + %273 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %272 %265 + OpStore %273 %266 + OpBranch %255 + %255 = OpLabel + %274 = OpLoad %uint %innerCol_0 + %275 = OpIAdd %uint %274 %uint_1 + OpStore %innerCol_0 %275 + OpBranch %253 + %254 = OpLabel OpBranch %245 %245 = OpLabel - OpLoopMerge %246 %247 None - OpBranch %248 - %248 = OpLabel - %250 = OpLoad %uint %innerCol_0 - %251 = OpULessThan %bool %250 %uint_4 - %249 = OpLogicalNot %bool %251 - OpSelectionMerge %252 None - OpBranchConditional %249 %253 %252 - %253 = OpLabel - OpBranch %246 - %252 = OpLabel - %254 = OpLoad %uint %innerRow_0 - %255 = OpIAdd %uint %188 %254 - %256 = OpLoad %uint %innerCol_0 - %257 = OpIAdd %uint %151 %256 - %259 = OpLoad %uint %t - %260 = OpIMul %uint %259 %uint_64 - %261 = OpIAdd %uint %260 %255 - %262 = OpLoad %uint %innerCol_0 - %263 = OpIAdd %uint %155 %262 - %258 = OpFunctionCall %float %mm_readB %261 %263 - %264 = OpLoad %uint %innerCol_0 - %265 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %264 %257 - OpStore %265 %258 - OpBranch %247 - %247 = OpLabel - %266 = OpLoad %uint %innerCol_0 - %267 = OpIAdd %uint %266 %uint_1 - OpStore %innerCol_0 %267 - OpBranch %245 - %246 = OpLabel - OpBranch %237 - %237 = OpLabel - %268 = OpLoad %uint %innerRow_0 - %269 = OpIAdd %uint %268 %uint_1 - OpStore %innerRow_0 %269 - OpBranch %235 - %236 = OpLabel + %276 = OpLoad %uint %innerRow_0 + %277 = OpIAdd %uint %276 %uint_1 + OpStore %innerRow_0 %277 + OpBranch %243 + %244 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - OpStore %k %124 - OpBranch %272 - %272 = OpLabel - OpLoopMerge %273 %274 None - OpBranch %275 - %275 = OpLabel - %277 = OpLoad %uint %k - %278 = OpULessThan %bool %277 %uint_64 - %276 = OpLogicalNot %bool %278 - OpSelectionMerge %279 None - OpBranchConditional %276 %280 %279 + OpStore %k %31 + OpBranch %280 %280 = OpLabel - OpBranch %273 - %279 = OpLabel - OpStore %inner %124 + OpLoopMerge %281 %282 None + OpBranch %283 + %283 = OpLabel + %285 = OpLoad %uint %k + %286 = OpULessThan %bool %285 %uint_64 + %284 = OpLogicalNot %bool %286 + OpSelectionMerge %287 None + OpBranchConditional %284 %288 %287 + %288 = OpLabel + OpBranch %281 + %287 = OpLabel + OpStore %inner %31 + OpBranch %290 + %290 = OpLabel + OpLoopMerge %291 %292 None + OpBranch %293 + %293 = OpLabel + %295 = OpLoad %uint %inner + %296 = OpULessThan %bool %295 %uint_4 + %294 = OpLogicalNot %bool %296 + OpSelectionMerge %297 None + OpBranchConditional %294 %298 %297 + %298 = OpLabel + OpBranch %291 + %297 = OpLabel + %299 = OpLoad %uint %inner + %300 = OpAccessChain %_ptr_Function_float %BCached %299 + %301 = OpLoad %uint %k + %302 = OpLoad %uint %inner + %303 = OpIAdd %uint %159 %302 + %304 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %301 %303 + %305 = OpLoad %float %304 + OpStore %300 %305 + OpBranch %292 + %292 = OpLabel + %306 = OpLoad %uint %inner + %307 = OpIAdd %uint %306 %uint_1 + OpStore %inner %307 + OpBranch %290 + %291 = OpLabel + OpStore %innerRow_1 %31 + OpBranch %309 + %309 = OpLabel + OpLoopMerge %310 %311 None + OpBranch %312 + %312 = OpLabel + %314 = OpLoad %uint %innerRow_1 + %315 = OpULessThan %bool %314 %uint_4 + %313 = OpLogicalNot %bool %315 + OpSelectionMerge %316 None + OpBranchConditional %313 %317 %316 + %317 = OpLabel + OpBranch %310 + %316 = OpLabel + %318 = OpLoad %uint %innerRow_1 + %319 = OpIAdd %uint %157 %318 + %320 = OpLoad %uint %k + %321 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %319 %320 + %322 = OpLoad %float %321 + OpStore %ACached %322 + OpStore %innerCol_1 %31 + OpBranch %324 + %324 = OpLabel + OpLoopMerge %325 %326 None + OpBranch %327 + %327 = OpLabel + %329 = OpLoad %uint %innerCol_1 + %330 = OpULessThan %bool %329 %uint_4 + %328 = OpLogicalNot %bool %330 + OpSelectionMerge %331 None + OpBranchConditional %328 %332 %331 + %332 = OpLabel + OpBranch %325 + %331 = OpLabel + %333 = OpLoad %uint %innerRow_1 + %334 = OpIMul %uint %333 %uint_4 + %335 = OpLoad %uint %innerCol_1 + %336 = OpIAdd %uint %334 %335 + %337 = OpAccessChain %_ptr_Function_float %acc %336 + %338 = OpAccessChain %_ptr_Function_float %acc %336 + %339 = OpLoad %float %338 + %340 = OpLoad %float %ACached + %341 = OpLoad %uint %innerCol_1 + %342 = OpAccessChain %_ptr_Function_float %BCached %341 + %343 = OpLoad %float %342 + %344 = OpFMul %float %340 %343 + %345 = OpFAdd %float %339 %344 + OpStore %337 %345 + OpBranch %326 + %326 = OpLabel + %346 = OpLoad %uint %innerCol_1 + %347 = OpIAdd %uint %346 %uint_1 + OpStore %innerCol_1 %347 + OpBranch %324 + %325 = OpLabel + OpBranch %311 + %311 = OpLabel + %348 = OpLoad %uint %innerRow_1 + %349 = OpIAdd %uint %348 %uint_1 + OpStore %innerRow_1 %349 + OpBranch %309 + %310 = OpLabel OpBranch %282 %282 = OpLabel - OpLoopMerge %283 %284 None - OpBranch %285 - %285 = OpLabel - %287 = OpLoad %uint %inner - %288 = OpULessThan %bool %287 %uint_4 - %286 = OpLogicalNot %bool %288 - OpSelectionMerge %289 None - OpBranchConditional %286 %290 %289 - %290 = OpLabel - OpBranch %283 - %289 = OpLabel - %291 = OpLoad %uint %inner - %292 = OpAccessChain %_ptr_Function_float %BCached %291 - %293 = OpLoad %uint %k - %294 = OpLoad %uint %inner - %295 = OpIAdd %uint %151 %294 - %296 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %293 %295 - %297 = OpLoad %float %296 - OpStore %292 %297 - OpBranch %284 - %284 = OpLabel - %298 = OpLoad %uint %inner - %299 = OpIAdd %uint %298 %uint_1 - OpStore %inner %299 - OpBranch %282 - %283 = OpLabel - OpStore %innerRow_1 %124 - OpBranch %301 - %301 = OpLabel - OpLoopMerge %302 %303 None - OpBranch %304 - %304 = OpLabel - %306 = OpLoad %uint %innerRow_1 - %307 = OpULessThan %bool %306 %uint_4 - %305 = OpLogicalNot %bool %307 - OpSelectionMerge %308 None - OpBranchConditional %305 %309 %308 - %309 = OpLabel - OpBranch %302 - %308 = OpLabel - %310 = OpLoad %uint %innerRow_1 - %311 = OpIAdd %uint %149 %310 - %312 = OpLoad %uint %k - %313 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %311 %312 - %314 = OpLoad %float %313 - OpStore %ACached %314 - OpStore %innerCol_1 %124 - OpBranch %316 - %316 = OpLabel - OpLoopMerge %317 %318 None - OpBranch %319 - %319 = OpLabel - %321 = OpLoad %uint %innerCol_1 - %322 = OpULessThan %bool %321 %uint_4 - %320 = OpLogicalNot %bool %322 - OpSelectionMerge %323 None - OpBranchConditional %320 %324 %323 - %324 = OpLabel - OpBranch %317 - %323 = OpLabel - %325 = OpLoad %uint %innerRow_1 - %326 = OpIMul %uint %325 %uint_4 - %327 = OpLoad %uint %innerCol_1 - %328 = OpIAdd %uint %326 %327 - %329 = OpAccessChain %_ptr_Function_float %acc %328 - %330 = OpAccessChain %_ptr_Function_float %acc %328 - %331 = OpLoad %float %330 - %332 = OpLoad %float %ACached - %333 = OpLoad %uint %innerCol_1 - %334 = OpAccessChain %_ptr_Function_float %BCached %333 - %335 = OpLoad %float %334 - %336 = OpFMul %float %332 %335 - %337 = OpFAdd %float %331 %336 - OpStore %329 %337 - OpBranch %318 - %318 = OpLabel - %338 = OpLoad %uint %innerCol_1 - %339 = OpIAdd %uint %338 %uint_1 - OpStore %innerCol_1 %339 - OpBranch %316 - %317 = OpLabel - OpBranch %303 - %303 = OpLabel - %340 = OpLoad %uint %innerRow_1 - %341 = OpIAdd %uint %340 %uint_1 - OpStore %innerRow_1 %341 - OpBranch %301 - %302 = OpLabel - OpBranch %274 - %274 = OpLabel - %342 = OpLoad %uint %k - %343 = OpIAdd %uint %342 %uint_1 - OpStore %k %343 - OpBranch %272 - %273 = OpLabel + %350 = OpLoad %uint %k + %351 = OpIAdd %uint %350 %uint_1 + OpStore %k %351 + OpBranch %280 + %281 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - OpBranch %192 - %192 = OpLabel - %345 = OpLoad %uint %t - %346 = OpIAdd %uint %345 %uint_1 - OpStore %t %346 - OpBranch %190 - %191 = OpLabel - OpStore %innerRow_2 %124 - OpBranch %348 - %348 = OpLabel - OpLoopMerge %349 %350 None - OpBranch %351 - %351 = OpLabel - %353 = OpLoad %uint %innerRow_2 - %354 = OpULessThan %bool %353 %uint_4 - %352 = OpLogicalNot %bool %354 - OpSelectionMerge %355 None - OpBranchConditional %352 %356 %355 + OpBranch %200 + %200 = OpLabel + %353 = OpLoad %uint %t + %354 = OpIAdd %uint %353 %uint_1 + OpStore %t %354 + OpBranch %198 + %199 = OpLabel + OpStore %innerRow_2 %31 + OpBranch %356 %356 = OpLabel - OpBranch %349 - %355 = OpLabel - OpStore %innerCol_2 %124 + OpLoopMerge %357 %358 None + OpBranch %359 + %359 = OpLabel + %361 = OpLoad %uint %innerRow_2 + %362 = OpULessThan %bool %361 %uint_4 + %360 = OpLogicalNot %bool %362 + OpSelectionMerge %363 None + OpBranchConditional %360 %364 %363 + %364 = OpLabel + OpBranch %357 + %363 = OpLabel + OpStore %innerCol_2 %31 + OpBranch %366 + %366 = OpLabel + OpLoopMerge %367 %368 None + OpBranch %369 + %369 = OpLabel + %371 = OpLoad %uint %innerCol_2 + %372 = OpULessThan %bool %371 %uint_4 + %370 = OpLogicalNot %bool %372 + OpSelectionMerge %373 None + OpBranchConditional %370 %374 %373 + %374 = OpLabel + OpBranch %367 + %373 = OpLabel + %375 = OpLoad %uint %innerRow_2 + %376 = OpIMul %uint %375 %uint_4 + %377 = OpLoad %uint %innerCol_2 + %378 = OpIAdd %uint %376 %377 + %380 = OpLoad %uint %innerRow_2 + %381 = OpIAdd %uint %161 %380 + %382 = OpLoad %uint %innerCol_2 + %383 = OpIAdd %uint %163 %382 + %384 = OpAccessChain %_ptr_Function_float %acc %378 + %385 = OpLoad %float %384 + %379 = OpFunctionCall %void %mm_write %381 %383 %385 + OpBranch %368 + %368 = OpLabel + %386 = OpLoad %uint %innerCol_2 + %387 = OpIAdd %uint %386 %uint_1 + OpStore %innerCol_2 %387 + OpBranch %366 + %367 = OpLabel OpBranch %358 %358 = OpLabel - OpLoopMerge %359 %360 None - OpBranch %361 - %361 = OpLabel - %363 = OpLoad %uint %innerCol_2 - %364 = OpULessThan %bool %363 %uint_4 - %362 = OpLogicalNot %bool %364 - OpSelectionMerge %365 None - OpBranchConditional %362 %366 %365 - %366 = OpLabel - OpBranch %359 - %365 = OpLabel - %367 = OpLoad %uint %innerRow_2 - %368 = OpIMul %uint %367 %uint_4 - %369 = OpLoad %uint %innerCol_2 - %370 = OpIAdd %uint %368 %369 - %372 = OpLoad %uint %innerRow_2 - %373 = OpIAdd %uint %153 %372 - %374 = OpLoad %uint %innerCol_2 - %375 = OpIAdd %uint %155 %374 - %376 = OpAccessChain %_ptr_Function_float %acc %370 - %377 = OpLoad %float %376 - %371 = OpFunctionCall %void %mm_write %373 %375 %377 - OpBranch %360 - %360 = OpLabel - %378 = OpLoad %uint %innerCol_2 - %379 = OpIAdd %uint %378 %uint_1 - OpStore %innerCol_2 %379 - OpBranch %358 - %359 = OpLabel - OpBranch %350 - %350 = OpLabel - %380 = OpLoad %uint %innerRow_2 - %381 = OpIAdd %uint %380 %uint_1 - OpStore %innerRow_2 %381 - OpBranch %348 - %349 = OpLabel + %388 = OpLoad %uint %innerRow_2 + %389 = OpIAdd %uint %388 %uint_1 + OpStore %innerRow_2 %389 + OpBranch %356 + %357 = OpLabel OpReturn OpFunctionEnd - %main = OpFunction %void None %382 - %384 = OpLabel - %386 = OpLoad %v3uint %local_id_1 - %387 = OpLoad %v3uint %global_id_1 - %388 = OpLoad %uint %local_invocation_index_1 - %385 = OpFunctionCall %void %main_inner %386 %387 %388 + %main = OpFunction %void None %390 + %392 = OpLabel + %394 = OpLoad %v3uint %local_id_1 + %395 = OpLoad %v3uint %global_id_1 + %396 = OpLoad %uint %local_invocation_index_1 + %393 = OpFunctionCall %void %main_inner %394 %395 %396 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl index 0f2d328b0c..e445348236 100644 --- a/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl +++ b/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl @@ -1,3 +1,7 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + SamplerState samp : register(s0, space0); cbuffer cbuffer_params : register(b1, space0) { uint4 params[1]; @@ -25,7 +29,7 @@ void main_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_invocatio } } GroupMemoryBarrierWithGroupSync(); - const uint filterOffset = ((params[0].x - 1u) / 2u); + const uint filterOffset = tint_div((params[0].x - 1u), 2u); int3 tint_tmp; inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z); const uint2 dims = tint_tmp.xy; diff --git a/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl index 0f2d328b0c..e445348236 100644 --- a/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl +++ b/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl @@ -1,3 +1,7 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + SamplerState samp : register(s0, space0); cbuffer cbuffer_params : register(b1, space0) { uint4 params[1]; @@ -25,7 +29,7 @@ void main_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_invocatio } } GroupMemoryBarrierWithGroupSync(); - const uint filterOffset = ((params[0].x - 1u) / 2u); + const uint filterOffset = tint_div((params[0].x - 1u), 2u); int3 tint_tmp; inputTex.GetDimensions(0, tint_tmp.x, tint_tmp.y, tint_tmp.z); const uint2 dims = tint_tmp.xy; diff --git a/test/tint/bug/tint/942.wgsl.expected.glsl b/test/tint/bug/tint/942.wgsl.expected.glsl index 6f68af7b02..77b463ae82 100644 --- a/test/tint/bug/tint/942.wgsl.expected.glsl +++ b/test/tint/bug/tint/942.wgsl.expected.glsl @@ -1,5 +1,9 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + struct Params { uint filterDim; uint blockDim; @@ -36,7 +40,7 @@ void tint_symbol(uvec3 WorkGroupID, uvec3 LocalInvocationID, uint local_invocati } } barrier(); - uint filterOffset = ((params.inner.filterDim - 1u) / 2u); + uint filterOffset = tint_div((params.inner.filterDim - 1u), 2u); uvec2 dims = uvec2(textureSize(inputTex_1, 0)); uvec2 baseIndex = (((WorkGroupID.xy * uvec2(params.inner.blockDim, 4u)) + (LocalInvocationID.xy * uvec2(4u, 1u))) - uvec2(filterOffset, 0u)); { diff --git a/test/tint/bug/tint/942.wgsl.expected.msl b/test/tint/bug/tint/942.wgsl.expected.msl index 4d884bfce8..507e1bcefa 100644 --- a/test/tint/bug/tint/942.wgsl.expected.msl +++ b/test/tint/bug/tint/942.wgsl.expected.msl @@ -14,6 +14,10 @@ struct tint_array { T elements[N]; }; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + struct Params { /* 0x0000 */ uint filterDim; /* 0x0004 */ uint blockDim; @@ -30,7 +34,7 @@ void tint_symbol_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_in (*(tint_symbol_1))[i_1][i_2] = float3(0.0f); } threadgroup_barrier(mem_flags::mem_threadgroup); - uint const filterOffset = (((*(tint_symbol_2)).filterDim - 1u) / 2u); + uint const filterOffset = tint_div(((*(tint_symbol_2)).filterDim - 1u), 2u); uint2 const dims = uint2(tint_symbol_3.get_width(0), tint_symbol_3.get_height(0)); uint2 const baseIndex = (((uint3(WorkGroupID).xy * uint2((*(tint_symbol_2)).blockDim, 4u)) + (uint3(LocalInvocationID).xy * uint2(4u, 1u))) - uint2(filterOffset, 0u)); for(uint r = 0u; (r < 4u); r = (r + 1u)) { diff --git a/test/tint/bug/tint/942.wgsl.expected.spvasm b/test/tint/bug/tint/942.wgsl.expected.spvasm index 05b4009329..711cab87f8 100644 --- a/test/tint/bug/tint/942.wgsl.expected.spvasm +++ b/test/tint/bug/tint/942.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 253 +; Bound: 261 ; Schema: 0 OpCapability Shader OpCapability ImageQuery @@ -26,6 +26,9 @@ OpMemberName %Flip 0 "value" OpName %flip "flip" OpName %tile "tile" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %main_inner "main_inner" OpName %WorkGroupID "WorkGroupID" OpName %LocalInvocationID "LocalInvocationID" @@ -98,311 +101,321 @@ %_arr__arr_v3float_uint_256_uint_4 = OpTypeArray %_arr_v3float_uint_256 %uint_4 %_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 = OpTypePointer Workgroup %_arr__arr_v3float_uint_256_uint_4 %tile = OpVariable %_ptr_Workgroup__arr__arr_v3float_uint_256_uint_4 Workgroup - %void = OpTypeVoid - %33 = OpTypeFunction %void %v3uint %v3uint %uint -%_ptr_Function_uint = OpTypePointer Function %uint - %42 = OpConstantNull %uint - %uint_1024 = OpConstant %uint 1024 + %33 = OpTypeFunction %uint %uint %uint + %39 = OpConstantNull %uint %bool = OpTypeBool + %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %44 = OpTypeFunction %void %v3uint %v3uint %uint +%_ptr_Function_uint = OpTypePointer Function %uint + %uint_1024 = OpConstant %uint 1024 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float - %60 = OpConstantNull %v3float + %69 = OpConstantNull %v3float %uint_64 = OpConstant %uint 64 %uint_2 = OpConstant %uint 2 %uint_264 = OpConstant %uint 264 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_uint = OpTypePointer Uniform %uint - %uint_1 = OpConstant %uint 1 %v2uint = OpTypeVector %uint 2 %int = OpTypeInt 32 1 - %78 = OpConstantNull %int - %85 = OpConstantComposite %v2uint %uint_4 %uint_1 + %86 = OpConstantNull %int + %93 = OpConstantComposite %v2uint %uint_4 %uint_1 %_ptr_Function_v2uint = OpTypePointer Function %v2uint - %116 = OpConstantNull %v2uint + %124 = OpConstantNull %v2uint %v4float = OpTypeVector %float 4 - %134 = OpTypeSampledImage %17 + %142 = OpTypeSampledImage %17 %v2float = OpTypeVector %float 2 %float_0_25 = OpConstant %float 0.25 - %140 = OpConstantComposite %v2float %float_0_25 %float_0_25 - %144 = OpConstantNull %float + %148 = OpConstantComposite %v2float %float_0_25 %float_0_25 + %152 = OpConstantNull %float %v2bool = OpTypeVector %bool 2 %_ptr_Function_v3float = OpTypePointer Function %v3float %float_1 = OpConstant %float 1 - %246 = OpTypeFunction %void - %main_inner = OpFunction %void None %33 + %254 = OpTypeFunction %void + %tint_div = OpFunction %uint None %33 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %37 = OpLabel + %40 = OpIEqual %bool %rhs %39 + %38 = OpSelect %uint %40 %uint_1 %rhs + %43 = OpUDiv %uint %lhs %38 + OpReturnValue %43 + OpFunctionEnd + %main_inner = OpFunction %void None %44 %WorkGroupID = OpFunctionParameter %v3uint %LocalInvocationID = OpFunctionParameter %v3uint %local_invocation_index = OpFunctionParameter %uint - %39 = OpLabel - %idx = OpVariable %_ptr_Function_uint Function %42 - %r = OpVariable %_ptr_Function_uint Function %42 - %c = OpVariable %_ptr_Function_uint Function %42 - %loadIndex = OpVariable %_ptr_Function_v2uint Function %116 - %r_0 = OpVariable %_ptr_Function_uint Function %42 - %c_0 = OpVariable %_ptr_Function_uint Function %42 - %writeIndex = OpVariable %_ptr_Function_v2uint Function %116 - %acc = OpVariable %_ptr_Function_v3float Function %60 - %f = OpVariable %_ptr_Function_uint Function %42 - %i = OpVariable %_ptr_Function_uint Function %42 + %50 = OpLabel + %idx = OpVariable %_ptr_Function_uint Function %39 + %r = OpVariable %_ptr_Function_uint Function %39 + %c = OpVariable %_ptr_Function_uint Function %39 + %loadIndex = OpVariable %_ptr_Function_v2uint Function %124 + %r_0 = OpVariable %_ptr_Function_uint Function %39 + %c_0 = OpVariable %_ptr_Function_uint Function %39 + %writeIndex = OpVariable %_ptr_Function_v2uint Function %124 + %acc = OpVariable %_ptr_Function_v3float Function %69 + %f = OpVariable %_ptr_Function_uint Function %39 + %i = OpVariable %_ptr_Function_uint Function %39 OpStore %idx %local_invocation_index - OpBranch %43 - %43 = OpLabel - OpLoopMerge %44 %45 None - OpBranch %46 - %46 = OpLabel - %48 = OpLoad %uint %idx - %50 = OpULessThan %bool %48 %uint_1024 - %47 = OpLogicalNot %bool %50 - OpSelectionMerge %52 None - OpBranchConditional %47 %53 %52 + OpBranch %53 %53 = OpLabel - OpBranch %44 - %52 = OpLabel - %54 = OpLoad %uint %idx - %55 = OpUDiv %uint %54 %uint_256 - %56 = OpLoad %uint %idx - %57 = OpUMod %uint %56 %uint_256 - %59 = OpAccessChain %_ptr_Workgroup_v3float %tile %55 %57 - OpStore %59 %60 - OpBranch %45 - %45 = OpLabel - %61 = OpLoad %uint %idx - %63 = OpIAdd %uint %61 %uint_64 - OpStore %idx %63 - OpBranch %43 - %44 = OpLabel + OpLoopMerge %54 %55 None + OpBranch %56 + %56 = OpLabel + %58 = OpLoad %uint %idx + %60 = OpULessThan %bool %58 %uint_1024 + %57 = OpLogicalNot %bool %60 + OpSelectionMerge %61 None + OpBranchConditional %57 %62 %61 + %62 = OpLabel + OpBranch %54 + %61 = OpLabel + %63 = OpLoad %uint %idx + %64 = OpUDiv %uint %63 %uint_256 + %65 = OpLoad %uint %idx + %66 = OpUMod %uint %65 %uint_256 + %68 = OpAccessChain %_ptr_Workgroup_v3float %tile %64 %66 + OpStore %68 %69 + OpBranch %55 + %55 = OpLabel + %70 = OpLoad %uint %idx + %72 = OpIAdd %uint %70 %uint_64 + OpStore %idx %72 + OpBranch %53 + %54 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - %69 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 - %70 = OpLoad %uint %69 - %72 = OpISub %uint %70 %uint_1 - %73 = OpUDiv %uint %72 %uint_2 - %76 = OpLoad %17 %inputTex - %74 = OpImageQuerySizeLod %v2uint %76 %78 - %79 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1 - %80 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_1 - %81 = OpLoad %uint %80 - %82 = OpCompositeConstruct %v2uint %81 %uint_4 - %83 = OpIMul %v2uint %79 %82 - %84 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1 - %86 = OpIMul %v2uint %84 %85 - %87 = OpIAdd %v2uint %83 %86 - %88 = OpCompositeConstruct %v2uint %73 %42 - %89 = OpISub %v2uint %87 %88 - OpStore %r %42 - OpBranch %91 - %91 = OpLabel - OpLoopMerge %92 %93 None - OpBranch %94 - %94 = OpLabel - %96 = OpLoad %uint %r - %97 = OpULessThan %bool %96 %uint_4 - %95 = OpLogicalNot %bool %97 - OpSelectionMerge %98 None - OpBranchConditional %95 %99 %98 + %79 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 + %80 = OpLoad %uint %79 + %81 = OpISub %uint %80 %uint_1 + %76 = OpFunctionCall %uint %tint_div %81 %uint_2 + %84 = OpLoad %17 %inputTex + %82 = OpImageQuerySizeLod %v2uint %84 %86 + %87 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1 + %88 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_1 + %89 = OpLoad %uint %88 + %90 = OpCompositeConstruct %v2uint %89 %uint_4 + %91 = OpIMul %v2uint %87 %90 + %92 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1 + %94 = OpIMul %v2uint %92 %93 + %95 = OpIAdd %v2uint %91 %94 + %96 = OpCompositeConstruct %v2uint %76 %39 + %97 = OpISub %v2uint %95 %96 + OpStore %r %39 + OpBranch %99 %99 = OpLabel - OpBranch %92 - %98 = OpLabel - OpStore %c %42 + OpLoopMerge %100 %101 None + OpBranch %102 + %102 = OpLabel + %104 = OpLoad %uint %r + %105 = OpULessThan %bool %104 %uint_4 + %103 = OpLogicalNot %bool %105 + OpSelectionMerge %106 None + OpBranchConditional %103 %107 %106 + %107 = OpLabel + OpBranch %100 + %106 = OpLabel + OpStore %c %39 + OpBranch %109 + %109 = OpLabel + OpLoopMerge %110 %111 None + OpBranch %112 + %112 = OpLabel + %114 = OpLoad %uint %c + %115 = OpULessThan %bool %114 %uint_4 + %113 = OpLogicalNot %bool %115 + OpSelectionMerge %116 None + OpBranchConditional %113 %117 %116 + %117 = OpLabel + OpBranch %110 + %116 = OpLabel + %118 = OpLoad %uint %c + %119 = OpLoad %uint %r + %120 = OpCompositeConstruct %v2uint %118 %119 + %121 = OpIAdd %v2uint %97 %120 + OpStore %loadIndex %121 + %125 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0 + %126 = OpLoad %uint %125 + %127 = OpINotEqual %bool %126 %39 + OpSelectionMerge %128 None + OpBranchConditional %127 %129 %128 + %129 = OpLabel + %130 = OpLoad %v2uint %loadIndex + %131 = OpVectorShuffle %v2uint %130 %130 1 0 + OpStore %loadIndex %131 + OpBranch %128 + %128 = OpLabel + %132 = OpLoad %uint %r + %133 = OpCompositeExtract %uint %LocalInvocationID 0 + %134 = OpIMul %uint %uint_4 %133 + %135 = OpLoad %uint %c + %136 = OpIAdd %uint %134 %135 + %137 = OpAccessChain %_ptr_Workgroup_v3float %tile %132 %136 + %140 = OpLoad %10 %samp + %141 = OpLoad %17 %inputTex + %143 = OpSampledImage %142 %141 %140 + %146 = OpLoad %v2uint %loadIndex + %144 = OpConvertUToF %v2float %146 + %149 = OpFAdd %v2float %144 %148 + %150 = OpConvertUToF %v2float %82 + %151 = OpFDiv %v2float %149 %150 + %138 = OpImageSampleExplicitLod %v4float %143 %151 Lod %152 + %153 = OpVectorShuffle %v3float %138 %138 0 1 2 + OpStore %137 %153 + OpBranch %111 + %111 = OpLabel + %154 = OpLoad %uint %c + %155 = OpIAdd %uint %154 %uint_1 + OpStore %c %155 + OpBranch %109 + %110 = OpLabel OpBranch %101 %101 = OpLabel - OpLoopMerge %102 %103 None - OpBranch %104 - %104 = OpLabel - %106 = OpLoad %uint %c - %107 = OpULessThan %bool %106 %uint_4 - %105 = OpLogicalNot %bool %107 - OpSelectionMerge %108 None - OpBranchConditional %105 %109 %108 - %109 = OpLabel - OpBranch %102 - %108 = OpLabel - %110 = OpLoad %uint %c - %111 = OpLoad %uint %r - %112 = OpCompositeConstruct %v2uint %110 %111 - %113 = OpIAdd %v2uint %89 %112 - OpStore %loadIndex %113 - %117 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0 - %118 = OpLoad %uint %117 - %119 = OpINotEqual %bool %118 %42 - OpSelectionMerge %120 None - OpBranchConditional %119 %121 %120 - %121 = OpLabel - %122 = OpLoad %v2uint %loadIndex - %123 = OpVectorShuffle %v2uint %122 %122 1 0 - OpStore %loadIndex %123 - OpBranch %120 - %120 = OpLabel - %124 = OpLoad %uint %r - %125 = OpCompositeExtract %uint %LocalInvocationID 0 - %126 = OpIMul %uint %uint_4 %125 - %127 = OpLoad %uint %c - %128 = OpIAdd %uint %126 %127 - %129 = OpAccessChain %_ptr_Workgroup_v3float %tile %124 %128 - %132 = OpLoad %10 %samp - %133 = OpLoad %17 %inputTex - %135 = OpSampledImage %134 %133 %132 - %138 = OpLoad %v2uint %loadIndex - %136 = OpConvertUToF %v2float %138 - %141 = OpFAdd %v2float %136 %140 - %142 = OpConvertUToF %v2float %74 - %143 = OpFDiv %v2float %141 %142 - %130 = OpImageSampleExplicitLod %v4float %135 %143 Lod %144 - %145 = OpVectorShuffle %v3float %130 %130 0 1 2 - OpStore %129 %145 - OpBranch %103 - %103 = OpLabel - %146 = OpLoad %uint %c - %147 = OpIAdd %uint %146 %uint_1 - OpStore %c %147 - OpBranch %101 - %102 = OpLabel - OpBranch %93 - %93 = OpLabel - %148 = OpLoad %uint %r - %149 = OpIAdd %uint %148 %uint_1 - OpStore %r %149 - OpBranch %91 - %92 = OpLabel + %156 = OpLoad %uint %r + %157 = OpIAdd %uint %156 %uint_1 + OpStore %r %157 + OpBranch %99 + %100 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - OpStore %r_0 %42 - OpBranch %152 - %152 = OpLabel - OpLoopMerge %153 %154 None - OpBranch %155 - %155 = OpLabel - %157 = OpLoad %uint %r_0 - %158 = OpULessThan %bool %157 %uint_4 - %156 = OpLogicalNot %bool %158 - OpSelectionMerge %159 None - OpBranchConditional %156 %160 %159 + OpStore %r_0 %39 + OpBranch %160 %160 = OpLabel - OpBranch %153 - %159 = OpLabel - OpStore %c_0 %42 - OpBranch %162 - %162 = OpLabel - OpLoopMerge %163 %164 None - OpBranch %165 - %165 = OpLabel - %167 = OpLoad %uint %c_0 - %168 = OpULessThan %bool %167 %uint_4 - %166 = OpLogicalNot %bool %168 - OpSelectionMerge %169 None - OpBranchConditional %166 %170 %169 - %170 = OpLabel + OpLoopMerge %161 %162 None OpBranch %163 - %169 = OpLabel - %171 = OpLoad %uint %c_0 - %172 = OpLoad %uint %r_0 - %173 = OpCompositeConstruct %v2uint %171 %172 - %174 = OpIAdd %v2uint %89 %173 - OpStore %writeIndex %174 - %176 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0 - %177 = OpLoad %uint %176 - %178 = OpINotEqual %bool %177 %42 - OpSelectionMerge %179 None - OpBranchConditional %178 %180 %179 - %180 = OpLabel - %181 = OpLoad %v2uint %writeIndex - %182 = OpVectorShuffle %v2uint %181 %181 1 0 + %163 = OpLabel + %165 = OpLoad %uint %r_0 + %166 = OpULessThan %bool %165 %uint_4 + %164 = OpLogicalNot %bool %166 + OpSelectionMerge %167 None + OpBranchConditional %164 %168 %167 + %168 = OpLabel + OpBranch %161 + %167 = OpLabel + OpStore %c_0 %39 + OpBranch %170 + %170 = OpLabel + OpLoopMerge %171 %172 None + OpBranch %173 + %173 = OpLabel + %175 = OpLoad %uint %c_0 + %176 = OpULessThan %bool %175 %uint_4 + %174 = OpLogicalNot %bool %176 + OpSelectionMerge %177 None + OpBranchConditional %174 %178 %177 + %178 = OpLabel + OpBranch %171 + %177 = OpLabel + %179 = OpLoad %uint %c_0 + %180 = OpLoad %uint %r_0 + %181 = OpCompositeConstruct %v2uint %179 %180 + %182 = OpIAdd %v2uint %97 %181 OpStore %writeIndex %182 - OpBranch %179 - %179 = OpLabel - %183 = OpCompositeExtract %uint %LocalInvocationID 0 - %184 = OpIMul %uint %uint_4 %183 - %185 = OpLoad %uint %c_0 - %186 = OpIAdd %uint %184 %185 - %187 = OpUGreaterThanEqual %bool %186 %73 - OpSelectionMerge %188 None - OpBranchConditional %187 %189 %188 - %189 = OpLabel - %190 = OpISub %uint %uint_256 %73 - %191 = OpULessThan %bool %186 %190 - OpBranch %188 + %184 = OpAccessChain %_ptr_Uniform_uint %flip %uint_0 %uint_0 + %185 = OpLoad %uint %184 + %186 = OpINotEqual %bool %185 %39 + OpSelectionMerge %187 None + OpBranchConditional %186 %188 %187 %188 = OpLabel - %192 = OpPhi %bool %187 %179 %191 %189 - OpSelectionMerge %193 None - OpBranchConditional %192 %194 %193 - %194 = OpLabel - %196 = OpLoad %v2uint %writeIndex - %197 = OpULessThan %v2bool %196 %74 - %195 = OpAll %bool %197 - OpBranch %193 - %193 = OpLabel - %199 = OpPhi %bool %192 %188 %195 %194 - OpSelectionMerge %200 None - OpBranchConditional %199 %201 %200 + %189 = OpLoad %v2uint %writeIndex + %190 = OpVectorShuffle %v2uint %189 %189 1 0 + OpStore %writeIndex %190 + OpBranch %187 + %187 = OpLabel + %191 = OpCompositeExtract %uint %LocalInvocationID 0 + %192 = OpIMul %uint %uint_4 %191 + %193 = OpLoad %uint %c_0 + %194 = OpIAdd %uint %192 %193 + %195 = OpUGreaterThanEqual %bool %194 %76 + OpSelectionMerge %196 None + OpBranchConditional %195 %197 %196 + %197 = OpLabel + %198 = OpISub %uint %uint_256 %76 + %199 = OpULessThan %bool %194 %198 + OpBranch %196 + %196 = OpLabel + %200 = OpPhi %bool %195 %187 %199 %197 + OpSelectionMerge %201 None + OpBranchConditional %200 %202 %201 + %202 = OpLabel + %204 = OpLoad %v2uint %writeIndex + %205 = OpULessThan %v2bool %204 %82 + %203 = OpAll %bool %205 + OpBranch %201 %201 = OpLabel - OpStore %acc %60 - OpStore %f %42 - OpBranch %205 - %205 = OpLabel - OpLoopMerge %206 %207 None + %207 = OpPhi %bool %200 %196 %203 %202 + OpSelectionMerge %208 None + OpBranchConditional %207 %209 %208 + %209 = OpLabel + OpStore %acc %69 + OpStore %f %39 + OpBranch %213 + %213 = OpLabel + OpLoopMerge %214 %215 None + OpBranch %216 + %216 = OpLabel + %218 = OpLoad %uint %f + %219 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 + %220 = OpLoad %uint %219 + %221 = OpULessThan %bool %218 %220 + %217 = OpLogicalNot %bool %221 + OpSelectionMerge %222 None + OpBranchConditional %217 %223 %222 + %223 = OpLabel + OpBranch %214 + %222 = OpLabel + %224 = OpLoad %uint %f + %225 = OpIAdd %uint %194 %224 + %226 = OpISub %uint %225 %76 + OpStore %i %226 + %228 = OpLoad %v3float %acc + %231 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 + %232 = OpLoad %uint %231 + %230 = OpConvertUToF %float %232 + %233 = OpFDiv %float %float_1 %230 + %234 = OpLoad %uint %r_0 + %235 = OpLoad %uint %i + %236 = OpAccessChain %_ptr_Workgroup_v3float %tile %234 %235 + %237 = OpLoad %v3float %236 + %238 = OpVectorTimesScalar %v3float %237 %233 + %239 = OpFAdd %v3float %228 %238 + OpStore %acc %239 + OpBranch %215 + %215 = OpLabel + %240 = OpLoad %uint %f + %241 = OpIAdd %uint %240 %uint_1 + OpStore %f %241 + OpBranch %213 + %214 = OpLabel + %243 = OpLoad %21 %outputTex + %244 = OpLoad %v2uint %writeIndex + %245 = OpLoad %v3float %acc + %246 = OpCompositeExtract %float %245 0 + %247 = OpCompositeExtract %float %245 1 + %248 = OpCompositeExtract %float %245 2 + %249 = OpCompositeConstruct %v4float %246 %247 %248 %float_1 + OpImageWrite %243 %244 %249 OpBranch %208 %208 = OpLabel - %210 = OpLoad %uint %f - %211 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 - %212 = OpLoad %uint %211 - %213 = OpULessThan %bool %210 %212 - %209 = OpLogicalNot %bool %213 - OpSelectionMerge %214 None - OpBranchConditional %209 %215 %214 - %215 = OpLabel - OpBranch %206 - %214 = OpLabel - %216 = OpLoad %uint %f - %217 = OpIAdd %uint %186 %216 - %218 = OpISub %uint %217 %73 - OpStore %i %218 - %220 = OpLoad %v3float %acc - %223 = OpAccessChain %_ptr_Uniform_uint %params %uint_0 %uint_0 - %224 = OpLoad %uint %223 - %222 = OpConvertUToF %float %224 - %225 = OpFDiv %float %float_1 %222 - %226 = OpLoad %uint %r_0 - %227 = OpLoad %uint %i - %228 = OpAccessChain %_ptr_Workgroup_v3float %tile %226 %227 - %229 = OpLoad %v3float %228 - %230 = OpVectorTimesScalar %v3float %229 %225 - %231 = OpFAdd %v3float %220 %230 - OpStore %acc %231 - OpBranch %207 - %207 = OpLabel - %232 = OpLoad %uint %f - %233 = OpIAdd %uint %232 %uint_1 - OpStore %f %233 - OpBranch %205 - %206 = OpLabel - %235 = OpLoad %21 %outputTex - %236 = OpLoad %v2uint %writeIndex - %237 = OpLoad %v3float %acc - %238 = OpCompositeExtract %float %237 0 - %239 = OpCompositeExtract %float %237 1 - %240 = OpCompositeExtract %float %237 2 - %241 = OpCompositeConstruct %v4float %238 %239 %240 %float_1 - OpImageWrite %235 %236 %241 - OpBranch %200 - %200 = OpLabel - OpBranch %164 - %164 = OpLabel - %242 = OpLoad %uint %c_0 - %243 = OpIAdd %uint %242 %uint_1 - OpStore %c_0 %243 + OpBranch %172 + %172 = OpLabel + %250 = OpLoad %uint %c_0 + %251 = OpIAdd %uint %250 %uint_1 + OpStore %c_0 %251 + OpBranch %170 + %171 = OpLabel OpBranch %162 - %163 = OpLabel - OpBranch %154 - %154 = OpLabel - %244 = OpLoad %uint %r_0 - %245 = OpIAdd %uint %244 %uint_1 - OpStore %r_0 %245 - OpBranch %152 - %153 = OpLabel + %162 = OpLabel + %252 = OpLoad %uint %r_0 + %253 = OpIAdd %uint %252 %uint_1 + OpStore %r_0 %253 + OpBranch %160 + %161 = OpLabel OpReturn OpFunctionEnd - %main = OpFunction %void None %246 - %248 = OpLabel - %250 = OpLoad %v3uint %WorkGroupID_1 - %251 = OpLoad %v3uint %LocalInvocationID_1 - %252 = OpLoad %uint %local_invocation_index_1 - %249 = OpFunctionCall %void %main_inner %250 %251 %252 + %main = OpFunction %void None %254 + %256 = OpLabel + %258 = OpLoad %v3uint %WorkGroupID_1 + %259 = OpLoad %v3uint %LocalInvocationID_1 + %260 = OpLoad %uint %local_invocation_index_1 + %257 = OpFunctionCall %void %main_inner %258 %259 %260 OpReturn OpFunctionEnd diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl index a24f87a3f6..b3bbd36e50 100644 --- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl +++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl @@ -1,3 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + static uint local_invocation_index_1 = 0u; groupshared uint wg[3][2][1]; @@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) { const uint x_31 = idx; const uint x_33 = idx; const uint x_35 = idx; + const uint tint_symbol_2 = tint_div(x_31, 2u); + const uint tint_symbol_3 = tint_mod(x_33, 2u); + const uint tint_symbol_4 = tint_mod(x_35, 1u); uint atomic_result = 0u; - InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); + InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result); { const uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl index a24f87a3f6..b3bbd36e50 100644 --- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl +++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl @@ -1,3 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + static uint local_invocation_index_1 = 0u; groupshared uint wg[3][2][1]; @@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) { const uint x_31 = idx; const uint x_33 = idx; const uint x_35 = idx; + const uint tint_symbol_2 = tint_div(x_31, 2u); + const uint tint_symbol_3 = tint_mod(x_33, 2u); + const uint tint_symbol_4 = tint_mod(x_35, 1u); uint atomic_result = 0u; - InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); + InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result); { const uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl index f73d1c9a70..d21534a2b5 100644 --- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl +++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl @@ -1,5 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + uint local_invocation_index_1 = 0u; shared uint wg[3][2][1]; void compute_main_inner(uint local_invocation_index) { @@ -13,7 +21,10 @@ void compute_main_inner(uint local_invocation_index) { uint x_31 = idx; uint x_33 = idx; uint x_35 = idx; - atomicExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u); + uint tint_symbol = tint_div(x_31, 2u); + uint tint_symbol_1 = tint_mod(x_33, 2u); + uint tint_symbol_2 = tint_mod(x_35, 1u); + atomicExchange(wg[tint_symbol][tint_symbol_1][tint_symbol_2], 0u); { uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl index 943a64cf5c..f1220afa5b 100644 --- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl +++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl @@ -14,7 +14,15 @@ struct tint_array { T elements[N]; }; -void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol) { +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + +void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol_3) { uint idx = 0u; idx = local_invocation_index; while (true) { @@ -25,39 +33,42 @@ void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol_2) { - uint const x_57 = *(tint_symbol_1); - compute_main_inner(x_57, tint_symbol_2); +void compute_main_1(thread uint* const tint_symbol_4, threadgroup tint_array, 2>, 3>* const tint_symbol_5) { + uint const x_57 = *(tint_symbol_4); + compute_main_inner(x_57, tint_symbol_5); return; } -void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) { +void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array, 2>, 3>* const tint_symbol_6, thread uint* const tint_symbol_7) { for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) { uint const i = (idx_1 / 2u); uint const i_1 = (idx_1 % 2u); uint const i_2 = (idx_1 % 1u); - atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed); + atomic_store_explicit(&((*(tint_symbol_6))[i][i_1][i_2]), 0u, memory_order_relaxed); } threadgroup_barrier(mem_flags::mem_threadgroup); - *(tint_symbol_4) = local_invocation_index_1_param; - compute_main_1(tint_symbol_4, tint_symbol_3); + *(tint_symbol_7) = local_invocation_index_1_param; + compute_main_1(tint_symbol_7, tint_symbol_6); } kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) { - threadgroup tint_array, 2>, 3> tint_symbol_5; - thread uint tint_symbol_6 = 0u; - compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6)); + threadgroup tint_array, 2>, 3> tint_symbol_8; + thread uint tint_symbol_9 = 0u; + compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_8), &(tint_symbol_9)); return; } diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm index 8091c97689..fb00bc8230 100644 --- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm +++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 90 +; Bound: 105 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,6 +10,12 @@ OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1" OpName %local_invocation_index_1 "local_invocation_index_1" OpName %wg "wg" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" + OpName %tint_mod "tint_mod" + OpName %lhs_0 "lhs" + OpName %rhs_0 "rhs" OpName %compute_main_inner "compute_main_inner" OpName %local_invocation_index "local_invocation_index" OpName %idx "idx" @@ -36,105 +42,124 @@ %_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3 %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3 %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup + %15 = OpTypeFunction %uint %uint %uint + %bool = OpTypeBool %void = OpTypeVoid - %15 = OpTypeFunction %void %uint + %31 = OpTypeFunction %void %uint %_ptr_Function_uint = OpTypePointer Function %uint %uint_6 = OpConstant %uint 6 - %bool = OpTypeBool %uint_0 = OpConstant %uint 0 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint %uint_264 = OpConstant %uint 264 %int = OpTypeInt 32 1 %int_2 = OpConstant %int 2 %int_1 = OpConstant %int 1 - %53 = OpConstantNull %int - %55 = OpTypeFunction %void -%compute_main_inner = OpFunction %void None %15 -%local_invocation_index = OpFunctionParameter %uint + %68 = OpConstantNull %int + %70 = OpTypeFunction %void + %tint_div = OpFunction %uint None %15 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint %19 = OpLabel + %21 = OpIEqual %bool %rhs %6 + %20 = OpSelect %uint %21 %uint_1 %rhs + %23 = OpUDiv %uint %lhs %20 + OpReturnValue %23 + OpFunctionEnd + %tint_mod = OpFunction %uint None %15 + %lhs_0 = OpFunctionParameter %uint + %rhs_0 = OpFunctionParameter %uint + %27 = OpLabel + %29 = OpIEqual %bool %rhs_0 %6 + %28 = OpSelect %uint %29 %uint_1 %rhs_0 + %30 = OpUMod %uint %lhs_0 %28 + OpReturnValue %30 + OpFunctionEnd +%compute_main_inner = OpFunction %void None %31 +%local_invocation_index = OpFunctionParameter %uint + %35 = OpLabel %idx = OpVariable %_ptr_Function_uint Function %6 OpStore %idx %6 OpStore %idx %local_invocation_index - OpBranch %22 - %22 = OpLabel - OpLoopMerge %23 %24 None - OpBranch %25 - %25 = OpLabel - %26 = OpLoad %uint %idx - %29 = OpULessThan %bool %26 %uint_6 - %27 = OpLogicalNot %bool %29 - OpSelectionMerge %31 None - OpBranchConditional %27 %32 %31 - %32 = OpLabel - OpBranch %23 - %31 = OpLabel - %33 = OpLoad %uint %idx - %34 = OpLoad %uint %idx - %35 = OpLoad %uint %idx - %39 = OpUDiv %uint %33 %uint_2 - %40 = OpUMod %uint %34 %uint_2 - %41 = OpUMod %uint %35 %uint_1 - %43 = OpAccessChain %_ptr_Workgroup_uint %wg %39 %40 %41 - OpAtomicStore %43 %uint_2 %uint_0 %6 - OpBranch %24 - %24 = OpLabel - %44 = OpLoad %uint %idx - %45 = OpIAdd %uint %44 %uint_1 - OpStore %idx %45 - OpBranch %22 - %23 = OpLabel + OpBranch %38 + %38 = OpLabel + OpLoopMerge %39 %40 None + OpBranch %41 + %41 = OpLabel + %42 = OpLoad %uint %idx + %45 = OpULessThan %bool %42 %uint_6 + %43 = OpLogicalNot %bool %45 + OpSelectionMerge %46 None + OpBranchConditional %43 %47 %46 + %47 = OpLabel + OpBranch %39 + %46 = OpLabel + %48 = OpLoad %uint %idx + %49 = OpLoad %uint %idx + %50 = OpLoad %uint %idx + %51 = OpFunctionCall %uint %tint_div %48 %uint_2 + %52 = OpFunctionCall %uint %tint_mod %49 %uint_2 + %53 = OpFunctionCall %uint %tint_mod %50 %uint_1 + %58 = OpAccessChain %_ptr_Workgroup_uint %wg %51 %52 %53 + OpAtomicStore %58 %uint_2 %uint_0 %6 + OpBranch %40 + %40 = OpLabel + %59 = OpLoad %uint %idx + %60 = OpIAdd %uint %59 %uint_1 + OpStore %idx %60 + OpBranch %38 + %39 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - %54 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %53 - OpAtomicStore %54 %uint_2 %uint_0 %uint_1 + %69 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %68 + OpAtomicStore %69 %uint_2 %uint_0 %uint_1 OpReturn OpFunctionEnd -%compute_main_1 = OpFunction %void None %55 - %57 = OpLabel - %58 = OpLoad %uint %local_invocation_index_1 - %59 = OpFunctionCall %void %compute_main_inner %58 +%compute_main_1 = OpFunction %void None %70 + %72 = OpLabel + %73 = OpLoad %uint %local_invocation_index_1 + %74 = OpFunctionCall %void %compute_main_inner %73 OpReturn OpFunctionEnd -%compute_main_inner_1 = OpFunction %void None %15 +%compute_main_inner_1 = OpFunction %void None %31 %local_invocation_index_1_param = OpFunctionParameter %uint - %62 = OpLabel + %77 = OpLabel %idx_1 = OpVariable %_ptr_Function_uint Function %6 OpStore %idx_1 %local_invocation_index_1_param - OpBranch %64 - %64 = OpLabel - OpLoopMerge %65 %66 None - OpBranch %67 - %67 = OpLabel - %69 = OpLoad %uint %idx_1 - %70 = OpULessThan %bool %69 %uint_6 - %68 = OpLogicalNot %bool %70 - OpSelectionMerge %71 None - OpBranchConditional %68 %72 %71 - %72 = OpLabel - OpBranch %65 - %71 = OpLabel - %73 = OpLoad %uint %idx_1 - %74 = OpUDiv %uint %73 %uint_2 - %75 = OpLoad %uint %idx_1 - %76 = OpUMod %uint %75 %uint_2 - %77 = OpLoad %uint %idx_1 - %78 = OpUMod %uint %77 %uint_1 - %81 = OpAccessChain %_ptr_Workgroup_uint %wg %74 %76 %78 - OpAtomicStore %81 %uint_2 %uint_0 %6 - OpBranch %66 - %66 = OpLabel - %82 = OpLoad %uint %idx_1 - %83 = OpIAdd %uint %82 %uint_1 - OpStore %idx_1 %83 - OpBranch %64 - %65 = OpLabel + OpBranch %79 + %79 = OpLabel + OpLoopMerge %80 %81 None + OpBranch %82 + %82 = OpLabel + %84 = OpLoad %uint %idx_1 + %85 = OpULessThan %bool %84 %uint_6 + %83 = OpLogicalNot %bool %85 + OpSelectionMerge %86 None + OpBranchConditional %83 %87 %86 + %87 = OpLabel + OpBranch %80 + %86 = OpLabel + %88 = OpLoad %uint %idx_1 + %89 = OpUDiv %uint %88 %uint_2 + %90 = OpLoad %uint %idx_1 + %91 = OpUMod %uint %90 %uint_2 + %92 = OpLoad %uint %idx_1 + %93 = OpUMod %uint %92 %uint_1 + %96 = OpAccessChain %_ptr_Workgroup_uint %wg %89 %91 %93 + OpAtomicStore %96 %uint_2 %uint_0 %6 + OpBranch %81 + %81 = OpLabel + %97 = OpLoad %uint %idx_1 + %98 = OpIAdd %uint %97 %uint_1 + OpStore %idx_1 %98 + OpBranch %79 + %80 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 OpStore %local_invocation_index_1 %local_invocation_index_1_param - %85 = OpFunctionCall %void %compute_main_1 + %100 = OpFunctionCall %void %compute_main_1 OpReturn OpFunctionEnd -%compute_main = OpFunction %void None %55 - %87 = OpLabel - %89 = OpLoad %uint %local_invocation_index_1_param_1 - %88 = OpFunctionCall %void %compute_main_inner_1 %89 +%compute_main = OpFunction %void None %70 + %102 = OpLabel + %104 = OpLoad %uint %local_invocation_index_1_param_1 + %103 = OpFunctionCall %void %compute_main_inner_1 %104 OpReturn OpFunctionEnd diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl index a24f87a3f6..b3bbd36e50 100644 --- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl +++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl @@ -1,3 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + static uint local_invocation_index_1 = 0u; groupshared uint wg[3][2][1]; @@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) { const uint x_31 = idx; const uint x_33 = idx; const uint x_35 = idx; + const uint tint_symbol_2 = tint_div(x_31, 2u); + const uint tint_symbol_3 = tint_mod(x_33, 2u); + const uint tint_symbol_4 = tint_mod(x_35, 1u); uint atomic_result = 0u; - InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); + InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result); { const uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl index a24f87a3f6..b3bbd36e50 100644 --- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl +++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl @@ -1,3 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + static uint local_invocation_index_1 = 0u; groupshared uint wg[3][2][1]; @@ -12,8 +20,11 @@ void compute_main_inner(uint local_invocation_index) { const uint x_31 = idx; const uint x_33 = idx; const uint x_35 = idx; + const uint tint_symbol_2 = tint_div(x_31, 2u); + const uint tint_symbol_3 = tint_mod(x_33, 2u); + const uint tint_symbol_4 = tint_mod(x_35, 1u); uint atomic_result = 0u; - InterlockedExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u, atomic_result); + InterlockedExchange(wg[tint_symbol_2][tint_symbol_3][tint_symbol_4], 0u, atomic_result); { const uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl index f73d1c9a70..d21534a2b5 100644 --- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl +++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl @@ -1,5 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + uint local_invocation_index_1 = 0u; shared uint wg[3][2][1]; void compute_main_inner(uint local_invocation_index) { @@ -13,7 +21,10 @@ void compute_main_inner(uint local_invocation_index) { uint x_31 = idx; uint x_33 = idx; uint x_35 = idx; - atomicExchange(wg[(x_31 / 2u)][(x_33 % 2u)][(x_35 % 1u)], 0u); + uint tint_symbol = tint_div(x_31, 2u); + uint tint_symbol_1 = tint_mod(x_33, 2u); + uint tint_symbol_2 = tint_mod(x_35, 1u); + atomicExchange(wg[tint_symbol][tint_symbol_1][tint_symbol_2], 0u); { uint x_42 = idx; idx = (x_42 + 1u); diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl index 943a64cf5c..f1220afa5b 100644 --- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl +++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl @@ -14,7 +14,15 @@ struct tint_array { T elements[N]; }; -void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol) { +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + +void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol_3) { uint idx = 0u; idx = local_invocation_index; while (true) { @@ -25,39 +33,42 @@ void compute_main_inner(uint local_invocation_index, threadgroup tint_array, 2>, 3>* const tint_symbol_2) { - uint const x_57 = *(tint_symbol_1); - compute_main_inner(x_57, tint_symbol_2); +void compute_main_1(thread uint* const tint_symbol_4, threadgroup tint_array, 2>, 3>* const tint_symbol_5) { + uint const x_57 = *(tint_symbol_4); + compute_main_inner(x_57, tint_symbol_5); return; } -void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array, 2>, 3>* const tint_symbol_3, thread uint* const tint_symbol_4) { +void compute_main_inner_1(uint local_invocation_index_1_param, threadgroup tint_array, 2>, 3>* const tint_symbol_6, thread uint* const tint_symbol_7) { for(uint idx_1 = local_invocation_index_1_param; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) { uint const i = (idx_1 / 2u); uint const i_1 = (idx_1 % 2u); uint const i_2 = (idx_1 % 1u); - atomic_store_explicit(&((*(tint_symbol_3))[i][i_1][i_2]), 0u, memory_order_relaxed); + atomic_store_explicit(&((*(tint_symbol_6))[i][i_1][i_2]), 0u, memory_order_relaxed); } threadgroup_barrier(mem_flags::mem_threadgroup); - *(tint_symbol_4) = local_invocation_index_1_param; - compute_main_1(tint_symbol_4, tint_symbol_3); + *(tint_symbol_7) = local_invocation_index_1_param; + compute_main_1(tint_symbol_7, tint_symbol_6); } kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]]) { - threadgroup tint_array, 2>, 3> tint_symbol_5; - thread uint tint_symbol_6 = 0u; - compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_5), &(tint_symbol_6)); + threadgroup tint_array, 2>, 3> tint_symbol_8; + thread uint tint_symbol_9 = 0u; + compute_main_inner_1(local_invocation_index_1_param, &(tint_symbol_8), &(tint_symbol_9)); return; } diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm index 8091c97689..fb00bc8230 100644 --- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm +++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 90 +; Bound: 105 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,6 +10,12 @@ OpName %local_invocation_index_1_param_1 "local_invocation_index_1_param_1" OpName %local_invocation_index_1 "local_invocation_index_1" OpName %wg "wg" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" + OpName %tint_mod "tint_mod" + OpName %lhs_0 "lhs" + OpName %rhs_0 "rhs" OpName %compute_main_inner "compute_main_inner" OpName %local_invocation_index "local_invocation_index" OpName %idx "idx" @@ -36,105 +42,124 @@ %_arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypeArray %_arr__arr_uint_uint_1_uint_2 %uint_3 %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 = OpTypePointer Workgroup %_arr__arr__arr_uint_uint_1_uint_2_uint_3 %wg = OpVariable %_ptr_Workgroup__arr__arr__arr_uint_uint_1_uint_2_uint_3 Workgroup + %15 = OpTypeFunction %uint %uint %uint + %bool = OpTypeBool %void = OpTypeVoid - %15 = OpTypeFunction %void %uint + %31 = OpTypeFunction %void %uint %_ptr_Function_uint = OpTypePointer Function %uint %uint_6 = OpConstant %uint 6 - %bool = OpTypeBool %uint_0 = OpConstant %uint 0 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint %uint_264 = OpConstant %uint 264 %int = OpTypeInt 32 1 %int_2 = OpConstant %int 2 %int_1 = OpConstant %int 1 - %53 = OpConstantNull %int - %55 = OpTypeFunction %void -%compute_main_inner = OpFunction %void None %15 -%local_invocation_index = OpFunctionParameter %uint + %68 = OpConstantNull %int + %70 = OpTypeFunction %void + %tint_div = OpFunction %uint None %15 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint %19 = OpLabel + %21 = OpIEqual %bool %rhs %6 + %20 = OpSelect %uint %21 %uint_1 %rhs + %23 = OpUDiv %uint %lhs %20 + OpReturnValue %23 + OpFunctionEnd + %tint_mod = OpFunction %uint None %15 + %lhs_0 = OpFunctionParameter %uint + %rhs_0 = OpFunctionParameter %uint + %27 = OpLabel + %29 = OpIEqual %bool %rhs_0 %6 + %28 = OpSelect %uint %29 %uint_1 %rhs_0 + %30 = OpUMod %uint %lhs_0 %28 + OpReturnValue %30 + OpFunctionEnd +%compute_main_inner = OpFunction %void None %31 +%local_invocation_index = OpFunctionParameter %uint + %35 = OpLabel %idx = OpVariable %_ptr_Function_uint Function %6 OpStore %idx %6 OpStore %idx %local_invocation_index - OpBranch %22 - %22 = OpLabel - OpLoopMerge %23 %24 None - OpBranch %25 - %25 = OpLabel - %26 = OpLoad %uint %idx - %29 = OpULessThan %bool %26 %uint_6 - %27 = OpLogicalNot %bool %29 - OpSelectionMerge %31 None - OpBranchConditional %27 %32 %31 - %32 = OpLabel - OpBranch %23 - %31 = OpLabel - %33 = OpLoad %uint %idx - %34 = OpLoad %uint %idx - %35 = OpLoad %uint %idx - %39 = OpUDiv %uint %33 %uint_2 - %40 = OpUMod %uint %34 %uint_2 - %41 = OpUMod %uint %35 %uint_1 - %43 = OpAccessChain %_ptr_Workgroup_uint %wg %39 %40 %41 - OpAtomicStore %43 %uint_2 %uint_0 %6 - OpBranch %24 - %24 = OpLabel - %44 = OpLoad %uint %idx - %45 = OpIAdd %uint %44 %uint_1 - OpStore %idx %45 - OpBranch %22 - %23 = OpLabel + OpBranch %38 + %38 = OpLabel + OpLoopMerge %39 %40 None + OpBranch %41 + %41 = OpLabel + %42 = OpLoad %uint %idx + %45 = OpULessThan %bool %42 %uint_6 + %43 = OpLogicalNot %bool %45 + OpSelectionMerge %46 None + OpBranchConditional %43 %47 %46 + %47 = OpLabel + OpBranch %39 + %46 = OpLabel + %48 = OpLoad %uint %idx + %49 = OpLoad %uint %idx + %50 = OpLoad %uint %idx + %51 = OpFunctionCall %uint %tint_div %48 %uint_2 + %52 = OpFunctionCall %uint %tint_mod %49 %uint_2 + %53 = OpFunctionCall %uint %tint_mod %50 %uint_1 + %58 = OpAccessChain %_ptr_Workgroup_uint %wg %51 %52 %53 + OpAtomicStore %58 %uint_2 %uint_0 %6 + OpBranch %40 + %40 = OpLabel + %59 = OpLoad %uint %idx + %60 = OpIAdd %uint %59 %uint_1 + OpStore %idx %60 + OpBranch %38 + %39 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 - %54 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %53 - OpAtomicStore %54 %uint_2 %uint_0 %uint_1 + %69 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %68 + OpAtomicStore %69 %uint_2 %uint_0 %uint_1 OpReturn OpFunctionEnd -%compute_main_1 = OpFunction %void None %55 - %57 = OpLabel - %58 = OpLoad %uint %local_invocation_index_1 - %59 = OpFunctionCall %void %compute_main_inner %58 +%compute_main_1 = OpFunction %void None %70 + %72 = OpLabel + %73 = OpLoad %uint %local_invocation_index_1 + %74 = OpFunctionCall %void %compute_main_inner %73 OpReturn OpFunctionEnd -%compute_main_inner_1 = OpFunction %void None %15 +%compute_main_inner_1 = OpFunction %void None %31 %local_invocation_index_1_param = OpFunctionParameter %uint - %62 = OpLabel + %77 = OpLabel %idx_1 = OpVariable %_ptr_Function_uint Function %6 OpStore %idx_1 %local_invocation_index_1_param - OpBranch %64 - %64 = OpLabel - OpLoopMerge %65 %66 None - OpBranch %67 - %67 = OpLabel - %69 = OpLoad %uint %idx_1 - %70 = OpULessThan %bool %69 %uint_6 - %68 = OpLogicalNot %bool %70 - OpSelectionMerge %71 None - OpBranchConditional %68 %72 %71 - %72 = OpLabel - OpBranch %65 - %71 = OpLabel - %73 = OpLoad %uint %idx_1 - %74 = OpUDiv %uint %73 %uint_2 - %75 = OpLoad %uint %idx_1 - %76 = OpUMod %uint %75 %uint_2 - %77 = OpLoad %uint %idx_1 - %78 = OpUMod %uint %77 %uint_1 - %81 = OpAccessChain %_ptr_Workgroup_uint %wg %74 %76 %78 - OpAtomicStore %81 %uint_2 %uint_0 %6 - OpBranch %66 - %66 = OpLabel - %82 = OpLoad %uint %idx_1 - %83 = OpIAdd %uint %82 %uint_1 - OpStore %idx_1 %83 - OpBranch %64 - %65 = OpLabel + OpBranch %79 + %79 = OpLabel + OpLoopMerge %80 %81 None + OpBranch %82 + %82 = OpLabel + %84 = OpLoad %uint %idx_1 + %85 = OpULessThan %bool %84 %uint_6 + %83 = OpLogicalNot %bool %85 + OpSelectionMerge %86 None + OpBranchConditional %83 %87 %86 + %87 = OpLabel + OpBranch %80 + %86 = OpLabel + %88 = OpLoad %uint %idx_1 + %89 = OpUDiv %uint %88 %uint_2 + %90 = OpLoad %uint %idx_1 + %91 = OpUMod %uint %90 %uint_2 + %92 = OpLoad %uint %idx_1 + %93 = OpUMod %uint %92 %uint_1 + %96 = OpAccessChain %_ptr_Workgroup_uint %wg %89 %91 %93 + OpAtomicStore %96 %uint_2 %uint_0 %6 + OpBranch %81 + %81 = OpLabel + %97 = OpLoad %uint %idx_1 + %98 = OpIAdd %uint %97 %uint_1 + OpStore %idx_1 %98 + OpBranch %79 + %80 = OpLabel OpControlBarrier %uint_2 %uint_2 %uint_264 OpStore %local_invocation_index_1 %local_invocation_index_1_param - %85 = OpFunctionCall %void %compute_main_1 + %100 = OpFunctionCall %void %compute_main_1 OpReturn OpFunctionEnd -%compute_main = OpFunction %void None %55 - %87 = OpLabel - %89 = OpLoad %uint %local_invocation_index_1_param_1 - %88 = OpFunctionCall %void %compute_main_inner_1 %89 +%compute_main = OpFunction %void None %70 + %102 = OpLabel + %104 = OpLoad %uint %local_invocation_index_1_param_1 + %103 = OpFunctionCall %void %compute_main_inner_1 %104 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.dxc.hlsl index 14717d643d..9a4fe9bbe1 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 2; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.fxc.hlsl index 14717d643d..9a4fe9bbe1 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 2; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.glsl index 3af5945962..db43bc2b0c 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void f() { int a = 1; int b = 2; - int r = (a / b); + int r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.msl index 17d17098e5..8be210c24f 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int const a = 1; int const b = 2; - int const r = (a / b); + int const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.spvasm index b5a41dcaea..86e459e21a 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,20 +1,41 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 25 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %int_2 = OpConstant %int 2 - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpSDiv %int %int_1 %int_2 + %tint_div = 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 = OpSDiv %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %24 = OpFunctionCall %int %tint_div %int_1 %int_2 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.dxc.hlsl index 668387a951..3aabfa6134 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 2u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.fxc.hlsl index 668387a951..3aabfa6134 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 2u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.glsl index 5780a271f3..e3a69186d0 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 2u; - uint r = (a / b); + uint r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.msl index fa9d9e76e7..679758c782 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint const a = 1u; uint const b = 2u; - uint const r = (a / b); + uint const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.spvasm index 012fb2b4b1..ba6afb4aab 100644 --- a/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,20 +1,35 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 19 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpUDiv %uint %uint_1 %uint_2 + %tint_div = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUDiv %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %18 = OpFunctionCall %uint %tint_div %uint_1 %uint_2 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.dxc.hlsl index c41e7ef6d6..21ccbde337 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(1, 2, 3); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.fxc.hlsl index c41e7ef6d6..21ccbde337 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(1, 2, 3); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.glsl index 94f8b1f06d..324ae7bb62 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(1, 2, 3); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.msl index 41242231ca..0dd80df723 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int const a = 4; int3 const b = int3(1, 2, 3); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.spvasm index c52ce21e29..8bf91039f0 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 - %int_4 = OpConstant %int 4 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void + %int_4 = OpConstant %int 4 %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %11 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %12 = OpSDiv %v3int %16 %11 + %32 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %tint_div = 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 = OpSDiv %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_div %int_4 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.dxc.hlsl index ac675e22d1..fc09d79508 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(1u, 2u, 3u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.fxc.hlsl index ac675e22d1..fc09d79508 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(1u, 2u, 3u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.glsl index ff9ebbea41..39dc7a7544 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(1u, 2u, 3u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.msl index aa59c35cfc..6228ec26c2 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint const a = 4u; uint3 const b = uint3(1u, 2u, 3u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.spvasm index 3bf5436f14..29ec8aba8d 100644 --- a/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void + %uint_4 = OpConstant %uint 4 %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %11 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %12 = OpUDiv %v3uint %16 %11 + %24 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUDiv %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_div %uint_4 %24 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 8278e3bcbf..9c7f38619b 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 4; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 8278e3bcbf..9c7f38619b 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 4; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.glsl index a690f5fab9..1451a224c5 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 4; - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.msl index 73678c8c36..30eaa91c67 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int const b = 4; - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.spvasm index be6616aa35..7307e915cc 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %12 = OpSDiv %v3int %10 %16 + %tint_div = 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 = OpSDiv %v3int %lhs %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_div %31 %int_4 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.dxc.hlsl index 7c2f9245d8..16a364b458 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 4u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.fxc.hlsl index 7c2f9245d8..16a364b458 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 4u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.glsl index abcbfa7b12..a64873331b 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs / mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 4u; - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.msl index 749829bbc0..c34665b428 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs / select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint const b = 4u; - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.spvasm index 9a52fdc8fd..b3e4924a52 100644 --- a/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %uint_4 = OpConstant %uint 4 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %12 = OpUDiv %v3uint %10 %16 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUDiv %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_div %23 %uint_4 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.dxc.hlsl index 98c4e64f45..fe730554c3 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(4, 5, 6); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.fxc.hlsl index 98c4e64f45..fe730554c3 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(4, 5, 6); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.glsl index 6d611687f1..db941fa4bc 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(4, 5, 6); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.msl index bb0f942bf9..a2d1a2c98f 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int3 const b = int3(4, 5, 6); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.spvasm index f0115f72a5..ab422bc5c2 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,27 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 36 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 %int_5 = OpConstant %int 5 %int_6 = OpConstant %int 6 - %14 = OpConstantComposite %v3int %int_4 %int_5 %int_6 - %f = OpFunction %void None %1 - %4 = OpLabel - %15 = OpSDiv %v3int %10 %14 + %34 = OpConstantComposite %v3int %int_4 %int_5 %int_6 + %tint_div = 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 = OpSDiv %v3int %lhs %8 + OpReturnValue %23 + OpFunctionEnd + %f = OpFunction %void None %24 + %27 = OpLabel + %35 = OpFunctionCall %v3int %tint_div %30 %34 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.dxc.hlsl index 2f2a501ee5..7e4d88c46c 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(4u, 5u, 6u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.fxc.hlsl index 2f2a501ee5..7e4d88c46c 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(4u, 5u, 6u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.glsl index 75013bc189..8320c3fe11 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uvec3 rhs) { + return (lhs / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(4u, 5u, 6u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.msl index bfddf5a686..a79a7ab1e9 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint3 const b = uint3(4u, 5u, 6u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.spvasm index 116085e20f..acb2bbfe54 100644 --- a/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,27 +1,44 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 28 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %uint_4 = OpConstant %uint 4 %uint_5 = OpConstant %uint 5 %uint_6 = OpConstant %uint 6 - %14 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6 - %f = OpFunction %void None %1 - %4 = OpLabel - %15 = OpUDiv %v3uint %10 %14 + %26 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUDiv %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %27 = OpFunctionCall %v3uint %tint_div %22 %26 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl index 1969e5f231..57589da0eb 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl index 1969e5f231..57589da0eb 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl index 8ec81fdb95..5cdd98871e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void f() { int a = 1; int b = 0; - int r = (a / b); + int r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl index 0923684eb6..092d9a9e96 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int const a = 1; int const b = 0; - int const r = (a / b); + int const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm index fa188bd8fe..162cf507bb 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,20 +1,40 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 24 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 - %7 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpSDiv %int %int_1 %7 + %void = OpTypeVoid + %19 = OpTypeFunction %void + %tint_div = 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 = OpSDiv %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %23 = OpFunctionCall %int %tint_div %int_1 %8 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl index ce15f243fd..92efb5019e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 0u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl index ce15f243fd..92efb5019e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 0u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl index aee0413c79..30a1f0ca1f 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a / b); + uint r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl index 2c1b78a3b3..5247453310 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint const a = 1u; uint const b = 0u; - uint const r = (a / b); + uint const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm index 57df98086c..af0914e16a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,20 +1,34 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 18 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 - %7 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpUDiv %uint %uint_1 %7 + %void = OpTypeVoid + %13 = OpTypeFunction %void + %tint_div = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUDiv %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %17 = OpFunctionCall %uint %tint_div %uint_1 %8 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl index 99ed924ffe..69aec329b8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(0, 2, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl index 99ed924ffe..69aec329b8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(0, 2, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl index 2fdf8fe69b..a33eaa70bf 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl index 89df256097..bf13240f01 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int const a = 4; int3 const b = int3(0, 2, 0); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm index 7cfcbadf7f..8b76fe040d 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,27 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 - %int_4 = OpConstant %int 4 %v3int = OpTypeVector %int 3 - %8 = OpConstantNull %int + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void + %int_4 = OpConstant %int 4 + %30 = OpConstantNull %int %int_2 = OpConstant %int 2 - %10 = OpConstantComposite %v3int %8 %int_2 %8 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %14 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %12 = OpVariable %_ptr_Function_v3int Function %14 - %15 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %11 = OpSDiv %v3int %15 %10 + %32 = OpConstantComposite %v3int %30 %int_2 %30 + %tint_div = 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 = OpSDiv %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_div %int_4 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl index 1ebcc7f0ca..e4319c1e89 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl index 1ebcc7f0ca..e4319c1e89 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl index 6d14d8f6c3..50ab5b37dd 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl index eb1c975c99..248755dca4 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint const a = 4u; uint3 const b = uint3(0u, 2u, 0u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm index 81b44169de..b0ce71b2f4 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,27 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 %v3uint = OpTypeVector %uint 3 - %8 = OpConstantNull %uint + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void + %uint_4 = OpConstant %uint 4 + %22 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %10 = OpConstantComposite %v3uint %8 %uint_2 %8 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %14 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %12 = OpVariable %_ptr_Function_v3uint Function %14 - %15 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %11 = OpUDiv %v3uint %15 %10 + %24 = OpConstantComposite %v3uint %22 %uint_2 %22 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUDiv %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_div %uint_4 %24 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 7029295b9d..e24fb822a6 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 0; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 7029295b9d..e24fb822a6 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 0; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl index 0c7f6a9c23..28ba692625 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl index c187dd2cf6..82f039bd37 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int const b = 0; - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm index af40beba9b..c78b7c405a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %11 = OpConstantNull %int -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %11 %11 %11 - %12 = OpSDiv %v3int %10 %16 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %32 = OpConstantNull %int + %tint_div = 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 = OpSDiv %v3int %lhs %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_div %31 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl index bfe9e027cc..267d104dfa 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 0u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl index bfe9e027cc..267d104dfa 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 0u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl index 05bca8adc6..926d784dc7 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs / mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl index 2d342e7ecb..716c969b67 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs / select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint const b = 0u; - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm index 2a83009118..618d427ba8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 - %11 = OpConstantNull %uint -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %11 %11 %11 - %12 = OpUDiv %v3uint %10 %16 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %24 = OpConstantNull %uint + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUDiv %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_div %23 %24 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl index 30d26ca22f..f6889c125e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(0, 5, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl index 30d26ca22f..f6889c125e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(0, 5, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl index 6e11b344e4..2ea6128504 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl index 7cf268154e..97271f2207 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int3 const b = int3(0, 5, 0); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm index e986304d30..4ba4fc87dc 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,26 +1,51 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 15 +; Bound: 35 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %11 = OpConstantNull %int + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantNull %int %int_5 = OpConstant %int 5 - %13 = OpConstantComposite %v3int %11 %int_5 %11 - %f = OpFunction %void None %1 - %4 = OpLabel - %14 = OpSDiv %v3int %10 %13 + %33 = OpConstantComposite %v3int %31 %int_5 %31 + %tint_div = 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 = OpSDiv %v3int %lhs %8 + OpReturnValue %23 + OpFunctionEnd + %f = OpFunction %void None %24 + %27 = OpLabel + %34 = OpFunctionCall %v3int %tint_div %30 %33 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl index c337dc39a8..46dca5aa8b 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl index c337dc39a8..46dca5aa8b 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl index 657cdb4b69..000bf89fc4 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uvec3 rhs) { + return (lhs / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl index 66ee158e1b..dac86ae742 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint3 const b = uint3(0u, 5u, 0u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm index 2536318538..45bde36959 100644 --- a/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,26 +1,43 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 15 +; Bound: 27 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 - %11 = OpConstantNull %uint + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %13 = OpConstantComposite %v3uint %11 %uint_5 %11 - %f = OpFunction %void None %1 - %4 = OpLabel - %14 = OpUDiv %v3uint %10 %13 + %25 = OpConstantComposite %v3uint %23 %uint_5 %23 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUDiv %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %26 = OpFunctionCall %v3uint %tint_div %22 %25 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl index 6ed443002a..e6a148824e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a / value_or_one_if_zero_int((b + b))); + const int r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl index 6ed443002a..e6a148824e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a / value_or_one_if_zero_int((b + b))); + const int r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl index b3aef3b7db..9109801818 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void f() { int a = 1; int b = 0; - int r = (a / (b + b)); + int r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl index c319da3281..e0cf597f6c 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int a = 1; int b = 0; - int const r = (a / as_type((as_type(b) + as_type(b)))); + int const r = tint_div(a, as_type((as_type(b) + as_type(b)))); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm index 2cad16a763..5891caa4c8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,31 +1,51 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 31 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_int Function %9 + %tint_div = 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 = OpSDiv %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %a = OpVariable %_ptr_Function_int Function %8 + %b = OpVariable %_ptr_Function_int Function %8 OpStore %a %int_1 - OpStore %b %9 - %11 = OpLoad %int %a - %12 = OpLoad %int %b - %13 = OpLoad %int %b - %14 = OpIAdd %int %12 %13 - %15 = OpSDiv %int %11 %14 + OpStore %b %8 + %27 = OpLoad %int %a + %28 = OpLoad %int %b + %29 = OpLoad %int %b + %30 = OpIAdd %int %28 %29 + %26 = OpFunctionCall %int %tint_div %27 %30 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl index ec658be559..e7b89f21a8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a / value_or_one_if_zero_uint((b + b))); + const uint r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl index ec658be559..e7b89f21a8 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a / value_or_one_if_zero_uint((b + b))); + const uint r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl index b15631c956..cf9e7399a0 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a / (b + b)); + uint r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl index ad2302ff51..64d213b188 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint a = 1u; uint b = 0u; - uint const r = (a / (b + b)); + uint const r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm index f245f406fb..9fbd92f974 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,31 +1,45 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 25 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_uint Function %9 + %tint_div = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUDiv %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %8 + %b = OpVariable %_ptr_Function_uint Function %8 OpStore %a %uint_1 - OpStore %b %9 - %11 = OpLoad %uint %a - %12 = OpLoad %uint %b - %13 = OpLoad %uint %b - %14 = OpIAdd %uint %12 %13 - %15 = OpUDiv %uint %11 %14 + OpStore %b %8 + %21 = OpLoad %uint %a + %22 = OpLoad %uint %b + %23 = OpLoad %uint %b + %24 = OpIAdd %uint %22 %23 + %20 = OpFunctionCall %uint %tint_div %21 %24 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl index f23bda330e..52f716ffab 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a / value_or_one_if_zero_int3((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl index f23bda330e..52f716ffab 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a / value_or_one_if_zero_int3((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl index d2f146a6d5..0a46644c4a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a / (b + b)); + ivec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl index 72cb90c2b1..b414a14e4d 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int a = 4; int3 b = int3(0, 2, 0); - int3 const r = (a / as_type((as_type(b) + as_type(b)))); + int3 const r = tint_div(a, as_type((as_type(b) + as_type(b)))); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm index ac46dbb214..ef478ddc27 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,38 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %v3int = OpTypeVector %int 3 + %32 = OpConstantNull %int %int_2 = OpConstant %int 2 - %12 = OpConstantComposite %v3int %9 %int_2 %9 + %34 = OpConstantComposite %v3int %32 %int_2 %32 %_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %15 - %21 = OpVariable %_ptr_Function_v3int Function %15 + %tint_div = 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 = OpSDiv %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %a = OpVariable %_ptr_Function_int Function %32 + %b = OpVariable %_ptr_Function_v3int Function %10 OpStore %a %int_4 - OpStore %b %12 - %16 = OpLoad %int %a - %17 = OpLoad %v3int %b - %18 = OpLoad %v3int %b - %19 = OpIAdd %v3int %17 %18 - %22 = OpCompositeConstruct %v3int %16 %16 %16 - %20 = OpSDiv %v3int %22 %19 + OpStore %b %34 + %38 = OpLoad %int %a + %39 = OpLoad %v3int %b + %40 = OpLoad %v3int %b + %41 = OpIAdd %v3int %39 %40 + %37 = OpFunctionCall %v3int %tint_div %38 %41 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl index ec3621c697..9ad34b2785 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl index ec3621c697..9ad34b2785 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl index 67af12eb01..187744bce9 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a / (b + b)); + uvec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl index f742cd5e21..8722f2a06a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - uint3 const r = (a / (b + b)); + uint3 const r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm index d4fb717401..7eba1c625c 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,38 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_4 = OpConstant %uint 4 %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %v3uint = OpTypeVector %uint 3 + %24 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %12 = OpConstantComposite %v3uint %9 %uint_2 %9 + %26 = OpConstantComposite %v3uint %24 %uint_2 %24 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_v3uint Function %15 - %21 = OpVariable %_ptr_Function_v3uint Function %15 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUDiv %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %24 + %b = OpVariable %_ptr_Function_v3uint Function %10 OpStore %a %uint_4 - OpStore %b %12 - %16 = OpLoad %uint %a - %17 = OpLoad %v3uint %b - %18 = OpLoad %v3uint %b - %19 = OpIAdd %v3uint %17 %18 - %22 = OpCompositeConstruct %v3uint %16 %16 %16 - %20 = OpUDiv %v3uint %22 %19 + OpStore %b %26 + %30 = OpLoad %uint %a + %31 = OpLoad %v3uint %b + %32 = OpLoad %v3uint %b + %33 = OpIAdd %v3uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_div %30 %33 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 964d2751f3..6bdd31eecc 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a / value_or_one_if_zero_int((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 964d2751f3..6bdd31eecc 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a / value_or_one_if_zero_int((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl index 1ee33f9ad2..4221f2a899 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a / (b + b)); + ivec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl index b2a2e6a942..79b0f7963a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int b = 0; - int3 const r = (a / as_type((as_type(b) + as_type(b)))); + int3 const r = tint_div(a, as_type((as_type(b) + as_type(b)))); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm index 565dd46094..a07a5ea966 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,39 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 24 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %34 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_int Function %14 - %22 = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3int %a - %18 = OpLoad %int %b - %19 = OpLoad %int %b - %20 = OpIAdd %int %18 %19 - %23 = OpCompositeConstruct %v3int %20 %20 %20 - %21 = OpSDiv %v3int %17 %23 + %tint_div = 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 = OpSDiv %v3int %lhs %9 + OpReturnValue %24 + 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_div %38 %41 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl index f4bd21bd64..9ef2147fb0 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a / value_or_one_if_zero_uint((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl index f4bd21bd64..9ef2147fb0 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a / value_or_one_if_zero_uint((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl index e592a96046..4f7e3f3a81 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs / mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a / (b + b)); + uvec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl index 05e7e6e6f9..b2df05ce8d 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs / select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - uint3 const r = (a / (b + b)); + uint3 const r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm index 726b715e18..3fe925bf26 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,39 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 24 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %26 = OpConstantNull %uint %_ptr_Function_uint = OpTypePointer Function %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_uint Function %14 - %22 = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3uint %a - %18 = OpLoad %uint %b - %19 = OpLoad %uint %b - %20 = OpIAdd %uint %18 %19 - %23 = OpCompositeConstruct %v3uint %20 %20 %20 - %21 = OpUDiv %v3uint %17 %23 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUDiv %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %10 + %b = OpVariable %_ptr_Function_uint Function %26 + OpStore %a %23 + OpStore %b %26 + %30 = OpLoad %v3uint %a + %31 = OpLoad %uint %b + %32 = OpLoad %uint %b + %33 = OpIAdd %uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_div %30 %33 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl index fefc614241..dd810eaae6 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a / value_or_one_if_zero_int3((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl index fefc614241..dd810eaae6 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a / value_or_one_if_zero_int3((b + b))); + const int3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl index a4756fbf79..36f0cc23a1 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a / (b + b)); + ivec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl index e2a2a76026..8c124b5a4e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - int3 const r = (a / as_type((as_type(b) + as_type(b)))); + int3 const r = tint_div(a, as_type((as_type(b) + as_type(b)))); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm index 03b642c93e..75ecf79559 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,38 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %33 = OpConstantNull %int %int_5 = OpConstant %int 5 - %16 = OpConstantComposite %v3int %14 %int_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3int %a - %19 = OpLoad %v3int %b - %20 = OpLoad %v3int %b - %21 = OpIAdd %v3int %19 %20 - %22 = OpSDiv %v3int %18 %21 + %35 = OpConstantComposite %v3int %33 %int_5 %33 + %tint_div = 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 = OpSDiv %v3int %lhs %8 + OpReturnValue %23 + 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_div %38 %41 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl index 841bf62a9f..d8a010e47a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl index 841bf62a9f..d8a010e47a 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl index 567059c031..22846e65bd 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uvec3 rhs) { + return (lhs / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a / (b + b)); + uvec3 r = tint_div(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl index e055047d10..781eb5540b 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - uint3 const r = (a / (b + b)); + uint3 const r = tint_div(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm index 9cde60af40..56eee5f59c 100644 --- a/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,38 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %25 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %16 = OpConstantComposite %v3uint %14 %uint_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3uint %a - %19 = OpLoad %v3uint %b - %20 = OpLoad %v3uint %b - %21 = OpIAdd %v3uint %19 %20 - %22 = OpUDiv %v3uint %18 %21 + %27 = OpConstantComposite %v3uint %25 %uint_5 %25 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUDiv %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %9 + %b = OpVariable %_ptr_Function_v3uint Function %9 + OpStore %a %22 + OpStore %b %27 + %30 = OpLoad %v3uint %a + %31 = OpLoad %v3uint %b + %32 = OpLoad %v3uint %b + %33 = OpIAdd %v3uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_div %30 %33 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl index 111cfc9df4..dcf5a24f5e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl index 111cfc9df4..dcf5a24f5e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a / (b == 0 ? 1 : b)); + const int r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl index 8ec81fdb95..5cdd98871e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void f() { int a = 1; int b = 0; - int r = (a / b); + int r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl index a3201dc502..4968408c4f 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int a = 1; int b = 0; - int const r = (a / b); + int const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm index 96e1544311..dbb1acfba1 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/i32.wgsl.expected.spvasm @@ -1,29 +1,49 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 14 +; Bound: 29 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_int Function %9 + %tint_div = 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 = OpSDiv %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %a = OpVariable %_ptr_Function_int Function %8 + %b = OpVariable %_ptr_Function_int Function %8 OpStore %a %int_1 - OpStore %b %9 - %11 = OpLoad %int %a - %12 = OpLoad %int %b - %13 = OpSDiv %int %11 %12 + OpStore %b %8 + %27 = OpLoad %int %a + %28 = OpLoad %int %b + %26 = OpFunctionCall %int %tint_div %27 %28 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl index 289c446b63..ffaaaba7d0 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl index 289c446b63..ffaaaba7d0 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a / (b == 0u ? 1u : b)); + const uint r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl index aee0413c79..30a1f0ca1f 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_div(uint lhs, uint rhs) { + return (lhs / ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a / b); + uint r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl index bf7517d8e7..7c6233acf9 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_div(uint lhs, uint rhs) { + return (lhs / select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint a = 1u; uint b = 0u; - uint const r = (a / b); + uint const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm index ce40e45760..6ce20d2b80 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,29 +1,43 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 14 +; Bound: 23 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_uint Function %9 + %tint_div = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUDiv %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %8 + %b = OpVariable %_ptr_Function_uint Function %8 OpStore %a %uint_1 - OpStore %b %9 - %11 = OpLoad %uint %a - %12 = OpLoad %uint %b - %13 = OpUDiv %uint %11 %12 + OpStore %b %8 + %21 = OpLoad %uint %a + %22 = OpLoad %uint %b + %20 = OpFunctionCall %uint %tint_div %21 %22 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl index 24f0e8fde9..afaf8fa9cd 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl index 24f0e8fde9..afaf8fa9cd 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int lhs, int3 rhs) { + const int3 l = int3((lhs).xxx); + return (l / (((rhs == (0).xxx) | ((l == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl index 2fdf8fe69b..a33eaa70bf 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl index 03ac311e55..f65bafbe70 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int a = 4; int3 b = int3(0, 2, 0); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm index 34cd2cfe46..95c85837f1 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/i32.wgsl.expected.spvasm @@ -1,36 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %v3int = OpTypeVector %int 3 + %32 = OpConstantNull %int %int_2 = OpConstant %int 2 - %12 = OpConstantComposite %v3int %9 %int_2 %9 + %34 = OpConstantComposite %v3int %32 %int_2 %32 %_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %15 - %19 = OpVariable %_ptr_Function_v3int Function %15 + %tint_div = 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 = OpSDiv %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %a = OpVariable %_ptr_Function_int Function %32 + %b = OpVariable %_ptr_Function_v3int Function %10 OpStore %a %int_4 - OpStore %b %12 - %16 = OpLoad %int %a - %17 = OpLoad %v3int %b - %20 = OpCompositeConstruct %v3int %16 %16 %16 - %18 = OpSDiv %v3int %20 %17 + OpStore %b %34 + %38 = OpLoad %int %a + %39 = OpLoad %v3int %b + %37 = OpFunctionCall %v3int %tint_div %38 %39 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl index 0692d218e0..930f7421c3 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl index 0692d218e0..930f7421c3 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl index 6d14d8f6c3..50ab5b37dd 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl index b7bf1d7ae5..c318ec4d96 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm index 9f6d5d567b..5d6ee99aea 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,36 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_4 = OpConstant %uint 4 %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %v3uint = OpTypeVector %uint 3 + %24 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %12 = OpConstantComposite %v3uint %9 %uint_2 %9 + %26 = OpConstantComposite %v3uint %24 %uint_2 %24 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_v3uint Function %15 - %19 = OpVariable %_ptr_Function_v3uint Function %15 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUDiv %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %24 + %b = OpVariable %_ptr_Function_v3uint Function %10 OpStore %a %uint_4 - OpStore %b %12 - %16 = OpLoad %uint %a - %17 = OpLoad %v3uint %b - %20 = OpCompositeConstruct %v3uint %16 %16 %16 - %18 = OpUDiv %v3uint %20 %17 + OpStore %b %26 + %30 = OpLoad %uint %a + %31 = OpLoad %v3uint %b + %29 = OpFunctionCall %v3uint %tint_div %30 %31 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl index 4f87f70de4..5418cb1765 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl index 4f87f70de4..5418cb1765 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +int3 tint_div(int3 lhs, int rhs) { + const int3 r = int3((rhs).xxx); + return (lhs / (((r == (0).xxx) | ((lhs == (-2147483648).xxx) & (r == (-1).xxx))) ? (1).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a / (b == 0 ? 1 : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl index 0c7f6a9c23..28ba692625 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl index 8e25431d47..2282152416 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +int3 tint_div(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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int b = 0; - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm index 88da03782c..3a2d07da93 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/i32.wgsl.expected.spvasm @@ -1,37 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 22 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %34 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_int Function %14 - %20 = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3int %a - %18 = OpLoad %int %b - %21 = OpCompositeConstruct %v3int %18 %18 %18 - %19 = OpSDiv %v3int %17 %21 + %tint_div = 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 = OpSDiv %v3int %lhs %9 + OpReturnValue %24 + 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_div %38 %39 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl index 012cb29b31..6be2d0ad8f 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl index 012cb29b31..6be2d0ad8f 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_div(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs / ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a / (b == 0u ? 1u : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl index 05bca8adc6..926d784dc7 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs / mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl index 126ec2a62c..3c1918125d 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs / select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm index 759be2a7bc..fcff67039e 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,37 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 22 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %26 = OpConstantNull %uint %_ptr_Function_uint = OpTypePointer Function %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_uint Function %14 - %20 = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3uint %a - %18 = OpLoad %uint %b - %21 = OpCompositeConstruct %v3uint %18 %18 %18 - %19 = OpUDiv %v3uint %17 %21 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUDiv %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %10 + %b = OpVariable %_ptr_Function_uint Function %26 + OpStore %a %23 + OpStore %b %26 + %30 = OpLoad %v3uint %a + %31 = OpLoad %uint %b + %29 = OpFunctionCall %v3uint %tint_div %30 %31 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl index 3e1ba7ffa9..c7a531b354 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl index 3e1ba7ffa9..c7a531b354 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a / (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl index 6e11b344e4..2ea6128504 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +ivec3 tint_div(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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a / b); + ivec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl index 298e7fa990..82eed13673 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +int3 tint_div(int3 lhs, int3 rhs) { + return (lhs / select(rhs, int3(1), ((rhs == int3(0)) | ((lhs == int3((-2147483647 - 1))) & (rhs == int3(-1)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - int3 const r = (a / b); + int3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm index 575bfe6acc..cd02515282 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/i32.wgsl.expected.spvasm @@ -1,36 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %33 = OpConstantNull %int %int_5 = OpConstant %int 5 - %16 = OpConstantComposite %v3int %14 %int_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3int %a - %19 = OpLoad %v3int %b - %20 = OpSDiv %v3int %18 %19 + %35 = OpConstantComposite %v3int %33 %int_5 %33 + %tint_div = 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 = OpSDiv %v3int %lhs %8 + OpReturnValue %23 + 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_div %38 %39 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl index 5f022e4092..ccdc79c98b 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl index 5f022e4092..ccdc79c98b 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a / (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl index 657cdb4b69..000bf89fc4 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_div(uvec3 lhs, uvec3 rhs) { + return (lhs / mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a / b); + uvec3 r = tint_div(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl index d300954dd7..b6c99930a6 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_div(uint3 lhs, uint3 rhs) { + return (lhs / select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - uint3 const r = (a / b); + uint3 const r = tint_div(a, b); return; } diff --git a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm index 033612735b..8d1b38fd6c 100644 --- a/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/div_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,36 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %25 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %16 = OpConstantComposite %v3uint %14 %uint_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3uint %a - %19 = OpLoad %v3uint %b - %20 = OpUDiv %v3uint %18 %19 + %27 = OpConstantComposite %v3uint %25 %uint_5 %25 + %tint_div = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUDiv %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %9 + %b = OpVariable %_ptr_Function_v3uint Function %9 + OpStore %a %22 + OpStore %b %27 + %30 = OpLoad %v3uint %a + %31 = OpLoad %v3uint %b + %29 = OpFunctionCall %v3uint %tint_div %30 %31 OpReturn OpFunctionEnd 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 e5e75d33b2..84546915fc 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 2; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 e5e75d33b2..84546915fc 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 2; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 8c128158a4..70e79ddd0f 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,9 +1,13 @@ #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)); +} + void f() { int a = 1; int b = 2; - int r = (a % b); + int r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 a67d6fed75..15c78158c1 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 @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int const a = 1; int const b = 2; - int const r = (a % b); + int const r = tint_mod(a, b); return; } 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 3e9f94433c..f68a5e6401 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,20 +1,41 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 25 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %int_2 = OpConstant %int 2 - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpSMod %int %int_1 %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 = OpSMod %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %24 = OpFunctionCall %int %tint_mod %int_1 %int_2 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.dxc.hlsl index ea912bd6b7..b2cc513610 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 2u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.fxc.hlsl index ea912bd6b7..b2cc513610 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 2u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.glsl index 485ed72260..920fd38114 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 2u; - uint r = (a % b); + uint r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.msl index 5d4b949e72..89b2a107c7 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint const a = 1u; uint const b = 2u; - uint const r = (a % b); + uint const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.spvasm index 57f2d3832b..13e89ae30d 100644 --- a/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,20 +1,35 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 19 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpUMod %uint %uint_1 %uint_2 + %tint_mod = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUMod %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %18 = OpFunctionCall %uint %tint_mod %uint_1 %uint_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 847b0fbbe2..6fc93b7e92 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(1, 2, 3); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 847b0fbbe2..6fc93b7e92 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(1, 2, 3); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 016701693f..f9117fb4b3 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(1, 2, 3); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 533d47785e..9b89ade458 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int const a = 4; int3 const b = int3(1, 2, 3); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 6dd950cd8d..2621d821f8 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,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 - %int_4 = OpConstant %int 4 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void + %int_4 = OpConstant %int 4 %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %11 = OpConstantComposite %v3int %int_1 %int_2 %int_3 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %12 = OpSMod %v3int %16 %11 + %32 = 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 = OpSMod %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_mod %int_4 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.dxc.hlsl index 396d57a875..2cbda43bdb 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(1u, 2u, 3u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.fxc.hlsl index 396d57a875..2cbda43bdb 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(1u, 2u, 3u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.glsl index f150a9277c..f8540889b5 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(1u, 2u, 3u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.msl index a5e85ceaac..930bfff226 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint const a = 4u; uint3 const b = uint3(1u, 2u, 3u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.spvasm index 99afb7629e..97bf152285 100644 --- a/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void + %uint_4 = OpConstant %uint 4 %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %11 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %12 = OpUMod %v3uint %16 %11 + %24 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUMod %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_mod %uint_4 %24 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 469e7c0136..3e147af81d 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 4; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 469e7c0136..3e147af81d 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 4; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 3ae9594413..5564275d6c 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 4; - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 8df9cbeada..9a30326165 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int const b = 4; - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 70a8d1e444..3be0691ce3 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,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %12 = OpSMod %v3int %10 %16 + %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 = OpSMod %v3int %lhs %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_mod %31 %int_4 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.dxc.hlsl index 6a481d4c4f..b5477115ea 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 4u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.fxc.hlsl index 6a481d4c4f..b5477115ea 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 4u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.glsl index 40204d3e69..f7513275d1 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs % mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 4u; - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.msl index 3adb345851..ad715a869d 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs % select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint const b = 4u; - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.spvasm index 3fdde36c66..01d662c690 100644 --- a/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %uint_4 = OpConstant %uint 4 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %12 = OpUMod %v3uint %10 %16 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUMod %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_mod %23 %uint_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 86d89a53e5..c12408d50b 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(4, 5, 6); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 86d89a53e5..c12408d50b 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(4, 5, 6); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 56d7104b65..36bb83c9dc 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,9 +1,13 @@ #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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(4, 5, 6); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 2bd4b5f005..770ab3f534 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 @@ -1,10 +1,14 @@ #include 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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int3 const b = int3(4, 5, 6); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 af8e4543a8..36e0abbc96 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,27 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 36 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %int_4 = OpConstant %int 4 %int_5 = OpConstant %int 5 %int_6 = OpConstant %int 6 - %14 = OpConstantComposite %v3int %int_4 %int_5 %int_6 - %f = OpFunction %void None %1 - %4 = OpLabel - %15 = OpSMod %v3int %10 %14 + %34 = 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 = OpSMod %v3int %lhs %8 + OpReturnValue %23 + OpFunctionEnd + %f = OpFunction %void None %24 + %27 = OpLabel + %35 = OpFunctionCall %v3int %tint_mod %30 %34 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.dxc.hlsl index 5d234b8432..d543c858ce 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(4u, 5u, 6u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.fxc.hlsl index 5d234b8432..d543c858ce 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(4u, 5u, 6u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.glsl index bd85a3e397..78f38034c1 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uvec3 rhs) { + return (lhs % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(4u, 5u, 6u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.msl index 954924cc5c..66fe1c5d5d 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint3 const b = uint3(4u, 5u, 6u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.spvasm index 6f69999900..bfc25a558f 100644 --- a/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,27 +1,44 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 28 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %uint_4 = OpConstant %uint 4 %uint_5 = OpConstant %uint 5 %uint_6 = OpConstant %uint 6 - %14 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6 - %f = OpFunction %void None %1 - %4 = OpLabel - %15 = OpUMod %v3uint %10 %14 + %26 = OpConstantComposite %v3uint %uint_4 %uint_5 %uint_6 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUMod %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %27 = OpFunctionCall %v3uint %tint_mod %22 %26 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 7511c9699f..a5f5597b34 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 7511c9699f..a5f5597b34 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int a = 1; const int b = 0; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 1f7158fec4..ddb6a6b810 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,9 +1,13 @@ #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)); +} + void f() { int a = 1; int b = 0; - int r = (a % b); + int r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 98f1698b74..8d879ce523 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 @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int const a = 1; int const b = 0; - int const r = (a % b); + int const r = tint_mod(a, b); return; } 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 bf9393fa49..a384178bb4 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,20 +1,40 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 24 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 - %7 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpSMod %int %int_1 %7 + %void = OpTypeVoid + %19 = 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 = OpSMod %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %23 = OpFunctionCall %int %tint_mod %int_1 %8 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl index 16b133d069..cf35054cd7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 0u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl index 16b133d069..cf35054cd7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 1u; const uint b = 0u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl index d30fde881d..9fd11d77cb 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a % b); + uint r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl index 456e3b9caa..5ab74b7d87 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint const a = 1u; uint const b = 0u; - uint const r = (a % b); + uint const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm index 94d22635b1..f429d8410f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,20 +1,34 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 9 +; Bound: 18 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 - %7 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %8 = OpUMod %uint %uint_1 %7 + %void = OpTypeVoid + %13 = OpTypeFunction %void + %tint_mod = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUMod %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %17 = OpFunctionCall %uint %tint_mod %uint_1 %8 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 dfe722c849..f199262055 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(0, 2, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 dfe722c849..f199262055 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int a = 4; const int3 b = int3(0, 2, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 e19dc4632d..412aedf276 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 95a93f72b8..49b1bee619 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int const a = 4; int3 const b = int3(0, 2, 0); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 65d27ce133..860c94d43d 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,27 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 - %int_4 = OpConstant %int 4 %v3int = OpTypeVector %int 3 - %8 = OpConstantNull %int + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void + %int_4 = OpConstant %int 4 + %30 = OpConstantNull %int %int_2 = OpConstant %int 2 - %10 = OpConstantComposite %v3int %8 %int_2 %8 -%_ptr_Function_v3int = OpTypePointer Function %v3int - %14 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %12 = OpVariable %_ptr_Function_v3int Function %14 - %15 = OpCompositeConstruct %v3int %int_4 %int_4 %int_4 - %11 = OpSMod %v3int %15 %10 + %32 = OpConstantComposite %v3int %30 %int_2 %30 + %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 = OpSMod %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_mod %int_4 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl index 5583772270..1866409218 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl index 5583772270..1866409218 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint a = 4u; const uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl index 633b9edba9..534cab7017 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl index 16fa02517d..1b3131f8bc 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint const a = 4u; uint3 const b = uint3(0u, 2u, 0u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm index 03b04093aa..f5f89258c7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,27 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 %v3uint = OpTypeVector %uint 3 - %8 = OpConstantNull %uint + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void + %uint_4 = OpConstant %uint 4 + %22 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %10 = OpConstantComposite %v3uint %8 %uint_2 %8 -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %14 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %12 = OpVariable %_ptr_Function_v3uint Function %14 - %15 = OpCompositeConstruct %v3uint %uint_4 %uint_4 %uint_4 - %11 = OpUMod %v3uint %15 %10 + %24 = OpConstantComposite %v3uint %22 %uint_2 %22 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUMod %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_mod %uint_4 %24 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 63e5792c70..418539b3c3 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 0; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 63e5792c70..418539b3c3 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int b = 0; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 d74047afa9..788c7fee9c 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 cbac4c79f6..a3b8e521d1 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int const b = 0; - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 64592c9d9b..bef3e02954 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,28 +1,50 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %11 = OpConstantNull %int -%_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3int Function %15 - %16 = OpCompositeConstruct %v3int %11 %11 %11 - %12 = OpSMod %v3int %10 %16 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %32 = 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 = OpSMod %v3int %lhs %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %33 = OpFunctionCall %v3int %tint_mod %31 %32 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl index 4da3d28a70..3274f2828d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 0u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl index 4da3d28a70..3274f2828d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint b = 0u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl index d84b14b180..03f7867de4 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs % mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl index 78398ec53e..ff6d8d19d7 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs % select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint const b = 0u; - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm index 79e64e8ae9..e60c38ba12 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,28 +1,42 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 - %11 = OpConstantNull %uint -%_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %13 = OpVariable %_ptr_Function_v3uint Function %15 - %16 = OpCompositeConstruct %v3uint %11 %11 %11 - %12 = OpUMod %v3uint %10 %16 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %24 = OpConstantNull %uint + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUMod %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %25 = OpFunctionCall %v3uint %tint_mod %23 %24 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 ce3cfcaaaa..f5613073b2 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(0, 5, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 ce3cfcaaaa..f5613073b2 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const int3 a = int3(1, 2, 3); const int3 b = int3(0, 5, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 809b454345..e1da39494e 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,9 +1,13 @@ #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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 7619c9c3eb..cc6b827ef4 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 @@ -1,10 +1,14 @@ #include 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)))))); +} + kernel void f() { int3 const a = int3(1, 2, 3); int3 const b = int3(0, 5, 0); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 64e929a48d..d7f2971b93 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,26 +1,51 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 15 +; Bound: 35 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 - %11 = OpConstantNull %int + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantNull %int %int_5 = OpConstant %int 5 - %13 = OpConstantComposite %v3int %11 %int_5 %11 - %f = OpFunction %void None %1 - %4 = OpLabel - %14 = OpSMod %v3int %10 %13 + %33 = OpConstantComposite %v3int %31 %int_5 %31 + %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 = OpSMod %v3int %lhs %8 + OpReturnValue %23 + OpFunctionEnd + %f = OpFunction %void None %24 + %27 = OpLabel + %34 = OpFunctionCall %v3int %tint_mod %30 %33 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl index ef3ed4541b..31e3caaaf5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl index ef3ed4541b..31e3caaaf5 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { const uint3 a = uint3(1u, 2u, 3u); const uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl index af4c44fdcf..e6cd33b337 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uvec3 rhs) { + return (lhs % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl index 028424af19..dc39ae4c95 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 const a = uint3(1u, 2u, 3u); uint3 const b = uint3(0u, 5u, 0u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm index 1dd5605b1a..8084654d7a 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_constant/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,26 +1,43 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 15 +; Bound: 27 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 - %11 = OpConstantNull %uint + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %13 = OpConstantComposite %v3uint %11 %uint_5 %11 - %f = OpFunction %void None %1 - %4 = OpLabel - %14 = OpUMod %v3uint %10 %13 + %25 = OpConstantComposite %v3uint %23 %uint_5 %23 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUMod %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %26 = OpFunctionCall %v3uint %tint_mod %22 %25 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 fd4f932ff7..ee8f7775f0 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,11 +1,11 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a % value_or_one_if_zero_int((b + b))); + const int r = tint_mod(a, (b + b)); return; } 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 fd4f932ff7..ee8f7775f0 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,11 +1,11 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); } [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a % value_or_one_if_zero_int((b + b))); + const int r = tint_mod(a, (b + b)); return; } 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 e5b14013f7..7edd1670aa 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,9 +1,13 @@ #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)); +} + void f() { int a = 1; int b = 0; - int r = (a % (b + b)); + int r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 ead2dcea05..8bd7973ff8 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 @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int a = 1; int b = 0; - int const r = (a % as_type((as_type(b) + as_type(b)))); + int const r = tint_mod(a, as_type((as_type(b) + as_type(b)))); return; } 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 fac854f6d1..6fb330ed42 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,31 +1,51 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 31 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_int Function %9 + %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 = OpSMod %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %a = OpVariable %_ptr_Function_int Function %8 + %b = OpVariable %_ptr_Function_int Function %8 OpStore %a %int_1 - OpStore %b %9 - %11 = OpLoad %int %a - %12 = OpLoad %int %b - %13 = OpLoad %int %b - %14 = OpIAdd %int %12 %13 - %15 = OpSMod %int %11 %14 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl index f8f7511f41..2373dcf99f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a % value_or_one_if_zero_uint((b + b))); + const uint r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl index f8f7511f41..2373dcf99f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a % value_or_one_if_zero_uint((b + b))); + const uint r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl index 7b7c6b3c0f..23248d3d74 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a % (b + b)); + uint r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl index 33bf9ab1b4..96b1555cb8 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint a = 1u; uint b = 0u; - uint const r = (a % (b + b)); + uint const r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm index ca8d7a50ef..db8c7df1c8 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,31 +1,45 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 16 +; Bound: 25 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_uint Function %9 + %tint_mod = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUMod %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %8 + %b = OpVariable %_ptr_Function_uint Function %8 OpStore %a %uint_1 - OpStore %b %9 - %11 = OpLoad %uint %a - %12 = OpLoad %uint %b - %13 = OpLoad %uint %b - %14 = OpIAdd %uint %12 %13 - %15 = OpUMod %uint %11 %14 + OpStore %b %8 + %21 = OpLoad %uint %a + %22 = OpLoad %uint %b + %23 = OpLoad %uint %b + %24 = OpIAdd %uint %22 %23 + %20 = OpFunctionCall %uint %tint_mod %21 %24 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 8e8a7d0533..7186ef9aa6 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,11 +1,12 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +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)); } [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a % value_or_one_if_zero_int3((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 8e8a7d0533..7186ef9aa6 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,11 +1,12 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +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)); } [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a % value_or_one_if_zero_int3((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 d633601cf0..e2aa4af88a 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a % (b + b)); + ivec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 12f1a72cc2..2a01a507c1 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int a = 4; int3 b = int3(0, 2, 0); - int3 const r = (a % as_type((as_type(b) + as_type(b)))); + int3 const r = tint_mod(a, as_type((as_type(b) + as_type(b)))); return; } 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 a4acd729a8..07eb4e7e6e 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,38 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %v3int = OpTypeVector %int 3 + %32 = OpConstantNull %int %int_2 = OpConstant %int 2 - %12 = OpConstantComposite %v3int %9 %int_2 %9 + %34 = OpConstantComposite %v3int %32 %int_2 %32 %_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %15 - %21 = OpVariable %_ptr_Function_v3int Function %15 + %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 = OpSMod %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %a = OpVariable %_ptr_Function_int Function %32 + %b = OpVariable %_ptr_Function_v3int Function %10 OpStore %a %int_4 - OpStore %b %12 - %16 = OpLoad %int %a - %17 = OpLoad %v3int %b - %18 = OpLoad %v3int %b - %19 = OpIAdd %v3int %17 %18 - %22 = OpCompositeConstruct %v3int %16 %16 %16 - %20 = OpSMod %v3int %22 %19 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl index 2330363261..046ce3a89c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl index 2330363261..046ce3a89c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl index aa981b7570..47e9d7e393 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a % (b + b)); + uvec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl index a7511f2241..6b16b4aa7d 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - uint3 const r = (a % (b + b)); + uint3 const r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm index 296cc5c0a8..23a8288b3c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,38 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_4 = OpConstant %uint 4 %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %v3uint = OpTypeVector %uint 3 + %24 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %12 = OpConstantComposite %v3uint %9 %uint_2 %9 + %26 = OpConstantComposite %v3uint %24 %uint_2 %24 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_v3uint Function %15 - %21 = OpVariable %_ptr_Function_v3uint Function %15 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUMod %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %24 + %b = OpVariable %_ptr_Function_v3uint Function %10 OpStore %a %uint_4 - OpStore %b %12 - %16 = OpLoad %uint %a - %17 = OpLoad %v3uint %b - %18 = OpLoad %v3uint %b - %19 = OpIAdd %v3uint %17 %18 - %22 = OpCompositeConstruct %v3uint %16 %16 %16 - %20 = OpUMod %v3uint %22 %19 + OpStore %b %26 + %30 = OpLoad %uint %a + %31 = OpLoad %v3uint %b + %32 = OpLoad %v3uint %b + %33 = OpIAdd %v3uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_mod %30 %33 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 ea6b4cbb42..8eebf875fa 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,11 +1,12 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +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)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a % value_or_one_if_zero_int((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 ea6b4cbb42..8eebf875fa 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,11 +1,12 @@ -int value_or_one_if_zero_int(int value) { - return value == 0 ? 1 : value; +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)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a % value_or_one_if_zero_int((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 5b6590ccfe..8d0fbcc9d7 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a % (b + b)); + ivec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 ba6626b194..ccd2c1e384 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int b = 0; - int3 const r = (a % as_type((as_type(b) + as_type(b)))); + int3 const r = tint_mod(a, as_type((as_type(b) + as_type(b)))); return; } 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 1b579c4a1e..6fc00bde55 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,39 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 24 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %34 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_int Function %14 - %22 = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3int %a - %18 = OpLoad %int %b - %19 = OpLoad %int %b - %20 = OpIAdd %int %18 %19 - %23 = OpCompositeConstruct %v3int %20 %20 %20 - %21 = OpSMod %v3int %17 %23 + %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 = OpSMod %v3int %lhs %9 + OpReturnValue %24 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl index dca1662c8d..b3a498d2d2 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,12 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a % value_or_one_if_zero_uint((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl index dca1662c8d..b3a498d2d2 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,12 @@ -uint value_or_one_if_zero_uint(uint value) { - return value == 0u ? 1u : value; +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a % value_or_one_if_zero_uint((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl index f388f008e2..82a5991ee3 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs % mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a % (b + b)); + uvec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl index 96dba81ec4..95cf58069c 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs % select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - uint3 const r = (a % (b + b)); + uint3 const r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm index 4676fea349..20a784d5d6 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,39 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 24 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %26 = OpConstantNull %uint %_ptr_Function_uint = OpTypePointer Function %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_uint Function %14 - %22 = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3uint %a - %18 = OpLoad %uint %b - %19 = OpLoad %uint %b - %20 = OpIAdd %uint %18 %19 - %23 = OpCompositeConstruct %v3uint %20 %20 %20 - %21 = OpUMod %v3uint %17 %23 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUMod %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %10 + %b = OpVariable %_ptr_Function_uint Function %26 + OpStore %a %23 + OpStore %b %26 + %30 = OpLoad %v3uint %a + %31 = OpLoad %uint %b + %32 = OpLoad %uint %b + %33 = OpIAdd %uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_mod %30 %33 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 f33a43d8ef..6b63195902 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,11 +1,11 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a % value_or_one_if_zero_int3((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 f33a43d8ef..6b63195902 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,11 +1,11 @@ -int3 value_or_one_if_zero_int3(int3 value) { - return value == int3(0, 0, 0) ? int3(1, 1, 1) : value; +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a % value_or_one_if_zero_int3((b + b))); + const int3 r = tint_mod(a, (b + b)); return; } 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 f97a7fae2c..fab324117c 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,9 +1,13 @@ #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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a % (b + b)); + ivec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 61356dc074..46862681b3 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 @@ -1,10 +1,14 @@ #include 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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - int3 const r = (a % as_type((as_type(b) + as_type(b)))); + int3 const r = tint_mod(a, as_type((as_type(b) + as_type(b)))); return; } 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 0a116e033e..352b6fdde8 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,38 +1,62 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 42 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %33 = OpConstantNull %int %int_5 = OpConstant %int 5 - %16 = OpConstantComposite %v3int %14 %int_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3int %a - %19 = OpLoad %v3int %b - %20 = OpLoad %v3int %b - %21 = OpIAdd %v3int %19 %20 - %22 = OpSMod %v3int %18 %21 + %35 = OpConstantComposite %v3int %33 %int_5 %33 + %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 = OpSMod %v3int %lhs %8 + OpReturnValue %23 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl index f112cf8458..1cb142e68f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,11 +1,11 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl index f112cf8458..1cb142e68f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,11 +1,11 @@ -uint3 value_or_one_if_zero_uint3(uint3 value) { - return value == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : value; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); } [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % value_or_one_if_zero_uint3((b + b))); + const uint3 r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl index a2f09b16d5..2f2985a34f 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uvec3 rhs) { + return (lhs % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a % (b + b)); + uvec3 r = tint_mod(a, (b + b)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl index c6d0db5670..d40182b252 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - uint3 const r = (a % (b + b)); + uint3 const r = tint_mod(a, (b + b)); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm index 92c17181c7..55eb5ab0da 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_expression/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,38 +1,54 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 23 +; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %25 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %16 = OpConstantComposite %v3uint %14 %uint_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3uint %a - %19 = OpLoad %v3uint %b - %20 = OpLoad %v3uint %b - %21 = OpIAdd %v3uint %19 %20 - %22 = OpUMod %v3uint %18 %21 + %27 = OpConstantComposite %v3uint %25 %uint_5 %25 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUMod %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %9 + %b = OpVariable %_ptr_Function_v3uint Function %9 + OpStore %a %22 + OpStore %b %27 + %30 = OpLoad %v3uint %a + %31 = OpLoad %v3uint %b + %32 = OpLoad %v3uint %b + %33 = OpIAdd %v3uint %31 %32 + %29 = OpFunctionCall %v3uint %tint_mod %30 %33 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 9f27720ec7..dcafd63729 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 9f27720ec7..dcafd63729 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,7 +1,11 @@ +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + [numthreads(1, 1, 1)] void f() { int a = 1; int b = 0; - const int r = (a % (b == 0 ? 1 : b)); + const int r = tint_mod(a, b); return; } 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 1f7158fec4..ddb6a6b810 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,9 +1,13 @@ #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)); +} + void f() { int a = 1; int b = 0; - int r = (a % b); + int r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 4a51c544cc..56de74d16b 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 @@ -1,10 +1,14 @@ #include using namespace metal; +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + kernel void f() { int a = 1; int b = 0; - int const r = (a % b); + int const r = tint_mod(a, b); return; } 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 68aabf4ccb..9519959ff8 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,29 +1,49 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 14 +; Bound: 29 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %1 = OpTypeFunction %int %int %int + %8 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 %int_1 = OpConstant %int 1 + %void = OpTypeVoid + %19 = OpTypeFunction %void %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_int Function %9 + %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 = OpSMod %int %lhs %7 + OpReturnValue %18 + OpFunctionEnd + %f = OpFunction %void None %19 + %22 = OpLabel + %a = OpVariable %_ptr_Function_int Function %8 + %b = OpVariable %_ptr_Function_int Function %8 OpStore %a %int_1 - OpStore %b %9 - %11 = OpLoad %int %a - %12 = OpLoad %int %b - %13 = OpSMod %int %11 %12 + OpStore %b %8 + %27 = OpLoad %int %a + %28 = OpLoad %int %b + %26 = OpFunctionCall %int %tint_mod %27 %28 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl index cc3d3c11d4..d2cfc632be 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl index cc3d3c11d4..d2cfc632be 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 1u; uint b = 0u; - const uint r = (a % (b == 0u ? 1u : b)); + const uint r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl index d30fde881d..9fd11d77cb 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uint tint_mod(uint lhs, uint rhs) { + return (lhs % ((rhs == 0u) ? 1u : rhs)); +} + void f() { uint a = 1u; uint b = 0u; - uint r = (a % b); + uint r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl index 8849d0d91f..98aa1081a3 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint tint_mod(uint lhs, uint rhs) { + return (lhs % select(rhs, 1u, (rhs == 0u))); +} + kernel void f() { uint a = 1u; uint b = 0u; - uint const r = (a % b); + uint const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm index 62435a14ba..c5ec4da885 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-scalar/u32.wgsl.expected.spvasm @@ -1,29 +1,43 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 14 +; Bound: 23 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %1 = OpTypeFunction %uint %uint %uint + %8 = OpConstantNull %uint + %bool = OpTypeBool %uint_1 = OpConstant %uint 1 + %void = OpTypeVoid + %13 = OpTypeFunction %void %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_uint Function %9 + %tint_mod = OpFunction %uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %uint + %6 = OpLabel + %9 = OpIEqual %bool %rhs %8 + %7 = OpSelect %uint %9 %uint_1 %rhs + %12 = OpUMod %uint %lhs %7 + OpReturnValue %12 + OpFunctionEnd + %f = OpFunction %void None %13 + %16 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %8 + %b = OpVariable %_ptr_Function_uint Function %8 OpStore %a %uint_1 - OpStore %b %9 - %11 = OpLoad %uint %a - %12 = OpLoad %uint %b - %13 = OpUMod %uint %11 %12 + OpStore %b %8 + %21 = OpLoad %uint %a + %22 = OpLoad %uint %b + %20 = OpFunctionCall %uint %tint_mod %21 %22 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 0b14c77017..4c97839e39 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 0b14c77017..4c97839e39 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { int a = 4; int3 b = int3(0, 2, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 e19dc4632d..412aedf276 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { int a = 4; ivec3 b = ivec3(0, 2, 0); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 ae32a8616b..143e92e409 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int a = 4; int3 b = int3(0, 2, 0); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 4ceb097d01..43fb6053d3 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,36 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %int %v3int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 + %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_4 = OpConstant %int 4 %_ptr_Function_int = OpTypePointer Function %int - %9 = OpConstantNull %int - %v3int = OpTypeVector %int 3 + %32 = OpConstantNull %int %int_2 = OpConstant %int 2 - %12 = OpConstantComposite %v3int %9 %int_2 %9 + %34 = OpConstantComposite %v3int %32 %int_2 %32 %_ptr_Function_v3int = OpTypePointer Function %v3int - %15 = OpConstantNull %v3int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_int Function %9 - %b = OpVariable %_ptr_Function_v3int Function %15 - %19 = OpVariable %_ptr_Function_v3int Function %15 + %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 = OpSMod %v3int %8 %9 + OpReturnValue %24 + OpFunctionEnd + %f = OpFunction %void None %25 + %28 = OpLabel + %a = OpVariable %_ptr_Function_int Function %32 + %b = OpVariable %_ptr_Function_v3int Function %10 OpStore %a %int_4 - OpStore %b %12 - %16 = OpLoad %int %a - %17 = OpLoad %v3int %b - %20 = OpCompositeConstruct %v3int %16 %16 %16 - %18 = OpSMod %v3int %20 %17 + OpStore %b %34 + %38 = OpLoad %int %a + %39 = OpLoad %v3int %b + %37 = OpFunctionCall %v3int %tint_mod %38 %39 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl index fa88822f21..bc7a07ef13 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl index fa88822f21..bc7a07ef13 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint lhs, uint3 rhs) { + const uint3 l = uint3((lhs).xxx); + return (l % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl index 633b9edba9..534cab7017 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uint lhs, uvec3 rhs) { + uvec3 l = uvec3(lhs); + return (l % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uint a = 4u; uvec3 b = uvec3(0u, 2u, 0u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl index bc4bada4be..0de3b769ad 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint lhs, uint3 rhs) { + uint3 const l = uint3(lhs); + return (l % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint a = 4u; uint3 b = uint3(0u, 2u, 0u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm index 3c1d47c9e2..7adf383b0b 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/scalar-vec3/u32.wgsl.expected.spvasm @@ -1,36 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %uint %v3uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 + %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_4 = OpConstant %uint 4 %_ptr_Function_uint = OpTypePointer Function %uint - %9 = OpConstantNull %uint - %v3uint = OpTypeVector %uint 3 + %24 = OpConstantNull %uint %uint_2 = OpConstant %uint 2 - %12 = OpConstantComposite %v3uint %9 %uint_2 %9 + %26 = OpConstantComposite %v3uint %24 %uint_2 %24 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %15 = OpConstantNull %v3uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_uint Function %9 - %b = OpVariable %_ptr_Function_v3uint Function %15 - %19 = OpVariable %_ptr_Function_v3uint Function %15 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %lhs %lhs %lhs + %11 = OpIEqual %v3bool %rhs %10 + %9 = OpSelect %v3uint %11 %15 %rhs + %16 = OpUMod %v3uint %8 %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_uint Function %24 + %b = OpVariable %_ptr_Function_v3uint Function %10 OpStore %a %uint_4 - OpStore %b %12 - %16 = OpLoad %uint %a - %17 = OpLoad %v3uint %b - %20 = OpCompositeConstruct %v3uint %16 %16 %16 - %18 = OpUMod %v3uint %20 %17 + OpStore %b %26 + %30 = OpLoad %uint %a + %31 = OpLoad %v3uint %b + %29 = OpFunctionCall %v3uint %tint_mod %30 %31 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 208637ee75..fc3af835ea 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 208637ee75..fc3af835ea 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,7 +1,12 @@ +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)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int b = 0; - const int3 r = (a % (b == 0 ? 1 : b)); + const int3 r = tint_mod(a, b); return; } 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 d74047afa9..788c7fee9c 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 @@ -1,9 +1,14 @@ #version 310 es +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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); int b = 0; - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 39d00f808b..e84bf2fb88 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 @@ -1,10 +1,15 @@ #include 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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int b = 0; - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 d5f44f4be2..703e72d0e6 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,37 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 22 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %int + %10 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %15 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %18 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %25 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %31 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %34 = OpConstantNull %int %_ptr_Function_int = OpTypePointer Function %int - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_int Function %14 - %20 = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3int %a - %18 = OpLoad %int %b - %21 = OpCompositeConstruct %v3int %18 %18 %18 - %19 = OpSMod %v3int %17 %21 + %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 = OpSMod %v3int %lhs %9 + OpReturnValue %24 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl index 0cb79cfea2..b9e649a447 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl index 0cb79cfea2..b9e649a447 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,12 @@ +uint3 tint_mod(uint3 lhs, uint rhs) { + const uint3 r = uint3((rhs).xxx); + return (lhs % ((r == (0u).xxx) ? (1u).xxx : r)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - const uint3 r = (a % (b == 0u ? 1u : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl index d84b14b180..03f7867de4 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.glsl @@ -1,9 +1,14 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uint rhs) { + uvec3 r = uvec3(rhs); + return (lhs % mix(r, uvec3(1u), equal(r, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uint b = 0u; - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl index 3c8b16e08e..c6a3362339 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.msl @@ -1,10 +1,15 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint rhs) { + uint3 const r = uint3(rhs); + return (lhs % select(r, uint3(1u), (r == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint b = 0u; - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm index 36e59096a8..a1b3a0e777 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-scalar/u32.wgsl.expected.spvasm @@ -1,37 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 22 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %uint + %10 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %17 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %23 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %26 = OpConstantNull %uint %_ptr_Function_uint = OpTypePointer Function %uint - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_uint Function %14 - %20 = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %14 - %17 = OpLoad %v3uint %a - %18 = OpLoad %uint %b - %21 = OpCompositeConstruct %v3uint %18 %18 %18 - %19 = OpUMod %v3uint %17 %21 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %uint + %7 = OpLabel + %8 = OpCompositeConstruct %v3uint %rhs %rhs %rhs + %11 = OpIEqual %v3bool %8 %10 + %9 = OpSelect %v3uint %11 %15 %8 + %16 = OpUMod %v3uint %lhs %9 + OpReturnValue %16 + OpFunctionEnd + %f = OpFunction %void None %17 + %20 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %10 + %b = OpVariable %_ptr_Function_uint Function %26 + OpStore %a %23 + OpStore %b %26 + %30 = OpLoad %v3uint %a + %31 = OpLoad %uint %b + %29 = OpFunctionCall %v3uint %tint_mod %30 %31 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 97e59e6254..6369536021 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 97e59e6254..6369536021 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,7 +1,11 @@ +int3 tint_mod(int3 lhs, int3 rhs) { + return (lhs % (((rhs == (0).xxx) | ((lhs == (-2147483648).xxx) & (rhs == (-1).xxx))) ? (1).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - const int3 r = (a % (b == int3(0, 0, 0) ? int3(1, 1, 1) : b)); + const int3 r = tint_mod(a, b); return; } 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 809b454345..e1da39494e 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,9 +1,13 @@ #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)))))))); +} + void f() { ivec3 a = ivec3(1, 2, 3); ivec3 b = ivec3(0, 5, 0); - ivec3 r = (a % b); + ivec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 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 e6b07ad968..847e9f6adb 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 @@ -1,10 +1,14 @@ #include 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)))))); +} + kernel void f() { int3 a = int3(1, 2, 3); int3 b = int3(0, 5, 0); - int3 const r = (a % b); + int3 const r = tint_mod(a, b); return; } 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 fe57bb5a5d..bb96ac7ead 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,36 +1,60 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 40 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %int = OpTypeInt 32 1 %v3int = OpTypeVector %int 3 + %1 = OpTypeFunction %v3int %v3int %v3int + %9 = OpConstantNull %v3int + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 +%int_n2147483648 = OpConstant %int -2147483648 + %14 = OpConstantComposite %v3int %int_n2147483648 %int_n2147483648 %int_n2147483648 + %int_n1 = OpConstant %int -1 + %17 = OpConstantComposite %v3int %int_n1 %int_n1 %int_n1 %int_1 = OpConstant %int 1 + %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1 + %void = OpTypeVoid + %24 = OpTypeFunction %void %int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 - %10 = OpConstantComposite %v3int %int_1 %int_2 %int_3 + %30 = OpConstantComposite %v3int %int_1 %int_2 %int_3 %_ptr_Function_v3int = OpTypePointer Function %v3int - %13 = OpConstantNull %v3int - %14 = OpConstantNull %int + %33 = OpConstantNull %int %int_5 = OpConstant %int 5 - %16 = OpConstantComposite %v3int %14 %int_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3int Function %13 - %b = OpVariable %_ptr_Function_v3int Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3int %a - %19 = OpLoad %v3int %b - %20 = OpSMod %v3int %18 %19 + %35 = OpConstantComposite %v3int %33 %int_5 %33 + %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 = OpSMod %v3int %lhs %8 + OpReturnValue %23 + 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 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl index b041731b55..1411197460 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.dxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl index b041731b55..1411197460 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.fxc.hlsl @@ -1,7 +1,11 @@ +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % ((rhs == (0u).xxx) ? (1u).xxx : rhs)); +} + [numthreads(1, 1, 1)] void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - const uint3 r = (a % (b == uint3(0u, 0u, 0u) ? uint3(1u, 1u, 1u) : b)); + const uint3 r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl index af4c44fdcf..e6cd33b337 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.glsl @@ -1,9 +1,13 @@ #version 310 es +uvec3 tint_mod(uvec3 lhs, uvec3 rhs) { + return (lhs % mix(rhs, uvec3(1u), equal(rhs, uvec3(0u)))); +} + void f() { uvec3 a = uvec3(1u, 2u, 3u); uvec3 b = uvec3(0u, 5u, 0u); - uvec3 r = (a % b); + uvec3 r = tint_mod(a, b); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl index 46e36b05b4..db9d1c97e1 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.msl @@ -1,10 +1,14 @@ #include using namespace metal; +uint3 tint_mod(uint3 lhs, uint3 rhs) { + return (lhs % select(rhs, uint3(1u), (rhs == uint3(0u)))); +} + kernel void f() { uint3 a = uint3(1u, 2u, 3u); uint3 b = uint3(0u, 5u, 0u); - uint3 const r = (a % b); + uint3 const r = tint_mod(a, b); return; } diff --git a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm index 2c87495019..c5096e6d77 100644 --- a/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm +++ b/test/tint/expressions/binary/mod_by_zero/by_identifier/vec3-vec3/u32.wgsl.expected.spvasm @@ -1,36 +1,52 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 21 +; Bound: 32 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %f "f" OpExecutionMode %f LocalSize 1 1 1 + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %f "f" OpName %a "a" OpName %b "b" - %void = OpTypeVoid - %1 = OpTypeFunction %void %uint = OpTypeInt 32 0 %v3uint = OpTypeVector %uint 3 + %1 = OpTypeFunction %v3uint %v3uint %v3uint + %9 = OpConstantNull %v3uint + %bool = OpTypeBool + %v3bool = OpTypeVector %bool 3 %uint_1 = OpConstant %uint 1 + %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 + %void = OpTypeVoid + %16 = OpTypeFunction %void %uint_2 = OpConstant %uint 2 %uint_3 = OpConstant %uint 3 - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 + %22 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 %_ptr_Function_v3uint = OpTypePointer Function %v3uint - %13 = OpConstantNull %v3uint - %14 = OpConstantNull %uint + %25 = OpConstantNull %uint %uint_5 = OpConstant %uint 5 - %16 = OpConstantComposite %v3uint %14 %uint_5 %14 - %f = OpFunction %void None %1 - %4 = OpLabel - %a = OpVariable %_ptr_Function_v3uint Function %13 - %b = OpVariable %_ptr_Function_v3uint Function %13 - OpStore %a %10 - OpStore %b %16 - %18 = OpLoad %v3uint %a - %19 = OpLoad %v3uint %b - %20 = OpUMod %v3uint %18 %19 + %27 = OpConstantComposite %v3uint %25 %uint_5 %25 + %tint_mod = OpFunction %v3uint None %1 + %lhs = OpFunctionParameter %v3uint + %rhs = OpFunctionParameter %v3uint + %7 = OpLabel + %10 = OpIEqual %v3bool %rhs %9 + %8 = OpSelect %v3uint %10 %14 %rhs + %15 = OpUMod %v3uint %lhs %8 + OpReturnValue %15 + OpFunctionEnd + %f = OpFunction %void None %16 + %19 = OpLabel + %a = OpVariable %_ptr_Function_v3uint Function %9 + %b = OpVariable %_ptr_Function_v3uint Function %9 + OpStore %a %22 + OpStore %b %27 + %30 = OpLoad %v3uint %a + %31 = OpLoad %v3uint %b + %29 = OpFunctionCall %v3uint %tint_mod %30 %31 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl index c9c2c3d2bd..2edcd67a42 100644 --- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl @@ -25,8 +25,11 @@ int bar() { void main() { S x = (S)0; - const int tint_symbol_2 = foo(); - const int tint_symbol_save = tint_symbol_2; + const int tint_symbol_save = foo(); const int tint_symbol_1 = bar(); - set_int4(x.a[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5)); + { + int4 tint_symbol_3[4] = x.a; + set_int4(tint_symbol_3[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5)); + x.a = tint_symbol_3; + } } diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl index c9c2c3d2bd..2edcd67a42 100644 --- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl @@ -25,8 +25,11 @@ int bar() { void main() { S x = (S)0; - const int tint_symbol_2 = foo(); - const int tint_symbol_save = tint_symbol_2; + const int tint_symbol_save = foo(); const int tint_symbol_1 = bar(); - set_int4(x.a[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5)); + { + int4 tint_symbol_3[4] = x.a; + set_int4(tint_symbol_3[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5)); + x.a = tint_symbol_3; + } } 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 b90f3577b4..35dd3113ef 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 @@ -3,14 +3,22 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + static int a = 0; static float b = 0.0f; void foo(int maybe_zero) { - a = (a / 1); - a = (a % 1); - a = (a / (maybe_zero == 0 ? 1 : maybe_zero)); - a = (a % (maybe_zero == 0 ? 1 : maybe_zero)); + a = tint_div(a, 0); + a = tint_mod(a, 0); + a = tint_div(a, maybe_zero); + a = tint_mod(a, maybe_zero); b = (b / 0.0f); b = (b % 0.0f); b = (b / float(maybe_zero)); diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.fxc.hlsl index b90f3577b4..35dd3113ef 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 @@ -3,14 +3,22 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + static int a = 0; static float b = 0.0f; void foo(int maybe_zero) { - a = (a / 1); - a = (a % 1); - a = (a / (maybe_zero == 0 ? 1 : maybe_zero)); - a = (a % (maybe_zero == 0 ? 1 : maybe_zero)); + a = tint_div(a, 0); + a = tint_mod(a, 0); + a = tint_div(a, maybe_zero); + a = tint_mod(a, maybe_zero); b = (b / 0.0f); b = (b % 0.0f); b = (b / float(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 5a32830091..3af799e954 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 @@ -9,13 +9,21 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : 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 a = 0; float b = 0.0f; void foo(int maybe_zero) { - a = (a / 0); - a = (a % 0); - a = (a / maybe_zero); - a = (a % maybe_zero); + a = tint_div(a, 0); + a = tint_mod(a, 0); + a = tint_div(a, maybe_zero); + a = tint_mod(a, maybe_zero); b = (b / 0.0f); b = tint_float_modulo(b, 0.0f); b = (b / float(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 aa0605fc58..0a9040112f 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 @@ -1,13 +1,21 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + void foo(int maybe_zero) { thread int tint_symbol = 0; thread float tint_symbol_1 = 0.0f; - tint_symbol = (tint_symbol / 0); - tint_symbol = (tint_symbol % 0); - tint_symbol = (tint_symbol / maybe_zero); - tint_symbol = (tint_symbol % maybe_zero); + tint_symbol = tint_div(tint_symbol, 0); + tint_symbol = tint_mod(tint_symbol, 0); + tint_symbol = tint_div(tint_symbol, maybe_zero); + tint_symbol = tint_mod(tint_symbol, maybe_zero); tint_symbol_1 = (tint_symbol_1 / 0.0f); tint_symbol_1 = fmod(tint_symbol_1, 0.0f); tint_symbol_1 = (tint_symbol_1 / float(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 c5bc009db6..af5ae1fe92 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: 35 +; Bound: 62 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -10,6 +10,12 @@ OpName %a "a" OpName %b "b" OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" + OpName %tint_mod "tint_mod" + OpName %lhs_0 "lhs" + OpName %rhs_0 "rhs" OpName %foo "foo" OpName %maybe_zero "maybe_zero" %int = OpTypeInt 32 1 @@ -22,39 +28,70 @@ %b = OpVariable %_ptr_Private_float Private %8 %void = OpTypeVoid %9 = OpTypeFunction %void - %13 = OpTypeFunction %void %int + %13 = OpTypeFunction %int %int %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 + %40 = OpTypeFunction %void %int %unused_entry_point = OpFunction %void None %9 %12 = OpLabel OpReturn OpFunctionEnd - %foo = OpFunction %void None %13 + %tint_div = OpFunction %int None %13 + %lhs = OpFunctionParameter %int + %rhs = OpFunctionParameter %int + %17 = OpLabel + %19 = OpIEqual %bool %rhs %4 + %22 = OpIEqual %bool %lhs %int_n2147483648 + %24 = OpIEqual %bool %rhs %int_n1 + %25 = OpLogicalAnd %bool %22 %24 + %26 = OpLogicalOr %bool %19 %25 + %18 = OpSelect %int %26 %int_1 %rhs + %28 = OpSDiv %int %lhs %18 + OpReturnValue %28 + OpFunctionEnd + %tint_mod = OpFunction %int None %13 + %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 = OpSMod %int %lhs_0 %33 + OpReturnValue %39 + OpFunctionEnd + %foo = OpFunction %void None %40 %maybe_zero = OpFunctionParameter %int - %16 = OpLabel - %17 = OpLoad %int %a - %18 = OpSDiv %int %17 %4 - OpStore %a %18 - %19 = OpLoad %int %a - %20 = OpSMod %int %19 %4 - OpStore %a %20 - %21 = OpLoad %int %a - %22 = OpSDiv %int %21 %maybe_zero - OpStore %a %22 - %23 = OpLoad %int %a - %24 = OpSMod %int %23 %maybe_zero - OpStore %a %24 - %25 = OpLoad %float %b - %26 = OpFDiv %float %25 %8 - OpStore %b %26 - %27 = OpLoad %float %b - %28 = OpFRem %float %27 %8 - OpStore %b %28 - %29 = OpLoad %float %b - %30 = OpConvertSToF %float %maybe_zero - %31 = OpFDiv %float %29 %30 - OpStore %b %31 - %32 = OpLoad %float %b - %33 = OpConvertSToF %float %maybe_zero - %34 = OpFRem %float %32 %33 - OpStore %b %34 + %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 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl index 828cc6ebb6..3c72263b8d 100644 --- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl @@ -23,20 +23,18 @@ int idx3() { void foo() { float a[4] = (float[4])0; - const int tint_symbol_2 = idx1(); - const int tint_symbol_save = tint_symbol_2; + const int tint_symbol_save = idx1(); { a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f); while (true) { - const int tint_symbol_3 = idx2(); - if (!((a[tint_symbol_3] < 10.0f))) { + const int tint_symbol_2 = idx2(); + if (!((a[tint_symbol_2] < 10.0f))) { break; } { } { - const int tint_symbol_4 = idx3(); - const int tint_symbol_1_save = tint_symbol_4; + const int tint_symbol_1_save = idx3(); a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f); } } diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl index 828cc6ebb6..3c72263b8d 100644 --- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl @@ -23,20 +23,18 @@ int idx3() { void foo() { float a[4] = (float[4])0; - const int tint_symbol_2 = idx1(); - const int tint_symbol_save = tint_symbol_2; + const int tint_symbol_save = idx1(); { a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f); while (true) { - const int tint_symbol_3 = idx2(); - if (!((a[tint_symbol_3] < 10.0f))) { + const int tint_symbol_2 = idx2(); + if (!((a[tint_symbol_2] < 10.0f))) { break; } { } { - const int tint_symbol_4 = idx3(); - const int tint_symbol_1_save = tint_symbol_4; + const int tint_symbol_1_save = idx3(); a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f); } } diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/function.wgsl.expected.dxc.hlsl index bfdebdb6dc..04f0a97659 100644 --- a/test/tint/statements/compound_assign/function.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/function.wgsl.expected.dxc.hlsl @@ -3,11 +3,15 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + void foo() { int a = 0; float4 b = float4(0.0f, 0.0f, 0.0f, 0.0f); float2x2 c = float2x2(0.0f, 0.0f, 0.0f, 0.0f); - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/function.wgsl.expected.fxc.hlsl index bfdebdb6dc..04f0a97659 100644 --- a/test/tint/statements/compound_assign/function.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/function.wgsl.expected.fxc.hlsl @@ -3,11 +3,15 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + void foo() { int a = 0; float4 b = float4(0.0f, 0.0f, 0.0f, 0.0f); float2x2 c = float2x2(0.0f, 0.0f, 0.0f, 0.0f); - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.glsl b/test/tint/statements/compound_assign/function.wgsl.expected.glsl index 7b4c01c6de..5c71b85358 100644 --- a/test/tint/statements/compound_assign/function.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/function.wgsl.expected.glsl @@ -4,11 +4,15 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + void foo() { int a = 0; vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f); mat2 c = mat2(0.0f, 0.0f, 0.0f, 0.0f); - a = (a / 2); + a = tint_div(a, 2); b = (b * mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f))); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.msl b/test/tint/statements/compound_assign/function.wgsl.expected.msl index 3acbce949b..bbe0262544 100644 --- a/test/tint/statements/compound_assign/function.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/function.wgsl.expected.msl @@ -1,11 +1,15 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + void foo() { int a = 0; float4 b = 0.0f; float2x2 c = float2x2(0.0f); - a = (a / 2); + a = tint_div(a, 2); b = (b * float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f))); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.spvasm b/test/tint/statements/compound_assign/function.wgsl.expected.spvasm index eee238313c..d01700d7eb 100644 --- a/test/tint/statements/compound_assign/function.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/function.wgsl.expected.spvasm @@ -1,13 +1,16 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 31 +; Bound: 47 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %unused_entry_point "unused_entry_point" OpExecutionMode %unused_entry_point LocalSize 1 1 1 OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpName %a "a" OpName %b "b" @@ -15,37 +18,55 @@ %void = OpTypeVoid %1 = OpTypeFunction %void %int = OpTypeInt 32 1 + %5 = OpTypeFunction %int %int %int + %12 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 %_ptr_Function_int = OpTypePointer Function %int - %10 = OpConstantNull %int %float = OpTypeFloat 32 %v4float = OpTypeVector %float 4 %_ptr_Function_v4float = OpTypePointer Function %v4float - %15 = OpConstantNull %v4float + %31 = OpConstantNull %v4float %v2float = OpTypeVector %float 2 %mat2v2float = OpTypeMatrix %v2float 2 %_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float - %20 = OpConstantNull %mat2v2float + %36 = OpConstantNull %mat2v2float %int_2 = OpConstant %int 2 %mat4v4float = OpTypeMatrix %v4float 4 - %26 = OpConstantNull %mat4v4float + %42 = OpConstantNull %mat4v4float %float_2 = OpConstant %float 2 %unused_entry_point = OpFunction %void None %1 %4 = OpLabel OpReturn OpFunctionEnd + %tint_div = OpFunction %int None %5 + %lhs = OpFunctionParameter %int + %rhs = OpFunctionParameter %int + %10 = OpLabel + %13 = OpIEqual %bool %rhs %12 + %16 = OpIEqual %bool %lhs %int_n2147483648 + %18 = OpIEqual %bool %rhs %int_n1 + %19 = OpLogicalAnd %bool %16 %18 + %20 = OpLogicalOr %bool %13 %19 + %11 = OpSelect %int %20 %int_1 %rhs + %22 = OpSDiv %int %lhs %11 + OpReturnValue %22 + OpFunctionEnd %foo = OpFunction %void None %1 - %6 = OpLabel - %a = OpVariable %_ptr_Function_int Function %10 - %b = OpVariable %_ptr_Function_v4float Function %15 - %c = OpVariable %_ptr_Function_mat2v2float Function %20 - %21 = OpLoad %int %a - %23 = OpSDiv %int %21 %int_2 - OpStore %a %23 - %24 = OpLoad %v4float %b - %27 = OpVectorTimesMatrix %v4float %24 %26 - OpStore %b %27 - %28 = OpLoad %mat2v2float %c - %30 = OpMatrixTimesScalar %mat2v2float %28 %float_2 - OpStore %c %30 + %24 = OpLabel + %a = OpVariable %_ptr_Function_int Function %12 + %b = OpVariable %_ptr_Function_v4float Function %31 + %c = OpVariable %_ptr_Function_mat2v2float Function %36 + %38 = OpLoad %int %a + %37 = OpFunctionCall %int %tint_div %38 %int_2 + OpStore %a %37 + %40 = OpLoad %v4float %b + %43 = OpVectorTimesMatrix %v4float %40 %42 + OpStore %b %43 + %44 = OpLoad %mat2v2float %c + %46 = OpMatrixTimesScalar %mat2v2float %44 %float_2 + OpStore %c %46 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/private.wgsl.expected.dxc.hlsl index f01cc42ffa..2de2195033 100644 --- a/test/tint/statements/compound_assign/private.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/private.wgsl.expected.dxc.hlsl @@ -3,12 +3,16 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + static int a = 0; static float4 b = float4(0.0f, 0.0f, 0.0f, 0.0f); static float2x2 c = float2x2(0.0f, 0.0f, 0.0f, 0.0f); void foo() { - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/private.wgsl.expected.fxc.hlsl index f01cc42ffa..2de2195033 100644 --- a/test/tint/statements/compound_assign/private.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/private.wgsl.expected.fxc.hlsl @@ -3,12 +3,16 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + static int a = 0; static float4 b = float4(0.0f, 0.0f, 0.0f, 0.0f); static float2x2 c = float2x2(0.0f, 0.0f, 0.0f, 0.0f); void foo() { - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.glsl b/test/tint/statements/compound_assign/private.wgsl.expected.glsl index 33efe429c5..4efe337dd4 100644 --- a/test/tint/statements/compound_assign/private.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/private.wgsl.expected.glsl @@ -4,11 +4,15 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + int a = 0; vec4 b = vec4(0.0f, 0.0f, 0.0f, 0.0f); mat2 c = mat2(0.0f, 0.0f, 0.0f, 0.0f); void foo() { - a = (a / 2); + a = tint_div(a, 2); b = (b * mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f))); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.msl b/test/tint/statements/compound_assign/private.wgsl.expected.msl index 327107f790..f573620089 100644 --- a/test/tint/statements/compound_assign/private.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/private.wgsl.expected.msl @@ -1,11 +1,15 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + void foo() { thread int tint_symbol = 0; thread float4 tint_symbol_1 = 0.0f; thread float2x2 tint_symbol_2 = float2x2(0.0f); - tint_symbol = (tint_symbol / 2); + tint_symbol = tint_div(tint_symbol, 2); tint_symbol_1 = (tint_symbol_1 * float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f))); tint_symbol_2 = (tint_symbol_2 * 2.0f); } diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.spvasm b/test/tint/statements/compound_assign/private.wgsl.expected.spvasm index 473958d590..7294863bd1 100644 --- a/test/tint/statements/compound_assign/private.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/private.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 31 +; Bound: 47 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -11,6 +11,9 @@ OpName %b "b" OpName %c "c" OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" %int = OpTypeInt 32 1 %_ptr_Private_int = OpTypePointer Private %int @@ -28,24 +31,42 @@ %c = OpVariable %_ptr_Private_mat2v2float Private %14 %void = OpTypeVoid %15 = OpTypeFunction %void + %19 = OpTypeFunction %int %int %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 %int_2 = OpConstant %int 2 %mat4v4float = OpTypeMatrix %v4float 4 - %26 = OpConstantNull %mat4v4float + %42 = OpConstantNull %mat4v4float %float_2 = OpConstant %float 2 %unused_entry_point = OpFunction %void None %15 %18 = OpLabel OpReturn OpFunctionEnd + %tint_div = OpFunction %int None %19 + %lhs = OpFunctionParameter %int + %rhs = OpFunctionParameter %int + %23 = OpLabel + %25 = OpIEqual %bool %rhs %4 + %28 = OpIEqual %bool %lhs %int_n2147483648 + %30 = OpIEqual %bool %rhs %int_n1 + %31 = OpLogicalAnd %bool %28 %30 + %32 = OpLogicalOr %bool %25 %31 + %24 = OpSelect %int %32 %int_1 %rhs + %34 = OpSDiv %int %lhs %24 + OpReturnValue %34 + OpFunctionEnd %foo = OpFunction %void None %15 - %20 = OpLabel - %21 = OpLoad %int %a - %23 = OpSDiv %int %21 %int_2 - OpStore %a %23 - %24 = OpLoad %v4float %b - %27 = OpVectorTimesMatrix %v4float %24 %26 - OpStore %b %27 - %28 = OpLoad %mat2v2float %c - %30 = OpMatrixTimesScalar %mat2v2float %28 %float_2 - OpStore %c %30 + %36 = OpLabel + %38 = OpLoad %int %a + %37 = OpFunctionCall %int %tint_div %38 %int_2 + OpStore %a %37 + %40 = OpLoad %v4float %b + %43 = OpVectorTimesMatrix %v4float %40 %42 + OpStore %b %43 + %44 = OpLoad %mat2v2float %c + %46 = OpMatrixTimesScalar %mat2v2float %44 %float_2 + OpStore %c %46 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.dxc.hlsl index affbb2bf49..e84dd9abe5 100644 --- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.dxc.hlsl @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store(0u, asuint((asint(v.Load(0u)) / 2))); + const int tint_symbol = tint_div(asint(v.Load(0u)), 2); + v.Store(0u, asuint(tint_symbol)); } diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.fxc.hlsl index affbb2bf49..e84dd9abe5 100644 --- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.fxc.hlsl @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store(0u, asuint((asint(v.Load(0u)) / 2))); + const int tint_symbol = tint_div(asint(v.Load(0u)), 2); + v.Store(0u, asuint(tint_symbol)); } diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.glsl b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.glsl index 369c9899ab..43823fcc6c 100644 --- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.glsl @@ -4,6 +4,10 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + struct S { int a; }; @@ -13,6 +17,7 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; void foo() { - v.inner.a = (v.inner.a / 2); + int tint_symbol = tint_div(v.inner.a, 2); + v.inner.a = tint_symbol; } diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl index 9c197242d3..855cb61e70 100644 --- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl @@ -1,11 +1,16 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + struct S { /* 0x0000 */ int a; }; -void foo(device S* const tint_symbol) { - (*(tint_symbol)).a = ((*(tint_symbol)).a / 2); +void foo(device S* const tint_symbol_1) { + int const tint_symbol = tint_div((*(tint_symbol_1)).a, 2); + (*(tint_symbol_1)).a = tint_symbol; } diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.spvasm b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.spvasm index e4078d1f57..e1c28b21ee 100644 --- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 20 +; Bound: 37 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %S 0 "a" OpName %v "v" OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -26,6 +29,12 @@ %v = OpVariable %_ptr_StorageBuffer_v_block StorageBuffer %void = OpTypeVoid %6 = OpTypeFunction %void + %10 = OpTypeFunction %int %int %int + %16 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int @@ -34,12 +43,25 @@ %9 = OpLabel OpReturn OpFunctionEnd + %tint_div = OpFunction %int None %10 + %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 = OpSDiv %int %lhs %15 + OpReturnValue %26 + OpFunctionEnd %foo = OpFunction %void None %6 - %11 = OpLabel - %15 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - %16 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - %17 = OpLoad %int %16 - %19 = OpSDiv %int %17 %int_2 - OpStore %15 %19 + %28 = OpLabel + %33 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 + %34 = OpLoad %int %33 + %29 = OpFunctionCall %int %tint_div %34 %int_2 + %36 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 + OpStore %36 %29 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 fec5816468..92912b2e72 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 @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store(0u, asuint((asint(v.Load(0u)) % 2))); + const int tint_symbol = tint_mod(asint(v.Load(0u)), 2); + v.Store(0u, asuint(tint_symbol)); } 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 fec5816468..92912b2e72 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 @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int tint_mod(int lhs, int rhs) { + return (lhs % (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store(0u, asuint((asint(v.Load(0u)) % 2))); + const int tint_symbol = tint_mod(asint(v.Load(0u)), 2); + v.Store(0u, asuint(tint_symbol)); } 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 8e34ac7068..f3cf594097 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.glsl @@ -4,6 +4,10 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_mod(int lhs, int rhs) { + return (lhs % (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + struct S { int a; }; @@ -13,6 +17,7 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; void foo() { - v.inner.a = (v.inner.a % 2); + int tint_symbol = tint_mod(v.inner.a, 2); + v.inner.a = tint_symbol; } 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 74cbbf7a80..978e63014d 100644 --- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl @@ -1,11 +1,16 @@ #include using namespace metal; +int tint_mod(int lhs, int rhs) { + return (lhs % select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + struct S { /* 0x0000 */ int a; }; -void foo(device S* const tint_symbol) { - (*(tint_symbol)).a = ((*(tint_symbol)).a % 2); +void foo(device S* const tint_symbol_1) { + int const tint_symbol = tint_mod((*(tint_symbol_1)).a, 2); + (*(tint_symbol_1)).a = tint_symbol; } 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 4c9f181906..395fc7014f 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: 20 +; Bound: 37 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %S 0 "a" OpName %v "v" OpName %unused_entry_point "unused_entry_point" + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -26,6 +29,12 @@ %v = OpVariable %_ptr_StorageBuffer_v_block StorageBuffer %void = OpTypeVoid %6 = OpTypeFunction %void + %10 = OpTypeFunction %int %int %int + %16 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int @@ -34,12 +43,25 @@ %9 = OpLabel OpReturn OpFunctionEnd + %tint_mod = OpFunction %int None %10 + %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 = OpSMod %int %lhs %15 + OpReturnValue %26 + OpFunctionEnd %foo = OpFunction %void None %6 - %11 = OpLabel - %15 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - %16 = OpAccessChain %_ptr_StorageBuffer_int %v %uint_0 %uint_0 - %17 = OpLoad %int %16 - %19 = OpSMod %int %17 %int_2 - OpStore %15 %19 + %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 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.dxc.hlsl index 0e66d73f8a..d519f35f4e 100644 --- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.dxc.hlsl @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) / (2).xxxx))); + const int4 tint_symbol = tint_div(asint(v.Load4(0u)), (2).xxxx); + v.Store4(0u, asuint(tint_symbol)); } diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.fxc.hlsl index 0e66d73f8a..d519f35f4e 100644 --- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.fxc.hlsl @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) / (2).xxxx))); + const int4 tint_symbol = tint_div(asint(v.Load4(0u)), (2).xxxx); + v.Store4(0u, asuint(tint_symbol)); } diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.glsl b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.glsl index 5f6f244a01..aa704fec0b 100644 --- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.glsl @@ -4,6 +4,10 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +ivec4 tint_div(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)))))))); +} + struct S { ivec4 a; }; @@ -13,6 +17,7 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; void foo() { - v.inner.a = (v.inner.a / ivec4(2)); + ivec4 tint_symbol = tint_div(v.inner.a, ivec4(2)); + v.inner.a = tint_symbol; } diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl index ace4828023..782112cf4c 100644 --- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl @@ -1,11 +1,16 @@ #include using namespace metal; +int4 tint_div(int4 lhs, int4 rhs) { + return (lhs / select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1)))))); +} + struct S { /* 0x0000 */ int4 a; }; -void foo(device S* const tint_symbol) { - (*(tint_symbol)).a = ((*(tint_symbol)).a / int4(2)); +void foo(device S* const tint_symbol_1) { + int4 const tint_symbol = tint_div((*(tint_symbol_1)).a, int4(2)); + (*(tint_symbol_1)).a = tint_symbol; } diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.spvasm b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.spvasm index 9b7ff51579..cfca72af03 100644 --- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 22 +; Bound: 43 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %S 0 "a" OpName %v "v" OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -27,21 +30,44 @@ %v = OpVariable %_ptr_StorageBuffer_v_block StorageBuffer %void = OpTypeVoid %7 = OpTypeFunction %void + %11 = OpTypeFunction %v4int %v4int %v4int + %17 = OpConstantNull %v4int + %bool = OpTypeBool + %v4bool = OpTypeVector %bool 4 +%int_n2147483648 = OpConstant %int -2147483648 + %22 = 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 + %int_1 = OpConstant %int 1 + %30 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int %int_2 = OpConstant %int 2 - %20 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 + %41 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 %unused_entry_point = OpFunction %void None %7 %10 = OpLabel OpReturn OpFunctionEnd + %tint_div = OpFunction %v4int None %11 + %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 = OpSDiv %v4int %lhs %16 + OpReturnValue %31 + OpFunctionEnd %foo = OpFunction %void None %7 - %12 = OpLabel - %16 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %17 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %18 = OpLoad %v4int %17 - %21 = OpSDiv %v4int %18 %20 - OpStore %16 %21 + %33 = OpLabel + %38 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + %39 = OpLoad %v4int %38 + %34 = OpFunctionCall %v4int %tint_div %39 %41 + %42 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 + OpStore %42 %34 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 f5f8675647..e0195aae3b 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 @@ -3,8 +3,14 @@ void unused_entry_point() { return; } +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)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) % 2))); + const int4 tint_symbol = tint_mod(asint(v.Load4(0u)), 2); + v.Store4(0u, asuint(tint_symbol)); } 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 f5f8675647..e0195aae3b 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 @@ -3,8 +3,14 @@ void unused_entry_point() { return; } +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)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) % 2))); + const int4 tint_symbol = tint_mod(asint(v.Load4(0u)), 2); + v.Store4(0u, asuint(tint_symbol)); } 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 53e18c8864..ed2d419ad1 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 @@ -4,6 +4,11 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +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)))))))); +} + struct S { ivec4 a; }; @@ -13,6 +18,7 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; void foo() { - v.inner.a = (v.inner.a % 2); + ivec4 tint_symbol = tint_mod(v.inner.a, 2); + v.inner.a = tint_symbol; } 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 697323bd87..db6580245d 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 @@ -1,11 +1,17 @@ #include using namespace metal; +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)))))); +} + struct S { /* 0x0000 */ int4 a; }; -void foo(device S* const tint_symbol) { - (*(tint_symbol)).a = ((*(tint_symbol)).a % 2); +void foo(device S* const tint_symbol_1) { + int4 const tint_symbol = tint_mod((*(tint_symbol_1)).a, 2); + (*(tint_symbol_1)).a = tint_symbol; } 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 137c568e01..1467a4bb20 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: 25 +; Bound: 43 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %S 0 "a" OpName %v "v" OpName %unused_entry_point "unused_entry_point" + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -27,24 +30,44 @@ %v = OpVariable %_ptr_StorageBuffer_v_block StorageBuffer %void = OpTypeVoid %7 = OpTypeFunction %void + %11 = OpTypeFunction %v4int %v4int %int + %18 = OpConstantNull %v4int + %bool = OpTypeBool + %v4bool = OpTypeVector %bool 4 +%int_n2147483648 = OpConstant %int -2147483648 + %23 = 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 + %int_1 = OpConstant %int 1 + %31 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int %int_2 = OpConstant %int 2 -%_ptr_Function_v4int = OpTypePointer Function %v4int - %23 = OpConstantNull %v4int %unused_entry_point = OpFunction %void None %7 %10 = OpLabel OpReturn OpFunctionEnd + %tint_mod = OpFunction %v4int None %11 + %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 = OpSMod %v4int %lhs %17 + OpReturnValue %32 + OpFunctionEnd %foo = OpFunction %void None %7 - %12 = OpLabel - %21 = OpVariable %_ptr_Function_v4int Function %23 - %16 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %17 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %18 = OpLoad %v4int %17 - %24 = OpCompositeConstruct %v4int %int_2 %int_2 %int_2 %int_2 - %20 = OpSMod %v4int %18 %24 - OpStore %16 %20 + %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 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 b54d9803e7..f413ff635f 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 @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int4 tint_mod(int4 lhs, int4 rhs) { + return (lhs % (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) % (2).xxxx))); + const int4 tint_symbol = tint_mod(asint(v.Load4(0u)), (2).xxxx); + v.Store4(0u, asuint(tint_symbol)); } 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 b54d9803e7..f413ff635f 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 @@ -3,8 +3,13 @@ void unused_entry_point() { return; } +int4 tint_mod(int4 lhs, int4 rhs) { + return (lhs % (((rhs == (0).xxxx) | ((lhs == (-2147483648).xxxx) & (rhs == (-1).xxxx))) ? (1).xxxx : rhs)); +} + RWByteAddressBuffer v : register(u0, space0); void foo() { - v.Store4(0u, asuint((asint(v.Load4(0u)) % (2).xxxx))); + const int4 tint_symbol = tint_mod(asint(v.Load4(0u)), (2).xxxx); + v.Store4(0u, asuint(tint_symbol)); } 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 d837a08dd7..1f5c0c42f0 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.glsl @@ -4,6 +4,10 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +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)))))))); +} + struct S { ivec4 a; }; @@ -13,6 +17,7 @@ layout(binding = 0, std430) buffer v_block_ssbo { } v; void foo() { - v.inner.a = (v.inner.a % ivec4(2)); + ivec4 tint_symbol = tint_mod(v.inner.a, ivec4(2)); + v.inner.a = tint_symbol; } 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 fafddb8d87..2435db2633 100644 --- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl @@ -1,11 +1,16 @@ #include using namespace metal; +int4 tint_mod(int4 lhs, int4 rhs) { + return (lhs % select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1)))))); +} + struct S { /* 0x0000 */ int4 a; }; -void foo(device S* const tint_symbol) { - (*(tint_symbol)).a = ((*(tint_symbol)).a % int4(2)); +void foo(device S* const tint_symbol_1) { + int4 const tint_symbol = tint_mod((*(tint_symbol_1)).a, int4(2)); + (*(tint_symbol_1)).a = tint_symbol; } 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 74e9f79c23..220fe57b60 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: 22 +; Bound: 43 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -13,6 +13,9 @@ OpMemberName %S 0 "a" OpName %v "v" OpName %unused_entry_point "unused_entry_point" + OpName %tint_mod "tint_mod" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" OpDecorate %v_block Block OpMemberDecorate %v_block 0 Offset 0 @@ -27,21 +30,44 @@ %v = OpVariable %_ptr_StorageBuffer_v_block StorageBuffer %void = OpTypeVoid %7 = OpTypeFunction %void + %11 = OpTypeFunction %v4int %v4int %v4int + %17 = OpConstantNull %v4int + %bool = OpTypeBool + %v4bool = OpTypeVector %bool 4 +%int_n2147483648 = OpConstant %int -2147483648 + %22 = 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 + %int_1 = OpConstant %int 1 + %30 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int %int_2 = OpConstant %int 2 - %20 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 + %41 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 %unused_entry_point = OpFunction %void None %7 %10 = OpLabel OpReturn OpFunctionEnd + %tint_mod = OpFunction %v4int None %11 + %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 = OpSMod %v4int %lhs %16 + OpReturnValue %31 + OpFunctionEnd %foo = OpFunction %void None %7 - %12 = OpLabel - %16 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %17 = OpAccessChain %_ptr_StorageBuffer_v4int %v %uint_0 %uint_0 - %18 = OpLoad %v4int %17 - %21 = OpSMod %v4int %18 %20 - OpStore %16 %21 + %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 OpReturn OpFunctionEnd diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/workgroup.wgsl.expected.dxc.hlsl index dae8e54896..d6246e401b 100644 --- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.dxc.hlsl @@ -3,12 +3,16 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + groupshared int a; groupshared float4 b; groupshared float2x2 c; void foo() { - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/workgroup.wgsl.expected.fxc.hlsl index dae8e54896..d6246e401b 100644 --- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.fxc.hlsl @@ -3,12 +3,16 @@ void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (((rhs == 0) | ((lhs == -2147483648) & (rhs == -1))) ? 1 : rhs)); +} + groupshared int a; groupshared float4 b; groupshared float2x2 c; void foo() { - a = (a / 2); + a = tint_div(a, 2); b = mul(float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx), b); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.glsl b/test/tint/statements/compound_assign/workgroup.wgsl.expected.glsl index d762d8fbe4..3b920a20d8 100644 --- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.glsl +++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.glsl @@ -4,11 +4,15 @@ layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void unused_entry_point() { return; } +int tint_div(int lhs, int rhs) { + return (lhs / (bool(uint((rhs == 0)) | uint(bool(uint((lhs == -2147483648)) & uint((rhs == -1))))) ? 1 : rhs)); +} + shared int a; shared vec4 b; shared mat2 c; void foo() { - a = (a / 2); + a = tint_div(a, 2); b = (b * mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f))); c = (c * 2.0f); } diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl b/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl index 4335b158fa..588738a95b 100644 --- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl +++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl @@ -1,8 +1,12 @@ #include using namespace metal; +int tint_div(int lhs, int rhs) { + return (lhs / select(rhs, 1, bool((rhs == 0) | bool((lhs == (-2147483647 - 1)) & (rhs == -1))))); +} + void foo(threadgroup int* const tint_symbol, threadgroup float4* const tint_symbol_1, threadgroup float2x2* const tint_symbol_2) { - *(tint_symbol) = (*(tint_symbol) / 2); + *(tint_symbol) = tint_div(*(tint_symbol), 2); *(tint_symbol_1) = (*(tint_symbol_1) * float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f))); *(tint_symbol_2) = (*(tint_symbol_2) * 2.0f); } diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.spvasm b/test/tint/statements/compound_assign/workgroup.wgsl.expected.spvasm index ddf0b14c93..18be5445a1 100644 --- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.spvasm +++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 28 +; Bound: 45 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -11,6 +11,9 @@ OpName %b "b" OpName %c "c" OpName %unused_entry_point "unused_entry_point" + OpName %tint_div "tint_div" + OpName %lhs "lhs" + OpName %rhs "rhs" OpName %foo "foo" %int = OpTypeInt 32 1 %_ptr_Workgroup_int = OpTypePointer Workgroup %int @@ -25,24 +28,43 @@ %c = OpVariable %_ptr_Workgroup_mat2v2float Workgroup %void = OpTypeVoid %12 = OpTypeFunction %void + %16 = OpTypeFunction %int %int %int + %22 = OpConstantNull %int + %bool = OpTypeBool +%int_n2147483648 = OpConstant %int -2147483648 + %int_n1 = OpConstant %int -1 + %int_1 = OpConstant %int 1 %int_2 = OpConstant %int 2 %mat4v4float = OpTypeMatrix %v4float 4 - %23 = OpConstantNull %mat4v4float + %40 = OpConstantNull %mat4v4float %float_2 = OpConstant %float 2 %unused_entry_point = OpFunction %void None %12 %15 = OpLabel OpReturn OpFunctionEnd + %tint_div = OpFunction %int None %16 + %lhs = OpFunctionParameter %int + %rhs = OpFunctionParameter %int + %20 = OpLabel + %23 = OpIEqual %bool %rhs %22 + %26 = OpIEqual %bool %lhs %int_n2147483648 + %28 = OpIEqual %bool %rhs %int_n1 + %29 = OpLogicalAnd %bool %26 %28 + %30 = OpLogicalOr %bool %23 %29 + %21 = OpSelect %int %30 %int_1 %rhs + %32 = OpSDiv %int %lhs %21 + OpReturnValue %32 + OpFunctionEnd %foo = OpFunction %void None %12 - %17 = OpLabel - %18 = OpLoad %int %a - %20 = OpSDiv %int %18 %int_2 - OpStore %a %20 - %21 = OpLoad %v4float %b - %24 = OpVectorTimesMatrix %v4float %21 %23 - OpStore %b %24 - %25 = OpLoad %mat2v2float %c - %27 = OpMatrixTimesScalar %mat2v2float %25 %float_2 - OpStore %c %27 + %34 = OpLabel + %36 = OpLoad %int %a + %35 = OpFunctionCall %int %tint_div %36 %int_2 + OpStore %a %35 + %38 = OpLoad %v4float %b + %41 = OpVectorTimesMatrix %v4float %38 %40 + OpStore %b %41 + %42 = OpLoad %mat2v2float %c + %44 = OpMatrixTimesScalar %mat2v2float %42 %float_2 + OpStore %c %44 OpReturn OpFunctionEnd diff --git a/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl index 94574a100e..ad26e2f4ba 100644 --- a/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl @@ -37,10 +37,8 @@ int idx6() { } void main() { - const int tint_symbol_4 = idx1(); - const int tint_symbol_5 = idx2(); - const int tint_symbol_save = tint_symbol_4; - const int tint_symbol_save_1 = tint_symbol_5; + const int tint_symbol_save = idx1(); + const int tint_symbol_save_1 = idx2(); const int tint_symbol_1 = idx3(); { buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) - 1))); @@ -51,10 +49,8 @@ void main() { { } { - const int tint_symbol_6 = idx4(); - const int tint_symbol_7 = idx5(); - const int tint_symbol_2_save = tint_symbol_6; - const int tint_symbol_2_save_1 = tint_symbol_7; + const int tint_symbol_2_save = idx4(); + const int tint_symbol_2_save_1 = idx5(); const int tint_symbol_3 = idx6(); buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) - 1))); } diff --git a/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl index 94574a100e..ad26e2f4ba 100644 --- a/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl @@ -37,10 +37,8 @@ int idx6() { } void main() { - const int tint_symbol_4 = idx1(); - const int tint_symbol_5 = idx2(); - const int tint_symbol_save = tint_symbol_4; - const int tint_symbol_save_1 = tint_symbol_5; + const int tint_symbol_save = idx1(); + const int tint_symbol_save_1 = idx2(); const int tint_symbol_1 = idx3(); { buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) - 1))); @@ -51,10 +49,8 @@ void main() { { } { - const int tint_symbol_6 = idx4(); - const int tint_symbol_7 = idx5(); - const int tint_symbol_2_save = tint_symbol_6; - const int tint_symbol_2_save_1 = tint_symbol_7; + const int tint_symbol_2_save = idx4(); + const int tint_symbol_2_save_1 = idx5(); const int tint_symbol_3 = idx6(); buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) - 1))); } diff --git a/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl index 74aa1b7422..dc0b8b1a82 100644 --- a/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl +++ b/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl @@ -37,10 +37,8 @@ int idx6() { } void main() { - const int tint_symbol_4 = idx1(); - const int tint_symbol_5 = idx2(); - const int tint_symbol_save = tint_symbol_4; - const int tint_symbol_save_1 = tint_symbol_5; + const int tint_symbol_save = idx1(); + const int tint_symbol_save_1 = idx2(); const int tint_symbol_1 = idx3(); { buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) + 1))); @@ -51,10 +49,8 @@ void main() { { } { - const int tint_symbol_6 = idx4(); - const int tint_symbol_7 = idx5(); - const int tint_symbol_2_save = tint_symbol_6; - const int tint_symbol_2_save_1 = tint_symbol_7; + const int tint_symbol_2_save = idx4(); + const int tint_symbol_2_save_1 = idx5(); const int tint_symbol_3 = idx6(); buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) + 1))); } diff --git a/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl index 74aa1b7422..dc0b8b1a82 100644 --- a/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl +++ b/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl @@ -37,10 +37,8 @@ int idx6() { } void main() { - const int tint_symbol_4 = idx1(); - const int tint_symbol_5 = idx2(); - const int tint_symbol_save = tint_symbol_4; - const int tint_symbol_save_1 = tint_symbol_5; + const int tint_symbol_save = idx1(); + const int tint_symbol_save_1 = idx2(); const int tint_symbol_1 = idx3(); { buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) + 1))); @@ -51,10 +49,8 @@ void main() { { } { - const int tint_symbol_6 = idx4(); - const int tint_symbol_7 = idx5(); - const int tint_symbol_2_save = tint_symbol_6; - const int tint_symbol_2_save_1 = tint_symbol_7; + const int tint_symbol_2_save = idx4(); + const int tint_symbol_2_save_1 = idx5(); const int tint_symbol_3 = idx6(); buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) + 1))); }