[spirv-reader] Test OpSMod
Also, it's not clear if OpSRem has a direct mapping.
Bug: tint:3
Change-Id: Ie7834253cf14109fbebd2ece8e18d9899b29753b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19881
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 3d42885..c76f882 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -82,6 +82,8 @@
default:
break;
}
+ // It's not clear what OpSMod should map to.
+ // https://bugs.chromium.org/p/tint/issues/detail?id=52
return ast::BinaryOp::kNone;
}
diff --git a/src/reader/spirv/function_arithmetic_test.cc b/src/reader/spirv/function_arithmetic_test.cc
index 31ac7f0..cd9f8a6 100644
--- a/src/reader/spirv/function_arithmetic_test.cc
+++ b/src/reader/spirv/function_arithmetic_test.cc
@@ -463,6 +463,9 @@
"__vec_2__u32", AstFor("v2uint_10_20"), "modulo",
AstFor("v2uint_20_10")}));
+// Currently WGSL is missing a mapping for OpSRem
+// https://github.com/gpuweb/gpuweb/issues/702
+
INSTANTIATE_TEST_SUITE_P(
SpvParserTest_SMod,
SpvBinaryTest,
@@ -476,6 +479,110 @@
AstFor("v2int_40_30")}));
INSTANTIATE_TEST_SUITE_P(
+ SpvParserTest_SMod_MixedSignednessOperands,
+ SpvBinaryTest,
+ ::testing::Values(
+ // Mixed, returning int, second arg uint
+ BinaryData{"int", "int_30", "OpSMod", "uint_10", "__i32",
+ "ScalarConstructor{30}", "modulo",
+ R"(As<__i32>{
+ ScalarConstructor{10}
+ })"},
+ // Mixed, returning int, first arg uint
+ BinaryData{"int", "uint_10", "OpSMod", "int_30", "__i32",
+ R"(As<__i32>{
+ ScalarConstructor{10}
+ })",
+ "modulo", "ScalarConstructor{30}"},
+ // Mixed, returning v2int, first arg v2uint
+ BinaryData{"v2int", "v2uint_10_20", "OpSMod", "v2int_30_40",
+ "__vec_2__i32", AstFor("cast_int_v2uint_10_20"), "modulo",
+ AstFor("v2int_30_40")},
+ // Mixed, returning v2int, second arg v2uint
+ BinaryData{"v2int", "v2int_30_40", "OpSMod", "v2uint_10_20",
+ "__vec_2__i32", AstFor("v2int_30_40"), "modulo",
+ AstFor("cast_int_v2uint_10_20")}));
+
+TEST_F(SpvBinaryTestBasic, 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
+ // wrap the result with an as-cast.
+ const auto assembly = CommonTypes() + R"(
+ %100 = OpFunction %void None %voidfn
+ %entry = OpLabel
+ %1 = OpSMod %uint %int_30 %int_40
+ 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();
+ EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
+ Variable{
+ x_1
+ none
+ __u32
+ {
+ As<__u32>{
+ Binary{
+ ScalarConstructor{30}
+ modulo
+ ScalarConstructor{40}
+ }
+ }
+ }
+ })"));
+}
+
+TEST_F(SpvBinaryTestBasic, 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
+ // wrap the result with an as-cast.
+ const auto assembly = CommonTypes() + R"(
+ %100 = OpFunction %void None %voidfn
+ %entry = OpLabel
+ %1 = OpSMod %v2uint %v2int_30_40 %v2int_40_30
+ 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();
+ EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(
+ Variable{
+ x_1
+ none
+ __vec_2__u32
+ {
+ As<__vec_2__u32>{
+ Binary{
+ TypeConstructor{
+ __vec_2__i32
+ ScalarConstructor{30}
+ ScalarConstructor{40}
+ }
+ modulo
+ TypeConstructor{
+ __vec_2__i32
+ ScalarConstructor{40}
+ ScalarConstructor{30}
+ }
+ }
+ }
+ }
+ })"))
+ << ToString(fe.ast_body());
+}
+
+INSTANTIATE_TEST_SUITE_P(
SpvParserTest_FMod,
SpvBinaryTest,
::testing::Values(
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 3139cb9..fa8b9f5 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -160,6 +160,7 @@
switch (opcode) {
// TODO(dneto): More arithmetic operations.
case SpvOpSDiv:
+ case SpvOpSMod:
return true;
default:
break;