[spirv-reader] Add OpNot
Bug: tint:3 Change-Id: I4fe2f7ba0e8597ac5bed1e4817e3ccc38dc06a82 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19885 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
00feb1ca60
commit
b4c49680b5
|
@ -51,7 +51,7 @@ bool GetUnaryOp(SpvOp opcode, ast::UnaryOp* ast_unary_op) {
|
|||
*ast_unary_op = ast::UnaryOp::kNegation;
|
||||
return true;
|
||||
case SpvOpLogicalNot:
|
||||
// TODO(dneto): SpvOpNot
|
||||
case SpvOpNot:
|
||||
*ast_unary_op = ast::UnaryOp::kNot;
|
||||
return true;
|
||||
default:
|
||||
|
|
|
@ -299,6 +299,39 @@ TEST_F(SpvUnaryArithTest, SNegate_SignedVec_UnsignedVec) {
|
|||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, SNegate_UnsignedVec_SignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpSNegate %v2uint %v2int_30_40
|
||||
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__u32
|
||||
{
|
||||
As<__vec_2__u32>{
|
||||
UnaryOp{
|
||||
negation
|
||||
TypeConstructor{
|
||||
__vec_2__i32
|
||||
ScalarConstructor{30}
|
||||
ScalarConstructor{40}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, SNegate_UnsignedVec_UnsignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
@ -1080,6 +1113,251 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
"__vec_2__i32", AstFor("v2int_40_30"), "xor",
|
||||
AstFor("v2uint_20_10")}));
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_Int_Int) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %int %int_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
|
||||
__i32
|
||||
{
|
||||
UnaryOp{
|
||||
not
|
||||
ScalarConstructor{30}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_Int_Uint) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %int %uint_10
|
||||
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
|
||||
__i32
|
||||
{
|
||||
As<__i32>{
|
||||
UnaryOp{
|
||||
not
|
||||
ScalarConstructor{10}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_Uint_Int) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %uint %int_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
|
||||
__u32
|
||||
{
|
||||
As<__u32>{
|
||||
UnaryOp{
|
||||
not
|
||||
ScalarConstructor{30}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_Uint_Uint) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %uint %uint_10
|
||||
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
|
||||
__u32
|
||||
{
|
||||
UnaryOp{
|
||||
not
|
||||
ScalarConstructor{10}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_SignedVec_SignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %v2int %v2int_30_40
|
||||
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__i32
|
||||
{
|
||||
UnaryOp{
|
||||
not
|
||||
TypeConstructor{
|
||||
__vec_2__i32
|
||||
ScalarConstructor{30}
|
||||
ScalarConstructor{40}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_SignedVec_UnsignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %v2int %v2uint_10_20
|
||||
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__i32
|
||||
{
|
||||
As<__vec_2__i32>{
|
||||
UnaryOp{
|
||||
not
|
||||
TypeConstructor{
|
||||
__vec_2__u32
|
||||
ScalarConstructor{10}
|
||||
ScalarConstructor{20}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
TEST_F(SpvUnaryArithTest, Not_UnsignedVec_SignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %v2uint %v2int_30_40
|
||||
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__u32
|
||||
{
|
||||
As<__vec_2__u32>{
|
||||
UnaryOp{
|
||||
not
|
||||
TypeConstructor{
|
||||
__vec_2__i32
|
||||
ScalarConstructor{30}
|
||||
ScalarConstructor{40}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
TEST_F(SpvUnaryArithTest, Not_UnsignedVec_UnsignedVec) {
|
||||
const auto assembly = CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
%entry = OpLabel
|
||||
%1 = OpNot %v2uint %v2uint_10_20
|
||||
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__u32
|
||||
{
|
||||
UnaryOp{
|
||||
not
|
||||
TypeConstructor{
|
||||
__vec_2__u32
|
||||
ScalarConstructor{10}
|
||||
ScalarConstructor{20}
|
||||
}
|
||||
}
|
||||
}
|
||||
})"))
|
||||
<< ToString(fe.ast_body());
|
||||
}
|
||||
|
||||
// TODO(dneto): OpBitFieldInsert
|
||||
// TODO(dneto): OpBitFieldSExtract
|
||||
// TODO(dneto): OpBitFieldUExtract
|
||||
// TODO(dneto): OpBitReverse
|
||||
// TODO(dneto): OpBitCount
|
||||
|
||||
// TODO(dneto): OpSRem. Missing from WGSL
|
||||
// https://github.com/gpuweb/gpuweb/issues/702
|
||||
|
||||
|
|
|
@ -949,7 +949,7 @@ ast::type::Type* ParserImpl::ForcedResultType(
|
|||
ast::type::Type* first_operand_type) {
|
||||
const bool binary_match_first_operand =
|
||||
AssumesResultSignednessMatchesBinaryFirstOperand(op);
|
||||
const bool unary_match_operand = (op == SpvOpSNegate);
|
||||
const bool unary_match_operand = (op == SpvOpSNegate) || (op == SpvOpNot);
|
||||
if (binary_match_first_operand || unary_match_operand) {
|
||||
return first_operand_type;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue