From 9cba3e18502a92c663e8d04112825573061f22a3 Mon Sep 17 00:00:00 2001 From: David Neto Date: Tue, 21 Apr 2020 17:44:44 +0000 Subject: [PATCH] [spirv-reader] Split arithmetic, bit tests Separate them into different test files, to match SPIR-V spec sections Bug: tint:3 Change-Id: I89fe76230740da060d57ac23870069a5483b2d7d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20043 Reviewed-by: dan sinclair --- BUILD.gn | 1 + src/CMakeLists.txt | 1 + src/reader/spirv/function_arithmetic_test.cc | 498 +------------- src/reader/spirv/function_bit_test.cc | 645 +++++++++++++++++++ 4 files changed, 669 insertions(+), 476 deletions(-) create mode 100644 src/reader/spirv/function_bit_test.cc diff --git a/BUILD.gn b/BUILD.gn index c79492cc0e..299e340054 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -511,6 +511,7 @@ source_set("tint_unittests_spv_reader_src") { "src/reader/spirv/enum_converter_test.cc", "src/reader/spirv/fail_stream_test.cc", "src/reader/spirv/function_arithmetic_test.cc", + "src/reader/spirv/function_bit_test.cc", "src/reader/spirv/function_cfg_test.cc", "src/reader/spirv/function_conversion_test.cc", "src/reader/spirv/function_decl_test.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1aa773f04c..7c0f91368a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -326,6 +326,7 @@ if(${TINT_BUILD_SPV_READER}) reader/spirv/enum_converter_test.cc reader/spirv/fail_stream_test.cc reader/spirv/function_arithmetic_test.cc + reader/spirv/function_bit_test.cc reader/spirv/function_cfg_test.cc reader/spirv/function_conversion_test.cc reader/spirv/function_decl_test.cc diff --git a/src/reader/spirv/function_arithmetic_test.cc b/src/reader/spirv/function_arithmetic_test.cc index ad5fb6d62c..f194de7f94 100644 --- a/src/reader/spirv/function_arithmetic_test.cc +++ b/src/reader/spirv/function_arithmetic_test.cc @@ -442,10 +442,11 @@ inline std::ostream& operator<<(std::ostream& out, BinaryData data) { return out; } -using SpvBinaryTest = SpvParserTestBase<::testing::TestWithParam>; -using SpvBinaryTestBasic = SpvParserTestBase<::testing::Test>; +using SpvBinaryArithTest = + SpvParserTestBase<::testing::TestWithParam>; +using SpvBinaryArithTestBasic = SpvParserTestBase<::testing::Test>; -TEST_P(SpvBinaryTest, EmitExpression) { +TEST_P(SpvBinaryArithTest, EmitExpression) { const auto assembly = CommonTypes() + R"( %100 = OpFunction %void None %voidfn %entry = OpLabel @@ -474,7 +475,7 @@ TEST_P(SpvBinaryTest, EmitExpression) { INSTANTIATE_TEST_SUITE_P( SpvParserTest_IAdd, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both uint BinaryData{"uint", "uint_10", "OpIAdd", "uint_20", "__u32", @@ -507,7 +508,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_FAdd, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Scalar float BinaryData{"float", "float_50", "OpFAdd", "float_60", "__f32", @@ -520,7 +521,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_ISub, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both uint BinaryData{"uint", "uint_10", "OpISub", "uint_20", "__u32", @@ -557,7 +558,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_FSub, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Scalar float BinaryData{"float", "float_50", "OpFSub", "float_60", "__f32", @@ -570,7 +571,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_IMul, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both uint BinaryData{"uint", "uint_10", "OpIMul", "uint_20", "__u32", @@ -607,7 +608,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_FMul, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Scalar float BinaryData{"float", "float_50", "OpFMul", "float_60", "__f32", @@ -620,7 +621,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_UDiv, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both uint BinaryData{"uint", "uint_10", "OpUDiv", "uint_20", "__u32", @@ -632,7 +633,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_SDiv, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both int BinaryData{"int", "int_30", "OpSDiv", "int_40", "__i32", @@ -644,7 +645,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_SDiv_MixedSignednessOperands, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Mixed, returning int, second arg uint BinaryData{"int", "int_30", "OpSDiv", "uint_10", "__i32", @@ -667,7 +668,7 @@ INSTANTIATE_TEST_SUITE_P( "__vec_2__i32", AstFor("v2int_30_40"), "divide", AstFor("cast_int_v2uint_10_20")})); -TEST_F(SpvBinaryTestBasic, SDiv_Scalar_UnsignedResult) { +TEST_F(SpvBinaryArithTestBasic, SDiv_Scalar_UnsignedResult) { // The WGSL signed division operator expects both operands to be signed // and the result is signed as well. // In this test SPIR-V demands an unsigned result, so we have to @@ -702,7 +703,7 @@ TEST_F(SpvBinaryTestBasic, SDiv_Scalar_UnsignedResult) { })")); } -TEST_F(SpvBinaryTestBasic, SDiv_Vector_UnsignedResult) { +TEST_F(SpvBinaryArithTestBasic, SDiv_Vector_UnsignedResult) { // The WGSL signed division operator expects both operands to be signed // and the result is signed as well. // In this test SPIR-V demands an unsigned result, so we have to @@ -748,7 +749,7 @@ TEST_F(SpvBinaryTestBasic, SDiv_Vector_UnsignedResult) { INSTANTIATE_TEST_SUITE_P( SpvParserTest_FDiv, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Scalar float BinaryData{"float", "float_50", "OpFDiv", "float_60", "__f32", @@ -761,7 +762,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_UMod, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both uint BinaryData{"uint", "uint_10", "OpUMod", "uint_20", "__u32", @@ -776,7 +777,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_SMod, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Both int BinaryData{"int", "int_30", "OpSMod", "int_40", "__i32", @@ -788,7 +789,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( SpvParserTest_SMod_MixedSignednessOperands, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Mixed, returning int, second arg uint BinaryData{"int", "int_30", "OpSMod", "uint_10", "__i32", @@ -811,7 +812,7 @@ INSTANTIATE_TEST_SUITE_P( "__vec_2__i32", AstFor("v2int_30_40"), "modulo", AstFor("cast_int_v2uint_10_20")})); -TEST_F(SpvBinaryTestBasic, SMod_Scalar_UnsignedResult) { +TEST_F(SpvBinaryArithTestBasic, SMod_Scalar_UnsignedResult) { // The WGSL signed modulus operator expects both operands to be signed // and the result is signed as well. // In this test SPIR-V demands an unsigned result, so we have to @@ -846,7 +847,7 @@ TEST_F(SpvBinaryTestBasic, SMod_Scalar_UnsignedResult) { })")); } -TEST_F(SpvBinaryTestBasic, SMod_Vector_UnsignedResult) { +TEST_F(SpvBinaryArithTestBasic, SMod_Vector_UnsignedResult) { // The WGSL signed modulus operator expects both operands to be signed // and the result is signed as well. // In this test SPIR-V demands an unsigned result, so we have to @@ -892,7 +893,7 @@ TEST_F(SpvBinaryTestBasic, SMod_Vector_UnsignedResult) { INSTANTIATE_TEST_SUITE_P( SpvParserTest_FMod, - SpvBinaryTest, + SpvBinaryArithTest, ::testing::Values( // Scalar float BinaryData{"float", "float_50", "OpFMod", "float_60", "__f32", @@ -903,461 +904,6 @@ INSTANTIATE_TEST_SUITE_P( "__vec_2__f32", AstFor("v2float_50_60"), "modulo", AstFor("v2float_60_50")})); -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_ShiftLeftLogical, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpShiftLeftLogical", "uint_20", "__u32", - "ScalarConstructor{10}", "shift_left", - "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpShiftLeftLogical", "int_40", "__i32", - "ScalarConstructor{30}", "shift_left", - "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpShiftLeftLogical", "uint_10", "__u32", - "ScalarConstructor{30}", "shift_left", - "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpShiftLeftLogical", "uint_10", "__i32", - "ScalarConstructor{30}", "shift_left", - "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpShiftLeftLogical", - "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), - "shift_left", AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpShiftLeftLogical", "v2int_40_30", - "__vec_2__i32", AstFor("v2int_30_40"), "shift_left", - AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpShiftLeftLogical", - "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), - "shift_left", AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpShiftLeftLogical", "v2uint_20_10", - "__vec_2__i32", AstFor("v2int_40_30"), "shift_left", - AstFor("v2uint_20_10")})); - -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_ShiftRightLogical, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpShiftRightLogical", "uint_20", "__u32", - "ScalarConstructor{10}", "shift_right", - "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpShiftRightLogical", "int_40", "__i32", - "ScalarConstructor{30}", "shift_right", - "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpShiftRightLogical", "uint_10", "__u32", - "ScalarConstructor{30}", "shift_right", - "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpShiftRightLogical", "uint_10", "__i32", - "ScalarConstructor{30}", "shift_right", - "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpShiftRightLogical", - "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), - "shift_right", AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpShiftRightLogical", "v2int_40_30", - "__vec_2__i32", AstFor("v2int_30_40"), "shift_right", - AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpShiftRightLogical", - "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), - "shift_right", AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpShiftRightLogical", - "v2uint_20_10", "__vec_2__i32", AstFor("v2int_40_30"), - "shift_right", AstFor("v2uint_20_10")})); - -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_ShiftRightArithmetic, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpShiftRightArithmetic", "uint_20", - "__u32", "ScalarConstructor{10}", "shift_right_arith", - "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpShiftRightArithmetic", "int_40", "__i32", - "ScalarConstructor{30}", "shift_right_arith", - "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpShiftRightArithmetic", "uint_10", - "__u32", "ScalarConstructor{30}", "shift_right_arith", - "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpShiftRightArithmetic", "uint_10", - "__i32", "ScalarConstructor{30}", "shift_right_arith", - "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpShiftRightArithmetic", - "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), - "shift_right_arith", AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpShiftRightArithmetic", - "v2int_40_30", "__vec_2__i32", AstFor("v2int_30_40"), - "shift_right_arith", AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpShiftRightArithmetic", - "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), - "shift_right_arith", AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpShiftRightArithmetic", - "v2uint_20_10", "__vec_2__i32", AstFor("v2int_40_30"), - "shift_right_arith", AstFor("v2uint_20_10")})); - -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_BitwiseAnd, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpBitwiseAnd", "uint_20", "__u32", - "ScalarConstructor{10}", "and", "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpBitwiseAnd", "int_40", "__i32", - "ScalarConstructor{30}", "and", "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpBitwiseAnd", "uint_10", "__u32", - "ScalarConstructor{30}", "and", "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpBitwiseAnd", "uint_10", "__i32", - "ScalarConstructor{30}", "and", "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseAnd", "v2uint_20_10", - "__vec_2__u32", AstFor("v2uint_10_20"), "and", - AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpBitwiseAnd", "v2int_40_30", - "__vec_2__i32", AstFor("v2int_30_40"), "and", - AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpBitwiseAnd", "v2uint_10_20", - "__vec_2__u32", AstFor("v2int_30_40"), "and", - AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpBitwiseAnd", "v2uint_20_10", - "__vec_2__i32", AstFor("v2int_40_30"), "and", - AstFor("v2uint_20_10")})); - -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_BitwiseOr, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpBitwiseOr", "uint_20", "__u32", - "ScalarConstructor{10}", "or", "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpBitwiseOr", "int_40", "__i32", - "ScalarConstructor{30}", "or", "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpBitwiseOr", "uint_10", "__u32", - "ScalarConstructor{30}", "or", "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpBitwiseOr", "uint_10", "__i32", - "ScalarConstructor{30}", "or", "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseOr", "v2uint_20_10", - "__vec_2__u32", AstFor("v2uint_10_20"), "or", - AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpBitwiseOr", "v2int_40_30", - "__vec_2__i32", AstFor("v2int_30_40"), "or", - AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpBitwiseOr", "v2uint_10_20", - "__vec_2__u32", AstFor("v2int_30_40"), "or", - AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpBitwiseOr", "v2uint_20_10", - "__vec_2__i32", AstFor("v2int_40_30"), "or", - AstFor("v2uint_20_10")})); - -INSTANTIATE_TEST_SUITE_P( - SpvParserTest_BitwiseXor, - SpvBinaryTest, - ::testing::Values( - // Both uint - BinaryData{"uint", "uint_10", "OpBitwiseXor", "uint_20", "__u32", - "ScalarConstructor{10}", "xor", "ScalarConstructor{20}"}, - // Both int - BinaryData{"int", "int_30", "OpBitwiseXor", "int_40", "__i32", - "ScalarConstructor{30}", "xor", "ScalarConstructor{40}"}, - // Mixed, returning uint - BinaryData{"uint", "int_30", "OpBitwiseXor", "uint_10", "__u32", - "ScalarConstructor{30}", "xor", "ScalarConstructor{10}"}, - // Mixed, returning int - BinaryData{"int", "int_30", "OpBitwiseXor", "uint_10", "__i32", - "ScalarConstructor{30}", "xor", "ScalarConstructor{10}"}, - // Both v2uint - BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseXor", "v2uint_20_10", - "__vec_2__u32", AstFor("v2uint_10_20"), "xor", - AstFor("v2uint_20_10")}, - // Both v2int - BinaryData{"v2int", "v2int_30_40", "OpBitwiseXor", "v2int_40_30", - "__vec_2__i32", AstFor("v2int_30_40"), "xor", - AstFor("v2int_40_30")}, - // Mixed, returning v2uint - BinaryData{"v2uint", "v2int_30_40", "OpBitwiseXor", "v2uint_10_20", - "__vec_2__u32", AstFor("v2int_30_40"), "xor", - AstFor("v2uint_10_20")}, - // Mixed, returning v2int - BinaryData{"v2int", "v2int_40_30", "OpBitwiseXor", "v2uint_20_10", - "__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 diff --git a/src/reader/spirv/function_bit_test.cc b/src/reader/spirv/function_bit_test.cc new file mode 100644 index 0000000000..c2b133c265 --- /dev/null +++ b/src/reader/spirv/function_bit_test.cc @@ -0,0 +1,645 @@ +// Copyright 2020 The Tint Authors. // +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "gmock/gmock.h" +#include "src/reader/spirv/function.h" +#include "src/reader/spirv/parser_impl.h" +#include "src/reader/spirv/parser_impl_test_helper.h" +#include "src/reader/spirv/spirv_tools_helpers_test.h" + +namespace tint { +namespace reader { +namespace spirv { +namespace { + +using ::testing::HasSubstr; + +std::string CommonTypes() { + return R"( + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %uint = OpTypeInt 32 0 + %int = OpTypeInt 32 1 + %float = OpTypeFloat 32 + + %uint_10 = OpConstant %uint 10 + %uint_20 = OpConstant %uint 20 + %int_30 = OpConstant %int 30 + %int_40 = OpConstant %int 40 + %float_50 = OpConstant %float 50 + %float_60 = OpConstant %float 60 + + %ptr_uint = OpTypePointer Function %uint + %ptr_int = OpTypePointer Function %int + %ptr_float = OpTypePointer Function %float + + %v2uint = OpTypeVector %uint 2 + %v2int = OpTypeVector %int 2 + %v2float = OpTypeVector %float 2 + + %v2uint_10_20 = OpConstantComposite %v2uint %uint_10 %uint_20 + %v2uint_20_10 = OpConstantComposite %v2uint %uint_20 %uint_10 + %v2int_30_40 = OpConstantComposite %v2int %int_30 %int_40 + %v2int_40_30 = OpConstantComposite %v2int %int_40 %int_30 + %v2float_50_60 = OpConstantComposite %v2float %float_50 %float_60 + %v2float_60_50 = OpConstantComposite %v2float %float_60 %float_50 +)"; +} + +// Returns the AST dump for a given SPIR-V assembly constant. +std::string AstFor(std::string assembly) { + if (assembly == "v2uint_10_20") { + return R"(TypeConstructor{ + __vec_2__u32 + ScalarConstructor{10} + ScalarConstructor{20} + })"; + } + if (assembly == "v2uint_20_10") { + return R"(TypeConstructor{ + __vec_2__u32 + ScalarConstructor{20} + ScalarConstructor{10} + })"; + } + if (assembly == "v2int_30_40") { + return R"(TypeConstructor{ + __vec_2__i32 + ScalarConstructor{30} + ScalarConstructor{40} + })"; + } + if (assembly == "v2int_40_30") { + return R"(TypeConstructor{ + __vec_2__i32 + ScalarConstructor{40} + ScalarConstructor{30} + })"; + } + if (assembly == "cast_int_v2uint_10_20") { + return R"(As<__vec_2__i32>{ + TypeConstructor{ + __vec_2__u32 + ScalarConstructor{10} + ScalarConstructor{20} + } + })"; + } + if (assembly == "v2float_50_60") { + return R"(TypeConstructor{ + __vec_2__f32 + ScalarConstructor{50.000000} + ScalarConstructor{60.000000} + })"; + } + if (assembly == "v2float_60_50") { + return R"(TypeConstructor{ + __vec_2__f32 + ScalarConstructor{60.000000} + ScalarConstructor{50.000000} + })"; + } + return "bad case"; +} + +using SpvUnaryBitTest = SpvParserTestBase<::testing::Test>; + +struct BinaryData { + const std::string res_type; + const std::string lhs; + const std::string op; + const std::string rhs; + const std::string ast_type; + const std::string ast_lhs; + const std::string ast_op; + const std::string ast_rhs; +}; +inline std::ostream& operator<<(std::ostream& out, BinaryData data) { + out << "BinaryData{" << data.res_type << "," << data.lhs << "," << data.op + << "," << data.rhs << "," << data.ast_type << "," << data.ast_lhs << "," + << data.ast_op << "," << data.ast_rhs << "}"; + return out; +} + +using SpvBinaryBitTest = + SpvParserTestBase<::testing::TestWithParam>; +using SpvBinaryBitTestBasic = SpvParserTestBase<::testing::Test>; + +TEST_P(SpvBinaryBitTest, EmitExpression) { + const auto assembly = CommonTypes() + R"( + %100 = OpFunction %void None %voidfn + %entry = OpLabel + %1 = )" + GetParam().op + + " %" + GetParam().res_type + " %" + GetParam().lhs + + " %" + GetParam().rhs + R"( + OpReturn + OpFunctionEnd + )"; + auto* p = parser(test::Assemble(assembly)); + ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) + << p->error() << "\n" + << assembly; + FunctionEmitter fe(p, *spirv_function(100)); + EXPECT_TRUE(fe.EmitBody()) << p->error(); + std::ostringstream ss; + ss << R"(Variable{ + x_1 + none + )" + << GetParam().ast_type << "\n {\n Binary{" + << "\n " << GetParam().ast_lhs << "\n " << GetParam().ast_op + << "\n " << GetParam().ast_rhs; + EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(ss.str())) << assembly; +} + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_ShiftLeftLogical, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpShiftLeftLogical", "uint_20", "__u32", + "ScalarConstructor{10}", "shift_left", + "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpShiftLeftLogical", "int_40", "__i32", + "ScalarConstructor{30}", "shift_left", + "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpShiftLeftLogical", "uint_10", "__u32", + "ScalarConstructor{30}", "shift_left", + "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpShiftLeftLogical", "uint_10", "__i32", + "ScalarConstructor{30}", "shift_left", + "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpShiftLeftLogical", + "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), + "shift_left", AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpShiftLeftLogical", "v2int_40_30", + "__vec_2__i32", AstFor("v2int_30_40"), "shift_left", + AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpShiftLeftLogical", + "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), + "shift_left", AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpShiftLeftLogical", "v2uint_20_10", + "__vec_2__i32", AstFor("v2int_40_30"), "shift_left", + AstFor("v2uint_20_10")})); + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_ShiftRightLogical, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpShiftRightLogical", "uint_20", "__u32", + "ScalarConstructor{10}", "shift_right", + "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpShiftRightLogical", "int_40", "__i32", + "ScalarConstructor{30}", "shift_right", + "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpShiftRightLogical", "uint_10", "__u32", + "ScalarConstructor{30}", "shift_right", + "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpShiftRightLogical", "uint_10", "__i32", + "ScalarConstructor{30}", "shift_right", + "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpShiftRightLogical", + "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), + "shift_right", AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpShiftRightLogical", "v2int_40_30", + "__vec_2__i32", AstFor("v2int_30_40"), "shift_right", + AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpShiftRightLogical", + "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), + "shift_right", AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpShiftRightLogical", + "v2uint_20_10", "__vec_2__i32", AstFor("v2int_40_30"), + "shift_right", AstFor("v2uint_20_10")})); + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_ShiftRightArithmetic, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpShiftRightArithmetic", "uint_20", + "__u32", "ScalarConstructor{10}", "shift_right_arith", + "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpShiftRightArithmetic", "int_40", "__i32", + "ScalarConstructor{30}", "shift_right_arith", + "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpShiftRightArithmetic", "uint_10", + "__u32", "ScalarConstructor{30}", "shift_right_arith", + "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpShiftRightArithmetic", "uint_10", + "__i32", "ScalarConstructor{30}", "shift_right_arith", + "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpShiftRightArithmetic", + "v2uint_20_10", "__vec_2__u32", AstFor("v2uint_10_20"), + "shift_right_arith", AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpShiftRightArithmetic", + "v2int_40_30", "__vec_2__i32", AstFor("v2int_30_40"), + "shift_right_arith", AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpShiftRightArithmetic", + "v2uint_10_20", "__vec_2__u32", AstFor("v2int_30_40"), + "shift_right_arith", AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpShiftRightArithmetic", + "v2uint_20_10", "__vec_2__i32", AstFor("v2int_40_30"), + "shift_right_arith", AstFor("v2uint_20_10")})); + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_BitwiseAnd, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpBitwiseAnd", "uint_20", "__u32", + "ScalarConstructor{10}", "and", "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpBitwiseAnd", "int_40", "__i32", + "ScalarConstructor{30}", "and", "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpBitwiseAnd", "uint_10", "__u32", + "ScalarConstructor{30}", "and", "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpBitwiseAnd", "uint_10", "__i32", + "ScalarConstructor{30}", "and", "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseAnd", "v2uint_20_10", + "__vec_2__u32", AstFor("v2uint_10_20"), "and", + AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpBitwiseAnd", "v2int_40_30", + "__vec_2__i32", AstFor("v2int_30_40"), "and", + AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpBitwiseAnd", "v2uint_10_20", + "__vec_2__u32", AstFor("v2int_30_40"), "and", + AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpBitwiseAnd", "v2uint_20_10", + "__vec_2__i32", AstFor("v2int_40_30"), "and", + AstFor("v2uint_20_10")})); + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_BitwiseOr, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpBitwiseOr", "uint_20", "__u32", + "ScalarConstructor{10}", "or", "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpBitwiseOr", "int_40", "__i32", + "ScalarConstructor{30}", "or", "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpBitwiseOr", "uint_10", "__u32", + "ScalarConstructor{30}", "or", "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpBitwiseOr", "uint_10", "__i32", + "ScalarConstructor{30}", "or", "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseOr", "v2uint_20_10", + "__vec_2__u32", AstFor("v2uint_10_20"), "or", + AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpBitwiseOr", "v2int_40_30", + "__vec_2__i32", AstFor("v2int_30_40"), "or", + AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpBitwiseOr", "v2uint_10_20", + "__vec_2__u32", AstFor("v2int_30_40"), "or", + AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpBitwiseOr", "v2uint_20_10", + "__vec_2__i32", AstFor("v2int_40_30"), "or", + AstFor("v2uint_20_10")})); + +INSTANTIATE_TEST_SUITE_P( + SpvParserTest_BitwiseXor, + SpvBinaryBitTest, + ::testing::Values( + // Both uint + BinaryData{"uint", "uint_10", "OpBitwiseXor", "uint_20", "__u32", + "ScalarConstructor{10}", "xor", "ScalarConstructor{20}"}, + // Both int + BinaryData{"int", "int_30", "OpBitwiseXor", "int_40", "__i32", + "ScalarConstructor{30}", "xor", "ScalarConstructor{40}"}, + // Mixed, returning uint + BinaryData{"uint", "int_30", "OpBitwiseXor", "uint_10", "__u32", + "ScalarConstructor{30}", "xor", "ScalarConstructor{10}"}, + // Mixed, returning int + BinaryData{"int", "int_30", "OpBitwiseXor", "uint_10", "__i32", + "ScalarConstructor{30}", "xor", "ScalarConstructor{10}"}, + // Both v2uint + BinaryData{"v2uint", "v2uint_10_20", "OpBitwiseXor", "v2uint_20_10", + "__vec_2__u32", AstFor("v2uint_10_20"), "xor", + AstFor("v2uint_20_10")}, + // Both v2int + BinaryData{"v2int", "v2int_30_40", "OpBitwiseXor", "v2int_40_30", + "__vec_2__i32", AstFor("v2int_30_40"), "xor", + AstFor("v2int_40_30")}, + // Mixed, returning v2uint + BinaryData{"v2uint", "v2int_30_40", "OpBitwiseXor", "v2uint_10_20", + "__vec_2__u32", AstFor("v2int_30_40"), "xor", + AstFor("v2uint_10_20")}, + // Mixed, returning v2int + BinaryData{"v2int", "v2int_40_30", "OpBitwiseXor", "v2uint_20_10", + "__vec_2__i32", AstFor("v2int_40_30"), "xor", + AstFor("v2uint_20_10")})); + +TEST_F(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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(SpvUnaryBitTest, 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 + +// TODO(dneto): OpFRem. Missing from WGSL +// https://github.com/gpuweb/gpuweb/issues/702 + +// TODO(dneto): OpVectorTimesScalar +// TODO(dneto): OpMatrixTimesScalar +// TODO(dneto): OpVectorTimesMatrix +// TODO(dneto): OpMatrixTimesVector +// TODO(dneto): OpMatrixTimesMatrix +// TODO(dneto): OpOuterProduct +// TODO(dneto): OpDot +// TODO(dneto): OpIAddCarry +// TODO(dneto): OpISubBorrow +// TODO(dneto): OpIMulExtended +// TODO(dneto): OpSMulExtended + +} // namespace +} // namespace spirv +} // namespace reader +} // namespace tint