[spirv-reader] Add ConvertSToF, ConvertUToF

Bug: tint:3
Change-Id: I28bcc109a207ef6f5225b9ea707bff11b1b6fd50
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23420
Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
David Neto 2020-06-17 20:48:56 +00:00 committed by dan sinclair
parent 3238eaa3b1
commit b961e0069b
4 changed files with 236 additions and 4 deletions

View File

@ -35,6 +35,7 @@
#include "src/ast/break_statement.h" #include "src/ast/break_statement.h"
#include "src/ast/call_expression.h" #include "src/ast/call_expression.h"
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/cast_expression.h"
#include "src/ast/continue_statement.h" #include "src/ast/continue_statement.h"
#include "src/ast/else_statement.h" #include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h" #include "src/ast/fallthrough_statement.h"
@ -2533,6 +2534,9 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
if (opcode == SpvOpVectorShuffle) { if (opcode == SpvOpVectorShuffle) {
return MakeVectorShuffle(inst); return MakeVectorShuffle(inst);
} }
if (opcode == SpvOpConvertSToF || opcode == SpvOpConvertUToF) {
return MakeNumericConversion(inst);
}
// builtin readonly function // builtin readonly function
// glsl.std.450 readonly function // glsl.std.450 readonly function
@ -2545,8 +2549,6 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue(
// OpSatConvertUToS // OpSatConvertUToS
// OpConvertFToS // OpConvertFToS
// OpConvertFToU // OpConvertFToU
// OpConvertSToF
// OpConvertUToF
// OpUConvert // Only needed when multiple widths supported // OpUConvert // Only needed when multiple widths supported
// OpSConvert // Only needed when multiple widths supported // OpSConvert // Only needed when multiple widths supported
// OpFConvert // Only needed when multiple widths supported // OpFConvert // Only needed when multiple widths supported
@ -2893,6 +2895,15 @@ void FunctionEmitter::RegisterValuesNeedingNamedDefinition() {
} }
} }
TypedExpression FunctionEmitter::MakeNumericConversion(
const spvtools::opt::Instruction& inst) {
auto* result_type = parser_impl_.ConvertType(inst.type_id());
auto arg_expr = MakeOperand(inst, 0);
return {result_type, std::make_unique<ast::CastExpression>(
result_type, std::move(arg_expr.expr))};
}
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader
} // namespace tint } // namespace tint

View File

@ -463,6 +463,11 @@ class FunctionEmitter {
/// @returns an AST expression for the instruction, or nullptr. /// @returns an AST expression for the instruction, or nullptr.
TypedExpression MakeVectorShuffle(const spvtools::opt::Instruction& inst); TypedExpression MakeVectorShuffle(const spvtools::opt::Instruction& inst);
/// Creates an expression for a numeric conversion.
/// @param inst a numeric conversion instruction
/// @returns an AST expression for the instruction, or nullptr.
TypedExpression MakeNumericConversion(const spvtools::opt::Instruction& inst);
/// Gets the block info for a block ID, if any exists /// Gets the block info for a block ID, if any exists
/// @param id the SPIR-V ID of the OpLabel instruction starting the block /// @param id the SPIR-V ID of the OpLabel instruction starting the block
/// @returns the block info for the given ID, if it exists, or nullptr /// @returns the block info for the given ID, if it exists, or nullptr

View File

@ -119,10 +119,224 @@ TEST_F(SpvUnaryConversionTest, Bitcast_Vector) {
<< ToString(fe.ast_body()); << ToString(fe.ast_body());
} }
TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromSigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %int %int_30
%1 = OpConvertSToF %float %30
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
__f32
{
Cast<__f32>(
Identifier{x_30}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertSToF_Scalar_FromUnsigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %uint %uint_10
%1 = OpConvertSToF %float %30
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
__f32
{
Cast<__f32>(
As<__i32>{
Identifier{x_30}
}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromSigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %v2int %v2int_30_40
%1 = OpConvertSToF %v2float %30
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
__vec_2__f32
{
Cast<__vec_2__f32>(
Identifier{x_30}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertSToF_Vector_FromUnsigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %v2uint %v2uint_10_20
%1 = OpConvertSToF %v2float %30
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
__vec_2__f32
{
Cast<__vec_2__f32>(
As<__vec_2__i32>{
Identifier{x_30}
}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromSigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %int %int_30
%1 = OpConvertUToF %float %30
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
__f32
{
Cast<__f32>(
As<__u32>{
Identifier{x_30}
}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertUToF_Scalar_FromUnsigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %uint %uint_10
%1 = OpConvertUToF %float %30
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
__f32
{
Cast<__f32>(
Identifier{x_30}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromSigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %v2int %v2int_30_40
%1 = OpConvertUToF %v2float %30
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
__vec_2__f32
{
Cast<__vec_2__f32>(
As<__vec_2__u32>{
Identifier{x_30}
}
)
}
})"))
<< ToString(fe.ast_body());
}
TEST_F(SpvUnaryConversionTest, ConvertUToF_Vector_FromUnsigned) {
const auto assembly = CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
%30 = OpCopyObject %v2uint %v2uint_10_20
%1 = OpConvertUToF %v2float %30
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
__vec_2__f32
{
Cast<__vec_2__f32>(
Identifier{x_30}
)
}
})"))
<< ToString(fe.ast_body());
}
// TODO(dneto): OpConvertFToU // TODO(dneto): OpConvertFToU
// TODO(dneto): OpConvertFToS // TODO(dneto): OpConvertFToS
// TODO(dneto): OpConvertUToF
// TODO(dneto): OpConvertSToF
// TODO(dneto): OpSConvert // only if multiple widths // TODO(dneto): OpSConvert // only if multiple widths
// TODO(dneto): OpUConvert // only if multiple widths // TODO(dneto): OpUConvert // only if multiple widths
// TODO(dneto): OpFConvert // only if multiple widths // TODO(dneto): OpFConvert // only if multiple widths

View File

@ -133,6 +133,7 @@ bool AssumesSignedOperands(SpvOp opcode) {
case SpvOpSLessThanEqual: case SpvOpSLessThanEqual:
case SpvOpSGreaterThan: case SpvOpSGreaterThan:
case SpvOpSGreaterThanEqual: case SpvOpSGreaterThanEqual:
case SpvOpConvertSToF:
return true; return true;
default: default:
break; break;
@ -149,6 +150,7 @@ bool AssumesUnsignedOperands(SpvOp opcode) {
case SpvOpULessThanEqual: case SpvOpULessThanEqual:
case SpvOpUGreaterThan: case SpvOpUGreaterThan:
case SpvOpUGreaterThanEqual: case SpvOpUGreaterThanEqual:
case SpvOpConvertUToF:
return true; return true;
default: default:
break; break;