[spirv-reader][ir] Convert the `OpFUnord` instructions.
This CL converts the `OpFUnordEqual`, `OpFUnordNotEqual`,
`OpFUnordGreaterThan`, `OpFUnordGreaterThanEqual`, `OpFUnordLessThan`,
and `OpFUnordLessThanEqual` into the equivalent IR instructions.
Bug: 391485740, 391487150, 391487131, 391486668, 391486344, 391486006
Change-Id: I4140a05f9d09177e788e97c48e6df9bcdd4f40cc
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/226897
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/reader/parser/logical_test.cc b/src/tint/lang/spirv/reader/parser/logical_test.cc
index fd83e1c..630dadc 100644
--- a/src/tint/lang/spirv/reader/parser/logical_test.cc
+++ b/src/tint/lang/spirv/reader/parser/logical_test.cc
@@ -39,8 +39,8 @@
return out;
}
-using SpirvParser_LogicalTest = SpirvParserTestWithParam<SpirvLogicalParam>;
-TEST_P(SpirvParser_LogicalTest, FOrd_Scalar) {
+using SpirvParser_FOrdLogicalTest = SpirvParserTestWithParam<SpirvLogicalParam>;
+TEST_P(SpirvParser_FOrdLogicalTest, Scalar) {
auto params = GetParam();
EXPECT_IR(R"(
OpCapability Shader
@@ -76,7 +76,7 @@
)");
}
-TEST_P(SpirvParser_LogicalTest, FOrd_Vector) {
+TEST_P(SpirvParser_FOrdLogicalTest, Vector) {
auto params = GetParam();
EXPECT_IR(R"(
OpCapability Shader
@@ -113,7 +113,7 @@
}
INSTANTIATE_TEST_SUITE_P(SpirvParser,
- SpirvParser_LogicalTest,
+ SpirvParser_FOrdLogicalTest,
testing::Values(SpirvLogicalParam{"Equal", "eq"},
SpirvLogicalParam{"NotEqual", "neq"},
SpirvLogicalParam{"GreaterThan", "gt"},
@@ -121,5 +121,89 @@
SpirvLogicalParam{"LessThan", "lt"},
SpirvLogicalParam{"LessThanEqual", "lte"}));
+using SpirvParser_FUnordLogicalTest = SpirvParserTestWithParam<SpirvLogicalParam>;
+TEST_P(SpirvParser_FUnordLogicalTest, FOrd_Scalar) {
+ auto params = GetParam();
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %f32 = OpTypeFloat 32
+ %one = OpConstant %f32 1
+ %two = OpConstant %f32 2
+ %v2bool = OpTypeVector %bool 2
+ %v2float = OpTypeVector %f32 2
+ %v2one = OpConstantComposite %v2float %one %one
+ %v2two = OpConstantComposite %v2float %two %two
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %1 = OpFUnord)" +
+ params.spv_name + R"( %bool %one %two
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:bool = )" + params.wgsl_name +
+ R"( 1.0f, 2.0f
+ %3:bool = not %2
+ ret
+ }
+}
+)");
+}
+
+TEST_P(SpirvParser_FUnordLogicalTest, FOrd_Vector) {
+ auto params = GetParam();
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %f32 = OpTypeFloat 32
+ %one = OpConstant %f32 1
+ %two = OpConstant %f32 2
+ %v2bool = OpTypeVector %bool 2
+ %v2float = OpTypeVector %f32 2
+ %v2one = OpConstantComposite %v2float %one %one
+ %v2two = OpConstantComposite %v2float %two %two
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %1 = OpFUnord)" +
+ params.spv_name + R"( %v2bool %v2one %v2two
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:vec2<bool> = )" +
+ params.wgsl_name + R"( vec2<f32>(1.0f), vec2<f32>(2.0f)
+ %3:vec2<bool> = not %2
+ ret
+ }
+}
+)");
+}
+
+INSTANTIATE_TEST_SUITE_P(SpirvParser,
+ SpirvParser_FUnordLogicalTest,
+ testing::Values(SpirvLogicalParam{"Equal", "neq"},
+ SpirvLogicalParam{"NotEqual", "eq"},
+ SpirvLogicalParam{"GreaterThan", "lte"},
+ SpirvLogicalParam{"GreaterThanEqual", "lt"},
+ SpirvLogicalParam{"LessThan", "gte"},
+ SpirvLogicalParam{"LessThanEqual", "gt"}));
+
} // namespace
} // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index bc98553..045cbcc 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -740,6 +740,24 @@
case spv::Op::OpFOrdLessThanEqual:
EmitBinary(inst, core::BinaryOp::kLessThanEqual);
break;
+ case spv::Op::OpFUnordEqual:
+ EmitInvertedBinary(inst, core::BinaryOp::kNotEqual);
+ break;
+ case spv::Op::OpFUnordNotEqual:
+ EmitInvertedBinary(inst, core::BinaryOp::kEqual);
+ break;
+ case spv::Op::OpFUnordGreaterThan:
+ EmitInvertedBinary(inst, core::BinaryOp::kLessThanEqual);
+ break;
+ case spv::Op::OpFUnordGreaterThanEqual:
+ EmitInvertedBinary(inst, core::BinaryOp::kLessThan);
+ break;
+ case spv::Op::OpFUnordLessThan:
+ EmitInvertedBinary(inst, core::BinaryOp::kGreaterThanEqual);
+ break;
+ case spv::Op::OpFUnordLessThanEqual:
+ EmitInvertedBinary(inst, core::BinaryOp::kGreaterThan);
+ break;
case spv::Op::OpISub:
EmitSpirvExplicitBuiltinCall(inst, spirv::BuiltinFn::kSub);
break;
@@ -1256,6 +1274,18 @@
Emit(binary, inst.result_id());
}
+ /// @param inst the SPIR-V instruction
+ /// @param op the binary operator to use
+ void EmitInvertedBinary(const spvtools::opt::Instruction& inst, core::BinaryOp op) {
+ auto* lhs = Value(inst.GetSingleWordOperand(2));
+ auto* rhs = Value(inst.GetSingleWordOperand(3));
+ auto* binary = b_.Binary(op, Type(inst.type_id()), lhs, rhs);
+ EmitWithoutSpvResult(binary);
+
+ auto* res = b_.Not(Type(inst.type_id()), binary);
+ Emit(res, inst.result_id());
+ }
+
/// @param inst the SPIR-V instruction for OpCompositeExtract
void EmitCompositeExtract(const spvtools::opt::Instruction& inst) {
Vector<core::ir::Value*, 4> indices;