[spirv-reader] Add OpBitcast
Bug: tint:3
Change-Id: I51f4521edeacf9e7c4d8dbf4a1832295b1705550
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19886
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 49a445b..3d68847 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -511,6 +511,7 @@
"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_conversion_test.cc",
"src/reader/spirv/function_decl_test.cc",
"src/reader/spirv/function_logical_test.cc",
"src/reader/spirv/function_memory_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6e2d82f..8a490be 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -326,6 +326,7 @@
reader/spirv/enum_converter_test.cc
reader/spirv/fail_stream_test.cc
reader/spirv/function_arithmetic_test.cc
+ reader/spirv/function_conversion_test.cc
reader/spirv/function_decl_test.cc
reader/spirv/function_logical_test.cc
reader/spirv/function_var_test.cc
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index d882907..33b6e4d 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -425,6 +425,13 @@
return {ast_type, std::move(unary_expr)};
}
+ if (inst.opcode() == SpvOpBitcast) {
+ auto target_ty = parser_impl_.ConvertType(inst.type_id());
+ auto cast = std::make_unique<ast::AsExpression>(target_ty, operand(0));
+ cast->set_result_type(target_ty);
+ return cast;
+ }
+
// builtin readonly function
// glsl.std.450 readonly function
@@ -434,13 +441,13 @@
// OpBitcast
// OpSatConvertSToU
// OpSatConvertUToS
- // OpSatConvertFToS
- // OpSatConvertFToU
- // OpSatConvertSToF
- // OpSatConvertUToF
- // OpUConvert
- // OpSConvert
- // OpFConvert
+ // OpConvertFToS
+ // OpConvertFToU
+ // OpConvertSToF
+ // OpConvertUToF
+ // OpUConvert // Only needed when multiple widths supported
+ // OpSConvert // Only needed when multiple widths supported
+ // OpFConvert // Only needed when multiple widths supported
// OpConvertPtrToU // Not in WebGPU
// OpConvertUToPtr // Not in WebGPU
// OpPtrCastToGeneric // Not in Vulkan
diff --git a/src/reader/spirv/function_conversion_test.cc b/src/reader/spirv/function_conversion_test.cc
new file mode 100644
index 0000000..bdb3f90
--- /dev/null
+++ b/src/reader/spirv/function_conversion_test.cc
@@ -0,0 +1,136 @@
+// 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 <string>
+#include <vector>
+
+#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
+)";
+}
+
+using SpvUnaryConversionTest = SpvParserTestBase<::testing::Test>;
+
+TEST_F(SpvUnaryConversionTest, Bitcast_Scalar) {
+ const auto assembly = CommonTypes() + R"(
+ %100 = OpFunction %void None %voidfn
+ %entry = OpLabel
+ %1 = OpBitcast %uint %float_50
+ 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>{
+ ScalarConstructor{50.000000}
+ }
+ }
+ })"))
+ << ToString(fe.ast_body());
+}
+
+TEST_F(SpvUnaryConversionTest, Bitcast_Vector) {
+ const auto assembly = CommonTypes() + R"(
+ %100 = OpFunction %void None %voidfn
+ %entry = OpLabel
+ %1 = OpBitcast %v2float %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__f32
+ {
+ As<__vec_2__f32>{
+ TypeConstructor{
+ __vec_2__u32
+ ScalarConstructor{10}
+ ScalarConstructor{20}
+ }
+ }
+ }
+ })"))
+ << ToString(fe.ast_body());
+}
+
+// TODO(dneto): OpConvertFToU
+// TODO(dneto): OpConvertFToS
+// TODO(dneto): OpConvertUToF
+// TODO(dneto): OpConvertSToF
+// TODO(dneto): OpSConvert // only if multiple widths
+// TODO(dneto): OpUConvert // only if multiple widths
+// TODO(dneto): OpFConvert // only if multiple widths
+// TODO(dneto): OpQuantizeToF16 // only if f16 supported
+// TODO(dneto): OpConvertSToU
+// TODO(dneto): OpConvertUToS
+
+} // namespace
+} // namespace spirv
+} // namespace reader
+} // namespace tint