mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-11 06:29:11 +00:00
[spirv-reader] Unordered float compares
Unordered float compares are not supported directly by WGSL. Translate them as negated ordered compares. Bug: tint:3 Change-Id: I4fea7c924054cffc9a39a8be3b3d9f088d302114 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/21540 Reviewed-by: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
parent
4484fe128d
commit
9f7297c766
@ -232,6 +232,31 @@ ast::BinaryOp ConvertBinaryOp(SpvOp opcode) {
|
|||||||
return ast::BinaryOp::kNone;
|
return ast::BinaryOp::kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the given SPIR-V opcode is a floating point unordered comparison,
|
||||||
|
// then returns the binary float comparison for which it is the negation.
|
||||||
|
// Othewrise returns BinaryOp::kNone.
|
||||||
|
// @param opcode SPIR-V opcode
|
||||||
|
// @returns operation corresponding to negated version of the SPIR-V opcode
|
||||||
|
ast::BinaryOp NegatedFloatCompare(SpvOp opcode) {
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpFUnordEqual:
|
||||||
|
return ast::BinaryOp::kNotEqual;
|
||||||
|
case SpvOpFUnordNotEqual:
|
||||||
|
return ast::BinaryOp::kEqual;
|
||||||
|
case SpvOpFUnordLessThan:
|
||||||
|
return ast::BinaryOp::kGreaterThanEqual;
|
||||||
|
case SpvOpFUnordLessThanEqual:
|
||||||
|
return ast::BinaryOp::kGreaterThan;
|
||||||
|
case SpvOpFUnordGreaterThan:
|
||||||
|
return ast::BinaryOp::kLessThanEqual;
|
||||||
|
case SpvOpFUnordGreaterThanEqual:
|
||||||
|
return ast::BinaryOp::kLessThan;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ast::BinaryOp::kNone;
|
||||||
|
}
|
||||||
|
|
||||||
// @returns the merge block ID for the given basic block, or 0 if there is none.
|
// @returns the merge block ID for the given basic block, or 0 if there is none.
|
||||||
uint32_t MergeFor(const spvtools::opt::BasicBlock& bb) {
|
uint32_t MergeFor(const spvtools::opt::BasicBlock& bb) {
|
||||||
// Get the OpSelectionMerge or OpLoopMerge instruction, if any.
|
// Get the OpSelectionMerge or OpLoopMerge instruction, if any.
|
||||||
@ -1502,6 +1527,17 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
|
|||||||
std::make_unique<ast::AsExpression>(target_ty, operand(0).expr)};
|
std::make_unique<ast::AsExpression>(target_ty, operand(0).expr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto negated_op = NegatedFloatCompare(inst.opcode());
|
||||||
|
if (negated_op != ast::BinaryOp::kNone) {
|
||||||
|
auto arg0 = operand(0);
|
||||||
|
auto arg1 = operand(1);
|
||||||
|
auto binary_expr = std::make_unique<ast::BinaryExpression>(
|
||||||
|
negated_op, std::move(arg0.expr), std::move(arg1.expr));
|
||||||
|
auto negated_expr = std::make_unique<ast::UnaryOpExpression>(
|
||||||
|
ast::UnaryOp::kNot, std::move(binary_expr));
|
||||||
|
return {ast_type, std::move(negated_expr)};
|
||||||
|
}
|
||||||
|
|
||||||
// builtin readonly function
|
// builtin readonly function
|
||||||
// glsl.std.450 readonly function
|
// glsl.std.450 readonly function
|
||||||
|
|
||||||
|
@ -682,21 +682,434 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
"__vec_2__bool", AstFor("v2int_30_40"), "less_than_equal",
|
"__vec_2__bool", AstFor("v2int_30_40"), "less_than_equal",
|
||||||
AstFor("cast_v2uint_20_10")}));
|
AstFor("cast_v2uint_20_10")}));
|
||||||
|
|
||||||
|
using SpvFUnordTest = SpvParserTestBase<::testing::Test>;
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordEqual_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordEqual %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
not_equal
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordEqual_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordEqual %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
not_equal
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordNotEqual_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordNotEqual %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
equal
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordNotEqual_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordNotEqual %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
equal
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordLessThan_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordLessThan %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
greater_than_equal
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordLessThan_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordLessThan %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
greater_than_equal
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordLessThanEqual_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordLessThanEqual %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
greater_than
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordLessThanEqual_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordLessThanEqual %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
greater_than
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordGreaterThan_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordGreaterThan %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
less_than_equal
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordGreaterThan_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordGreaterThan %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
less_than_equal
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Scalar) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordGreaterThanEqual %bool %float_50 %float_60
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
less_than
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Vector) {
|
||||||
|
const auto assembly = CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
%entry = OpLabel
|
||||||
|
%1 = OpFUnordGreaterThanEqual %bool %v2float_50_60 %v2float_60_50
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto* p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
|
||||||
|
Variable{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
__bool
|
||||||
|
{
|
||||||
|
UnaryOp{
|
||||||
|
not
|
||||||
|
Binary{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
}
|
||||||
|
less_than
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{60.000000}
|
||||||
|
ScalarConstructor{50.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"))
|
||||||
|
<< ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(dneto): OpAny - likely builtin function TBD
|
// TODO(dneto): OpAny - likely builtin function TBD
|
||||||
// TODO(dneto): OpAll - likely builtin function TBD
|
// TODO(dneto): OpAll - likely builtin function TBD
|
||||||
// TODO(dneto): OpIsNan - likely builtin function TBD
|
// TODO(dneto): OpIsNan - likely builtin function TBD
|
||||||
// TODO(dneto): OpIsInf - likely builtin function TBD
|
// TODO(dneto): OpIsInf - likely builtin function TBD
|
||||||
// TODO(dneto): Kernel-guarded instructions.
|
// TODO(dneto): Kernel-guarded instructions.
|
||||||
// TODO(dneto): OpSelect - likely builtin function TBD
|
// TODO(dneto): OpSelect - likely builtin function TBD
|
||||||
//
|
|
||||||
// Unordered float inequalities: blocked pending the resolution of
|
|
||||||
// https://github.com/gpuweb/gpuweb/issues/706
|
|
||||||
// TODO(dneto): OpFUnordEqual
|
|
||||||
// TODO(dneto): OpFUnordNotEqual
|
|
||||||
// TODO(dneto): OpFUnordLessThan
|
|
||||||
// TODO(dneto): OpFUnordGreaterThan
|
|
||||||
// TODO(dneto): OpFUnordLessThanEqual
|
|
||||||
// TODO(dneto): OpFUnordGreaterThanEqual
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
|
Loading…
x
Reference in New Issue
Block a user