[hlsl] Polyfill the HLSL IR select builtin.
This Cl adds a polyfil for the `select` builtin and converts it to a
custom HLSL ternary instruction.
Bug: 42251045
Change-Id: Iecb0b6d6e10fdd48c2df332890f5757dedd22ccf
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/195374
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/hlsl/ir/BUILD.bazel b/src/tint/lang/hlsl/ir/BUILD.bazel
index 758aef2..b8a34ae 100644
--- a/src/tint/lang/hlsl/ir/BUILD.bazel
+++ b/src/tint/lang/hlsl/ir/BUILD.bazel
@@ -40,9 +40,11 @@
name = "ir",
srcs = [
"builtin_call.cc",
+ "ternary.cc",
],
hdrs = [
"builtin_call.h",
+ "ternary.h",
],
deps = [
"//src/tint/api/common",
@@ -75,6 +77,7 @@
alwayslink = True,
srcs = [
"builtin_call_test.cc",
+ "ternary_test.cc",
],
deps = [
"//src/tint/api/common",
diff --git a/src/tint/lang/hlsl/ir/BUILD.cmake b/src/tint/lang/hlsl/ir/BUILD.cmake
index c94d5f4..f89052f 100644
--- a/src/tint/lang/hlsl/ir/BUILD.cmake
+++ b/src/tint/lang/hlsl/ir/BUILD.cmake
@@ -41,6 +41,8 @@
tint_add_target(tint_lang_hlsl_ir lib
lang/hlsl/ir/builtin_call.cc
lang/hlsl/ir/builtin_call.h
+ lang/hlsl/ir/ternary.cc
+ lang/hlsl/ir/ternary.h
)
tint_target_add_dependencies(tint_lang_hlsl_ir lib
@@ -73,6 +75,7 @@
################################################################################
tint_add_target(tint_lang_hlsl_ir_test test
lang/hlsl/ir/builtin_call_test.cc
+ lang/hlsl/ir/ternary_test.cc
)
tint_target_add_dependencies(tint_lang_hlsl_ir_test test
diff --git a/src/tint/lang/hlsl/ir/BUILD.gn b/src/tint/lang/hlsl/ir/BUILD.gn
index 2cb3e39..21087ee 100644
--- a/src/tint/lang/hlsl/ir/BUILD.gn
+++ b/src/tint/lang/hlsl/ir/BUILD.gn
@@ -46,6 +46,8 @@
sources = [
"builtin_call.cc",
"builtin_call.h",
+ "ternary.cc",
+ "ternary.h",
]
deps = [
"${tint_src_dir}/api/common",
@@ -73,7 +75,10 @@
}
if (tint_build_unittests) {
tint_unittests_source_set("unittests") {
- sources = [ "builtin_call_test.cc" ]
+ sources = [
+ "builtin_call_test.cc",
+ "ternary_test.cc",
+ ]
deps = [
"${tint_src_dir}:gmock_and_gtest",
"${tint_src_dir}/api/common",
diff --git a/src/tint/lang/hlsl/ir/ternary.cc b/src/tint/lang/hlsl/ir/ternary.cc
new file mode 100644
index 0000000..64af60a10
--- /dev/null
+++ b/src/tint/lang/hlsl/ir/ternary.cc
@@ -0,0 +1,49 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/ir/ternary.h"
+
+#include "src/tint/lang/core/ir/module.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::hlsl::ir::Ternary);
+
+namespace tint::hlsl::ir {
+
+Ternary::Ternary(core::ir::InstructionResult* result, VectorRef<core::ir::Value*> args) {
+ AddResult(result);
+ AddOperands(ArgsOperandOffset(), args);
+}
+
+Ternary::~Ternary() = default;
+
+Ternary* Ternary::Clone(core::ir::CloneContext& ctx) {
+ auto new_result = ctx.Clone(Result(0));
+ auto new_args = ctx.Remap<Ternary::kDefaultNumOperands>(operands_);
+ return ctx.ir.allocators.instructions.Create<Ternary>(new_result, new_args);
+}
+
+} // namespace tint::hlsl::ir
diff --git a/src/tint/lang/hlsl/ir/ternary.h b/src/tint/lang/hlsl/ir/ternary.h
new file mode 100644
index 0000000..136dccd
--- /dev/null
+++ b/src/tint/lang/hlsl/ir/ternary.h
@@ -0,0 +1,66 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_HLSL_IR_TERNARY_H_
+#define SRC_TINT_LANG_HLSL_IR_TERNARY_H_
+
+#include <string>
+
+#include "src/tint/lang/core/ir/call.h"
+#include "src/tint/lang/core/ir/clone_context.h"
+#include "src/tint/lang/core/ir/instruction_result.h"
+#include "src/tint/lang/core/ir/value.h"
+#include "src/tint/utils/rtti/castable.h"
+
+namespace tint::hlsl::ir {
+
+/// A ternary instruction in the IR.
+class Ternary final : public Castable<Ternary, core::ir::Call> {
+ public:
+ /// Constructor
+ Ternary(core::ir::InstructionResult* result, VectorRef<core::ir::Value*> args);
+ ~Ternary() override;
+
+ /// @copydoc Instruction::Clone()
+ Ternary* Clone(core::ir::CloneContext& ctx) override;
+
+ /// @returns the false value
+ core::ir::Value* False() const { return operands_[ArgsOperandOffset() + 0]; }
+
+ /// @returns the true value
+ core::ir::Value* True() const { return operands_[ArgsOperandOffset() + 1]; }
+
+ /// @returns the compare value
+ core::ir::Value* Cmp() const { return operands_[ArgsOperandOffset() + 2]; }
+
+ /// @returns the friendly name for the instruction
+ std::string FriendlyName() const override { return "hlsl.ternary"; }
+};
+
+} // namespace tint::hlsl::ir
+
+#endif // SRC_TINT_LANG_HLSL_IR_TERNARY_H_
diff --git a/src/tint/lang/hlsl/ir/ternary_test.cc b/src/tint/lang/hlsl/ir/ternary_test.cc
new file mode 100644
index 0000000..13bb252
--- /dev/null
+++ b/src/tint/lang/hlsl/ir/ternary_test.cc
@@ -0,0 +1,95 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/hlsl/ir/ternary.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/lang/core/ir/ir_helper_test.h"
+
+using namespace tint::core::fluent_types; // NOLINT
+using namespace tint::core::number_suffixes; // NOLINT
+
+namespace tint::hlsl::ir {
+namespace {
+
+using HlslIRTest = core::ir::IRTestHelper;
+using HlslIRDeathTest = HlslIRTest;
+
+TEST_F(HlslIRTest, SetsUsage) {
+ auto* true_ = b.Constant(u32(1));
+ auto* false_ = b.Constant(u32(2));
+ auto* cmp = b.Constant(true);
+
+ Vector<core::ir::Value*, 3> args = {false_, true_, cmp};
+ auto* t = b.ir.allocators.instructions.Create<Ternary>(b.InstructionResult(ty.u32()), args);
+
+ EXPECT_THAT(false_->Usages(), testing::UnorderedElementsAre(core::ir::Usage{t, 0u}));
+ EXPECT_THAT(true_->Usages(), testing::UnorderedElementsAre(core::ir::Usage{t, 1u}));
+ EXPECT_THAT(cmp->Usages(), testing::UnorderedElementsAre(core::ir::Usage{t, 2u}));
+}
+
+TEST_F(HlslIRTest, Result) {
+ auto* true_ = b.Constant(u32(1));
+ auto* false_ = b.Constant(u32(2));
+ auto* cmp = b.Constant(true);
+
+ Vector<core::ir::Value*, 3> args = {false_, true_, cmp};
+ auto* t = b.ir.allocators.instructions.Create<Ternary>(b.InstructionResult(ty.u32()), args);
+
+ EXPECT_EQ(t->Results().Length(), 1u);
+
+ EXPECT_TRUE(t->Result(0)->Is<core::ir::InstructionResult>());
+ EXPECT_EQ(t, t->Result(0)->Instruction());
+}
+
+TEST_F(HlslIRTest, Clone) {
+ auto* true_ = b.Constant(u32(1));
+ auto* false_ = b.Constant(u32(2));
+ auto* cmp = b.Constant(true);
+
+ Vector<core::ir::Value*, 3> args = {false_, true_, cmp};
+ auto* t = b.ir.allocators.instructions.Create<Ternary>(b.InstructionResult(ty.u32()), args);
+
+ auto* new_t = clone_ctx.Clone(t);
+
+ EXPECT_NE(t, new_t);
+
+ EXPECT_NE(t->Result(0), new_t->Result(0));
+ EXPECT_EQ(ty.u32(), new_t->Result(0)->Type());
+
+ EXPECT_NE(nullptr, new_t->True());
+ EXPECT_EQ(t->True(), new_t->True());
+
+ EXPECT_NE(nullptr, new_t->False());
+ EXPECT_EQ(t->False(), new_t->False());
+
+ EXPECT_NE(nullptr, new_t->Cmp());
+ EXPECT_EQ(t->Cmp(), new_t->Cmp());
+}
+
+} // namespace
+} // namespace tint::hlsl::ir
diff --git a/src/tint/lang/hlsl/writer/BUILD.bazel b/src/tint/lang/hlsl/writer/BUILD.bazel
index 38b2173..f1743b9 100644
--- a/src/tint/lang/hlsl/writer/BUILD.bazel
+++ b/src/tint/lang/hlsl/writer/BUILD.bazel
@@ -92,6 +92,7 @@
"access_test.cc",
"binary_test.cc",
"bitcast_test.cc",
+ "builtin_test.cc",
"constant_test.cc",
"construct_test.cc",
"convert_test.cc",
diff --git a/src/tint/lang/hlsl/writer/BUILD.cmake b/src/tint/lang/hlsl/writer/BUILD.cmake
index a0b853c..2ea842e 100644
--- a/src/tint/lang/hlsl/writer/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/BUILD.cmake
@@ -103,6 +103,7 @@
lang/hlsl/writer/access_test.cc
lang/hlsl/writer/binary_test.cc
lang/hlsl/writer/bitcast_test.cc
+ lang/hlsl/writer/builtin_test.cc
lang/hlsl/writer/constant_test.cc
lang/hlsl/writer/construct_test.cc
lang/hlsl/writer/convert_test.cc
diff --git a/src/tint/lang/hlsl/writer/BUILD.gn b/src/tint/lang/hlsl/writer/BUILD.gn
index 3e6fd99..36e2f40 100644
--- a/src/tint/lang/hlsl/writer/BUILD.gn
+++ b/src/tint/lang/hlsl/writer/BUILD.gn
@@ -95,6 +95,7 @@
"access_test.cc",
"binary_test.cc",
"bitcast_test.cc",
+ "builtin_test.cc",
"constant_test.cc",
"construct_test.cc",
"convert_test.cc",
diff --git a/src/tint/lang/hlsl/writer/builtin_test.cc b/src/tint/lang/hlsl/writer/builtin_test.cc
new file mode 100644
index 0000000..843951e
--- /dev/null
+++ b/src/tint/lang/hlsl/writer/builtin_test.cc
@@ -0,0 +1,87 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/core/fluent_types.h"
+#include "src/tint/lang/core/ir/function.h"
+#include "src/tint/lang/core/number.h"
+#include "src/tint/lang/hlsl/writer/helper_test.h"
+
+#include "gtest/gtest.h"
+
+using namespace tint::core::fluent_types; // NOLINT
+using namespace tint::core::number_suffixes; // NOLINT
+
+namespace tint::hlsl::writer {
+namespace {
+
+TEST_F(HlslWriterTest, SelectScalar) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* x = b.Let("x", 1_i);
+ auto* y = b.Let("y", 2_i);
+
+ auto* c = b.Call(ty.i32(), core::BuiltinFn::kSelect, x, y, true);
+ b.Let("w", c);
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ int x = 1;
+ int y = 2;
+ int w = ((true) ? (y) : (x));
+}
+
+)");
+}
+
+TEST_F(HlslWriterTest, SelectVector) {
+ auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+ b.Append(func->Block(), [&] {
+ auto* x = b.Let("x", b.Construct<vec2<i32>>(1_i, 2_i));
+ auto* y = b.Let("y", b.Construct<vec2<i32>>(3_i, 4_i));
+ auto* cmp = b.Construct<vec2<bool>>(true, false);
+
+ auto* c = b.Call(ty.vec2<i32>(), core::BuiltinFn::kSelect, x, y, cmp);
+ b.Let("w", c);
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.hlsl;
+ EXPECT_EQ(output_.hlsl, R"(
+void foo() {
+ int2 x = int2(1, 2);
+ int2 y = int2(3, 4);
+ int2 w = ((bool2(true, false)) ? (y) : (x));
+}
+
+)");
+}
+
+} // namespace
+} // namespace tint::hlsl::writer
diff --git a/src/tint/lang/hlsl/writer/printer/printer.cc b/src/tint/lang/hlsl/writer/printer/printer.cc
index 79847cb..bbbb103 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.cc
+++ b/src/tint/lang/hlsl/writer/printer/printer.cc
@@ -103,6 +103,7 @@
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/lang/hlsl/ir/builtin_call.h"
+#include "src/tint/lang/hlsl/ir/ternary.h"
#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/containers/map.h"
#include "src/tint/utils/generator/text_generator.h"
@@ -625,13 +626,24 @@
[&](const core::ir::Var* var) { out << NameOf(var->Result(0)); }, //
[&](const hlsl::ir::BuiltinCall* c) { EmitHlslBuiltinCall(out, c); }, //
-
+ [&](const hlsl::ir::Ternary* t) { EmitTernary(out, t); }, //
TINT_ICE_ON_NO_MATCH);
},
[&](const core::ir::FunctionParam* p) { out << NameOf(p); }, //
TINT_ICE_ON_NO_MATCH);
}
+ void EmitTernary(StringStream& out, const hlsl::ir::Ternary* t) {
+ out << "((";
+ EmitValue(out, t->Cmp());
+ out << ") ? (";
+ EmitValue(out, t->True());
+ out << ") : (";
+ EmitValue(out, t->False());
+ out << "))";
+ return;
+ }
+
void EmitHlslBuiltinCall(StringStream& out, const hlsl::ir::BuiltinCall* c) {
out << c->Func() << "(";
bool needs_comma = false;
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index eddb32c..b04094d 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -37,6 +37,7 @@
#include "src/tint/lang/core/type/manager.h"
#include "src/tint/lang/hlsl/builtin_fn.h"
#include "src/tint/lang/hlsl/ir/builtin_call.h"
+#include "src/tint/lang/hlsl/ir/ternary.h"
#include "src/tint/utils/containers/hashmap.h"
#include "src/tint/utils/math/hash.h"
@@ -68,9 +69,21 @@
void Process() {
// Find the bitcasts that need replacing.
Vector<core::ir::Bitcast*, 4> bitcast_worklist;
+ Vector<core::ir::CoreBuiltinCall*, 4> call_worklist;
for (auto* inst : ir.Instructions()) {
if (auto* bitcast = inst->As<core::ir::Bitcast>()) {
bitcast_worklist.Push(bitcast);
+ continue;
+ }
+ if (auto* call = inst->As<core::ir::CoreBuiltinCall>()) {
+ switch (call->Func()) {
+ case core::BuiltinFn::kSelect:
+ call_worklist.Push(call);
+ break;
+ default:
+ break;
+ }
+ continue;
}
}
@@ -90,6 +103,25 @@
ReplaceBitcastWithAs(bitcast);
}
}
+
+ // Replace the builtin calls that we found
+ for (auto* call : call_worklist) {
+ switch (call->Func()) {
+ case core::BuiltinFn::kSelect:
+ Select(call);
+ break;
+ default:
+ TINT_UNREACHABLE();
+ }
+ }
+ }
+
+ void Select(core::ir::CoreBuiltinCall* call) {
+ Vector<core::ir::Value*, 4> args = call->Args();
+ auto* ternary =
+ b.ir.allocators.instructions.Create<hlsl::ir::Ternary>(call->DetachResult(), args);
+ ternary->InsertBefore(call);
+ call->Destroy();
}
/// Replaces an identity bitcast result with the value.