[spirv-reader][ir] Support more binary operators Add support for more of the SPIR-V instructions which convert to binary operators. This includes: * OpFDiv * OpSDiv * OpUDiv * OpIMul * OpFRem * OpUMod * OpSMod * OpSRem * OpFSub * OpISub * OpVectorTimesScalar * OpMatrixTimesScalar * OpVectorTimesMatrix * OpMatrixTimesVector * OpMatrixTimesMatrix Bug: 42250952 Change-Id: I58f187578a85569afd4e9bd5ad9eb262e4bf6099 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/220499 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/reader/parser/binary_test.cc b/src/tint/lang/spirv/reader/parser/binary_test.cc index bf5d71a..dfe3c6d 100644 --- a/src/tint/lang/spirv/reader/parser/binary_test.cc +++ b/src/tint/lang/spirv/reader/parser/binary_test.cc
@@ -112,6 +112,28 @@ "%5:vec4<f32> = add %3, %4", }, + // OpFSub + BinaryCase{ + "f16", + "OpFSub", + "%5:f16 = sub %3, %4", + }, + BinaryCase{ + "f32", + "OpFSub", + "%5:f32 = sub %3, %4", + }, + BinaryCase{ + "vec3h", + "OpFSub", + "%5:vec3<f16> = sub %3, %4", + }, + BinaryCase{ + "vec4f", + "OpFSub", + "%5:vec4<f32> = sub %3, %4", + }, + // OpFMul BinaryCase{ "f16", @@ -134,6 +156,50 @@ "%5:vec4<f32> = mul %3, %4", }, + // OpFDiv + BinaryCase{ + "f16", + "OpFDiv", + "%5:f16 = div %3, %4", + }, + BinaryCase{ + "f32", + "OpFDiv", + "%5:f32 = div %3, %4", + }, + BinaryCase{ + "vec3h", + "OpFDiv", + "%5:vec3<f16> = div %3, %4", + }, + BinaryCase{ + "vec4f", + "OpFDiv", + "%5:vec4<f32> = div %3, %4", + }, + + // OpFRem + BinaryCase{ + "f16", + "OpFRem", + "%5:f16 = mod %3, %4", + }, + BinaryCase{ + "f32", + "OpFRem", + "%5:f32 = mod %3, %4", + }, + BinaryCase{ + "vec3h", + "OpFRem", + "%5:vec3<f16> = mod %3, %4", + }, + BinaryCase{ + "vec4f", + "OpFRem", + "%5:vec4<f32> = mod %3, %4", + }, + // OpIAdd BinaryCase{ "i32", @@ -154,8 +220,283 @@ "vec4u", "OpIAdd", "%5:vec4<u32> = add %3, %4", + }, + + // OpISub + BinaryCase{ + "i32", + "OpISub", + "%5:i32 = sub %3, %4", + }, + BinaryCase{ + "u32", + "OpISub", + "%5:u32 = sub %3, %4", + }, + BinaryCase{ + "vec3i", + "OpISub", + "%5:vec3<i32> = sub %3, %4", + }, + BinaryCase{ + "vec4u", + "OpISub", + "%5:vec4<u32> = sub %3, %4", + }, + + // OpIMul + BinaryCase{ + "i32", + "OpIMul", + "%5:i32 = mul %3, %4", + }, + BinaryCase{ + "u32", + "OpIMul", + "%5:u32 = mul %3, %4", + }, + BinaryCase{ + "vec3i", + "OpIMul", + "%5:vec3<i32> = mul %3, %4", + }, + BinaryCase{ + "vec4u", + "OpIMul", + "%5:vec4<u32> = mul %3, %4", + }, + + // OpSDiv + BinaryCase{ + "i32", + "OpSDiv", + "%5:i32 = div %3, %4", + }, + BinaryCase{ + "u32", + "OpSDiv", + "%5:u32 = div %3, %4", + }, + BinaryCase{ + "vec3i", + "OpSDiv", + "%5:vec3<i32> = div %3, %4", + }, + BinaryCase{ + "vec4u", + "OpSDiv", + "%5:vec4<u32> = div %3, %4", + }, + + // OpSMod + BinaryCase{ + "i32", + "OpSMod", + "%5:i32 = mod %3, %4", + }, + BinaryCase{ + "u32", + "OpSMod", + "%5:u32 = mod %3, %4", + }, + BinaryCase{ + "vec3i", + "OpSMod", + "%5:vec3<i32> = mod %3, %4", + }, + BinaryCase{ + "vec4u", + "OpSMod", + "%5:vec4<u32> = mod %3, %4", + }, + + // OpSRem + BinaryCase{ + "i32", + "OpSRem", + "%5:i32 = mod %3, %4", + }, + BinaryCase{ + "u32", + "OpSRem", + "%5:u32 = mod %3, %4", + }, + BinaryCase{ + "vec3i", + "OpSRem", + "%5:vec3<i32> = mod %3, %4", + }, + BinaryCase{ + "vec4u", + "OpSRem", + "%5:vec4<u32> = mod %3, %4", + }, + + // OpUDiv + BinaryCase{ + "u32", + "OpUDiv", + "%5:u32 = div %3, %4", + }, + BinaryCase{ + "vec4u", + "OpUDiv", + "%5:vec4<u32> = div %3, %4", + }, + + // OpUMod + BinaryCase{ + "u32", + "OpUMod", + "%5:u32 = mod %3, %4", + }, + BinaryCase{ + "vec4u", + "OpUMod", + "%5:vec4<u32> = mod %3, %4", }), PrintBuiltinCase); +struct VectorMatTimesCase { + std::string lhs_type; + std::string rhs_type; + std::string res_type; + std::string spirv_opcode; + std::string ir; +}; +std::string PrintVectorMatTimesCase(testing::TestParamInfo<VectorMatTimesCase> bc) { + return bc.param.spirv_opcode + "_" + bc.param.lhs_type + "_" + bc.param.rhs_type; +} + +using VectorScalarTest = SpirvParserTestWithParam<VectorMatTimesCase>; + +TEST_P(VectorScalarTest, All) { + 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 + %f16 = OpTypeFloat 16 + %f32 = OpTypeFloat 32 + %vec3h = OpTypeVector %f16 3 + %vec3f = OpTypeVector %f32 3 + %mat3x3f = OpTypeMatrix %vec3f 3 + %mat3x3h = OpTypeMatrix %vec3h 3 + %ep_type = OpTypeFunction %void + %fn_type = OpTypeFunction %)" + + params.res_type + " %" + params.lhs_type + " %" + params.rhs_type + R"( + %main = OpFunction %void None %ep_type + %main_start = OpLabel + OpReturn + OpFunctionEnd + + %foo = OpFunction %)" + + params.res_type + " " + R"( None %fn_type + %lhs = OpFunctionParameter %)" + + params.lhs_type + " " + R"( + %rhs = OpFunctionParameter %)" + + params.rhs_type + " " + R"( + %foo_start = OpLabel + %result = )" + + params.spirv_opcode + R"( %)" + params.res_type + " " + R"( %lhs %rhs + OpReturnValue %result + OpFunctionEnd +)", + R"( + $B2: { + )" + params.ir + + R"( + ret %5 + } +)"); +} + +INSTANTIATE_TEST_SUITE_P(SpirvParser, + VectorScalarTest, + testing::Values( + // OpVectorTimesScalar + VectorMatTimesCase{ + "vec3h", + "f16", + "vec3h", + "OpVectorTimesScalar", + "%5:vec3<f16> = mul %3, %4", + }, + VectorMatTimesCase{ + "vec3f", + "f32", + "vec3f", + "OpVectorTimesScalar", + "%5:vec3<f32> = mul %3, %4", + }, + + // OpMatrixTimesScalar + VectorMatTimesCase{ + "mat3x3h", + "f16", + "mat3x3h", + "OpMatrixTimesScalar", + "%5:mat3x3<f16> = mul %3, %4", + }, + VectorMatTimesCase{ + "mat3x3f", + "f32", + "mat3x3f", + "OpMatrixTimesScalar", + "%5:mat3x3<f32> = mul %3, %4", + }, + + // OpMatrixTimesVector + VectorMatTimesCase{ + "mat3x3h", + "vec3h", + "vec3h", + "OpMatrixTimesVector", + "%5:vec3<f16> = mul %3, %4", + }, + VectorMatTimesCase{ + "mat3x3f", + "vec3f", + "vec3f", + "OpMatrixTimesVector", + "%5:vec3<f32> = mul %3, %4", + }, + + // OpVectorTimesMatrix + VectorMatTimesCase{ + "vec3h", + "mat3x3h", + "vec3h", + "OpVectorTimesMatrix", + "%5:vec3<f16> = mul %3, %4", + }, + VectorMatTimesCase{ + "vec3f", + "mat3x3f", + "vec3f", + "OpVectorTimesMatrix", + "%5:vec3<f32> = mul %3, %4", + }, + + // OpMatrixTimesMatrix + VectorMatTimesCase{ + "mat3x3h", + "mat3x3h", + "mat3x3h", + "OpMatrixTimesMatrix", + "%5:mat3x3<f16> = mul %3, %4", + }, + VectorMatTimesCase{ + "mat3x3f", + "mat3x3f", + "mat3x3f", + "OpMatrixTimesMatrix", + "%5:mat3x3<f32> = mul %3, %4", + }), + PrintVectorMatTimesCase); + } // 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 20cbd4d..327566c 100644 --- a/src/tint/lang/spirv/reader/parser/parser.cc +++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -528,17 +528,36 @@ EmitCompositeExtract(inst); break; case spv::Op::OpFAdd: + case spv::Op::OpIAdd: EmitBinary(inst, core::BinaryOp::kAdd); break; + case spv::Op::OpFDiv: + case spv::Op::OpSDiv: + case spv::Op::OpUDiv: + EmitBinary(inst, core::BinaryOp::kDivide); + break; case spv::Op::OpFMul: + case spv::Op::OpIMul: + case spv::Op::OpVectorTimesScalar: + case spv::Op::OpMatrixTimesScalar: + case spv::Op::OpVectorTimesMatrix: + case spv::Op::OpMatrixTimesVector: + case spv::Op::OpMatrixTimesMatrix: EmitBinary(inst, core::BinaryOp::kMultiply); break; + case spv::Op::OpFRem: + case spv::Op::OpUMod: + case spv::Op::OpSMod: + case spv::Op::OpSRem: + EmitBinary(inst, core::BinaryOp::kModulo); + break; + case spv::Op::OpFSub: + case spv::Op::OpISub: + EmitBinary(inst, core::BinaryOp::kSubtract); + break; case spv::Op::OpFunctionCall: EmitFunctionCall(inst); break; - case spv::Op::OpIAdd: - EmitBinary(inst, core::BinaryOp::kAdd); - break; case spv::Op::OpLoad: Emit(b_.Load(Value(inst.GetSingleWordOperand(2))), inst.result_id()); break;