diff --git a/.gitignore b/.gitignore index d9c6a1a4..8a487875 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ compile_commands.json /build*/ /buildtools/ -/external/abseil_cpp/ /external/googletest /external/SPIRV-Headers /external/spirv-headers @@ -21,7 +20,7 @@ bazel-bin bazel-genfiles bazel-out bazel-spirv-tools -bazel-SPIRV-Tools +bazel-spirv-tools bazel-testlogs # Vim diff --git a/Android.mk b/Android.mk index afa04039..80c61b08 100644 --- a/Android.mk +++ b/Android.mk @@ -71,7 +71,6 @@ SPVTOOLS_SRC_FILES := \ source/val/validate_primitives.cpp \ source/val/validate_ray_query.cpp \ source/val/validate_ray_tracing.cpp \ - source/val/validate_ray_tracing_reorder.cpp \ source/val/validate_scopes.cpp \ source/val/validate_small_type_uses.cpp \ source/val/validate_type.cpp @@ -79,7 +78,6 @@ SPVTOOLS_SRC_FILES := \ SPVTOOLS_OPT_SRC_FILES := \ source/opt/aggressive_dead_code_elim_pass.cpp \ source/opt/amd_ext_to_khr.cpp \ - source/opt/analyze_live_input_pass.cpp \ source/opt/basic_block.cpp \ source/opt/block_merge_pass.cpp \ source/opt/block_merge_util.cpp \ @@ -111,9 +109,8 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/eliminate_dead_constant_pass.cpp \ source/opt/eliminate_dead_functions_pass.cpp \ source/opt/eliminate_dead_functions_util.cpp \ - source/opt/eliminate_dead_io_components_pass.cpp \ + source/opt/eliminate_dead_input_components_pass.cpp \ source/opt/eliminate_dead_members_pass.cpp \ - source/opt/eliminate_dead_output_stores_pass.cpp \ source/opt/feature_manager.cpp \ source/opt/fix_func_call_arguments.cpp \ source/opt/fix_storage_class.cpp \ @@ -136,11 +133,9 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/instrument_pass.cpp \ source/opt/interface_var_sroa.cpp \ source/opt/interp_fixup_pass.cpp \ - source/opt/invocation_interlock_placement_pass.cpp \ source/opt/ir_context.cpp \ source/opt/ir_loader.cpp \ source/opt/licm_pass.cpp \ - source/opt/liveness.cpp \ source/opt/local_access_chain_convert_pass.cpp \ source/opt/local_redundancy_elimination.cpp \ source/opt/local_single_block_elim_pass.cpp \ @@ -183,8 +178,6 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/strip_debug_info_pass.cpp \ source/opt/strip_nonsemantic_info_pass.cpp \ source/opt/struct_cfg_analysis.cpp \ - source/opt/switch_descriptorset_pass.cpp \ - source/opt/trim_capabilities_pass.cpp \ source/opt/type_manager.cpp \ source/opt/types.cpp \ source/opt/unify_const_pass.cpp \ @@ -224,8 +217,7 @@ $(1)/opencl.std.insts.inc \ --core-insts-output=$(1)/core.insts-unified1.inc \ --glsl-insts-output=$(1)/glsl.std.450.insts.inc \ --opencl-insts-output=$(1)/opencl.std.insts.inc \ - --operand-kinds-output=$(1)/operand.kinds-unified1.inc \ - --output-language=c++ + --operand-kinds-output=$(1)/operand.kinds-unified1.inc @echo "[$(TARGET_ARCH_ABI)] Grammar (from unified1) : instructions & operands <= grammar JSON files" $(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-unified1.inc $(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-unified1.inc @@ -299,8 +291,7 @@ $(1)/extension_enum.inc $(1)/enum_string_mapping.inc: \ --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ --extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \ --extension-enum-output=$(1)/extension_enum.inc \ - --enum-string-mapping-output=$(1)/enum_string_mapping.inc \ - --output-language=c++ + --enum-string-mapping-output=$(1)/enum_string_mapping.inc @echo "[$(TARGET_ARCH_ABI)] Generate enum<->string mapping <= grammar JSON files" # Generated header extension_enum.inc is transitively included by table.h, which is # used pervasively. Capture the pervasive dependency. @@ -343,7 +334,7 @@ LOCAL_C_INCLUDES := \ $(SPVTOOLS_OUT_PATH) LOCAL_EXPORT_C_INCLUDES := \ $(LOCAL_PATH)/include -LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror +LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror LOCAL_SRC_FILES:= $(SPVTOOLS_SRC_FILES) include $(BUILD_STATIC_LIBRARY) @@ -354,7 +345,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/source \ $(SPVHEADERS_LOCAL_PATH)/include \ $(SPVTOOLS_OUT_PATH) -LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror +LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror LOCAL_STATIC_LIBRARIES:=SPIRV-Tools LOCAL_SRC_FILES:= $(SPVTOOLS_OPT_SRC_FILES) include $(BUILD_STATIC_LIBRARY) diff --git a/BUILD.bazel b/BUILD.bazel index b83fd5ae..35dfd665 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,24 +1,27 @@ load( ":build_defs.bzl", - "CLDEBUGINFO100_GRAMMAR_JSON_FILE", "COMMON_COPTS", "DEBUGINFO_GRAMMAR_JSON_FILE", + "CLDEBUGINFO100_GRAMMAR_JSON_FILE", "SHDEBUGINFO100_GRAMMAR_JSON_FILE", "TEST_COPTS", + "base_test", "generate_core_tables", "generate_enum_string_mapping", "generate_extinst_lang_headers", "generate_glsl_tables", "generate_opencl_tables", "generate_vendor_tables", - "incompatible_with", + "link_test", + "lint_test", + "opt_test", + "reduce_test", + "util_test", + "val_test", ) package( default_visibility = ["//visibility:private"], - features = [ - "layering_check", - ], ) licenses(["notice"]) @@ -38,50 +41,35 @@ py_binary( srcs = ["utils/generate_language_headers.py"], ) -generate_core_tables(version = "unified1") +generate_core_tables("unified1") -generate_enum_string_mapping(version = "unified1") +generate_enum_string_mapping("unified1") -generate_opencl_tables(version = "unified1") +generate_opencl_tables("unified1") -generate_glsl_tables(version = "unified1") +generate_glsl_tables("unified1") -generate_vendor_tables(extension = "spv-amd-shader-explicit-vertex-parameter") +generate_vendor_tables("spv-amd-shader-explicit-vertex-parameter") -generate_vendor_tables(extension = "spv-amd-shader-trinary-minmax") +generate_vendor_tables("spv-amd-shader-trinary-minmax") -generate_vendor_tables(extension = "spv-amd-gcn-shader") +generate_vendor_tables("spv-amd-gcn-shader") -generate_vendor_tables(extension = "spv-amd-shader-ballot") +generate_vendor_tables("spv-amd-shader-ballot") -generate_vendor_tables(extension = "debuginfo") +generate_vendor_tables("debuginfo") -generate_vendor_tables(extension = "nonsemantic.clspvreflection") +generate_vendor_tables("opencl.debuginfo.100", "CLDEBUG100_") -generate_vendor_tables( - extension = "opencl.debuginfo.100", - operand_kind_prefix = "CLDEBUG100_", -) +generate_vendor_tables("nonsemantic.shader.debuginfo.100", "SHDEBUG100_") -generate_vendor_tables( - extension = "nonsemantic.shader.debuginfo.100", - operand_kind_prefix = "SHDEBUG100_", -) +generate_vendor_tables("nonsemantic.clspvreflection") -generate_extinst_lang_headers( - name = "DebugInfo", - grammar = DEBUGINFO_GRAMMAR_JSON_FILE, -) +generate_extinst_lang_headers("DebugInfo", DEBUGINFO_GRAMMAR_JSON_FILE) -generate_extinst_lang_headers( - name = "OpenCLDebugInfo100", - grammar = CLDEBUGINFO100_GRAMMAR_JSON_FILE, -) +generate_extinst_lang_headers("OpenCLDebugInfo100", CLDEBUGINFO100_GRAMMAR_JSON_FILE) -generate_extinst_lang_headers( - name = "NonSemanticShaderDebugInfo100", - grammar = SHDEBUGINFO100_GRAMMAR_JSON_FILE, -) +generate_extinst_lang_headers("NonSemanticShaderDebugInfo100", SHDEBUGINFO100_GRAMMAR_JSON_FILE) py_binary( name = "generate_registry_tables", @@ -89,12 +77,12 @@ py_binary( ) genrule( - name = "generators_inc", + name = "gen_registry_tables", srcs = ["@spirv_headers//:spirv_xml_registry"], outs = ["generators.inc"], - cmd = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)", - cmd_bat = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)", - tools = [":generate_registry_tables"], + cmd = "$(location generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)", + cmd_bat = "$(location //:generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)", + exec_tools = [":generate_registry_tables"], ) py_binary( @@ -103,103 +91,120 @@ py_binary( ) genrule( - name = "build_version_inc", + name = "gen_build_version", srcs = ["CHANGES"], outs = ["build-version.inc"], - cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(location CHANGES) $(location build-version.inc)", - cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location :update_build_version) $(location CHANGES) $(location build-version.inc)", - local = True, - tools = [":update_build_version"], + cmd = "SOURCE_DATE_EPOCH=0 $(location update_build_version) $(location CHANGES) $(location build-version.inc)", + cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location //:update_build_version) $(location CHANGES) $(location build-version.inc)", + exec_tools = [":update_build_version"], ) # Libraries cc_library( - name = "spirv_tools", + name = "generated_headers", hdrs = [ - "include/spirv-tools/libspirv.h", - "include/spirv-tools/libspirv.hpp", - ], - copts = COMMON_COPTS, - includes = ["include"], - linkstatic = 1, - visibility = ["//visibility:public"], - deps = [ - ":spirv_tools_internal", - ], -) - -cc_library( - name = "spirv_tools_internal", - srcs = glob([ - "source/*.cpp", - "source/util/*.cpp", - "source/val/*.cpp", - ]) + [ - ":build_version_inc", + ":gen_build_version", ":gen_core_tables_unified1", ":gen_enum_string_mapping", ":gen_extinst_lang_headers_DebugInfo", - ":gen_extinst_lang_headers_NonSemanticShaderDebugInfo100", ":gen_extinst_lang_headers_OpenCLDebugInfo100", + ":gen_extinst_lang_headers_NonSemanticShaderDebugInfo100", ":gen_glsl_tables_unified1", ":gen_opencl_tables_unified1", + ":gen_registry_tables", ":gen_vendor_tables_debuginfo", ":gen_vendor_tables_nonsemantic_clspvreflection", - ":gen_vendor_tables_nonsemantic_shader_debuginfo_100", ":gen_vendor_tables_opencl_debuginfo_100", + ":gen_vendor_tables_nonsemantic_shader_debuginfo_100", ":gen_vendor_tables_spv_amd_gcn_shader", ":gen_vendor_tables_spv_amd_shader_ballot", ":gen_vendor_tables_spv_amd_shader_explicit_vertex_parameter", ":gen_vendor_tables_spv_amd_shader_trinary_minmax", - ":generators_inc", ], - hdrs = [ + copts = COMMON_COPTS, +) + +cc_library( + name = "spirv_tools_headers", + hdrs = glob([ "include/spirv-tools/libspirv.h", "include/spirv-tools/libspirv.hpp", - ":gen_extinst_lang_headers_DebugInfo", - ":gen_extinst_lang_headers_NonSemanticShaderDebugInfo100", - ":gen_extinst_lang_headers_OpenCLDebugInfo100", - ] + glob([ "source/*.h", "source/util/*.h", "source/val/*.h", ]), copts = COMMON_COPTS, - includes = ["include"], + includes = ["source"], deps = [ - "@spirv_headers//:spirv_common_headers", - "@spirv_headers//:spirv_cpp11_headers", + "@spirv_headers//:spirv_c_headers", ], ) +cc_library( + name = "spirv_tools", + srcs = glob([ + "source/*.cpp", + "source/util/*.cpp", + "source/val/*.cpp", + ]), + hdrs = [ + "include/spirv-tools/libspirv.h", + "include/spirv-tools/libspirv.hpp", + ], + copts = COMMON_COPTS + select({ + "@bazel_tools//src/conditions:windows": [""], + "//conditions:default": ["-Wno-implicit-fallthrough"], + }), + includes = ["include"], + linkstatic = 1, + visibility = ["//visibility:public"], + deps = [ + ":generated_headers", + ":spirv_tools_headers", + "@spirv_headers//:spirv_c_headers", + "@spirv_headers//:spirv_common_headers", + ], +) + +cc_library( + name = "spirv_tools_comp", + srcs = glob([ + "source/comp/*.cpp", + "source/comp/*.h", + ]), + copts = COMMON_COPTS, + linkstatic = 1, + visibility = ["//visibility:public"], + deps = [ + ":generated_headers", + ":spirv_tools", + ":spirv_tools_headers", + "@spirv_headers//:spirv_common_headers", + ], +) + +cc_library( + name = "spirv_tools_opt_headers", + hdrs = glob(["source/opt/*.h"]), + copts = COMMON_COPTS, +) + cc_library( name = "spirv_tools_opt", + srcs = glob(["source/opt/*.cpp"]), hdrs = [ "include/spirv-tools/instrument.hpp", "include/spirv-tools/optimizer.hpp", ], copts = COMMON_COPTS, + includes = ["include"], linkstatic = 1, visibility = ["//visibility:public"], deps = [ ":spirv_tools", - ":spirv_tools_opt_internal", - ], -) - -cc_library( - name = "spirv_tools_opt_internal", - srcs = glob(["source/opt/*.cpp"]) + [ - ":gen_vendor_tables_spv_amd_shader_ballot", - ], - hdrs = glob(["source/opt/*.h"]) + [ - "include/spirv-tools/instrument.hpp", - "include/spirv-tools/optimizer.hpp", - ], - copts = COMMON_COPTS, - deps = [ - ":spirv_tools_internal", + ":spirv_tools_headers", + ":spirv_tools_opt_headers", "@spirv_headers//:spirv_common_headers", ], ) @@ -209,9 +214,11 @@ cc_library( srcs = glob(["source/reduce/*.cpp"]), hdrs = glob(["source/reduce/*.h"]), copts = COMMON_COPTS, + linkstatic = 1, + visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", + ":spirv_tools", + ":spirv_tools_opt", ], ) @@ -223,38 +230,21 @@ cc_library( linkstatic = 1, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - ], -) - -cc_library( - name = "spirv_tools_lint_internal", - srcs = glob([ - "source/lint/*.cpp", - "source/lint/*.h", - ]), - hdrs = ["include/spirv-tools/linter.hpp"] + glob([ - "source/lint/*.h", - ]), - copts = COMMON_COPTS, - includes = ["include"], - deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", + ":spirv_tools", + ":spirv_tools_opt", ], ) cc_library( name = "spirv_tools_lint", + srcs = glob(["source/lint/*.cpp", "source/lint/*.h"]), hdrs = ["include/spirv-tools/linter.hpp"], copts = COMMON_COPTS, - includes = ["include"], linkstatic = 1, visibility = ["//visibility:public"], deps = [ ":spirv_tools", - ":spirv_tools_lint_internal", + ":spirv_tools_opt", ], ) @@ -263,28 +253,23 @@ cc_library( srcs = glob(["tools/util/*.cpp"]), hdrs = glob(["tools/util/*.h"]), copts = COMMON_COPTS, + linkstatic = 1, + visibility = ["//visibility:public"], deps = [":spirv_tools"], ) -cc_library( - name = "tools_io", - hdrs = ["tools/io.h"], - copts = COMMON_COPTS, -) - # Tools cc_binary( name = "spirv-as", srcs = [ "tools/as/as.cpp", + "tools/io.h", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":tools_io", - ":tools_util", + ":spirv_tools", ], ) @@ -292,44 +277,25 @@ cc_binary( name = "spirv-dis", srcs = [ "tools/dis/dis.cpp", + "tools/io.h", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ ":spirv_tools", - ":tools_io", - ":tools_util", - ], -) - -cc_binary( - name = "spirv-objdump", - srcs = [ - "tools/objdump/extract_source.cpp", - "tools/objdump/extract_source.h", - "tools/objdump/objdump.cpp", - ], - copts = COMMON_COPTS, - visibility = ["//visibility:public"], - deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - ":tools_io", - ":tools_util", - "@spirv_headers//:spirv_cpp_headers", ], ) cc_binary( name = "spirv-val", srcs = [ + "tools/io.h", "tools/val/val.cpp", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":tools_io", + ":spirv_tools", ":tools_util", ], ) @@ -337,14 +303,14 @@ cc_binary( cc_binary( name = "spirv-opt", srcs = [ + "tools/io.h", "tools/opt/opt.cpp", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - ":tools_io", + ":spirv_tools", + ":spirv_tools_opt", ":tools_util", ], ) @@ -352,15 +318,15 @@ cc_binary( cc_binary( name = "spirv-reduce", srcs = [ + "tools/io.h", "tools/reduce/reduce.cpp", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", + ":spirv_tools", + ":spirv_tools_opt", ":spirv_tools_reduce", - ":tools_io", ":tools_util", ], ) @@ -368,29 +334,28 @@ cc_binary( cc_binary( name = "spirv-link", srcs = [ + "tools/io.h", "tools/link/linker.cpp", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ - ":spirv_tools_internal", + ":spirv_tools", ":spirv_tools_link", - ":tools_io", - ":tools_util", ], ) cc_binary( name = "spirv-lint", srcs = [ + "tools/io.h", "tools/lint/lint.cpp", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], deps = [ + ":spirv_tools", ":spirv_tools_lint", - ":spirv_tools_opt_internal", - ":tools_io", ":tools_util", ], ) @@ -401,143 +366,50 @@ cc_binary( "tools/cfg/bin_to_dot.cpp", "tools/cfg/bin_to_dot.h", "tools/cfg/cfg.cpp", + "tools/io.h", ], copts = COMMON_COPTS, visibility = ["//visibility:public"], - deps = [ - ":spirv_tools_internal", - ":tools_io", - ":tools_util", - ], + deps = [":spirv_tools"], ) # Unit tests cc_library( - name = "test_lib", + name = "test_common", testonly = 1, srcs = [ - "test/unit_spirv.cpp", - ], - hdrs = [ "test/test_fixture.h", + "test/unit_spirv.cpp", "test/unit_spirv.h", ], + compatible_with = [], copts = TEST_COPTS, - deps = [ - ":spirv_tools_internal", - "@com_google_googletest//:gtest", - ], -) - -# PCH (precompiled header) tests only work when using CMake and MSVC on Windows, -# so they will be skipped in the Bazel builds. - -[cc_test( - name = "base_{testcase}_test".format(testcase = f[len("test/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS + ["-DTESTING"], - linkstatic = 1, - target_compatible_with = { - "test/timer_test.cpp": incompatible_with(["@bazel_tools//src/conditions:windows"]), - }.get(f, []), - deps = [ - "tools_util", - ":spirv_tools_internal", - ":test_lib", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob( - [ - "test/*_test.cpp", - "test/tools/*_test.cpp", - ], - exclude = [ - "test/cpp_interface_test.cpp", - "test/pch_test.cpp", - ], -)] - -cc_test( - name = "base_cpp_interface_test", - size = "small", - srcs = ["test/cpp_interface_test.cpp"], - linkstatic = 1, - deps = [ - ":spirv_tools_opt_internal", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - "@spirv_headers//:spirv_cpp11_headers", - ], -) - -cc_test( - name = "base_ilist_test", - size = "small", - srcs = ["test/util/ilist_test.cpp"], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":spirv_tools_internal", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "link_test_lib", - testonly = 1, - hdrs = ["test/link/linker_fixture.h"], - copts = TEST_COPTS, - deps = [ - ":spirv_tools_internal", - ":spirv_tools_link", - ":test_lib", - "@com_google_effcee//:effcee", - "@com_googlesource_code_re2//:re2", - ], -) - -[cc_test( - name = "link_{testcase}_test".format(testcase = f[len("test/link/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":link_test_lib", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob( - ["test/link/*_test.cpp"], -)] - -[cc_test( - name = "lint_{testcase}_test".format(testcase = f[len("test/lint/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, + includes = ["test"], linkstatic = 1, deps = [ ":spirv_tools", - ":spirv_tools_lint_internal", - ":spirv_tools_opt_internal", "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", ], -) for f in glob( - ["test/lint/*_test.cpp"], -)] +) cc_library( - name = "opt_test_lib", + name = "link_test_common", testonly = 1, - srcs = [ - "test/opt/pass_utils.cpp", + srcs = ["test/link/linker_fixture.h"], + compatible_with = [], + copts = TEST_COPTS, + linkstatic = 1, + deps = [ + ":spirv_tools_link", + ":test_common", ], +) + +cc_library( + name = "opt_test_common", + testonly = 1, + srcs = ["test/opt/pass_utils.cpp"], hdrs = [ "test/opt/assembly_builder.h", "test/opt/function_utils.h", @@ -545,181 +417,143 @@ cc_library( "test/opt/pass_fixture.h", "test/opt/pass_utils.h", ], + compatible_with = [], copts = TEST_COPTS, + linkstatic = 1, deps = [ - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - "@com_google_effcee//:effcee", - "@com_google_googletest//:gtest", + ":spirv_tools_opt", + ":test_common", ], ) -[cc_test( - name = "opt_{testcase}_test".format(testcase = f[len("test/opt/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":opt_test_lib", - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - ":test_lib", - "@com_google_effcee//:effcee", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob(["test/opt/*_test.cpp"])] - -[cc_test( - name = "opt_dom_tree_{testcase}_test".format(testcase = f[len("test/opt/dominator_tree/"):-len(".cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":opt_test_lib", - ":spirv_tools_opt_internal", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob( - ["test/opt/dominator_tree/*.cpp"], - exclude = ["test/opt/dominator_tree/pch_test_opt_dom.cpp"], -)] - -[cc_test( - name = "opt_loop_{testcase}_test".format(testcase = f[len("test/opt/loop_optimizations/"):-len(".cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":opt_test_lib", - ":spirv_tools", - ":spirv_tools_opt_internal", - "@com_google_effcee//:effcee", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob( - ["test/opt/loop_optimizations/*.cpp"], - exclude = ["test/opt/loop_optimizations/pch_test_opt_loop.cpp"], -)] - cc_library( - name = "reduce_test_lib", + name = "reduce_test_common", testonly = 1, srcs = [ "test/reduce/reduce_test_util.cpp", + "tools/io.h", ], hdrs = ["test/reduce/reduce_test_util.h"], + compatible_with = [], copts = TEST_COPTS, + linkstatic = 1, deps = [ - ":spirv_tools", - ":spirv_tools_opt_internal", ":spirv_tools_reduce", - ":test_lib", - ":tools_io", - "@com_google_googletest//:gtest", + ":test_common", ], ) -[cc_test( - name = "reduce_{testcase}_test".format(testcase = f[len("test/reduce/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":reduce_test_lib", - ":spirv_tools_internal", - ":spirv_tools_opt_internal", - ":spirv_tools_reduce", - "@com_google_googletest//:gtest_main", - ], -) for f in glob(["test/reduce/*_test.cpp"])] - -[cc_test( - name = "util_{testcase}_test".format(testcase = f[len("test/util/"):-len("_test.cpp")]), - size = "small", - srcs = [f], - copts = TEST_COPTS, - linkstatic = 1, - deps = [ - ":spirv_tools_internal", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) for f in glob(["test/util/*_test.cpp"])] - cc_library( - name = "val_test_lib", + name = "val_test_common", testonly = 1, srcs = [ "test/val/val_code_generator.cpp", + "test/val/val_fixtures.h", ], hdrs = [ "test/val/val_code_generator.h", - "test/val/val_fixtures.h", ], - copts = TEST_COPTS, - deps = [ - ":spirv_tools_internal", - ":test_lib", - ], -) - -[cc_test( - name = "val_{testcase}_test".format(testcase = f[len("test/val/val_"):-len("_test.cpp")]), - size = "small", - srcs = [f], + compatible_with = [], copts = TEST_COPTS, linkstatic = 1, - deps = [ - ":spirv_tools_internal", - ":test_lib", - ":val_test_lib", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], + deps = [":test_common"], +) + +# PCH (precompiled header) tests only work when using CMake and MSVC on Windows, +# so they will be skipped in the Bazel builds. + +[base_test( + name = f[5:-4], # strip test/, .cpp + srcs = [f], ) for f in glob( - ["test/val/val_*_test.cpp"], + ["test/*.cpp"], exclude = [ - "test/val/val_capability_test.cpp", - "test/val/val_limits_test.cpp", + "test/cpp_interface_test.cpp", # has its own base_test below. + "test/log_test.cpp", # has its own base_test below. + "test/pch_test.cpp", # pch tests are skipped. + "test/timer_test.cpp", # has its own base_test below. ], )] -cc_test( - name = "val_capability_test", - size = "large", - timeout = "long", - srcs = ["test/val/val_capability_test.cpp"], - copts = TEST_COPTS + ["-O3"], - linkstatic = 1, - deps = [ - ":spirv_tools_internal", - ":test_lib", - ":val_test_lib", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], +# This test uses unistd.h and does not run on Windows. +base_test( + name = "timer_test", + srcs = select({ + "@bazel_tools//src/conditions:windows": [], + "//conditions:default": ["test/timer_test.cpp"], + }), ) -cc_test( - name = "val_limits_test", - size = "large", - timeout = "long", - srcs = ["test/val/val_limits_test.cpp"], - copts = TEST_COPTS + [ - "-O3", - ], - linkstatic = 1, - deps = [ - ":test_lib", - ":val_test_lib", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], +base_test( + name = "cpp_interface_test", + srcs = ["test/cpp_interface_test.cpp"], + deps = [":spirv_tools_opt"], ) + +base_test( + name = "log_test", + srcs = ["test/log_test.cpp"], + deps = [":spirv_tools_opt"], +) + +[link_test( + name = f[10:-4], # strip test/link/, .cpp + srcs = [f], +) for f in glob( + ["test/link/*.cpp"], +)] + +[lint_test( + name = f[10:-4], # strip test/lint/, .cpp + srcs = [f], +) for f in glob( + ["test/lint/*.cpp"], +)] + +[opt_test( + name = f[9:-4], # strip test/opt/, .cpp + srcs = [f], +) for f in glob( + ["test/opt/*.cpp"], + # pch tests are skipped. + exclude = ["test/opt/pch_test_opt.cpp"], +)] + +[opt_test( + name = "dom_tree_" + f[24:-4], # strip test/opt/dominator_tree/, .cpp + srcs = [f], +) for f in glob( + ["test/opt/dominator_tree/*.cpp"], + # pch tests are skipped. + exclude = ["test/opt/dominator_tree/pch_test_opt_dom.cpp"], +)] + +[opt_test( + name = "loop_" + f[28:-4], # strip test/opt/loop_optimizations/, .cpp + srcs = [f], +) for f in glob( + ["test/opt/loop_optimizations/*.cpp"], + # pch tests are skipped. + exclude = ["test/opt/loop_optimizations/pch_test_opt_loop.cpp"], +)] + +[reduce_test( + name = f[12:-4], # strip test/reduce/, .cpp + srcs = [f], +) for f in glob(["test/reduce/*.cpp"])] + +[util_test( + name = f[10:-4], # strip test/util/, .cpp + srcs = [f], +) for f in glob(["test/util/*.cpp"])] + +[val_test( + name = f[9:-4], # strip test/val/, .cpp + srcs = [f], +) for f in glob( + ["test/val/*.cpp"], + exclude = [ + "test/val/pch_test_val.cpp", # pch tests are skipped. + ], +)] + diff --git a/BUILD.gn b/BUILD.gn index d50d58ef..f5fd1464 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -22,50 +22,30 @@ # FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS # IN THE MATERIALS. -import("//build/ohos.gni") -import("//third_party/vk-gl-cts/vk_gl_cts.gni") -if (build_with_chromium) { - import("//testing/test.gni") - import("//third_party/protobuf/proto_library.gni") -} - -# SPIRV-Tools may be part of multiple projects in the Chromium tree. -# Only enable building executables if this is the main copy. -abspath = get_path_info(".", "abspath") -spvtools_chromium_third_party = - abspath == "//third_party/vulkan-deps/spirv-tools/src/" -spvtools_build_executables = - build_with_chromium && spvtools_chromium_third_party - -# Fuchsia also requires building the executables. -# TODO(b/158002593): Avoid the use of dependent-specific variables. -if (defined(is_fuchsia_tree) && is_fuchsia_tree) { - spvtools_build_executables = true -} - -spirv_is_winuwp = is_win && target_os == "winuwp" - config("spv_headers_public_config") { include_dirs = [ "include" ] } -ohos_source_set("spv_headers") { +source_set("spv_headers") { sources = [ - "include/spirv/1.2/GLSL.std.450.h", - "include/spirv/1.2/OpenCL.std.h", - "include/spirv/1.2/spirv.h", - "include/spirv/1.2/spirv.hpp", - "include/spirv/unified1/GLSL.std.450.h", - "include/spirv/unified1/NonSemanticClspvReflection.h", - "include/spirv/unified1/NonSemanticDebugPrintf.h", - "include/spirv/unified1/OpenCL.std.h", - "include/spirv/unified1/spirv.h", - "include/spirv/unified1/spirv.hpp", + #"include/spirv/1.2/GLSL.std.450.h", + #"include/spirv/1.2/OpenCL.std.h", + #"include/spirv/1.2/spirv.h", + #"include/spirv/1.2/spirv.hpp", + #"include/spirv/unified1/GLSL.std.450.h", + #"include/spirv/unified1/NonSemanticClspvReflection.h", + #"include/spirv/unified1/NonSemanticDebugPrintf.h", + #"include/spirv/unified1/OpenCL.std.h", + #"include/spirv/unified1/spirv.h", + #"include/spirv/unified1/spirv.hpp", ] public_configs = [ ":spv_headers_public_config" ] } +import("//build/ohos.gni") +import("//third_party/vk-gl-cts/vk_gl_cts.gni") + config("deqp_spirvtool_config") { cflags_cc = deqp_common_cflags_cc cflags_cc += [ @@ -83,342 +63,78 @@ config("deqp_spirvtool_config") { ] } -template("spvtools_core_tables") { - assert(defined(invoker.version), "Need version in $target_name generation.") - - action("spvtools_core_tables_" + target_name) { - script = "utils/generate_grammar_tables.py" - - version = invoker.version - - core_json_file = "//third_party/spirv-headers/include/spirv/$version/spirv.core.grammar.json" - core_insts_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/core.insts-$version.inc" - operand_kinds_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/operand.kinds-$version.inc" - debuginfo_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json" - cldebuginfo100_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json" - - sources = [ - cldebuginfo100_insts_file, - core_json_file, - debuginfo_insts_file, - ] - outputs = [ - core_insts_file, - operand_kinds_file, - ] - args = [ - "--spirv-core-grammar", - rebase_path(core_json_file, root_build_dir), - "--core-insts-output", - rebase_path(core_insts_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debuginfo_insts_file, root_build_dir), - "--extinst-cldebuginfo100-grammar", - rebase_path(cldebuginfo100_insts_file, root_build_dir), - "--operand-kinds-output", - rebase_path(operand_kinds_file, root_build_dir), - "--output-language", - "c++", - ] - } -} - -template("spvtools_core_enums") { - assert(defined(invoker.version), "Need version in $target_name generation.") - - action("spvtools_core_enums_" + target_name) { - script = "utils/generate_grammar_tables.py" - - version = invoker.version - - core_json_file = "//third_party/spirv-headers/include/spirv/$version/spirv.core.grammar.json" - debuginfo_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json" - cldebuginfo100_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json" - - extension_enum_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/extension_enum.inc" - extension_map_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/enum_string_mapping.inc" - - args = [ - "--spirv-core-grammar", - rebase_path(core_json_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debuginfo_insts_file, root_build_dir), - "--extinst-cldebuginfo100-grammar", - rebase_path(cldebuginfo100_insts_file, root_build_dir), - "--extension-enum-output", - rebase_path(extension_enum_file, root_build_dir), - "--enum-string-mapping-output", - rebase_path(extension_map_file, root_build_dir), - "--output-language", - "c++", - ] - inputs = [ - core_json_file, - debuginfo_insts_file, - cldebuginfo100_insts_file, - ] - outputs = [ - extension_enum_file, - extension_map_file, - ] - } -} - -template("spvtools_glsl_tables") { - assert(defined(invoker.version), "Need version in $target_name generation.") - - action("spvtools_glsl_tables_" + target_name) { - script = "utils/generate_grammar_tables.py" - - version = invoker.version - - core_json_file = "//third_party/spirv-headers/include/spirv/$version/spirv.core.grammar.json" - glsl_json_file = "//third_party/spirv-headers/include/spirv/${version}/extinst.glsl.std.450.grammar.json" - debuginfo_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json" - cldebuginfo100_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json" - - glsl_insts_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/glsl.std.450.insts.inc" - - args = [ - "--spirv-core-grammar", - rebase_path(core_json_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debuginfo_insts_file, root_build_dir), - "--extinst-cldebuginfo100-grammar", - rebase_path(cldebuginfo100_insts_file, root_build_dir), - "--extinst-glsl-grammar", - rebase_path(glsl_json_file, root_build_dir), - "--glsl-insts-output", - rebase_path(glsl_insts_file, root_build_dir), - "--output-language", - "c++", - ] - inputs = [ - core_json_file, - glsl_json_file, - debuginfo_insts_file, - cldebuginfo100_insts_file, - ] - outputs = [ glsl_insts_file ] - } -} - -template("spvtools_opencl_tables") { - assert(defined(invoker.version), "Need version in $target_name generation.") - - action("spvtools_opencl_tables_" + target_name) { - script = "utils/generate_grammar_tables.py" - - version = invoker.version - - core_json_file = "//third_party/spirv-headers/include/spirv/$version/spirv.core.grammar.json" - opencl_json_file = "//third_party/spirv-headers/include/spirv/${version}/extinst.opencl.std.100.grammar.json" - debuginfo_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.debuginfo.grammar.json" - cldebuginfo100_insts_file = "//third_party/spirv-headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json" - - opencl_insts_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/opencl.std.insts.inc" - - args = [ - "--spirv-core-grammar", - rebase_path(core_json_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debuginfo_insts_file, root_build_dir), - "--extinst-cldebuginfo100-grammar", - rebase_path(cldebuginfo100_insts_file, root_build_dir), - "--extinst-opencl-grammar", - rebase_path(opencl_json_file, root_build_dir), - "--opencl-insts-output", - rebase_path(opencl_insts_file, root_build_dir), - ] - inputs = [ - core_json_file, - opencl_json_file, - debuginfo_insts_file, - cldebuginfo100_insts_file, - ] - outputs = [ opencl_insts_file ] - } -} - -template("spvtools_language_header") { - assert(defined(invoker.name), "Need name in $target_name generation.") - - action("spvtools_language_header_" + target_name) { - script = "utils/generate_language_headers.py" - - name = invoker.name - extinst_output_path = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/${name}.h" - - args = [ - "--extinst-grammar", - rebase_path(invoker.grammar_file, root_build_dir), - "--extinst-output-path", - rebase_path(extinst_output_path, root_build_dir), - ] - inputs = [ invoker.grammar_file ] - outputs = [ "${extinst_output_path}" ] - } -} - -template("spvtools_vendor_table") { - assert(defined(invoker.name), "Need name in $target_name generation.") - - action("spvtools_vendor_tables_" + target_name) { - script = "utils/generate_grammar_tables.py" - - name = invoker.name - extinst_vendor_grammar = "//third_party/spirv-headers/include/spirv/unified1/extinst.${name}.grammar.json" - extinst_file = "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools/${name}.insts.inc" - - args = [ - "--extinst-vendor-grammar", - rebase_path(extinst_vendor_grammar, root_build_dir), - "--vendor-insts-output", - rebase_path(extinst_file, root_build_dir), - "--vendor-operand-kind-prefix", - invoker.operand_kind_prefix, - ] - inputs = [ extinst_vendor_grammar ] - outputs = [ extinst_file ] - } -} - -config("spvtools_include_gen_dirs") { - include_dirs = - [ "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools" ] -} - -config("spvtools_internal_config") { - include_dirs = [ - ".", - "//third_party/spirv-headers/include", - ] - - configs = [ - ":spv_headers_public_config", - ":spvtools_include_gen_dirs", - ] - - cflags = [] - if (is_clang) { - cflags += [ - "-Wno-implicit-fallthrough", - "-Wno-newline-eof", - "-Wno-unreachable-code-break", - "-Wno-unreachable-code-return", - ] - } else if (!is_win) { - # Work around a false-positive on a Skia GCC 10 builder. - cflags += [ "-Wno-format-truncation" ] - } else { - # Make MSVC report the correct value for __cplusplus - cflags += [ "/Zc:__cplusplus" ] - } - - if (!is_win) { - cflags += [ "-std=c++17" ] - } else { - cflags += [ "/std:c++17" ] - } -} - -ohos_source_set("spvtools_headers") { - sources = [ - "include/spirv-tools/instrument.hpp", - "include/spirv-tools/libspirv.h", - "include/spirv-tools/libspirv.hpp", - "include/spirv-tools/linker.hpp", - "include/spirv-tools/optimizer.hpp", - ] - - public_configs = [ ":spv_headers_public_config" ] -} - ohos_source_set("deqp_spirvtool_source") { sources = [ - "include/spirv-tools/instrument.hpp", - "include/spirv-tools/libspirv.h", - "include/spirv-tools/libspirv.hpp", - "include/spirv-tools/linker.hpp", - "include/spirv-tools/optimizer.hpp", - "include/spirv/1.2/GLSL.std.450.h", - "include/spirv/1.2/OpenCL.std.h", - "include/spirv/1.2/spirv.h", - "include/spirv/1.2/spirv.hpp", - "include/spirv/unified1/GLSL.std.450.h", - "include/spirv/unified1/NonSemanticClspvReflection.h", - "include/spirv/unified1/NonSemanticDebugPrintf.h", - "include/spirv/unified1/OpenCL.std.h", - "include/spirv/unified1/spirv.h", - "include/spirv/unified1/spirv.hpp", - "source/assembly_grammar.cpp", - "source/assembly_grammar.h", - "source/binary.cpp", - "source/binary.h", - "source/cfa.h", - "source/common_debug_info.h", - "source/diagnostic.cpp", - "source/diagnostic.h", - "source/disassemble.cpp", - "source/disassemble.h", - "source/enum_set.h", - "source/enum_string_mapping.cpp", - "source/enum_string_mapping.h", - "source/ext_inst.cpp", - "source/ext_inst.h", - "source/extensions.cpp", - "source/extensions.h", - "source/instruction.h", - "source/latest_version_glsl_std_450_header.h", - "source/latest_version_opencl_std_header.h", - "source/latest_version_spirv_header.h", - "source/libspirv.cpp", - "source/macro.h", - "source/name_mapper.cpp", - "source/name_mapper.h", - "source/opcode.cpp", - "source/opcode.h", - "source/operand.cpp", - "source/operand.h", - "source/parsed_operand.cpp", - "source/parsed_operand.h", - "source/print.cpp", - "source/print.h", - "source/spirv_constant.h", - "source/spirv_definition.h", - "source/spirv_endian.cpp", - "source/spirv_endian.h", - "source/spirv_fuzzer_options.cpp", - "source/spirv_fuzzer_options.h", - "source/spirv_optimizer_options.cpp", - "source/spirv_optimizer_options.h", - "source/spirv_reducer_options.cpp", - "source/spirv_reducer_options.h", - "source/spirv_target_env.cpp", - "source/spirv_target_env.h", - "source/spirv_validator_options.cpp", - "source/spirv_validator_options.h", - "source/table.cpp", - "source/table.h", - "source/text.cpp", - "source/text.h", - "source/text_handler.cpp", - "source/text_handler.h", - "source/util/bit_vector.cpp", - "source/util/bit_vector.h", - "source/util/bitutils.h", - "source/util/hash_combine.h", - "source/util/hex_float.h", - "source/util/ilist.h", - "source/util/ilist_node.h", - "source/util/make_unique.h", - "source/util/parse_number.cpp", - "source/util/parse_number.h", - "source/util/small_vector.h", - "source/util/string_utils.cpp", - "source/util/string_utils.h", - "source/util/timer.cpp", - "source/util/timer.h", + "//third_party/spirv-tools/source/assembly_grammar.cpp", + "//third_party/spirv-tools/source/binary.cpp", + "//third_party/spirv-tools/source/diagnostic.cpp", + "//third_party/spirv-tools/source/disassemble.cpp", + "//third_party/spirv-tools/source/enum_string_mapping.cpp", + "//third_party/spirv-tools/source/ext_inst.cpp", + "//third_party/spirv-tools/source/extensions.cpp", + "//third_party/spirv-tools/source/libspirv.cpp", + "//third_party/spirv-tools/source/name_mapper.cpp", + "//third_party/spirv-tools/source/opcode.cpp", + "//third_party/spirv-tools/source/operand.cpp", + "//third_party/spirv-tools/source/parsed_operand.cpp", + "//third_party/spirv-tools/source/print.cpp", + "//third_party/spirv-tools/source/software_version.cpp", + "//third_party/spirv-tools/source/spirv_endian.cpp", + "//third_party/spirv-tools/source/spirv_fuzzer_options.cpp", + "//third_party/spirv-tools/source/spirv_optimizer_options.cpp", + "//third_party/spirv-tools/source/spirv_reducer_options.cpp", + "//third_party/spirv-tools/source/spirv_target_env.cpp", + "//third_party/spirv-tools/source/spirv_validator_options.cpp", + "//third_party/spirv-tools/source/table.cpp", + "//third_party/spirv-tools/source/text.cpp", + "//third_party/spirv-tools/source/text_handler.cpp", + "//third_party/spirv-tools/source/util/bit_vector.cpp", + "//third_party/spirv-tools/source/util/parse_number.cpp", + "//third_party/spirv-tools/source/util/string_utils.cpp", + "//third_party/spirv-tools/source/util/timer.cpp", + "//third_party/spirv-tools/source/val/basic_block.cpp", + "//third_party/spirv-tools/source/val/construct.cpp", + "//third_party/spirv-tools/source/val/function.cpp", + "//third_party/spirv-tools/source/val/instruction.cpp", + "//third_party/spirv-tools/source/val/validate.cpp", + "//third_party/spirv-tools/source/val/validate_adjacency.cpp", + "//third_party/spirv-tools/source/val/validate_annotation.cpp", + "//third_party/spirv-tools/source/val/validate_arithmetics.cpp", + "//third_party/spirv-tools/source/val/validate_atomics.cpp", + "//third_party/spirv-tools/source/val/validate_barriers.cpp", + "//third_party/spirv-tools/source/val/validate_bitwise.cpp", + "//third_party/spirv-tools/source/val/validate_builtins.cpp", + "//third_party/spirv-tools/source/val/validate_capability.cpp", + "//third_party/spirv-tools/source/val/validate_cfg.cpp", + "//third_party/spirv-tools/source/val/validate_composites.cpp", + "//third_party/spirv-tools/source/val/validate_constants.cpp", + "//third_party/spirv-tools/source/val/validate_conversion.cpp", + "//third_party/spirv-tools/source/val/validate_debug.cpp", + "//third_party/spirv-tools/source/val/validate_decorations.cpp", + "//third_party/spirv-tools/source/val/validate_derivatives.cpp", + "//third_party/spirv-tools/source/val/validate_execution_limitations.cpp", + "//third_party/spirv-tools/source/val/validate_extensions.cpp", + "//third_party/spirv-tools/source/val/validate_function.cpp", + "//third_party/spirv-tools/source/val/validate_id.cpp", + "//third_party/spirv-tools/source/val/validate_image.cpp", + "//third_party/spirv-tools/source/val/validate_instruction.cpp", + "//third_party/spirv-tools/source/val/validate_interfaces.cpp", + "//third_party/spirv-tools/source/val/validate_layout.cpp", + "//third_party/spirv-tools/source/val/validate_literals.cpp", + "//third_party/spirv-tools/source/val/validate_logicals.cpp", + "//third_party/spirv-tools/source/val/validate_memory.cpp", + "//third_party/spirv-tools/source/val/validate_memory_semantics.cpp", + "//third_party/spirv-tools/source/val/validate_mesh_shading.cpp", + "//third_party/spirv-tools/source/val/validate_misc.cpp", + "//third_party/spirv-tools/source/val/validate_mode_setting.cpp", + "//third_party/spirv-tools/source/val/validate_non_uniform.cpp", + "//third_party/spirv-tools/source/val/validate_primitives.cpp", + "//third_party/spirv-tools/source/val/validate_ray_query.cpp", + "//third_party/spirv-tools/source/val/validate_ray_tracing.cpp", + "//third_party/spirv-tools/source/val/validate_scopes.cpp", + "//third_party/spirv-tools/source/val/validate_small_type_uses.cpp", + "//third_party/spirv-tools/source/val/validate_type.cpp", + "//third_party/spirv-tools/source/val/validation_state.cpp", ] include_dirs = deqp_common_include_dirs @@ -429,13 +145,7 @@ ohos_source_set("deqp_spirvtool_source") { "//third_party/spirv-tools/include", ] - if (build_with_chromium) { - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - } - - configs = [ ":spvtools_internal_config" ] - configs += [ ":spv_headers_public_config" ] + configs = [ ":deqp_spirvtool_config" ] } ohos_static_library("libdeqp_spirvtools") { @@ -443,567 +153,3 @@ ohos_static_library("libdeqp_spirvtools") { part_name = "graphic_2d" subsystem_name = "graphic" } - -if (build_with_chromium && spvtools_build_executables) { - # The spirv-fuzz library is only built when in a Chromium checkout - # due to its dependency on protobuf. - - proto_library("spvtools_fuzz_proto") { - sources = [ "source/fuzz/protobufs/spvtoolsfuzz.proto" ] - generate_python = false - use_protobuf_full = true - } - - ohos_static_library("spvtools_fuzz") { - sources = [ - "source/fuzz/added_function_reducer.cpp", - "source/fuzz/added_function_reducer.h", - "source/fuzz/available_instructions.cpp", - "source/fuzz/available_instructions.h", - "source/fuzz/call_graph.cpp", - "source/fuzz/call_graph.h", - "source/fuzz/comparator_deep_blocks_first.h", - "source/fuzz/counter_overflow_id_source.cpp", - "source/fuzz/counter_overflow_id_source.h", - "source/fuzz/data_descriptor.cpp", - "source/fuzz/data_descriptor.h", - "source/fuzz/equivalence_relation.h", - "source/fuzz/fact_manager/constant_uniform_facts.cpp", - "source/fuzz/fact_manager/constant_uniform_facts.h", - "source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp", - "source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h", - "source/fuzz/fact_manager/dead_block_facts.cpp", - "source/fuzz/fact_manager/dead_block_facts.h", - "source/fuzz/fact_manager/fact_manager.cpp", - "source/fuzz/fact_manager/fact_manager.h", - "source/fuzz/fact_manager/irrelevant_value_facts.cpp", - "source/fuzz/fact_manager/irrelevant_value_facts.h", - "source/fuzz/fact_manager/livesafe_function_facts.cpp", - "source/fuzz/fact_manager/livesafe_function_facts.h", - "source/fuzz/force_render_red.cpp", - "source/fuzz/force_render_red.h", - "source/fuzz/fuzzer.cpp", - "source/fuzz/fuzzer.h", - "source/fuzz/fuzzer_context.cpp", - "source/fuzz/fuzzer_context.h", - "source/fuzz/fuzzer_pass.cpp", - "source/fuzz/fuzzer_pass.h", - "source/fuzz/fuzzer_pass_add_access_chains.cpp", - "source/fuzz/fuzzer_pass_add_access_chains.h", - "source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.cpp", - "source/fuzz/fuzzer_pass_add_bit_instruction_synonyms.h", - "source/fuzz/fuzzer_pass_add_composite_extract.cpp", - "source/fuzz/fuzzer_pass_add_composite_extract.h", - "source/fuzz/fuzzer_pass_add_composite_inserts.cpp", - "source/fuzz/fuzzer_pass_add_composite_inserts.h", - "source/fuzz/fuzzer_pass_add_composite_types.cpp", - "source/fuzz/fuzzer_pass_add_composite_types.h", - "source/fuzz/fuzzer_pass_add_copy_memory.cpp", - "source/fuzz/fuzzer_pass_add_copy_memory.h", - "source/fuzz/fuzzer_pass_add_dead_blocks.cpp", - "source/fuzz/fuzzer_pass_add_dead_blocks.h", - "source/fuzz/fuzzer_pass_add_dead_breaks.cpp", - "source/fuzz/fuzzer_pass_add_dead_breaks.h", - "source/fuzz/fuzzer_pass_add_dead_continues.cpp", - "source/fuzz/fuzzer_pass_add_dead_continues.h", - "source/fuzz/fuzzer_pass_add_equation_instructions.cpp", - "source/fuzz/fuzzer_pass_add_equation_instructions.h", - "source/fuzz/fuzzer_pass_add_function_calls.cpp", - "source/fuzz/fuzzer_pass_add_function_calls.h", - "source/fuzz/fuzzer_pass_add_global_variables.cpp", - "source/fuzz/fuzzer_pass_add_global_variables.h", - "source/fuzz/fuzzer_pass_add_image_sample_unused_components.cpp", - "source/fuzz/fuzzer_pass_add_image_sample_unused_components.h", - "source/fuzz/fuzzer_pass_add_loads.cpp", - "source/fuzz/fuzzer_pass_add_loads.h", - "source/fuzz/fuzzer_pass_add_local_variables.cpp", - "source/fuzz/fuzzer_pass_add_local_variables.h", - "source/fuzz/fuzzer_pass_add_loop_preheaders.cpp", - "source/fuzz/fuzzer_pass_add_loop_preheaders.h", - "source/fuzz/fuzzer_pass_add_loops_to_create_int_constant_synonyms.cpp", - "source/fuzz/fuzzer_pass_add_loops_to_create_int_constant_synonyms.h", - "source/fuzz/fuzzer_pass_add_no_contraction_decorations.cpp", - "source/fuzz/fuzzer_pass_add_no_contraction_decorations.h", - "source/fuzz/fuzzer_pass_add_opphi_synonyms.cpp", - "source/fuzz/fuzzer_pass_add_opphi_synonyms.h", - "source/fuzz/fuzzer_pass_add_parameters.cpp", - "source/fuzz/fuzzer_pass_add_parameters.h", - "source/fuzz/fuzzer_pass_add_relaxed_decorations.cpp", - "source/fuzz/fuzzer_pass_add_relaxed_decorations.h", - "source/fuzz/fuzzer_pass_add_stores.cpp", - "source/fuzz/fuzzer_pass_add_stores.h", - "source/fuzz/fuzzer_pass_add_synonyms.cpp", - "source/fuzz/fuzzer_pass_add_synonyms.h", - "source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.cpp", - "source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.h", - "source/fuzz/fuzzer_pass_adjust_branch_weights.cpp", - "source/fuzz/fuzzer_pass_adjust_branch_weights.h", - "source/fuzz/fuzzer_pass_adjust_function_controls.cpp", - "source/fuzz/fuzzer_pass_adjust_function_controls.h", - "source/fuzz/fuzzer_pass_adjust_loop_controls.cpp", - "source/fuzz/fuzzer_pass_adjust_loop_controls.h", - "source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp", - "source/fuzz/fuzzer_pass_adjust_memory_operands_masks.h", - "source/fuzz/fuzzer_pass_adjust_selection_controls.cpp", - "source/fuzz/fuzzer_pass_adjust_selection_controls.h", - "source/fuzz/fuzzer_pass_apply_id_synonyms.cpp", - "source/fuzz/fuzzer_pass_apply_id_synonyms.h", - "source/fuzz/fuzzer_pass_construct_composites.cpp", - "source/fuzz/fuzzer_pass_construct_composites.h", - "source/fuzz/fuzzer_pass_copy_objects.cpp", - "source/fuzz/fuzzer_pass_copy_objects.h", - "source/fuzz/fuzzer_pass_donate_modules.cpp", - "source/fuzz/fuzzer_pass_donate_modules.h", - "source/fuzz/fuzzer_pass_duplicate_regions_with_selections.cpp", - "source/fuzz/fuzzer_pass_duplicate_regions_with_selections.h", - "source/fuzz/fuzzer_pass_expand_vector_reductions.cpp", - "source/fuzz/fuzzer_pass_expand_vector_reductions.h", - "source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp", - "source/fuzz/fuzzer_pass_flatten_conditional_branches.h", - "source/fuzz/fuzzer_pass_inline_functions.cpp", - "source/fuzz/fuzzer_pass_inline_functions.h", - "source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.cpp", - "source/fuzz/fuzzer_pass_interchange_signedness_of_integer_operands.h", - "source/fuzz/fuzzer_pass_interchange_zero_like_constants.cpp", - "source/fuzz/fuzzer_pass_interchange_zero_like_constants.h", - "source/fuzz/fuzzer_pass_invert_comparison_operators.cpp", - "source/fuzz/fuzzer_pass_invert_comparison_operators.h", - "source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp", - "source/fuzz/fuzzer_pass_make_vector_operations_dynamic.h", - "source/fuzz/fuzzer_pass_merge_blocks.cpp", - "source/fuzz/fuzzer_pass_merge_blocks.h", - "source/fuzz/fuzzer_pass_merge_function_returns.cpp", - "source/fuzz/fuzzer_pass_merge_function_returns.h", - "source/fuzz/fuzzer_pass_mutate_pointers.cpp", - "source/fuzz/fuzzer_pass_mutate_pointers.h", - "source/fuzz/fuzzer_pass_obfuscate_constants.cpp", - "source/fuzz/fuzzer_pass_obfuscate_constants.h", - "source/fuzz/fuzzer_pass_outline_functions.cpp", - "source/fuzz/fuzzer_pass_outline_functions.h", - "source/fuzz/fuzzer_pass_permute_blocks.cpp", - "source/fuzz/fuzzer_pass_permute_blocks.h", - "source/fuzz/fuzzer_pass_permute_function_parameters.cpp", - "source/fuzz/fuzzer_pass_permute_function_parameters.h", - "source/fuzz/fuzzer_pass_permute_function_variables.cpp", - "source/fuzz/fuzzer_pass_permute_function_variables.h", - "source/fuzz/fuzzer_pass_permute_instructions.cpp", - "source/fuzz/fuzzer_pass_permute_instructions.h", - "source/fuzz/fuzzer_pass_permute_phi_operands.cpp", - "source/fuzz/fuzzer_pass_permute_phi_operands.h", - "source/fuzz/fuzzer_pass_propagate_instructions_down.cpp", - "source/fuzz/fuzzer_pass_propagate_instructions_down.h", - "source/fuzz/fuzzer_pass_propagate_instructions_up.cpp", - "source/fuzz/fuzzer_pass_propagate_instructions_up.h", - "source/fuzz/fuzzer_pass_push_ids_through_variables.cpp", - "source/fuzz/fuzzer_pass_push_ids_through_variables.h", - "source/fuzz/fuzzer_pass_replace_adds_subs_muls_with_carrying_extended.cpp", - "source/fuzz/fuzzer_pass_replace_adds_subs_muls_with_carrying_extended.h", - "source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.cpp", - "source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.h", - "source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.cpp", - "source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.h", - "source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.cpp", - "source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.h", - "source/fuzz/fuzzer_pass_replace_irrelevant_ids.cpp", - "source/fuzz/fuzzer_pass_replace_irrelevant_ids.h", - "source/fuzz/fuzzer_pass_replace_linear_algebra_instructions.cpp", - "source/fuzz/fuzzer_pass_replace_linear_algebra_instructions.h", - "source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.cpp", - "source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.h", - "source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.cpp", - "source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.h", - "source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.cpp", - "source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.h", - "source/fuzz/fuzzer_pass_replace_parameter_with_global.cpp", - "source/fuzz/fuzzer_pass_replace_parameter_with_global.h", - "source/fuzz/fuzzer_pass_replace_params_with_struct.cpp", - "source/fuzz/fuzzer_pass_replace_params_with_struct.h", - "source/fuzz/fuzzer_pass_split_blocks.cpp", - "source/fuzz/fuzzer_pass_split_blocks.h", - "source/fuzz/fuzzer_pass_swap_commutable_operands.cpp", - "source/fuzz/fuzzer_pass_swap_commutable_operands.h", - "source/fuzz/fuzzer_pass_swap_conditional_branch_operands.cpp", - "source/fuzz/fuzzer_pass_swap_conditional_branch_operands.h", - "source/fuzz/fuzzer_pass_swap_functions.cpp", - "source/fuzz/fuzzer_pass_swap_functions.h", - "source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp", - "source/fuzz/fuzzer_pass_toggle_access_chain_instruction.h", - "source/fuzz/fuzzer_pass_wrap_regions_in_selections.cpp", - "source/fuzz/fuzzer_pass_wrap_regions_in_selections.h", - "source/fuzz/fuzzer_pass_wrap_vector_synonym.cpp", - "source/fuzz/fuzzer_pass_wrap_vector_synonym.h", - "source/fuzz/fuzzer_util.cpp", - "source/fuzz/fuzzer_util.h", - "source/fuzz/id_use_descriptor.cpp", - "source/fuzz/id_use_descriptor.h", - "source/fuzz/instruction_descriptor.cpp", - "source/fuzz/instruction_descriptor.h", - "source/fuzz/instruction_message.cpp", - "source/fuzz/instruction_message.h", - "source/fuzz/overflow_id_source.cpp", - "source/fuzz/overflow_id_source.h", - "source/fuzz/pass_management/repeated_pass_instances.h", - "source/fuzz/pass_management/repeated_pass_manager.cpp", - "source/fuzz/pass_management/repeated_pass_manager.h", - "source/fuzz/pass_management/repeated_pass_manager_looped_with_recommendations.cpp", - "source/fuzz/pass_management/repeated_pass_manager_looped_with_recommendations.h", - "source/fuzz/pass_management/repeated_pass_manager_random_with_recommendations.cpp", - "source/fuzz/pass_management/repeated_pass_manager_random_with_recommendations.h", - "source/fuzz/pass_management/repeated_pass_manager_simple.cpp", - "source/fuzz/pass_management/repeated_pass_manager_simple.h", - "source/fuzz/pass_management/repeated_pass_recommender.cpp", - "source/fuzz/pass_management/repeated_pass_recommender.h", - "source/fuzz/pass_management/repeated_pass_recommender_standard.cpp", - "source/fuzz/pass_management/repeated_pass_recommender_standard.h", - "source/fuzz/protobufs/spirvfuzz_protobufs.h", - "source/fuzz/pseudo_random_generator.cpp", - "source/fuzz/pseudo_random_generator.h", - "source/fuzz/random_generator.cpp", - "source/fuzz/random_generator.h", - "source/fuzz/replayer.cpp", - "source/fuzz/replayer.h", - "source/fuzz/shrinker.cpp", - "source/fuzz/shrinker.h", - "source/fuzz/transformation.cpp", - "source/fuzz/transformation.h", - "source/fuzz/transformation_access_chain.cpp", - "source/fuzz/transformation_access_chain.h", - "source/fuzz/transformation_add_bit_instruction_synonym.cpp", - "source/fuzz/transformation_add_bit_instruction_synonym.h", - "source/fuzz/transformation_add_constant_boolean.cpp", - "source/fuzz/transformation_add_constant_boolean.h", - "source/fuzz/transformation_add_constant_composite.cpp", - "source/fuzz/transformation_add_constant_composite.h", - "source/fuzz/transformation_add_constant_null.cpp", - "source/fuzz/transformation_add_constant_null.h", - "source/fuzz/transformation_add_constant_scalar.cpp", - "source/fuzz/transformation_add_constant_scalar.h", - "source/fuzz/transformation_add_copy_memory.cpp", - "source/fuzz/transformation_add_copy_memory.h", - "source/fuzz/transformation_add_dead_block.cpp", - "source/fuzz/transformation_add_dead_block.h", - "source/fuzz/transformation_add_dead_break.cpp", - "source/fuzz/transformation_add_dead_break.h", - "source/fuzz/transformation_add_dead_continue.cpp", - "source/fuzz/transformation_add_dead_continue.h", - "source/fuzz/transformation_add_early_terminator_wrapper.cpp", - "source/fuzz/transformation_add_early_terminator_wrapper.h", - "source/fuzz/transformation_add_function.cpp", - "source/fuzz/transformation_add_function.h", - "source/fuzz/transformation_add_global_undef.cpp", - "source/fuzz/transformation_add_global_undef.h", - "source/fuzz/transformation_add_global_variable.cpp", - "source/fuzz/transformation_add_global_variable.h", - "source/fuzz/transformation_add_image_sample_unused_components.cpp", - "source/fuzz/transformation_add_image_sample_unused_components.h", - "source/fuzz/transformation_add_local_variable.cpp", - "source/fuzz/transformation_add_local_variable.h", - "source/fuzz/transformation_add_loop_preheader.cpp", - "source/fuzz/transformation_add_loop_preheader.h", - "source/fuzz/transformation_add_loop_to_create_int_constant_synonym.cpp", - "source/fuzz/transformation_add_loop_to_create_int_constant_synonym.h", - "source/fuzz/transformation_add_no_contraction_decoration.cpp", - "source/fuzz/transformation_add_no_contraction_decoration.h", - "source/fuzz/transformation_add_opphi_synonym.cpp", - "source/fuzz/transformation_add_opphi_synonym.h", - "source/fuzz/transformation_add_parameter.cpp", - "source/fuzz/transformation_add_parameter.h", - "source/fuzz/transformation_add_relaxed_decoration.cpp", - "source/fuzz/transformation_add_relaxed_decoration.h", - "source/fuzz/transformation_add_spec_constant_op.cpp", - "source/fuzz/transformation_add_spec_constant_op.h", - "source/fuzz/transformation_add_synonym.cpp", - "source/fuzz/transformation_add_synonym.h", - "source/fuzz/transformation_add_type_array.cpp", - "source/fuzz/transformation_add_type_array.h", - "source/fuzz/transformation_add_type_boolean.cpp", - "source/fuzz/transformation_add_type_boolean.h", - "source/fuzz/transformation_add_type_float.cpp", - "source/fuzz/transformation_add_type_float.h", - "source/fuzz/transformation_add_type_function.cpp", - "source/fuzz/transformation_add_type_function.h", - "source/fuzz/transformation_add_type_int.cpp", - "source/fuzz/transformation_add_type_int.h", - "source/fuzz/transformation_add_type_matrix.cpp", - "source/fuzz/transformation_add_type_matrix.h", - "source/fuzz/transformation_add_type_pointer.cpp", - "source/fuzz/transformation_add_type_pointer.h", - "source/fuzz/transformation_add_type_struct.cpp", - "source/fuzz/transformation_add_type_struct.h", - "source/fuzz/transformation_add_type_vector.cpp", - "source/fuzz/transformation_add_type_vector.h", - "source/fuzz/transformation_adjust_branch_weights.cpp", - "source/fuzz/transformation_adjust_branch_weights.h", - "source/fuzz/transformation_composite_construct.cpp", - "source/fuzz/transformation_composite_construct.h", - "source/fuzz/transformation_composite_extract.cpp", - "source/fuzz/transformation_composite_extract.h", - "source/fuzz/transformation_composite_insert.cpp", - "source/fuzz/transformation_composite_insert.h", - "source/fuzz/transformation_compute_data_synonym_fact_closure.cpp", - "source/fuzz/transformation_compute_data_synonym_fact_closure.h", - "source/fuzz/transformation_context.cpp", - "source/fuzz/transformation_context.h", - "source/fuzz/transformation_duplicate_region_with_selection.cpp", - "source/fuzz/transformation_duplicate_region_with_selection.h", - "source/fuzz/transformation_equation_instruction.cpp", - "source/fuzz/transformation_equation_instruction.h", - "source/fuzz/transformation_expand_vector_reduction.cpp", - "source/fuzz/transformation_expand_vector_reduction.h", - "source/fuzz/transformation_flatten_conditional_branch.cpp", - "source/fuzz/transformation_flatten_conditional_branch.h", - "source/fuzz/transformation_function_call.cpp", - "source/fuzz/transformation_function_call.h", - "source/fuzz/transformation_inline_function.cpp", - "source/fuzz/transformation_inline_function.h", - "source/fuzz/transformation_invert_comparison_operator.cpp", - "source/fuzz/transformation_invert_comparison_operator.h", - "source/fuzz/transformation_load.cpp", - "source/fuzz/transformation_load.h", - "source/fuzz/transformation_make_vector_operation_dynamic.cpp", - "source/fuzz/transformation_make_vector_operation_dynamic.h", - "source/fuzz/transformation_merge_blocks.cpp", - "source/fuzz/transformation_merge_blocks.h", - "source/fuzz/transformation_merge_function_returns.cpp", - "source/fuzz/transformation_merge_function_returns.h", - "source/fuzz/transformation_move_block_down.cpp", - "source/fuzz/transformation_move_block_down.h", - "source/fuzz/transformation_move_instruction_down.cpp", - "source/fuzz/transformation_move_instruction_down.h", - "source/fuzz/transformation_mutate_pointer.cpp", - "source/fuzz/transformation_mutate_pointer.h", - "source/fuzz/transformation_outline_function.cpp", - "source/fuzz/transformation_outline_function.h", - "source/fuzz/transformation_permute_function_parameters.cpp", - "source/fuzz/transformation_permute_function_parameters.h", - "source/fuzz/transformation_permute_phi_operands.cpp", - "source/fuzz/transformation_permute_phi_operands.h", - "source/fuzz/transformation_propagate_instruction_down.cpp", - "source/fuzz/transformation_propagate_instruction_down.h", - "source/fuzz/transformation_propagate_instruction_up.cpp", - "source/fuzz/transformation_propagate_instruction_up.h", - "source/fuzz/transformation_push_id_through_variable.cpp", - "source/fuzz/transformation_push_id_through_variable.h", - "source/fuzz/transformation_record_synonymous_constants.cpp", - "source/fuzz/transformation_record_synonymous_constants.h", - "source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.cpp", - "source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.h", - "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp", - "source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h", - "source/fuzz/transformation_replace_branch_from_dead_block_with_exit.cpp", - "source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h", - "source/fuzz/transformation_replace_constant_with_uniform.cpp", - "source/fuzz/transformation_replace_constant_with_uniform.h", - "source/fuzz/transformation_replace_copy_memory_with_load_store.cpp", - "source/fuzz/transformation_replace_copy_memory_with_load_store.h", - "source/fuzz/transformation_replace_copy_object_with_store_load.cpp", - "source/fuzz/transformation_replace_copy_object_with_store_load.h", - "source/fuzz/transformation_replace_id_with_synonym.cpp", - "source/fuzz/transformation_replace_id_with_synonym.h", - "source/fuzz/transformation_replace_irrelevant_id.cpp", - "source/fuzz/transformation_replace_irrelevant_id.h", - "source/fuzz/transformation_replace_linear_algebra_instruction.cpp", - "source/fuzz/transformation_replace_linear_algebra_instruction.h", - "source/fuzz/transformation_replace_load_store_with_copy_memory.cpp", - "source/fuzz/transformation_replace_load_store_with_copy_memory.h", - "source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.cpp", - "source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.h", - "source/fuzz/transformation_replace_opselect_with_conditional_branch.cpp", - "source/fuzz/transformation_replace_opselect_with_conditional_branch.h", - "source/fuzz/transformation_replace_parameter_with_global.cpp", - "source/fuzz/transformation_replace_parameter_with_global.h", - "source/fuzz/transformation_replace_params_with_struct.cpp", - "source/fuzz/transformation_replace_params_with_struct.h", - "source/fuzz/transformation_set_function_control.cpp", - "source/fuzz/transformation_set_function_control.h", - "source/fuzz/transformation_set_loop_control.cpp", - "source/fuzz/transformation_set_loop_control.h", - "source/fuzz/transformation_set_memory_operands_mask.cpp", - "source/fuzz/transformation_set_memory_operands_mask.h", - "source/fuzz/transformation_set_selection_control.cpp", - "source/fuzz/transformation_set_selection_control.h", - "source/fuzz/transformation_split_block.cpp", - "source/fuzz/transformation_split_block.h", - "source/fuzz/transformation_store.cpp", - "source/fuzz/transformation_store.h", - "source/fuzz/transformation_swap_commutable_operands.cpp", - "source/fuzz/transformation_swap_commutable_operands.h", - "source/fuzz/transformation_swap_conditional_branch_operands.cpp", - "source/fuzz/transformation_swap_conditional_branch_operands.h", - "source/fuzz/transformation_swap_function_variables.cpp", - "source/fuzz/transformation_swap_function_variables.h", - "source/fuzz/transformation_swap_two_functions.cpp", - "source/fuzz/transformation_swap_two_functions.h", - "source/fuzz/transformation_toggle_access_chain_instruction.cpp", - "source/fuzz/transformation_toggle_access_chain_instruction.h", - "source/fuzz/transformation_vector_shuffle.cpp", - "source/fuzz/transformation_vector_shuffle.h", - "source/fuzz/transformation_wrap_early_terminator_in_function.cpp", - "source/fuzz/transformation_wrap_early_terminator_in_function.h", - "source/fuzz/transformation_wrap_region_in_selection.cpp", - "source/fuzz/transformation_wrap_region_in_selection.h", - "source/fuzz/transformation_wrap_vector_synonym.cpp", - "source/fuzz/transformation_wrap_vector_synonym.h", - "source/fuzz/uniform_buffer_element_descriptor.cpp", - "source/fuzz/uniform_buffer_element_descriptor.h", - ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_fuzz_proto", - "//third_party/protobuf:protobuf_full", - "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/reduce:libdeqp_spirvtools-reduce", - ] - public_deps = [ ":spvtools_headers" ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - configs += [ ":spvtools_internal_config" ] - } -} - -ohos_source_set("spvtools_software_version") { - sources = [ "source/software_version.cpp" ] - deps = [ ":spvtools_headers" ] - configs = [ ":spvtools_internal_config" ] -} - -ohos_source_set("spvtools_tools_util") { - sources = [ - "tools/util/cli_consumer.cpp", - "tools/util/cli_consumer.h", - "tools/util/flags.cpp", - ] - deps = [ ":spvtools_headers" ] - configs = [ ":spvtools_internal_config" ] -} - -if (spvtools_build_executables) { - executable("spirv-as") { - sources = [ "tools/as/as.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - ] - configs += [ ":spvtools_internal_config" ] - } - - executable("spirv-dis") { - sources = [ "tools/dis/dis.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - ] - configs += [ ":spvtools_internal_config" ] - } - - executable("spirv-val") { - sources = [ "tools/val/val.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", - ] - configs += [ ":spvtools_internal_config" ] - } - - executable("spirv-cfg") { - sources = [ - "tools/cfg/bin_to_dot.cpp", - "tools/cfg/bin_to_dot.h", - "tools/cfg/cfg.cpp", - ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - ] - configs += [ ":spvtools_internal_config" ] - } - - executable("spirv-opt") { - sources = [ "tools/opt/opt.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", - ] - configs += [ ":spvtools_internal_config" ] - } - - executable("spirv-link") { - sources = [ "tools/link/linker.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - "//third_party/spirv-tools/source/link:libdeqp_spirvtools-link", - "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", - ] - configs += [ ":spvtools_internal_config" ] - } -} - -if (!is_ios && !spirv_is_winuwp && build_with_chromium && - spvtools_build_executables) { - # iOS and UWP do not allow std::system calls which spirv-fuzz - # requires. Additionally, spirv-fuzz is only built when in a - # Chromium checkout due to its dependency on protobuf. - - executable("spirv-fuzz") { - sources = [ "tools/fuzz/fuzz.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_fuzz", - ":spvtools_software_version", - ":spvtools_tools_util", - "//third_party/protobuf:protobuf_full", - "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/reduce:libdeqp_spirvtools-reduce", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", - ] - configs += [ ":spvtools_internal_config" ] - } -} - -if (!is_ios && !spirv_is_winuwp && spvtools_build_executables) { - # iOS and UWP do not allow std::system calls which spirv-reduce - # requires. - - executable("spirv-reduce") { - sources = [ "tools/reduce/reduce.cpp" ] - deps = [ - ":libdeqp_spirvtools", - ":spvtools_software_version", - ":spvtools_tools_util", - "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/reduce:libdeqp_spirvtools-reduce", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", - ] - configs += [ ":spvtools_internal_config" ] - } -} - -if (spvtools_build_executables) { - group("all_spirv_tools") { - deps = [ - ":spirv-as", - ":spirv-cfg", - ":spirv-dis", - ":spirv-link", - ":spirv-opt", - ":spirv-val", - ] - if (!is_ios && !spirv_is_winuwp && build_with_chromium) { - deps += [ ":spirv-fuzz" ] - } - if (!is_ios && !spirv_is_winuwp) { - deps += [ ":spirv-reduce" ] - } - } -} diff --git a/CHANGES b/CHANGES index 48aa8766..56a2d52f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,150 +1,5 @@ Revision history for SPIRV-Tools -v2023.6 2023-12-18 - - General - - update_build_version.py produce deterministic header. (#5426) - - Support missing git in update_build_version.py (#5473) - - Optimizer - - Add ComputeDerivativeGroup*NV capabilities to trim capabilities pass. (#5430) - - Do not crash when tryingto fold unsupported spec constant (#5496) - - instrument: Fix handling of gl_InvocationID (#5493) - - Fix nullptr argument in MarkInsertChain (#5465) - - opt: support 64-bit OpAccessChain index in FixStorageClass (#5446) - - opt: add StorageImageReadWithoutFormat to cap trim (#5475) - - opt: add PhysicalStorageBufferAddresses to trim (#5476) - - Fix array size calculation (#5463 - - Validator - - spirv-val: Loosen restriction on base type of DebugTypePointer and DebugTypeQualifier (#5479) - - spirv-val: Add WorkgroupMemoryExplicitLayoutKHR check for Block (#5461) - -v2023.5 2023-10-15 - - General - - Support 2 Intel extensions (#5357) - - SPV_QCOM_image_processing support (#5223) - - Optimizer - - opt: fix StorageInputOutput16 trimming. (#5359) - - opt: add StoragePushConstant16 to trim pass (#5366) - - opt: enable StorageUniform16 (#5371) - - opt: add bitmask support for capability trimming (#5372) - - opt: Add SwitchDescriptorSetPass (#5375) - - opt: add FragmentShader*InterlockEXT to capability trim pass (#5390) - - opt: add Int64 capability to trim pass (#5398) - - opt: add Float64 capability to trim pass (#5428) - - opt: add raytracing/rayquery to trim pass (#5397) - - opt: add ImageMSArray capability to trim pass. (#5395) - - Add SPV_KHR_physical_storage_buffer to allowlists (#5402) - - Add SPV_EXT_fragment_shader_interlock to allow lists (#5393) - - Make sure that fragment shader interlock instructions are not removed by DCE (#5400) - - instrument: Use Import linkage for instrumentation functions (#5355) - - Add a new legalization pass to dedupe invocation interlock instructions (#5409) - - instrument: Ensure linking works even of nothing is changed (#5419) - - Validator - - Move token version/cap/ext checks from parsing to validation (#5370) - - val: re-add ImageMSArray validation (#5394) - - Linker - - linker: Add --use-highest-version option - -v2023.4 2023-07-17 - - General - - Set cmake_policy CMP0128 (#5341) - - Add python3 requirement for the script (#5326) - - Add support for LiteralFloat type (#5323) - - SPV_KHR_cooperative_matrix (#5286) - - Allow OpTypeBool in UniformConstant (#5237) - - Allow physical storage buffer pointer in IO (#5251) - - Remove const zero image operands (#5232) - - Optimizer - - Enable vector constant folding (#4913) (#5272) - - Fold negation of integer vectors (#5269) - - Add folding rule for OpTranspose (#5241) - - Add SPV_NV_bindless_texture to spirv optimizations (#5231) - - Fix incorrect half float conversion (#5349) - - Add SPV_EXT_shader_atomic_float_add to allow lists (#5348) - - Instrument - - instrument: Cast gl_VertexIndex and InstanceIndex to uint (#5319) - - instrument: Fix buffer address length calculations (#5257) - - instrument: Reduce number of inst_bindless_stream_write_6 calls (#5327) - - Validator - - Validate GroupNonUniform instructions (#5296) - - spirv-val: Label SPV_KHR_cooperative_matrix VUID (#5301) - - Validate layouts for PhysicalStorageBuffer pointers (#5291) - - spirv-val: Remove VUID from 1.3.251 spec (#5244) - - Diff - - spirv-diff: Update test expectations (#5264) - - spirv-diff: Leave undefined ids unpaired. (#5262) - - spirv-diff: Properly match SPV_KHR_ray_query types. (#5259) - - diff: Don't give up entry point matching too early. (#5224) - -v2023.3 2023-05-15 - - General - - Update spirv_headers to include SPV_KHR_ray_tracing_position_fetch (#5205) - - spirv-tools: Add support for QNX (#5211) - - build: set std=c++17 for BUILD.gn (#5162) - - Optimizer - - Run ADCE when the printf extension is used. (#5215) - - Don't convert struct members to half (#5201) - - Apply scalar replacement on vars with Pointer decorations (#5208) - - opt: Fix null deref in OpMatrixTimesVector and OpVectorTimesMatrix (#5199) - - instrument: Add set and binding to bindless error records (#5204) - - instrument: Change descriptor state storage format (#5178) - - Fix LICMPass (#5087) - - Add Vulkan memory model to allow lists (#5173) - - Do not remove control barrier after spv1.3 (#5174) - - Validator - - spirv-val: Label Interface Location/Component VUIDs (#5221) - - Add support for SPV_EXT_shader_tile_image (#5188) - - Fix vector OpConstantComposite type validation (#5191) - - spirv-val: Label new Vulkan VUID 07951 (#5154) - - Fuzz - - Do not define GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE if it is already defined. (#5200) - -v2023.2 2023-03-10 - - General - - build: move from c++11 to c++17 (#4983) - - tools: refactorize tools flags parsing. (#5111) - - Add C interface for Optimizer (#5030) - - libspirv.cpp: adds c++ api for spvBinaryParse (#5109) - - build: change the way we set cxx version for bazel. (#5114) - - Optimizer - - Fix null pointer in FoldInsertWithConstants. (#5093) - - Fix removal of dependent non-semantic instructions (#5122) - - Remove duplicate lists of constant and type opcodes (#5106) - - opt: fix spirv ABI on Linux again. (#5113) - - Validator - - Validate decoration of structs with RuntimeArray (#5094) - - Validate operand type before operating on it (#5092) - - spirv-val: Conditional Branch without an exit is invalid in loop header (#5069) - - spirv-val: Initial SPV_EXT_mesh_shader builtins (#5080) - -v2023.1 2023-01-17 - - General - - Renamed "master" to "main" (issue#5051) - - Validate version 5 of clspv reflection (#5050) - - Remove testing support for VS2015 (#5027) - - Fix undef behaviour in hex float parsing (#5025) - - Require C++11 *or later* (#5020) - - Instrument - - Instrument: Fix bindless checking for BufferDeviceAddress (#5049) - - Optimizer - - Optimize allocation of spvtools::opt::Instruction::operands_ (#5024) - - spirv-opt: Fix OpCompositeInsert with Null Constant (#5008) - - spirv-opt: Handle null CompositeInsert (#4998) - - Add option to ADCE to remove output variables from interface. (#4994) - - Add support for tesc, tese and geom to EliminateDead*Components (#4990) - - Add pass to eliminate dead output components (#4982) - - spirv-opt: Add const folding for CompositeInsert (#4943) - - Add passes to eliminate dead output stores (#4970) - - Prevent eliminating case constructs in block merging (#4976) - - Validator - - Fix layout validation (#5015) - - Fix use of invalid analysis (#5013) - - Fix infinite loop in validator (#5006) - - Add validation support for SPV_NV_shader_invocation_reorder. (#4979) - - Only validate full layout in Vulkan environments (#4972) - - spirv-val: Label new Vulkan OpPtrAccessChain VUs (#4975) - - spirv-val: Add OpPtrAccessChain Base checks (#4965) - - v2022.4 2022-10-12 - General - Support Narrow Types in BitCast Folding Rule (#4941) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07be2dfc..1b8fe92f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2023 The Khronos Group Inc. +# Copyright (c) 2015-2016 The Khronos Group Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,38 +12,26 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.17.2) - -project(spirv-tools) - -# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for -# targets in test/*, when those tests need -std=c++17. -# https://github.com/KhronosGroup/SPIRV-Tools/issues/5340 -# The bug is fixed in CMake 3.22.2 -if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.1") - if (${CMAKE_VERSION} VERSION_LESS "3.22.2") - cmake_policy(SET CMP0128 NEW) - endif() +cmake_minimum_required(VERSION 2.8.12) +if (POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif() +if (POLICY CMP0054) + # Avoid dereferencing variables or interpret keywords that have been + # quoted or bracketed. + # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html + cmake_policy(SET CMP0054 NEW) endif() - set_property(GLOBAL PROPERTY USE_FOLDERS ON) +project(spirv-tools) enable_testing() set(SPIRV_TOOLS "SPIRV-Tools") include(GNUInstallDirs) set(CMAKE_POSITION_INDEPENDENT_CODE ON) - -# Require at least C++17 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) -endif() -if(${CMAKE_CXX_STANDARD} LESS 17) - message(FATAL_ERROR "SPIRV-Tools requires C++17 or later, but is configured for C++${CMAKE_CXX_STANDARD})") -endif() -set(CMAKE_CXX_EXTENSIONS OFF) - +set(CMAKE_CXX_STANDARD 11) option(ENABLE_RTTI "Enables RTTI" OFF) option(SPIRV_ALLOW_TIMERS "Allow timers via clock_gettime on supported platforms" ON) @@ -63,8 +51,6 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS") add_definitions(-DSPIRV_IOS) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "tvOS") add_definitions(-DSPIRV_TVOS) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "visionOS") - add_definitions(-DSPIRV_VISIONOS) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") add_definitions(-DSPIRV_ANDROID) set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS}) @@ -76,8 +62,6 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") add_definitions(-DSPIRV_FUCHSIA) elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU") add_definitions(-DSPIRV_GNU) -elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "QNX") - add_definitions(-DSPIRV_QNX) else() message(FATAL_ERROR "Your platform '${CMAKE_SYSTEM_NAME}' is not supported!") endif() @@ -204,9 +188,10 @@ function(spvtools_default_compile_options TARGET) target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS}) if (${COMPILER_IS_LIKE_GNU}) + target_compile_options(${TARGET} PRIVATE -std=c++11 -fno-exceptions) target_compile_options(${TARGET} PRIVATE -Wall -Wextra -Wno-long-long -Wshadow -Wundef -Wconversion - -Wno-sign-conversion -fno-exceptions) + -Wno-sign-conversion) if(NOT ENABLE_RTTI) add_compile_options(-fno-rtti) @@ -215,7 +200,7 @@ function(spvtools_default_compile_options TARGET) if(NOT "${SPIRV_PERF}" STREQUAL "") target_compile_options(${TARGET} PRIVATE -fno-omit-frame-pointer) endif() - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(SPIRV_USE_SANITIZER "" CACHE STRING "Use the clang sanitizer [address|memory|thread|...]") if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "") @@ -243,7 +228,7 @@ function(spvtools_default_compile_options TARGET) # For MinGW cross compile, statically link to the C++ runtime. # But it still depends on MSVCRT.dll. if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - if (NOT MSVC) + if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -static -static-libgcc -static-libstdc++) endif() @@ -262,7 +247,7 @@ if(NOT COMMAND find_host_program) endif() # Tests require Python3 -find_host_package(Python3 REQUIRED) +find_host_package(PythonInterp 3 REQUIRED) # Check for symbol exports on Linux. # At the moment, this check will fail on the OSX build machines for the Android NDK. @@ -271,7 +256,7 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") macro(spvtools_check_symbol_exports TARGET) if (NOT "${SPIRV_SKIP_TESTS}") add_test(NAME spirv-tools-symbol-exports-${TARGET} - COMMAND Python3::Interpreter + COMMAND ${PYTHON_EXECUTABLE} ${spirv-tools_SOURCE_DIR}/utils/check_symbol_exports.py "$") endif() endmacro() @@ -284,7 +269,7 @@ else() endif() if(ENABLE_SPIRV_TOOLS_INSTALL) - if(WIN32 AND NOT MINGW) + if(WIN32) macro(spvtools_config_package_dir TARGET PATH) set(${PATH} ${TARGET}/cmake) endmacro() @@ -304,23 +289,15 @@ if(ENABLE_SPIRV_TOOLS_INSTALL) endmacro() endif() -# Currently iOS and Android are very similar. -# They both have their own packaging (APP/APK). -# Which makes regular executables/testing problematic. -# -# Currently the only deliverables for these platforms are -# libraries (either STATIC or SHARED). -# -# Furthermore testing is equally problematic. -if (IOS OR ANDROID) - set(SPIRV_SKIP_EXECUTABLES ON) -endif() - -option(SPIRV_SKIP_EXECUTABLES "Skip building the executable and tests along with the library") -if (SPIRV_SKIP_EXECUTABLES) +# Defaults to OFF if the user didn't set it. +option(SPIRV_SKIP_EXECUTABLES + "Skip building the executable and tests along with the library" + ${SPIRV_SKIP_EXECUTABLES}) +option(SPIRV_SKIP_TESTS + "Skip building tests along with the library" ${SPIRV_SKIP_TESTS}) +if ("${SPIRV_SKIP_EXECUTABLES}") set(SPIRV_SKIP_TESTS ON) endif() -option(SPIRV_SKIP_TESTS "Skip building tests along with the library") # Defaults to ON. The checks can be time consuming. # Turn off if they take too long. @@ -378,7 +355,7 @@ endif(ENABLE_SPIRV_TOOLS_INSTALL) if (NOT "${SPIRV_SKIP_TESTS}") add_test(NAME spirv-tools-copyrights - COMMAND Python3::Interpreter utils/check_copyright.py + COMMAND ${PYTHON_EXECUTABLE} utils/check_copyright.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 11fb4e2c..1eb8b689 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,8 +2,9 @@ ## For users: Reporting bugs and requesting features -We organize known future work in GitHub projects. See -[Tracking SPIRV-Tools work with GitHub projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/docs/projects.md) +We organize known future work in GitHub projects. See [Tracking SPIRV-Tools work +with GitHub +projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/docs/projects.md) for more. To report a new bug or request a new feature, please file a GitHub issue. Please @@ -35,9 +36,9 @@ create a new issue, as with bugs. In the issue provide ## For developers: Contributing a patch -Before we can use your code, you must sign the -[Khronos Open Source Contributor License Agreement](https://cla-assistant.io/KhronosGroup/SPIRV-Tools) -(CLA), which you can do online. The CLA is necessary mainly because you own the +Before we can use your code, you must sign the [Khronos Open Source Contributor +License Agreement](https://cla-assistant.io/KhronosGroup/SPIRV-Tools) (CLA), +which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also need to be sure of various other things -- for instance that you'll tell us if @@ -46,20 +47,20 @@ sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase. See -[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/README.md) +[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/README.md) for instruction on how to get, build, and test the source. Once you have made your changes: -* Ensure the code follows the - [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html). - Running `clang-format -style=file -i [modified-files]` can help. +* Ensure the code follows the [Google C++ Style + Guide](https://google.github.io/styleguide/cppguide.html). Running + `clang-format -style=file -i [modified-files]` can help. * Create a pull request (PR) with your patch. * Make sure the PR description clearly identified the problem, explains the solution, and references the issue if applicable. * If your patch completely fixes bug 1234, the commit message should say - `Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1234` When you do - this, the issue will be closed automatically when the commit goes into - main. Also, this helps us update the [CHANGES](CHANGES) file. + `Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1234` + When you do this, the issue will be closed automatically when the commit + goes into master. Also, this helps us update the [CHANGES](CHANGES) file. * Watch the continuous builds to make sure they pass. * Request a code review. @@ -81,8 +82,8 @@ Instructions for this are given below. The formal code reviews are done on GitHub. Reviewers are to look for all of the usual things: -* Coding style follows the - [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) +* Coding style follows the [Google C++ Style + Guide](https://google.github.io/styleguide/cppguide.html) * Identify potential functional problems. * Identify code duplication. * Ensure the unit tests have enough coverage. @@ -101,49 +102,84 @@ should pay particular attention to: updated. For example, a new instruction is added, but the def-use manager is not updated. Later on, it is possible that the def-use manager will be used, and give wrong results. -* If a pass gets the id of a type from the type manager, make sure the type is - not a struct or array. It there are two structs that look the same, the type - manager can return the wrong one. ## For maintainers: Merging a PR -We intend to maintain a linear history on the GitHub main branch, and the +We intend to maintain a linear history on the GitHub master branch, and the build and its tests should pass at each commit in that history. A linear always-working history is easier to understand and to bisect in case we want to -find which commit introduced a bug. The -[Squash and Merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) -button on the GitHub web interface. All other ways of merging on the web -interface have been disabled. +find which commit introduced a bug. -Before merging, we generally require: +### Initial merge setup -1. All tests except for the smoke test pass. See - [failing smoke test](#failing-smoke-test). -1. The PR is approved by at least one of the maintainers. If the PR modifies - different parts of the code, then multiple reviewers might be necessary. +The following steps should be done exactly once (when you are about to merge a +PR for the first time): -The squash-and-merge button will turn green when these requirements are met. -Maintainers have the to power to merge even if the button is not green, but that -is discouraged. +* It is assumed that upstream points to + [git@github.com](mailto:git@github.com):KhronosGroup/SPIRV-Tools.git or + https://github.com/KhronosGroup/SPIRV-Tools.git. -### Failing smoke test +* Find out the local name for the main github repo in your git configuration. + For example, in this configuration, it is labeled `upstream`. -The purpose of the smoke test is to let us know if -[shaderc](https://github.com/google/shaderc) fails to build with the change. If -it fails, the maintainer needs to determine if the reason for the failure is a -problem in the current PR or if another repository needs to be changed. Most of -the time [Glslang](https://github.com/KhronosGroup/glslang) needs to be updated -to account for the change in SPIR-V Tools. + ``` + git remote -v + [ ... ] + upstream https://github.com/KhronosGroup/SPIRV-Tools.git (fetch) + upstream https://github.com/KhronosGroup/SPIRV-Tools.git (push) + ``` -The PR can still be merged if the problem is not with that PR. +* Make sure that the `upstream` remote is set to fetch from the `refs/pull` + namespace: -## For maintainers: Running tests + ``` + git config --get-all remote.upstream.fetch + +refs/heads/*:refs/remotes/upstream/* + +refs/pull/*/head:refs/remotes/upstream/pr/* + ``` -For security reasons, not all tests will run automatically. When they do not, a -maintainer will have to start the tests. +* If the line `+refs/pull/*/head:refs/remotes/upstream/pr/*` is not present in + your configuration, you can add it with the command: -If the Github actions tests do not run on a PR, they can be initiated by closing -and reopening the PR. + ``` + git config --local --add remote.upstream.fetch '+refs/pull/*/head:refs/remotes/upstream/pr/*' + ``` -If the kokoro tests are not run, they can be run by adding the label -`kokoro:run` to the PR. +### Merge workflow + +The following steps should be done for every PR that you intend to merge: + +* Make sure your local copy of the master branch is up to date: + + ``` + git checkout master + git pull + ``` + +* Fetch all pull requests refs: + + ``` + git fetch upstream + ``` + +* Checkout the particular pull request you are going to review: + + ``` + git checkout pr/1048 + ``` + +* Rebase the PR on top of the master branch. If there are conflicts, send it + back to the author and ask them to rebase. During the interactive rebase be + sure to squash all of the commits down to a single commit. + + ``` + git rebase -i master + ``` + +* **Build and test the PR.** + +* If all of the tests pass, push the commit `git push upstream HEAD:master` + +* Close the PR and add a comment saying it was push using the commit that you + just pushed. See https://github.com/KhronosGroup/SPIRV-Tools/pull/935 as an + example. diff --git a/DEPS b/DEPS index a27f4fca..3a5f6145 100644 --- a/DEPS +++ b/DEPS @@ -3,32 +3,19 @@ use_relative_paths = True vars = { 'github': 'https://github.com', - 'abseil_revision': '79ca5d7aad63973c83a4962a66ab07cd623131ea', - - 'effcee_revision': '19b4aa87af25cb4ee779a071409732f34bfc305c', - - 'googletest_revision': 'b10fad38c4026a29ea6561ab15fc4818170d1c10', - - # Use protobufs before they gained the dependency on abseil - 'protobuf_revision': 'v21.12', - - 're2_revision': '7e0c1a9e2417e70e5f0efc323267ac71d1fa0685', - 'spirv_headers_revision': '1c6bb2743599e6eb6f37b2969acc0aef812e32e3', + 'effcee_revision': '35912e1b7778ec2ddcff7e7188177761539e59e0', + 'googletest_revision': 'd9bb8412d60b993365abb53f00b6dad9b2c01b62', + 're2_revision': 'd2836d1b1c34c4e330a85a1006201db474bf2c8a', + 'spirv_headers_revision': '85a1ed200d50660786c1a88d9166e871123cce39', } deps = { - 'external/abseil_cpp': - Var('github') + '/abseil/abseil-cpp.git@' + Var('abseil_revision'), - 'external/effcee': Var('github') + '/google/effcee.git@' + Var('effcee_revision'), 'external/googletest': Var('github') + '/google/googletest.git@' + Var('googletest_revision'), - 'external/protobuf': - Var('github') + '/protocolbuffers/protobuf.git@' + Var('protobuf_revision'), - 'external/re2': Var('github') + '/google/re2.git@' + Var('re2_revision'), diff --git a/OAT.xml b/OAT.xml old mode 100755 new mode 100644 diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 847deb76..dd3117f2 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -18,8 +18,6 @@ See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - LINT_FILTERS = [ "-build/storage_class", "-readability/casting", diff --git a/README.OpenSource b/README.OpenSource old mode 100755 new mode 100644 index a19e165c..fff0c972 --- a/README.OpenSource +++ b/README.OpenSource @@ -3,7 +3,7 @@ "Name": "spirv-tools", "License": "Apache-2.0", "License File": "LICENSE", - "Version Number": "sdk-1.3.275.0", + "Version Number": "v2022.4", "Owner": "zhangleiyu1@huawei.com", "Upstream URL": "https://github.com/KhronosGroup/SPIRV-Tools.git", "Description": "The SPIR-V Tools project provides an API and commands for processing SPIR-V modules." diff --git a/README.md b/README.md index 042b83da..e951e37f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ # SPIR-V Tools -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/SPIRV-Tools/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/SPIRV-Tools) - -NEWS 2023-01-11: Development occurs on the `main` branch. ## Overview @@ -26,7 +23,7 @@ headers, and XML registry. Linux[![Linux Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_linux_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html) MacOS[![MacOS Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html) -Windows[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2019_release.html) +Windows[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_release.html) [More downloads](docs/downloads.md) @@ -99,10 +96,10 @@ and in-progress work. *Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec. The validator will fail on a module that exceeds those minimum upper bound limits. -The validator has been parameterized to allow larger values, for use when targeting -a more-than-minimally-capable SPIR-V consumer. +It is [future work](https://github.com/KhronosGroup/SPIRV-Tools/projects/1#card-1052403) +to parameterize the validator to allow larger +limits accepted by a more than minimally capable SPIR-V consumer. -See [`tools/val/val.cpp`](tools/val/val.cpp) or run `spirv-val --help` for the command-line help. ### Optimizer @@ -274,7 +271,7 @@ Contributions via merge request are welcome. Changes should: `clang-format version 5.0.0` for SPIRV-Tools. Settings are defined by the included [.clang-format](.clang-format) file. -We intend to maintain a linear history on the GitHub `main` branch. +We intend to maintain a linear history on the GitHub `master` branch. ### Getting the source @@ -293,18 +290,16 @@ For some kinds of development, you may need the latest sources from the third-pa git clone https://github.com/google/googletest.git spirv-tools/external/googletest git clone https://github.com/google/effcee.git spirv-tools/external/effcee git clone https://github.com/google/re2.git spirv-tools/external/re2 - git clone https://github.com/abseil/abseil-cpp.git spirv-tools/external/abseil_cpp #### Dependency on Effcee Some tests depend on the [Effcee][effcee] library for stateful matching. -Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp]. +Effcee itself depends on [RE2][re2]. * If SPIRV-Tools is configured as part of a larger project that already uses Effcee, then that project should include Effcee before SPIRV-Tools. -* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`, - RE2 sources to appear in `external/re2`, and Abseil sources to appear in - `external/abseil_cpp`. +* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee` + and RE2 sources to appear in `external/re2`. ### Source code organization @@ -316,9 +311,6 @@ Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp]. * `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already configured by an enclosing project. (The Effcee project already requires RE2.) -* `external/abseil_cpp`: Location of [Abseil][abseil-cpp] sources, if Abseil is - not already configured by an enclosing project. - (The RE2 project already requires Abseil.) * `include/`: API clients should add this directory to the include search path * `external/spirv-headers`: Intended location for [SPIR-V headers][spirv-headers], not provided @@ -386,11 +378,10 @@ fuzzer tests. ### Build using Bazel You can also use [Bazel](https://bazel.build/) to build the project. - ```sh +cd bazel build :all ``` - ### Build a node.js package using Emscripten The SPIRV-Tools core library can be built to a WebAssembly [node.js](https://nodejs.org) @@ -441,13 +432,10 @@ On MacOS - AppleClang 11.0 On Windows +- Visual Studio 2015 - Visual Studio 2017 -- Visual Studio 2019 -- Visual Studio 2022 -Note: Visual Studio 2017 has incomplete c++17 support. We might stop -testing it soon. Other compilers or later versions may work, but they are not -tested. +Other compilers or later versions may work, but they are not tested. ### CMake options @@ -479,12 +467,12 @@ iterator debugging. ### Android ndk-build SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and -`libSPIRV-Tools-opt.a` for Android. Using the Android NDK r25c or later: +`libSPIRV-Tools-opt.a` for Android: ``` cd -export ANDROID_NDK=/path/to/your/ndk # NDK r25c or later +export ANDROID_NDK=/path/to/your/ndk mkdir build && cd build mkdir libs @@ -508,7 +496,7 @@ The script requires Chromium's ### Usage -The internals of the library use C++17 features, and are exposed via both a C +The internals of the library use C++11 features, and are exposed via both a C and C++ API. In order to use the library from an application, the include path should point @@ -730,16 +718,10 @@ Use `bazel test :all` to run all tests. This will run tests in parallel by defau To run a single test target, specify `:my_test_target` instead of `:all`. Test target names get printed when you run `bazel test :all`. For example, you can run `opt_def_use_test` with: - -on linux: ```shell -bazel test --cxxopt=-std=c++17 :opt_def_use_test +bazel test :opt_def_use_test ``` -on windows: -```shell -bazel test --cxxopt=/std:c++17 :opt_def_use_test -``` ## Future Work @@ -797,7 +779,6 @@ limitations under the License. [googletest-issue-610]: https://github.com/google/googletest/issues/610 [effcee]: https://github.com/google/effcee [re2]: https://github.com/google/re2 -[abseil-cpp]: https://github.com/abseil/abseil-cpp [CMake]: https://cmake.org/ [cpp-style-guide]: https://google.github.io/styleguide/cppguide.html [clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100755 index 99c5f441..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Policy - -## Supported Versions - -Security updates are applied only to the latest release. - -## Reporting a Vulnerability - -If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. - -Please disclose it at [security advisory](https://github.com/KhronosGroup/SPIRV-Tools/security/advisories/new). - -This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. diff --git a/WORKSPACE b/WORKSPACE index 589dc122..5abfc98b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,11 +1,3 @@ -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "bazel_skylib", - strip_prefix = "bazel-skylib-main", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/main.zip"], -) - local_repository( name = "spirv_headers", path = "external/spirv-headers", @@ -25,8 +17,3 @@ local_repository( name = "com_google_effcee", path = "external/effcee", ) - -local_repository( - name = "com_google_absl", - path = "external/abseil_cpp", -) diff --git a/android_test/Android.mk b/android_test/Android.mk index b9a00141..dbaf93ba 100644 --- a/android_test/Android.mk +++ b/android_test/Android.mk @@ -5,7 +5,7 @@ LOCAL_CPP_EXTENSION := .cc .cpp .cxx LOCAL_SRC_FILES:=test.cpp LOCAL_MODULE:=spirvtools_test LOCAL_LDLIBS:=-landroid -LOCAL_CXXFLAGS:=-std=c++17 -fno-exceptions -fno-rtti -Werror +LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror LOCAL_STATIC_LIBRARIES=SPIRV-Tools SPIRV-Tools-opt include $(BUILD_SHARED_LIBRARY) diff --git a/android_test/jni/Application.mk b/android_test/jni/Application.mk index 47c0acfb..4e664659 100644 --- a/android_test/jni/Application.mk +++ b/android_test/jni/Application.mk @@ -1,5 +1,5 @@ APP_ABI := all APP_BUILD_SCRIPT := Android.mk APP_STL := c++_static -APP_PLATFORM := android-24 +APP_PLATFORM := android-9 NDK_TOOLCHAIN_VERSION := 4.9 diff --git a/build_defs.bzl b/build_defs.bzl index 76bf3e79..71891372 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -1,21 +1,20 @@ -"""Constants and macros for spirv-tools BUILD.""" - COMMON_COPTS = [ - "-DSPIRV_CHECK_CONTEXT", - "-DSPIRV_COLOR_TERMINAL", -] + select({ - "@platforms//os:windows": [], + "-DSPIRV_CHECK_CONTEXT", + "-DSPIRV_COLOR_TERMINAL", + ] + select({ + "@bazel_tools//src/conditions:windows": [""], "//conditions:default": [ "-DSPIRV_LINUX", "-DSPIRV_TIMER_ENABLED", - "-fvisibility=hidden", - "-fno-exceptions", - "-fno-rtti", "-Wall", "-Wextra", "-Wnon-virtual-dtor", "-Wno-missing-field-initializers", "-Werror", + "-std=c++11", + "-fvisibility=hidden", + "-fno-exceptions", + "-fno-rtti", "-Wno-long-long", "-Wshadow", "-Wundef", @@ -24,211 +23,324 @@ COMMON_COPTS = [ ], }) -TEST_COPTS = COMMON_COPTS + [ -] + select({ - "@platforms//os:windows": [ +TEST_COPTS = COMMON_COPTS + select({ + "@bazel_tools//src/conditions:windows": [ # Disable C4503 "decorated name length exceeded" warning, # triggered by some heavily templated types. # We don't care much about that in test code. # Important to do since we have warnings-as-errors. - "/wd4503", + "/wd4503" ], "//conditions:default": [ "-Wno-undef", "-Wno-self-assign", "-Wno-shadow", - "-Wno-unused-parameter", + "-Wno-unused-parameter" ], }) -def incompatible_with(incompatible_constraints): - return select(_merge_dicts([{"//conditions:default": []}, { - constraint: ["@platforms//:incompatible"] - for constraint in incompatible_constraints - }])) - DEBUGINFO_GRAMMAR_JSON_FILE = "@spirv_headers//:spirv_ext_inst_debuginfo_grammar_unified1" CLDEBUGINFO100_GRAMMAR_JSON_FILE = "@spirv_headers//:spirv_ext_inst_opencl_debuginfo_100_grammar_unified1" SHDEBUGINFO100_GRAMMAR_JSON_FILE = "@spirv_headers//:spirv_ext_inst_nonsemantic_shader_debuginfo_100_grammar_unified1" -def _merge_dicts(dicts): - merged = {} - for d in dicts: - merged.update(d) - return merged - -def generate_core_tables(version): +def generate_core_tables(version = None): if not version: fail("Must specify version", "version") - - grammars = dict( - core_grammar = "@spirv_headers//:spirv_core_grammar_{}".format(version), - debuginfo_grammar = DEBUGINFO_GRAMMAR_JSON_FILE, - cldebuginfo_grammar = CLDEBUGINFO100_GRAMMAR_JSON_FILE, - ) - - outs = dict( - core_insts_output = "core.insts-{}.inc".format(version), - operand_kinds_output = "operand.kinds-{}.inc".format(version), - ) - - cmd = ( - "$(location :generate_grammar_tables)" + - " --spirv-core-grammar=$(location {core_grammar})" + - " --extinst-debuginfo-grammar=$(location {debuginfo_grammar})" + - " --extinst-cldebuginfo100-grammar=$(location {cldebuginfo_grammar})" + - " --core-insts-output=$(location {core_insts_output})" + - " --operand-kinds-output=$(location {operand_kinds_output})" + - " --output-language=c++" - ).format(**_merge_dicts([grammars, outs])) - + grammars = [ + "@spirv_headers//:spirv_core_grammar_" + version, + DEBUGINFO_GRAMMAR_JSON_FILE, + CLDEBUGINFO100_GRAMMAR_JSON_FILE, + ] + outs = [ + "core.insts-{}.inc".format(version), + "operand.kinds-{}.inc".format(version), + ] + fmtargs = grammars + outs native.genrule( name = "gen_core_tables_" + version, - srcs = grammars.values(), - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_grammar_tables"], + srcs = grammars, + outs = outs, + cmd = ( + "$(location :generate_grammar_tables) " + + "--spirv-core-grammar=$(location {0}) " + + "--extinst-debuginfo-grammar=$(location {1}) " + + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--core-insts-output=$(location {3}) " + + "--operand-kinds-output=$(location {4})" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_grammar_tables) " + + "--spirv-core-grammar=$(location {0}) " + + "--extinst-debuginfo-grammar=$(location {1}) " + + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--core-insts-output=$(location {3}) " + + "--operand-kinds-output=$(location {4})" + ).format(*fmtargs), + exec_tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], ) -def generate_enum_string_mapping(version): +def generate_enum_string_mapping(version = None): if not version: fail("Must specify version", "version") - - grammars = dict( - core_grammar = "@spirv_headers//:spirv_core_grammar_{}".format(version), - debuginfo_grammar = DEBUGINFO_GRAMMAR_JSON_FILE, - cldebuginfo_grammar = CLDEBUGINFO100_GRAMMAR_JSON_FILE, - ) - - outs = dict( - extension_enum_ouput = "extension_enum.inc", - enum_string_mapping_output = "enum_string_mapping.inc", - ) - - cmd = ( - "$(location :generate_grammar_tables)" + - " --spirv-core-grammar=$(location {core_grammar})" + - " --extinst-debuginfo-grammar=$(location {debuginfo_grammar})" + - " --extinst-cldebuginfo100-grammar=$(location {cldebuginfo_grammar})" + - " --extension-enum-output=$(location {extension_enum_ouput})" + - " --enum-string-mapping-output=$(location {enum_string_mapping_output})" + - " --output-language=c++" - ).format(**_merge_dicts([grammars, outs])) - + grammars = [ + "@spirv_headers//:spirv_core_grammar_" + version, + DEBUGINFO_GRAMMAR_JSON_FILE, + CLDEBUGINFO100_GRAMMAR_JSON_FILE, + ] + outs = [ + "extension_enum.inc", + "enum_string_mapping.inc", + ] + fmtargs = grammars + outs native.genrule( name = "gen_enum_string_mapping", - srcs = grammars.values(), - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_grammar_tables"], + srcs = grammars, + outs = outs, + cmd = ( + "$(location :generate_grammar_tables) " + + "--spirv-core-grammar=$(location {0}) " + + "--extinst-debuginfo-grammar=$(location {1}) " + + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--extension-enum-output=$(location {3}) " + + "--enum-string-mapping-output=$(location {4})" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_grammar_tables) " + + "--spirv-core-grammar=$(location {0}) " + + "--extinst-debuginfo-grammar=$(location {1}) " + + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--extension-enum-output=$(location {3}) " + + "--enum-string-mapping-output=$(location {4})" + ).format(*fmtargs), + exec_tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], ) -def generate_opencl_tables(version): +def generate_opencl_tables(version = None): if not version: fail("Must specify version", "version") - - grammars = dict( - opencl_grammar = "@spirv_headers//:spirv_opencl_grammar_{}".format(version), - ) - - outs = dict( - opencl_insts_output = "opencl.std.insts.inc", - ) - - cmd = ( - "$(location :generate_grammar_tables)" + - " --extinst-opencl-grammar=$(location {opencl_grammar})" + - " --opencl-insts-output=$(location {opencl_insts_output})" - ).format(**_merge_dicts([grammars, outs])) - + grammars = [ + "@spirv_headers//:spirv_opencl_grammar_" + version, + ] + outs = ["opencl.std.insts.inc"] + fmtargs = grammars + outs native.genrule( name = "gen_opencl_tables_" + version, - srcs = grammars.values(), - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_grammar_tables"], + srcs = grammars, + outs = outs, + cmd = ( + "$(location :generate_grammar_tables) " + + "--extinst-opencl-grammar=$(location {0}) " + + "--opencl-insts-output=$(location {1})" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_grammar_tables) " + + "--extinst-opencl-grammar=$(location {0}) " + + "--opencl-insts-output=$(location {1})" + ).format(*fmtargs), + exec_tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], ) -def generate_glsl_tables(version): +def generate_glsl_tables(version = None): if not version: fail("Must specify version", "version") - - grammars = dict( - gsls_grammar = "@spirv_headers//:spirv_glsl_grammar_{}".format(version), - ) - outs = dict( - gsls_insts_outs = "glsl.std.450.insts.inc", - ) - - cmd = ( - "$(location :generate_grammar_tables)" + - " --extinst-glsl-grammar=$(location {gsls_grammar})" + - " --glsl-insts-output=$(location {gsls_insts_outs})" + - " --output-language=c++" - ).format(**_merge_dicts([grammars, outs])) - + grammars = [ + "@spirv_headers//:spirv_glsl_grammar_" + version, + ] + outs = ["glsl.std.450.insts.inc"] + fmtargs = grammars + outs native.genrule( name = "gen_glsl_tables_" + version, - srcs = grammars.values(), - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_grammar_tables"], + srcs = grammars, + outs = outs, + cmd = ( + "$(location :generate_grammar_tables) " + + "--extinst-glsl-grammar=$(location {0}) " + + "--glsl-insts-output=$(location {1})" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_grammar_tables) " + + "--extinst-glsl-grammar=$(location {0}) " + + "--glsl-insts-output=$(location {1})" + ).format(*fmtargs), + exec_tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], ) def generate_vendor_tables(extension, operand_kind_prefix = ""): if not extension: fail("Must specify extension", "extension") - extension_rule = extension.replace("-", "_").replace(".", "_") - grammars = dict( - vendor_grammar = "@spirv_headers//:spirv_ext_inst_{}_grammar_unified1".format(extension_rule), - ) - outs = dict( - vendor_insts_output = "{}.insts.inc".format(extension), - ) - cmd = ( - "$(location :generate_grammar_tables)" + - " --extinst-vendor-grammar=$(location {vendor_grammar})" + - " --vendor-insts-output=$(location {vendor_insts_output})" + - " --vendor-operand-kind-prefix={operand_kind_prefix}" - ).format(operand_kind_prefix = operand_kind_prefix, **_merge_dicts([grammars, outs])) - + grammars = ["@spirv_headers//:spirv_ext_inst_{}_grammar_unified1".format(extension_rule)] + outs = ["{}.insts.inc".format(extension)] + prefices = [operand_kind_prefix] + fmtargs = grammars + outs + prefices native.genrule( name = "gen_vendor_tables_" + extension_rule, - srcs = grammars.values(), - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_grammar_tables"], + srcs = grammars, + outs = outs, + cmd = ( + "$(location :generate_grammar_tables) " + + "--extinst-vendor-grammar=$(location {0}) " + + "--vendor-insts-output=$(location {1}) " + + "--vendor-operand-kind-prefix={2}" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_grammar_tables) " + + "--extinst-vendor-grammar=$(location {0}) " + + "--vendor-insts-output=$(location {1}) " + + "--vendor-operand-kind-prefix={2}" + ).format(*fmtargs), + exec_tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], ) def generate_extinst_lang_headers(name, grammar = None): if not grammar: fail("Must specify grammar", "grammar") - outs = dict( - extinst_output_path = name + ".h", - ) - cmd = ( - "$(location :generate_language_headers)" + - " --extinst-grammar=$<" + - " --extinst-output-path=$(location {extinst_output_path})" - ).format(**outs) - + outs = [name + ".h"] + fmtargs = outs native.genrule( - name = "gen_extinst_lang_headers_{}".format(name), + name = "gen_extinst_lang_headers_" + name, srcs = [grammar], - outs = outs.values(), - cmd = cmd, - cmd_bat = cmd, - tools = [":generate_language_headers"], + outs = outs, + cmd = ( + "$(location :generate_language_headers) " + + "--extinst-grammar=$< " + + "--extinst-output-path=$(location {0})" + ).format(*fmtargs), + cmd_bat = ( + "$(location :generate_language_headers) " + + "--extinst-grammar=$< " + + "--extinst-output-path=$(location {0})" + ).format(*fmtargs), + exec_tools = [":generate_language_headers"], visibility = ["//visibility:private"], ) + +def base_test(name, srcs, deps = []): + if srcs == []: + return + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "base_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":test_common", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def lint_test(name, srcs, deps = []): + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "lint_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":spirv_tools_lint", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def link_test(name, srcs, deps = []): + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "link_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":link_test_common", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def opt_test(name, srcs, deps = []): + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "opt_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":opt_test_common", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def reduce_test(name, srcs, deps = []): + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "reduce_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":reduce_test_common", + ":spirv_tools_reduce", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def util_test(name, srcs, deps = []): + if name[-5:] != "_test": + name = name + "_test" + native.cc_test( + name = "util_" + name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS, + size = "large", + deps = [ + ":opt_test_common", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + ) + +def val_test(name, srcs = [], copts = [], deps = [], **kwargs): + if name[-5:] != "_test": + name = name + "_test" + if name[:4] != "val_": + name = "val_" + name + native.cc_test( + name = name, + srcs = srcs, + compatible_with = [], + copts = TEST_COPTS + copts, + size = "large", + deps = [ + ":val_test_common", + "@com_google_googletest//:gtest_main", + "@com_google_googletest//:gtest", + "@com_google_effcee//:effcee", + ] + deps, + **kwargs + ) diff --git a/docker-compose.yml b/docker-compose.yml old mode 100755 new mode 100644 diff --git a/docs/downloads.md b/docs/downloads.md index f56b6fe9..168937a7 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -2,7 +2,7 @@ ## Latest builds -Download the latest builds of the [main](https://github.com/KhronosGroup/SPIRV-Tools/tree/main) branch. +Download the latest builds of the [master](https://github.com/KhronosGroup/SPIRV-Tools/tree/master) branch. ### Release build | Windows | Linux | MacOS | diff --git a/docs/projects.md b/docs/projects.md index cc88cb3f..8f7f0bcd 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -34,7 +34,7 @@ through the project workflow: ones. * They determine if the work for a card has been completed. * Normally they are the person (or persons) who can approve and merge a pull - request into the `main` branch. + request into the `master` branch. Our projects organize cards into the following columns: * `Ideas`: Work which could be done, captured either as Cards or Notes. @@ -51,7 +51,7 @@ Our projects organize cards into the following columns: claimed by someone. * `Done`: Issues which have been resolved, by completing their work. * The changes have been applied to the repository, typically by being pushed - into the `main` branch. + into the `master` branch. * Other kinds of work could update repository settings, for example. * `Rejected ideas`: Work which has been considered, but which we don't want implemented. diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 5d8a3dab..179a4012 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -30,7 +30,11 @@ if (DEFINED SPIRV-Headers_SOURCE_DIR) # This allows flexible position of the SPIRV-Headers repo. set(SPIRV_HEADER_DIR ${SPIRV-Headers_SOURCE_DIR}) else() - set(SPIRV_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/spirv-headers) + if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SPIRV-Headers) + set(SPIRV_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/SPIRV-Headers) + else() + set(SPIRV_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/spirv-headers) + endif() endif() if (IS_DIRECTORY ${SPIRV_HEADER_DIR}) @@ -41,6 +45,8 @@ if (IS_DIRECTORY ${SPIRV_HEADER_DIR}) # Do this so enclosing projects can use SPIRV-Headers_SOURCE_DIR to find # headers to include. if (NOT DEFINED SPIRV-Headers_SOURCE_DIR) + set(SPIRV_HEADERS_SKIP_INSTALL ON) + set(SPIRV_HEADERS_SKIP_EXAMPLES ON) add_subdirectory(${SPIRV_HEADER_DIR}) endif() else() @@ -54,9 +60,7 @@ if (NOT ${SPIRV_SKIP_TESTS}) if (TARGET gmock) message(STATUS "Google Mock already configured") else() - if (NOT GMOCK_DIR) - set(GMOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest) - endif() + set(GMOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/googletest) if(EXISTS ${GMOCK_DIR}) if(MSVC) # Our tests use ::testing::Combine. Work around a compiler @@ -73,7 +77,7 @@ if (NOT ${SPIRV_SKIP_TESTS}) # gtest requires special defines for building as a shared # library, simply always build as static. push_variable(BUILD_SHARED_LIBS 0) - add_subdirectory(${GMOCK_DIR} ${CMAKE_CURRENT_BINARY_DIR}/googletest EXCLUDE_FROM_ALL) + add_subdirectory(${GMOCK_DIR} EXCLUDE_FROM_ALL) pop_variable(BUILD_SHARED_LIBS) endif() endif() @@ -91,22 +95,10 @@ if (NOT ${SPIRV_SKIP_TESTS}) # Find Effcee and RE2, for testing. - # RE2 depends on Abseil. We set absl_SOURCE_DIR if it is not already set, so - # that effcee can find abseil. - if(NOT TARGET absl::base) - if (NOT absl_SOURCE_DIR) - if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp) - set(absl_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp" CACHE STRING "Abseil source dir" ) - endif() - endif() - endif() - # First find RE2, since Effcee depends on it. # If already configured, then use that. Otherwise, prefer to find it under 're2' # in this directory. if (NOT TARGET re2) - - # If we are configuring RE2, then turn off its testing. It takes a long time and # does not add much value for us. If an enclosing project configured RE2, then it # has already chosen whether to enable RE2 testing. @@ -164,7 +156,7 @@ if(SPIRV_BUILD_FUZZER) if(NOT TARGET protobuf::libprotobuf OR NOT TARGET protobuf::protoc) - set(SPIRV_TOOLS_PROTOBUF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/protobuf) + set(SPIRV_TOOLS_PROTOBUF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/protobuf/cmake) if (NOT IS_DIRECTORY ${SPIRV_TOOLS_PROTOBUF_DIR}) message( FATAL_ERROR diff --git a/include/spirv-tools/instrument.hpp b/include/spirv-tools/instrument.hpp index 0a6e6306..a19491fd 100644 --- a/include/spirv-tools/instrument.hpp +++ b/include/spirv-tools/instrument.hpp @@ -36,25 +36,16 @@ namespace spvtools { // generated by InstrumentPass::GenDebugStreamWrite. This method is utilized // by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass. // -// The 1st member of the debug output buffer contains a set of flags -// controlling the behavior of instrumentation code. -static const int kDebugOutputFlagsOffset = 0; - -// Values stored at kDebugOutputFlagsOffset -enum kInstFlags : unsigned int { - kInstBufferOOBEnable = 0x1, -}; - -// The 2nd member of the debug output buffer contains the next available word +// The first member of the debug output buffer contains the next available word // in the data stream to be written. Shaders will atomically read and update // this value so as not to overwrite each others records. This value must be // initialized to zero -static const int kDebugOutputSizeOffset = 1; +static const int kDebugOutputSizeOffset = 0; -// The 3rd member of the output buffer is the start of the stream of records +// The second member of the output buffer is the start of the stream of records // written by the instrumented shaders. Each record represents a validation // error. The format of the records is documented below. -static const int kDebugOutputDataOffset = 2; +static const int kDebugOutputDataOffset = 1; // Common Stream Record Offsets // @@ -73,14 +64,196 @@ static const int kInstCommonOutShaderId = 1; // which generated the validation error. static const int kInstCommonOutInstructionIdx = 2; +// This is the stage which generated the validation error. This word is used +// to determine the contents of the next two words in the record. +// 0:Vert, 1:TessCtrl, 2:TessEval, 3:Geom, 4:Frag, 5:Compute +static const int kInstCommonOutStageIdx = 3; +static const int kInstCommonOutCnt = 4; + +// Stage-specific Stream Record Offsets +// +// Each stage will contain different values in the next set of words of the +// record used to identify which instantiation of the shader generated the +// validation error. +// +// Vertex Shader Output Record Offsets +static const int kInstVertOutVertexIndex = kInstCommonOutCnt; +static const int kInstVertOutInstanceIndex = kInstCommonOutCnt + 1; +static const int kInstVertOutUnused = kInstCommonOutCnt + 2; + +// Frag Shader Output Record Offsets +static const int kInstFragOutFragCoordX = kInstCommonOutCnt; +static const int kInstFragOutFragCoordY = kInstCommonOutCnt + 1; +static const int kInstFragOutUnused = kInstCommonOutCnt + 2; + +// Compute Shader Output Record Offsets +static const int kInstCompOutGlobalInvocationIdX = kInstCommonOutCnt; +static const int kInstCompOutGlobalInvocationIdY = kInstCommonOutCnt + 1; +static const int kInstCompOutGlobalInvocationIdZ = kInstCommonOutCnt + 2; + +// Tessellation Control Shader Output Record Offsets +static const int kInstTessCtlOutInvocationId = kInstCommonOutCnt; +static const int kInstTessCtlOutPrimitiveId = kInstCommonOutCnt + 1; +static const int kInstTessCtlOutUnused = kInstCommonOutCnt + 2; + +// Tessellation Eval Shader Output Record Offsets +static const int kInstTessEvalOutPrimitiveId = kInstCommonOutCnt; +static const int kInstTessEvalOutTessCoordU = kInstCommonOutCnt + 1; +static const int kInstTessEvalOutTessCoordV = kInstCommonOutCnt + 2; + +// Geometry Shader Output Record Offsets +static const int kInstGeomOutPrimitiveId = kInstCommonOutCnt; +static const int kInstGeomOutInvocationId = kInstCommonOutCnt + 1; +static const int kInstGeomOutUnused = kInstCommonOutCnt + 2; + +// Ray Tracing Shader Output Record Offsets +static const int kInstRayTracingOutLaunchIdX = kInstCommonOutCnt; +static const int kInstRayTracingOutLaunchIdY = kInstCommonOutCnt + 1; +static const int kInstRayTracingOutLaunchIdZ = kInstCommonOutCnt + 2; + +// Mesh Shader Output Record Offsets +static const int kInstMeshOutGlobalInvocationIdX = kInstCommonOutCnt; +static const int kInstMeshOutGlobalInvocationIdY = kInstCommonOutCnt + 1; +static const int kInstMeshOutGlobalInvocationIdZ = kInstCommonOutCnt + 2; + +// Task Shader Output Record Offsets +static const int kInstTaskOutGlobalInvocationIdX = kInstCommonOutCnt; +static const int kInstTaskOutGlobalInvocationIdY = kInstCommonOutCnt + 1; +static const int kInstTaskOutGlobalInvocationIdZ = kInstCommonOutCnt + 2; + +// Size of Common and Stage-specific Members +static const int kInstStageOutCnt = kInstCommonOutCnt + 3; + +// Validation Error Code Offset +// +// This identifies the validation error. It also helps to identify +// how many words follow in the record and their meaning. +static const int kInstValidationOutError = kInstStageOutCnt; + +// Validation-specific Output Record Offsets +// +// Each different validation will generate a potentially different +// number of words at the end of the record giving more specifics +// about the validation error. +// +// A bindless bounds error will output the index and the bound. +static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 1; +static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 2; +static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 3; +static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 4; + +// A descriptor uninitialized error will output the index. +static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 1; +static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 2; +static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 3; +static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 4; + +// A buffer out-of-bounds error will output the descriptor +// index, the buffer offset and the buffer size +static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 1; +static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 2; +static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 3; +static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 4; + +// A buffer address unalloc error will output the 64-bit pointer in +// two 32-bit pieces, lower bits first. +static const int kInstBuffAddrUnallocOutDescPtrLo = kInstStageOutCnt + 1; +static const int kInstBuffAddrUnallocOutDescPtrHi = kInstStageOutCnt + 2; +static const int kInstBuffAddrUnallocOutCnt = kInstStageOutCnt + 3; + +// Maximum Output Record Member Count +static const int kInstMaxOutCnt = kInstStageOutCnt + 4; + +// Validation Error Codes +// +// These are the possible validation error codes. +static const int kInstErrorBindlessBounds = 0; +static const int kInstErrorBindlessUninit = 1; +static const int kInstErrorBuffAddrUnallocRef = 2; +// Deleted: static const int kInstErrorBindlessBuffOOB = 3; +// This comment will will remain for 2 releases to allow +// for the transition of all builds. Buffer OOB is +// generating the following four differentiated codes instead: +static const int kInstErrorBuffOOBUniform = 4; +static const int kInstErrorBuffOOBStorage = 5; +static const int kInstErrorBuffOOBUniformTexel = 6; +static const int kInstErrorBuffOOBStorageTexel = 7; +static const int kInstErrorMax = kInstErrorBuffOOBStorageTexel; + +// Direct Input Buffer Offsets +// +// The following values provide member offsets into the input buffers +// consumed by InstrumentPass::GenDebugDirectRead(). This method is utilized +// by InstBindlessCheckPass. +// +// The only object in an input buffer is a runtime array of unsigned +// integers. Each validation will have its own formatting of this array. +static const int kDebugInputDataOffset = 0; + // Debug Buffer Bindings // // These are the bindings for the different buffers which are // read or written by the instrumentation passes. // +// This is the output buffer written by InstBindlessCheckPass, +// InstBuffAddrCheckPass, and possibly other future validations. +static const int kDebugOutputBindingStream = 0; + +// The binding for the input buffer read by InstBindlessCheckPass. +static const int kDebugInputBindingBindless = 1; + +// The binding for the input buffer read by InstBuffAddrCheckPass. +static const int kDebugInputBindingBuffAddr = 2; + // This is the output buffer written by InstDebugPrintfPass. static const int kDebugOutputPrintfStream = 3; +// Bindless Validation Input Buffer Format +// +// An input buffer for bindless validation consists of a single array of +// unsigned integers we will call Data[]. This array is formatted as follows. +// +// At offset kDebugInputBindlessInitOffset in Data[] is a single uint which +// gives an offset to the start of the bindless initialization data. More +// specifically, if the following value is zero, we know that the descriptor at +// (set = s, binding = b, index = i) is not initialized; if the value is +// non-zero, and the descriptor points to a buffer, the value is the length of +// the buffer in bytes and can be used to check for out-of-bounds buffer +// references: +// Data[ i + Data[ b + Data[ s + Data[ kDebugInputBindlessInitOffset ] ] ] ] +static const int kDebugInputBindlessInitOffset = 0; + +// At offset kDebugInputBindlessOffsetLengths is some number of uints which +// provide the bindless length data. More specifically, the number of +// descriptors at (set=s, binding=b) is: +// Data[ Data[ s + kDebugInputBindlessOffsetLengths ] + b ] +static const int kDebugInputBindlessOffsetLengths = 1; + +// Buffer Device Address Input Buffer Format +// +// An input buffer for buffer device address validation consists of a single +// array of unsigned 64-bit integers we will call Data[]. This array is +// formatted as follows: +// +// At offset kDebugInputBuffAddrPtrOffset is a list of sorted valid buffer +// addresses. The list is terminated with the address 0xffffffffffffffff. +// If 0x0 is not a valid buffer address, this address is inserted at the +// start of the list. +// +static const int kDebugInputBuffAddrPtrOffset = 1; +// +// At offset kDebugInputBuffAddrLengthOffset in Data[] is a single uint64 which +// gives an offset to the start of the buffer length data. More +// specifically, for a buffer whose pointer is located at input buffer offset +// i, the length is located at: +// +// Data[ i - kDebugInputBuffAddrPtrOffset +// + Data[ kDebugInputBuffAddrLengthOffset ] ] +// +// The length associated with the 0xffffffffffffffff address is zero. If +// not a valid buffer, the length associated with the 0x0 address is zero. +static const int kDebugInputBuffAddrLengthOffset = 0; + } // namespace spvtools #endif // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_ diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index b70f084a..b549efba 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -143,7 +143,6 @@ typedef enum spv_operand_type_t { // may be larger than 32, which would require such a typed literal value to // occupy multiple SPIR-V words. SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, - SPV_OPERAND_TYPE_LITERAL_FLOAT, // Always 32-bit float. // Set 3: The literal string operand type. SPV_OPERAND_TYPE_LITERAL_STRING, @@ -286,22 +285,6 @@ typedef enum spv_operand_type_t { // An optional packed vector format SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, - // Concrete operand types for cooperative matrix. - SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, - // An optional cooperative matrix operands - SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, - SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, - SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, - - // Enum type from SPV_INTEL_global_variable_fpga_decorations - SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, - // Enum type from SPV_INTEL_global_variable_host_access - SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, - // Enum type from SPV_INTEL_cache_controls - SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, - // Enum type from SPV_INTEL_cache_controls - SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, - // This is a sentinel value, and does not represent an operand type. // It should come last. SPV_OPERAND_TYPE_NUM_OPERAND_TYPES, @@ -419,19 +402,6 @@ typedef struct spv_parsed_instruction_t { uint16_t num_operands; } spv_parsed_instruction_t; -typedef struct spv_parsed_header_t { - // The magic number of the SPIR-V module. - uint32_t magic; - // Version number. - uint32_t version; - // Generator's magic number. - uint32_t generator; - // IDs bound for this module (0 < id < bound). - uint32_t bound; - // reserved. - uint32_t reserved; -} spv_parsed_header_t; - typedef struct spv_const_binary_t { const uint32_t* code; const size_t wordCount; @@ -471,8 +441,6 @@ typedef struct spv_reducer_options_t spv_reducer_options_t; typedef struct spv_fuzzer_options_t spv_fuzzer_options_t; -typedef struct spv_optimizer_t spv_optimizer_t; - // Type Definitions typedef spv_const_binary_t* spv_const_binary; @@ -932,63 +900,6 @@ SPIRV_TOOLS_EXPORT spv_result_t spvBinaryParse( const size_t num_words, spv_parsed_header_fn_t parse_header, spv_parsed_instruction_fn_t parse_instruction, spv_diagnostic* diagnostic); -// The optimizer interface. - -// A pointer to a function that accepts a log message from an optimizer. -typedef void (*spv_message_consumer)( - spv_message_level_t, const char*, const spv_position_t*, const char*); - -// Creates and returns an optimizer object. This object must be passed to -// optimizer APIs below and is valid until passed to spvOptimizerDestroy. -SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env); - -// Destroys the given optimizer object. -SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer); - -// Sets an spv_message_consumer on an optimizer object. -SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer( - spv_optimizer_t* optimizer, spv_message_consumer consumer); - -// Registers passes that attempt to legalize the generated code. -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses( - spv_optimizer_t* optimizer); - -// Registers passes that attempt to improve performance of generated code. -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses( - spv_optimizer_t* optimizer); - -// Registers passes that attempt to improve the size of generated code. -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses( - spv_optimizer_t* optimizer); - -// Registers a pass specified by a flag in an optimizer object. -SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag( - spv_optimizer_t* optimizer, const char* flag); - -// Registers passes specified by length number of flags in an optimizer object. -SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags( - spv_optimizer_t* optimizer, const char** flags, const size_t flag_count); - -// Optimizes the SPIR-V code of size |word_count| pointed to by |binary| and -// returns an optimized spv_binary in |optimized_binary|. -// -// Returns SPV_SUCCESS on successful optimization, whether or not the module is -// modified. Returns an SPV_ERROR_* if the module fails to validate or if -// errors occur when processing using any of the registered passes. In that -// case, no further passes are executed and the |optimized_binary| contents may -// be invalid. -// -// By default, the binary is validated before any transforms are performed, -// and optionally after each transform. Validation uses SPIR-V spec rules -// for the SPIR-V version named in the binary's header (at word offset 1). -// Additionally, if the target environment is a client API (such as -// Vulkan 1.1), then validate for that client API version, to the extent -// that it is verifiable from data in the binary itself, or from the -// validator options set on the optimizer options. -SPIRV_TOOLS_EXPORT spv_result_t spvOptimizerRun( - spv_optimizer_t* optimizer, const uint32_t* binary, const size_t word_count, - spv_binary* optimized_binary, const spv_optimizer_options options); - #ifdef __cplusplus } #endif diff --git a/include/spirv-tools/libspirv.hpp b/include/spirv-tools/libspirv.hpp index ee6c8469..408e3ebb 100644 --- a/include/spirv-tools/libspirv.hpp +++ b/include/spirv-tools/libspirv.hpp @@ -31,11 +31,6 @@ using MessageConsumer = std::function; -using HeaderParser = std::function; -using InstructionParser = - std::function; - // C++ RAII wrapper around the C context object spv_context. class Context { public: @@ -341,23 +336,6 @@ class SpirvTools { std::string* text, uint32_t options = kDefaultDisassembleOption) const; - // Parses a SPIR-V binary, specified as counted sequence of 32-bit words. - // Parsing feedback is provided via two callbacks provided as std::function. - // In a valid parse the parsed-header callback is called once, and - // then the parsed-instruction callback is called once for each instruction - // in the stream. - // Returns true on successful parsing. - // If diagnostic is non-null, a diagnostic is emitted on failed parsing. - // If diagnostic is null the context's message consumer - // will be used to emit any errors. If a callback returns anything other than - // SPV_SUCCESS, then that status code is returned, no further callbacks are - // issued, and no additional diagnostics are emitted. - // This is a wrapper around the C API spvBinaryParse. - bool Parse(const std::vector& binary, - const HeaderParser& header_parser, - const InstructionParser& instruction_parser, - spv_diagnostic* diagnostic = nullptr); - // Validates the given SPIR-V |binary|. Returns true if no issues are found. // Otherwise, returns false and communicates issues via the message consumer // registered. diff --git a/include/spirv-tools/linker.hpp b/include/spirv-tools/linker.hpp index 5b60cb9f..d2f3e72c 100644 --- a/include/spirv-tools/linker.hpp +++ b/include/spirv-tools/linker.hpp @@ -26,6 +26,11 @@ namespace spvtools { class LinkerOptions { public: + LinkerOptions() + : create_library_(false), + verify_ids_(false), + allow_partial_linkage_(false) {} + // Returns whether a library or an executable should be produced by the // linking phase. // @@ -58,16 +63,10 @@ class LinkerOptions { allow_partial_linkage_ = allow_partial_linkage; } - bool GetUseHighestVersion() const { return use_highest_version_; } - void SetUseHighestVersion(bool use_highest_vers) { - use_highest_version_ = use_highest_vers; - } - private: - bool create_library_{false}; - bool verify_ids_{false}; - bool allow_partial_linkage_{false}; - bool use_highest_version_{false}; + bool create_library_; + bool verify_ids_; + bool allow_partial_linkage_; }; // Links one or more SPIR-V modules into a new SPIR-V module. That is, combine diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp index 53ebc59f..94973560 100644 --- a/include/spirv-tools/optimizer.hpp +++ b/include/spirv-tools/optimizer.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -97,24 +96,12 @@ class Optimizer { // Registers passes that attempt to improve performance of generated code. // This sequence of passes is subject to constant review and will change // from time to time. - // - // If |preserve_interface| is true, all non-io variables in the entry point - // interface are considered live and are not eliminated. - // |preserve_interface| should be true if HLSL is generated - // from the SPIR-V bytecode. Optimizer& RegisterPerformancePasses(); - Optimizer& RegisterPerformancePasses(bool preserve_interface); // Registers passes that attempt to improve the size of generated code. // This sequence of passes is subject to constant review and will change // from time to time. - // - // If |preserve_interface| is true, all non-io variables in the entry point - // interface are considered live and are not eliminated. - // |preserve_interface| should be true if HLSL is generated - // from the SPIR-V bytecode. Optimizer& RegisterSizePasses(); - Optimizer& RegisterSizePasses(bool preserve_interface); // Registers passes that attempt to legalize the generated code. // @@ -124,13 +111,7 @@ class Optimizer { // // This sequence of passes is subject to constant review and will change // from time to time. - // - // If |preserve_interface| is true, all non-io variables in the entry point - // interface are considered live and are not eliminated. - // |preserve_interface| should be true if HLSL is generated - // from the SPIR-V bytecode. Optimizer& RegisterLegalizationPasses(); - Optimizer& RegisterLegalizationPasses(bool preserve_interface); // Register passes specified in the list of |flags|. Each flag must be a // string of a form accepted by Optimizer::FlagHasValidForm(). @@ -539,14 +520,8 @@ Optimizer::PassToken CreateDeadInsertElimPass(); // interface are considered live and are not eliminated. This mode is needed // by GPU-Assisted validation instrumentation, where a change in the interface // is not allowed. -// -// If |remove_outputs| is true, allow outputs to be removed from the interface. -// This is only safe if the caller knows that there is no corresponding input -// variable in the following shader. It is false by default. Optimizer::PassToken CreateAggressiveDCEPass(); Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface); -Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, - bool remove_outputs); // Creates a remove-unused-interface-variables pass. // Removes variables referenced on the |OpEntryPoint| instruction that are not @@ -766,9 +741,19 @@ Optimizer::PassToken CreateCombineAccessChainsPass(); // potentially de-optimizing the instrument code, for example, inlining // the debug record output function throughout the module. // -// The instrumentation will write |shader_id| in each output record +// The instrumentation will read and write buffers in debug +// descriptor set |desc_set|. It will write |shader_id| in each output record // to identify the shader module which generated the record. -Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id); +// |desc_length_enable| controls instrumentation of runtime descriptor array +// references, |desc_init_enable| controls instrumentation of descriptor +// initialization checking, and |buff_oob_enable| controls instrumentation +// of storage and uniform buffer bounds checking, all of which require input +// buffer support. |texbuff_oob_enable| controls instrumentation of texel +// buffers, which does not require input buffer support. +Optimizer::PassToken CreateInstBindlessCheckPass( + uint32_t desc_set, uint32_t shader_id, bool desc_length_enable = false, + bool desc_init_enable = false, bool buff_oob_enable = false, + bool texbuff_oob_enable = false); // Create a pass to instrument physical buffer address checking // This pass instruments all physical buffer address references to check that @@ -789,7 +774,8 @@ Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id); // The instrumentation will read and write buffers in debug // descriptor set |desc_set|. It will write |shader_id| in each output record // to identify the shader module which generated the record. -Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id); +Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t desc_set, + uint32_t shader_id); // Create a pass to instrument OpDebugPrintf instructions. // This pass replaces all OpDebugPrintf instructions with instructions to write @@ -901,59 +887,12 @@ Optimizer::PassToken CreateAmdExtToKhrPass(); Optimizer::PassToken CreateInterpolateFixupPass(); // Removes unused components from composite input variables. Current -// implementation just removes trailing unused components from input arrays -// and structs. The pass performs best after maximizing dead code removal. -// A subsequent dead code elimination pass would be beneficial in removing -// newly unused component types. -// -// WARNING: This pass can only be safely applied standalone to vertex shaders -// as it can otherwise cause interface incompatibilities with the preceding -// shader in the pipeline. If applied to non-vertex shaders, the user should -// follow by applying EliminateDeadOutputStores and -// EliminateDeadOutputComponents to the preceding shader. +// implementation just removes trailing unused components from input arrays. +// The pass performs best after maximizing dead code removal. A subsequent dead +// code elimination pass would be beneficial in removing newly unused component +// types. Optimizer::PassToken CreateEliminateDeadInputComponentsPass(); -// Removes unused components from composite output variables. Current -// implementation just removes trailing unused components from output arrays -// and structs. The pass performs best after eliminating dead output stores. -// A subsequent dead code elimination pass would be beneficial in removing -// newly unused component types. Currently only supports vertex and fragment -// shaders. -// -// WARNING: This pass cannot be safely applied standalone as it can cause -// interface incompatibility with the following shader in the pipeline. The -// user should first apply EliminateDeadInputComponents to the following -// shader, then apply EliminateDeadOutputStores to this shader. -Optimizer::PassToken CreateEliminateDeadOutputComponentsPass(); - -// Removes unused components from composite input variables. This safe -// version will not cause interface incompatibilities since it only changes -// vertex shaders. The current implementation just removes trailing unused -// components from input structs and input arrays. The pass performs best -// after maximizing dead code removal. A subsequent dead code elimination -// pass would be beneficial in removing newly unused component types. -Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass(); - -// Analyzes shader and populates |live_locs| and |live_builtins|. Best results -// will be obtained if shader has all dead code eliminated first. |live_locs| -// and |live_builtins| are subsequently used when calling -// CreateEliminateDeadOutputStoresPass on the preceding shader. Currently only -// supports tesc, tese, geom, and frag shaders. -Optimizer::PassToken CreateAnalyzeLiveInputPass( - std::unordered_set* live_locs, - std::unordered_set* live_builtins); - -// Removes stores to output locations not listed in |live_locs| or -// |live_builtins|. Best results are obtained if constant propagation is -// performed first. A subsequent call to ADCE will eliminate any dead code -// created by the removal of the stores. A subsequent call to -// CreateEliminateDeadOutputComponentsPass will eliminate any dead output -// components created by the elimination of the stores. Currently only supports -// vert, tesc, tese, and geom shaders. -Optimizer::PassToken CreateEliminateDeadOutputStoresPass( - std::unordered_set* live_locs, - std::unordered_set* live_builtins); - // Creates a convert-to-sampled-image pass to convert images and/or // samplers with given pairs of descriptor set and binding to sampled image. // If a pair of an image and a sampler have the same pair of descriptor set and @@ -978,28 +917,6 @@ Optimizer::PassToken CreateRemoveDontInlinePass(); // object, currently the pass would remove accesschain pointer argument passed // to the function Optimizer::PassToken CreateFixFuncCallArgumentsPass(); - -// Creates a trim-capabilities pass. -// This pass removes unused capabilities for a given module, and if possible, -// associated extensions. -// See `trim_capabilities.h` for the list of supported capabilities. -// -// If the module contains unsupported capabilities, this pass will ignore them. -// This should be fine in most cases, but could yield to incorrect results if -// the unknown capability interacts with one of the trimmed capabilities. -Optimizer::PassToken CreateTrimCapabilitiesPass(); - -// Creates a switch-descriptorset pass. -// This pass changes any DescriptorSet decorations with the value |ds_from| to -// use the new value |ds_to|. -Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t ds_from, - uint32_t ds_to); - -// Creates an invocation interlock placement pass. -// This pass ensures that an entry point will have at most one -// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that -// order. -Optimizer::PassToken CreateInvocationInterlockPlacementPass(); } // namespace spvtools #endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ diff --git a/kokoro/check-format/build.sh b/kokoro/check-format/build.sh index 96603e44..8a5df9a8 100644 --- a/kokoro/check-format/build.sh +++ b/kokoro/check-format/build.sh @@ -23,11 +23,6 @@ set -x BUILD_ROOT=$PWD SRC=$PWD/github/SPIRV-Tools -# This is required to run any git command in the docker since owner will -# have changed between the clone environment, and the docker container. -# Marking the root of the repo as safe for ownership changes. -git config --global --add safe.directory $SRC - # Get clang-format-5.0.0. # Once kokoro upgrades the Ubuntu VMs, we can use 'apt-get install clang-format' curl -L http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz -o clang-llvm.tar.xz diff --git a/kokoro/macos-clang-debug/build.sh b/kokoro/macos-clang-debug/build.sh index fca76fc6..8d9a062f 100644 --- a/kokoro/macos-clang-debug/build.sh +++ b/kokoro/macos-clang-debug/build.sh @@ -22,3 +22,4 @@ set -x SCRIPT_DIR=`dirname "$BASH_SOURCE"` source $SCRIPT_DIR/../scripts/macos/build.sh Debug + diff --git a/kokoro/macos-clang-release-bazel/build.sh b/kokoro/macos-clang-release-bazel/build.sh index 74f9e236..c62611ab 100644 --- a/kokoro/macos-clang-release-bazel/build.sh +++ b/kokoro/macos-clang-release-bazel/build.sh @@ -24,22 +24,21 @@ CC=clang CXX=clang++ SRC=$PWD/github/SPIRV-Tools -# This is required to run any git command in the docker since owner will -# have changed between the clone environment, and the docker container. -# Marking the root of the repo as safe for ownership changes. -git config --global --add safe.directory $SRC - cd $SRC -/usr/bin/python3 utils/git-sync-deps --treeless +git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers +git clone https://github.com/google/googletest external/googletest +cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd .. +git clone --depth=1 https://github.com/google/effcee external/effcee +git clone --depth=1 https://github.com/google/re2 external/re2 # Get bazel 5.0.0 gsutil cp gs://bazel/5.0.0/release/bazel-5.0.0-darwin-x86_64 . chmod +x bazel-5.0.0-darwin-x86_64 echo $(date): Build everything... -./bazel-5.0.0-darwin-x86_64 build --cxxopt=-std=c++17 :all +./bazel-5.0.0-darwin-x86_64 build :all echo $(date): Build completed. echo $(date): Starting bazel test... -./bazel-5.0.0-darwin-x86_64 test --cxxopt=-std=c++17 :all +./bazel-5.0.0-darwin-x86_64 test :all echo $(date): Bazel test completed. diff --git a/kokoro/macos-clang-release/build.sh b/kokoro/macos-clang-release/build.sh index b1460a97..ccc8b16a 100644 --- a/kokoro/macos-clang-release/build.sh +++ b/kokoro/macos-clang-release/build.sh @@ -22,3 +22,4 @@ set -x SCRIPT_DIR=`dirname "$BASH_SOURCE"` source $SCRIPT_DIR/../scripts/macos/build.sh RelWithDebInfo + diff --git a/kokoro/scripts/linux/build-docker.sh b/kokoro/scripts/linux/build-docker.sh index a0dc96ab..80043b8a 100755 --- a/kokoro/scripts/linux/build-docker.sh +++ b/kokoro/scripts/linux/build-docker.sh @@ -20,11 +20,6 @@ set -e # Display commands being run. set -x -# This is required to run any git command in the docker since owner will -# have changed between the clone environment, and the docker container. -# Marking the root of the repo as safe for ownership changes. -git config --global --add safe.directory $ROOT_DIR - . /bin/using.sh # Declare the bash `using` function for configuring toolchains. if [ $COMPILER = "clang" ]; then @@ -35,6 +30,14 @@ fi cd $ROOT_DIR +function clone_if_missing() { + url=$1 + dir=$2 + if [[ ! -d "$dir" ]]; then + git clone ${@:3} "$url" "$dir" + fi +} + function clean_dir() { dir=$1 if [[ -d "$dir" ]]; then @@ -43,10 +46,12 @@ function clean_dir() { mkdir "$dir" } -if [ $TOOL != "cmake-smoketest" ]; then - # Get source for dependencies, as specified in the DEPS file - /usr/bin/python3 utils/git-sync-deps --treeless -fi +clone_if_missing https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers --depth=1 +clone_if_missing https://github.com/google/googletest external/googletest +pushd external/googletest; git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7; popd +clone_if_missing https://github.com/google/effcee external/effcee --depth=1 +clone_if_missing https://github.com/google/re2 external/re2 --depth=1 +clone_if_missing https://github.com/protocolbuffers/protobuf external/protobuf --branch v3.13.0.1 if [ $TOOL = "cmake" ]; then using cmake-3.17.2 @@ -131,7 +136,6 @@ elif [ $TOOL = "cmake-smoketest" ]; then git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers git clone https://github.com/google/re2 git clone https://github.com/google/effcee - git clone https://github.com/abseil/abseil-cpp abseil_cpp cd $SHADERC_DIR mkdir build @@ -142,7 +146,7 @@ elif [ $TOOL = "cmake-smoketest" ]; then cmake -GNinja -DRE2_BUILD_TESTING=OFF -DCMAKE_BUILD_TYPE="Release" .. echo $(date): Build glslang... - ninja glslang-standalone + ninja glslangValidator echo $(date): Build everything... ninja @@ -156,7 +160,7 @@ elif [ $TOOL = "cmake-smoketest" ]; then echo $(date): ctest completed. elif [ $TOOL = "cmake-android-ndk" ]; then using cmake-3.17.2 - using ndk-r25c + using ndk-r21d using ninja-1.10.0 clean_dir "$ROOT_DIR/build" @@ -164,7 +168,7 @@ elif [ $TOOL = "cmake-android-ndk" ]; then echo $(date): Starting build... cmake -DCMAKE_BUILD_TYPE=Release \ - -DANDROID_NATIVE_API_LEVEL=android-24 \ + -DANDROID_NATIVE_API_LEVEL=android-16 \ -DANDROID_ABI="armeabi-v7a with NEON" \ -DSPIRV_SKIP_TESTS=ON \ -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \ @@ -176,7 +180,7 @@ elif [ $TOOL = "cmake-android-ndk" ]; then ninja echo $(date): Build completed. elif [ $TOOL = "android-ndk-build" ]; then - using ndk-r25c + using ndk-r21d clean_dir "$ROOT_DIR/build" cd "$ROOT_DIR/build" @@ -194,10 +198,10 @@ elif [ $TOOL = "bazel" ]; then using bazel-5.0.0 echo $(date): Build everything... - bazel build --cxxopt=-std=c++17 :all + bazel build :all echo $(date): Build completed. echo $(date): Starting bazel test... - bazel test --cxxopt=-std=c++17 :all + bazel test :all echo $(date): Bazel test completed. fi diff --git a/kokoro/scripts/linux/build.sh b/kokoro/scripts/linux/build.sh index 688ba793..85d4b61a 100644 --- a/kokoro/scripts/linux/build.sh +++ b/kokoro/scripts/linux/build.sh @@ -26,18 +26,6 @@ COMPILER=$2 TOOL=$3 BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT} -# chown the given directory to the current user, if it exists. -# Docker creates files with the root user - this can upset the Kokoro artifact copier. -function chown_dir() { - dir=$1 - if [[ -d "$dir" ]]; then - sudo chown -R "$(id -u):$(id -g)" "$dir" - fi -} - -set +e -# Allow build failures - # "--privileged" is required to run ptrace in the asan builds. docker run --rm -i \ --privileged \ @@ -53,11 +41,16 @@ docker run --rm -i \ --env BUILD_SHA="${BUILD_SHA}" \ --entrypoint "${SCRIPT_DIR}/build-docker.sh" \ "gcr.io/shaderc-build/radial-build:latest" -RESULT=$? -# This is important. If the permissions are not fixed, kokoro will fail -# to pull build artifacts, and put the build in tool-failure state, which -# blocks the logs. + +# chown the given directory to the current user, if it exists. +# Docker creates files with the root user - this can upset the Kokoro artifact copier. +function chown_dir() { + dir=$1 + if [[ -d "$dir" ]]; then + sudo chown -R "$(id -u):$(id -g)" "$dir" + fi +} + chown_dir "${ROOT_DIR}/build" chown_dir "${ROOT_DIR}/external" -exit $RESULT diff --git a/kokoro/scripts/macos/build.sh b/kokoro/scripts/macos/build.sh index 8381f87d..46128238 100644 --- a/kokoro/scripts/macos/build.sh +++ b/kokoro/scripts/macos/build.sh @@ -24,11 +24,6 @@ BUILD_ROOT=$PWD SRC=$PWD/github/SPIRV-Tools BUILD_TYPE=$1 -# This is required to run any git command in the docker since owner will -# have changed between the clone environment, and the docker container. -# Marking the root of the repo as safe for ownership changes. -git config --global --add safe.directory $SRC - # Get NINJA. wget -q https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip unzip -q ninja-mac.zip @@ -36,16 +31,23 @@ chmod +x ninja export PATH="$PWD:$PATH" cd $SRC -python3 utils/git-sync-deps --treeless +git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers +git clone https://github.com/google/googletest external/googletest +cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd .. +git clone --depth=1 https://github.com/google/effcee external/effcee +git clone --depth=1 https://github.com/google/re2 external/re2 +git clone --depth=1 --branch v3.13.0.1 https://github.com/protocolbuffers/protobuf external/protobuf mkdir build && cd $SRC/build # Invoke the build. BUILD_SHA=${KOKORO_GITHUB_COMMIT:-$KOKORO_GITHUB_PULL_REQUEST_COMMIT} echo $(date): Starting build... +# We need Python 3. At the moment python3.7 is the newest Python on Kokoro. cmake \ -GNinja \ -DCMAKE_INSTALL_PREFIX=$KOKORO_ARTIFACTS_DIR/install \ + -DPYTHON_EXECUTABLE:FILEPATH=/usr/local/bin/python3.7 \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ diff --git a/kokoro/scripts/windows/build.bat b/kokoro/scripts/windows/build.bat index fe15f2d7..8c9d6892 100644 --- a/kokoro/scripts/windows/build.bat +++ b/kokoro/scripts/windows/build.bat @@ -24,23 +24,26 @@ set VS_VERSION=%2 :: Force usage of python 3.6 set PATH=C:\python36;"C:\Program Files\cmake-3.23.1-windows-x86_64\bin";%PATH% +cd %SRC% +git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers +git clone https://github.com/google/googletest external/googletest +cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd .. +git clone --depth=1 https://github.com/google/effcee external/effcee +git clone --depth=1 https://github.com/google/re2 external/re2 +git clone --depth=1 --branch v3.13.0.1 https://github.com/protocolbuffers/protobuf external/protobuf + :: ######################################### :: set up msvc build env :: ######################################### if %VS_VERSION% == 2017 ( call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 echo "Using VS 2017..." - - :: RE2 does not support VS2017, we we must disable tests. - set BUILD_TESTS=NO -) else if %VS_VERSION% == 2019 ( - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 - echo "Using VS 2019..." +) else if %VS_VERSION% == 2015 ( + call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 + echo "Using VS 2015..." ) cd %SRC% -python utils/git-sync-deps --treeless - mkdir build cd build @@ -59,10 +62,6 @@ set CMAKE_FLAGS=-DCMAKE_INSTALL_PREFIX=%KOKORO_ARTIFACTS_DIR%\install -GNinja -D :: Build spirv-fuzz set CMAKE_FLAGS=%CMAKE_FLAGS% -DSPIRV_BUILD_FUZZER=ON -if "%BUILD_TESTS%" == "NO" ( - set CMAKE_FLAGS=-DSPIRV_SKIP_TESTS=ON %CMAKE_FLAGS% -) - cmake %CMAKE_FLAGS% .. if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% @@ -78,12 +77,10 @@ setlocal ENABLEDELAYEDEXPANSION :: ################################################ :: Run the tests :: ################################################ -if "%BUILD_TESTS%" NEQ "NO" ( - echo "Running Tests... %DATE% %TIME%" - ctest -C %BUILD_TYPE% --output-on-failure --timeout 300 - if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL! - echo "Tests Completed %DATE% %TIME%" -) +echo "Running Tests... %DATE% %TIME%" +ctest -C %BUILD_TYPE% --output-on-failure --timeout 300 +if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL! +echo "Tests Completed %DATE% %TIME%" :: ################################################ :: Install and package. diff --git a/kokoro/windows-msvc-2019-release/build.bat b/kokoro/windows-msvc-2013-release/build.bat old mode 100755 new mode 100644 similarity index 95% rename from kokoro/windows-msvc-2019-release/build.bat rename to kokoro/windows-msvc-2013-release/build.bat index 82129245..e77172af --- a/kokoro/windows-msvc-2019-release/build.bat +++ b/kokoro/windows-msvc-2013-release/build.bat @@ -1,4 +1,4 @@ -:: Copyright (c) 2023 Google LLC +:: Copyright (c) 2018 Google LLC. :: :: Licensed under the Apache License, Version 2.0 (the "License"); :: you may not use this file except in compliance with the License. @@ -20,5 +20,5 @@ set SCRIPT_DIR=%~dp0 :: Call with correct parameter -call %SCRIPT_DIR%\..\scripts\windows\build.bat RelWithDebInfo 2019 +call %SCRIPT_DIR%\..\scripts\windows\build.bat RelWithDebInfo 2013 diff --git a/kokoro/windows-msvc-2019-release/continuous.cfg b/kokoro/windows-msvc-2013-release/continuous.cfg old mode 100755 new mode 100644 similarity index 78% rename from kokoro/windows-msvc-2019-release/continuous.cfg rename to kokoro/windows-msvc-2013-release/continuous.cfg index 624ccbde..5dfcba63 --- a/kokoro/windows-msvc-2019-release/continuous.cfg +++ b/kokoro/windows-msvc-2013-release/continuous.cfg @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Google LLC. +# Copyright (c) 2018 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,10 +13,4 @@ # limitations under the License. # Continuous build configuration. -build_file: "SPIRV-Tools/kokoro/windows-msvc-2019-release/build.bat" - -action { - define_artifacts { - regex: "install.zip" - } -} +build_file: "SPIRV-Tools/kokoro/windows-msvc-2013-release/build.bat" diff --git a/kokoro/windows-msvc-2019-release/presubmit.cfg b/kokoro/windows-msvc-2013-release/presubmit.cfg old mode 100755 new mode 100644 similarity index 85% rename from kokoro/windows-msvc-2019-release/presubmit.cfg rename to kokoro/windows-msvc-2013-release/presubmit.cfg index 4c578e00..7d3b2382 --- a/kokoro/windows-msvc-2019-release/presubmit.cfg +++ b/kokoro/windows-msvc-2013-release/presubmit.cfg @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Google LLC. +# Copyright (c) 2018 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,4 +13,4 @@ # limitations under the License. # Presubmit build configuration. -build_file: "SPIRV-Tools/kokoro/windows-msvc-2019-release/build.bat" +build_file: "SPIRV-Tools/kokoro/windows-msvc-2013-release/build.bat" diff --git a/kokoro/windows-msvc-2015-release-bazel/build.bat b/kokoro/windows-msvc-2015-release-bazel/build.bat new file mode 100644 index 00000000..de20b0aa --- /dev/null +++ b/kokoro/windows-msvc-2015-release-bazel/build.bat @@ -0,0 +1,59 @@ +:: Copyright (c) 2019 Google LLC. +:: +:: 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. +:: +:: Windows Build Script. + +@echo on + +set SRC=%cd%\github\SPIRV-Tools + +:: Force usage of python 3.6 +set PATH=C:\python36;%PATH% + +:: Get dependencies +cd %SRC% +git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers +git clone https://github.com/google/googletest external/googletest +cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd .. +git clone --depth=1 https://github.com/google/effcee external/effcee +git clone --depth=1 https://github.com/google/re2 external/re2 + +:: REM Install Bazel. +wget -q https://github.com/bazelbuild/bazel/releases/download/5.0.0/bazel-5.0.0-windows-x86_64.zip +unzip -q bazel-5.0.0-windows-x86_64.zip + +:: Set up MSVC +call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 +set BAZEL_VS=C:\Program Files (x86)\Microsoft Visual Studio 14.0 +set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC +set BAZEL_PYTHON=c:\tools\python2\python.exe + +:: ######################################### +:: Start building. +:: ######################################### +echo "Build everything... %DATE% %TIME%" +bazel.exe build :all +if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% +echo "Build Completed %DATE% %TIME%" + +:: ############## +:: Run the tests +:: ############## +echo "Running Tests... %DATE% %TIME%" +bazel.exe test :all +if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% +echo "Tests Completed %DATE% %TIME%" + +exit /b 0 + diff --git a/kokoro/windows-msvc-2015-release-bazel/continuous.cfg b/kokoro/windows-msvc-2015-release-bazel/continuous.cfg new file mode 100644 index 00000000..f72cf059 --- /dev/null +++ b/kokoro/windows-msvc-2015-release-bazel/continuous.cfg @@ -0,0 +1,16 @@ +# Copyright (c) 2019 Google LLC. +# +# 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. + +# Continuous build configuration. +build_file: "SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat" diff --git a/kokoro/windows-msvc-2015-release-bazel/presubmit.cfg b/kokoro/windows-msvc-2015-release-bazel/presubmit.cfg new file mode 100644 index 00000000..148972ce --- /dev/null +++ b/kokoro/windows-msvc-2015-release-bazel/presubmit.cfg @@ -0,0 +1,16 @@ +# Copyright (c) 2019 Google LLC. +# +# 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. + +# Presubmit build configuration. +build_file: "SPIRV-Tools/kokoro/windows-msvc-2015-release-bazel/build.bat" diff --git a/kokoro/windows-msvc-2015-release/build.bat b/kokoro/windows-msvc-2015-release/build.bat new file mode 100644 index 00000000..c0e4bd31 --- /dev/null +++ b/kokoro/windows-msvc-2015-release/build.bat @@ -0,0 +1,24 @@ +:: Copyright (c) 2018 Google LLC. +:: +:: 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. +:: +:: Windows Build Script. + +@echo on + +:: Find out the directory of the common build script. +set SCRIPT_DIR=%~dp0 + +:: Call with correct parameter +call %SCRIPT_DIR%\..\scripts\windows\build.bat RelWithDebInfo 2015 + diff --git a/kokoro/windows-msvc-2015-release/continuous.cfg b/kokoro/windows-msvc-2015-release/continuous.cfg new file mode 100644 index 00000000..3e47e526 --- /dev/null +++ b/kokoro/windows-msvc-2015-release/continuous.cfg @@ -0,0 +1,16 @@ +# Copyright (c) 2018 Google LLC. +# +# 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. + +# Continuous build configuration. +build_file: "SPIRV-Tools/kokoro/windows-msvc-2015-release/build.bat" diff --git a/kokoro/windows-msvc-2015-release/presubmit.cfg b/kokoro/windows-msvc-2015-release/presubmit.cfg new file mode 100644 index 00000000..85a16259 --- /dev/null +++ b/kokoro/windows-msvc-2015-release/presubmit.cfg @@ -0,0 +1,16 @@ +# Copyright (c) 2018 Google LLC. +# +# 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. + +# Presubmit build configuration. +build_file: "SPIRV-Tools/kokoro/windows-msvc-2015-release/build.bat" diff --git a/kokoro/windows-msvc-2019-debug/build.bat b/kokoro/windows-msvc-2017-debug/build.bat old mode 100755 new mode 100644 similarity index 88% rename from kokoro/windows-msvc-2019-debug/build.bat rename to kokoro/windows-msvc-2017-debug/build.bat index 7ad94c19..25783a9e --- a/kokoro/windows-msvc-2019-debug/build.bat +++ b/kokoro/windows-msvc-2017-debug/build.bat @@ -1,4 +1,4 @@ -:: Copyright (c) 2023 Google LLC +:: Copyright (c) 2018 Google LLC. :: :: Licensed under the Apache License, Version 2.0 (the "License"); :: you may not use this file except in compliance with the License. @@ -20,4 +20,4 @@ set SCRIPT_DIR=%~dp0 :: Call with correct parameter -call %SCRIPT_DIR%\..\scripts\windows\build.bat Debug 2019 +call %SCRIPT_DIR%\..\scripts\windows\build.bat Debug 2017 diff --git a/kokoro/windows-msvc-2019-debug/continuous.cfg b/kokoro/windows-msvc-2017-debug/continuous.cfg old mode 100755 new mode 100644 similarity index 86% rename from kokoro/windows-msvc-2019-debug/continuous.cfg rename to kokoro/windows-msvc-2017-debug/continuous.cfg index e3a7863d..25c5e113 --- a/kokoro/windows-msvc-2019-debug/continuous.cfg +++ b/kokoro/windows-msvc-2017-debug/continuous.cfg @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Google LLC +# Copyright (c) 2018 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ # limitations under the License. # Continuous build configuration. -build_file: "SPIRV-Tools/kokoro/windows-msvc-2019-debug/build.bat" +build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat" action { define_artifacts { diff --git a/kokoro/windows-msvc-2019-debug/presubmit.cfg b/kokoro/windows-msvc-2017-debug/presubmit.cfg old mode 100755 new mode 100644 similarity index 85% rename from kokoro/windows-msvc-2019-debug/presubmit.cfg rename to kokoro/windows-msvc-2017-debug/presubmit.cfg index 0ed35940..a7a553ae --- a/kokoro/windows-msvc-2019-debug/presubmit.cfg +++ b/kokoro/windows-msvc-2017-debug/presubmit.cfg @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Google LLC +# Copyright (c) 2018 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,4 +13,4 @@ # limitations under the License. # Presubmit build configuration. -build_file: "SPIRV-Tools/kokoro/windows-msvc-2019-debug/build.bat" +build_file: "SPIRV-Tools/kokoro/windows-msvc-2017-debug/build.bat" diff --git a/read.me b/read.me old mode 100755 new mode 100644 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index f4ee3c84..668579ac 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -31,13 +31,12 @@ macro(spvtools_core_tables CONFIG_VERSION) set(GRAMMAR_INSTS_INC_FILE "${spirv-tools_BINARY_DIR}/core.insts-${CONFIG_VERSION}.inc") set(GRAMMAR_KINDS_INC_FILE "${spirv-tools_BINARY_DIR}/operand.kinds-${CONFIG_VERSION}.inc") add_custom_command(OUTPUT ${GRAMMAR_INSTS_INC_FILE} ${GRAMMAR_KINDS_INC_FILE} - COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --spirv-core-grammar=${GRAMMAR_JSON_FILE} --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} --core-insts-output=${GRAMMAR_INSTS_INC_FILE} --operand-kinds-output=${GRAMMAR_KINDS_INC_FILE} - --output-language=c++ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE} @@ -53,13 +52,12 @@ macro(spvtools_enum_string_mapping CONFIG_VERSION) set(GRAMMAR_ENUM_STRING_MAPPING_INC_FILE "${spirv-tools_BINARY_DIR}/enum_string_mapping.inc") add_custom_command(OUTPUT ${GRAMMAR_EXTENSION_ENUM_INC_FILE} ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE} - COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --spirv-core-grammar=${GRAMMAR_JSON_FILE} --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} --extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE} --enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE} - --output-language=c++ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE} @@ -75,7 +73,7 @@ macro(spvtools_vimsyntax CONFIG_VERSION CLVERSION) set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json") set(VIMSYNTAX_FILE "${spirv-tools_BINARY_DIR}/spvasm.vim") add_custom_command(OUTPUT ${VIMSYNTAX_FILE} - COMMAND Python3::Interpreter ${VIMSYNTAX_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${VIMSYNTAX_PROCESSING_SCRIPT} --spirv-core-grammar=${GRAMMAR_JSON_FILE} --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} --extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE} @@ -91,10 +89,9 @@ macro(spvtools_glsl_tables CONFIG_VERSION) set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json") set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/glsl.std.450.insts.inc") add_custom_command(OUTPUT ${GRAMMAR_INC_FILE} - COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE} --glsl-insts-output=${GRAMMAR_INC_FILE} - --output-language=c++ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${GLSL_GRAMMAR_JSON_FILE} COMMENT "Generate info tables for GLSL extended instructions and operands v${CONFIG_VERSION}.") list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE}) @@ -105,7 +102,7 @@ macro(spvtools_opencl_tables CONFIG_VERSION) set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json") set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/opencl.std.insts.inc") add_custom_command(OUTPUT ${GRAMMAR_INC_FILE} - COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE} --opencl-insts-output=${GRAMMAR_INC_FILE} DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE} @@ -120,7 +117,7 @@ macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX) set(GRAMMAR_FILE "${spirv-tools_SOURCE_DIR}/source/extinst.${VENDOR_TABLE}.grammar.json") endif() add_custom_command(OUTPUT ${INSTS_FILE} - COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --extinst-vendor-grammar=${GRAMMAR_FILE} --vendor-insts-output=${INSTS_FILE} --vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX} @@ -134,7 +131,7 @@ endmacro(spvtools_vendor_tables) macro(spvtools_extinst_lang_headers NAME GRAMMAR_FILE) set(OUT_H ${spirv-tools_BINARY_DIR}/${NAME}.h) add_custom_command(OUTPUT ${OUT_H} - COMMAND Python3::Interpreter ${LANG_HEADER_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${LANG_HEADER_PROCESSING_SCRIPT} --extinst-grammar=${GRAMMAR_FILE} --extinst-output-path=${OUT_H} DEPENDS ${LANG_HEADER_PROCESSING_SCRIPT} ${GRAMMAR_FILE} @@ -168,7 +165,7 @@ set_property(TARGET spirv-tools-vimsyntax PROPERTY FOLDER "SPIRV-Tools utilities set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc) set(SPIRV_XML_REGISTRY_FILE ${SPIRV_HEADER_INCLUDE_DIR}/spirv/spir-v.xml) add_custom_command(OUTPUT ${GENERATOR_INC_FILE} - COMMAND Python3::Interpreter ${XML_REGISTRY_PROCESSING_SCRIPT} + COMMAND ${PYTHON_EXECUTABLE} ${XML_REGISTRY_PROCESSING_SCRIPT} --xml=${SPIRV_XML_REGISTRY_FILE} --generator-output=${GENERATOR_INC_FILE} DEPENDS ${XML_REGISTRY_PROCESSING_SCRIPT} ${SPIRV_XML_REGISTRY_FILE} @@ -198,7 +195,7 @@ set(SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR set(SPIRV_TOOLS_CHANGES_FILE ${spirv-tools_SOURCE_DIR}/CHANGES) add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC} - COMMAND Python3::Interpreter + COMMAND ${PYTHON_EXECUTABLE} ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR} ${SPIRV_TOOLS_CHANGES_FILE} ${SPIRV_TOOLS_BUILD_VERSION_INC} DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR} @@ -328,7 +325,6 @@ set(SPIRV_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_primitives.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_query.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing_reorder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp @@ -418,8 +414,17 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") endif() endif() +if (ANDROID) + foreach(target ${SPIRV_TOOLS_TARGETS}) + target_link_libraries(${target} PRIVATE android log) + endforeach() +endif() + if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets) + install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake) spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR) diff --git a/source/assembly_grammar.cpp b/source/assembly_grammar.cpp index 0092d01a..4f5942ab 100644 --- a/source/assembly_grammar.cpp +++ b/source/assembly_grammar.cpp @@ -21,7 +21,6 @@ #include "source/ext_inst.h" #include "source/opcode.h" #include "source/operand.h" -#include "source/spirv_target_env.h" #include "source/table.h" namespace spvtools { @@ -79,16 +78,16 @@ spv_result_t spvTextParseMaskOperand(spv_target_env env, // Associates an opcode with its name. struct SpecConstantOpcodeEntry { - spv::Op opcode; + SpvOp opcode; const char* name; }; // All the opcodes allowed as the operation for OpSpecConstantOp. -// The name does not have the usual "Op" prefix. For example opcode -// spv::Op::IAdd is associated with the name "IAdd". +// The name does not have the usual "Op" prefix. For example opcode SpvOpIAdd +// is associated with the name "IAdd". // // clang-format off -#define CASE(NAME) { spv::Op::Op##NAME, #NAME } +#define CASE(NAME) { SpvOp##NAME, #NAME } const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = { // Conversion CASE(SConvert), @@ -155,12 +154,11 @@ const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = { CASE(InBoundsAccessChain), CASE(PtrAccessChain), CASE(InBoundsPtrAccessChain), - CASE(CooperativeMatrixLengthNV), - CASE(CooperativeMatrixLengthKHR) + CASE(CooperativeMatrixLengthNV) }; // The 60 is determined by counting the opcodes listed in the spec. -static_assert(61 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]), +static_assert(60 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]), "OpSpecConstantOp opcode table is incomplete"); #undef CASE // clang-format on @@ -175,20 +173,17 @@ bool AssemblyGrammar::isValid() const { } CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv( - const spv::Capability* cap_array, uint32_t count) const { + const SpvCapability* cap_array, uint32_t count) const { CapabilitySet cap_set; - const auto version = spvVersionForTargetEnv(target_env_); for (uint32_t i = 0; i < count; ++i) { - spv_operand_desc entry = {}; + spv_operand_desc cap_desc = {}; if (SPV_SUCCESS == lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, static_cast(cap_array[i]), - &entry)) { - // This token is visible in this environment if it's in an appropriate - // core version, or it is enabled by a capability or an extension. - if ((version >= entry->minVersion && version <= entry->lastVersion) || - entry->numExtensions > 0u || entry->numCapabilities > 0u) { - cap_set.insert(cap_array[i]); - } + &cap_desc)) { + // spvOperandTableValueLookup() filters capabilities internally + // according to the current target environment by itself. So we + // should be safe to add this capability if the lookup succeeds. + cap_set.Add(cap_array[i]); } } return cap_set; @@ -199,7 +194,7 @@ spv_result_t AssemblyGrammar::lookupOpcode(const char* name, return spvOpcodeTableNameLookup(target_env_, opcodeTable_, name, desc); } -spv_result_t AssemblyGrammar::lookupOpcode(spv::Op opcode, +spv_result_t AssemblyGrammar::lookupOpcode(SpvOp opcode, spv_opcode_desc* desc) const { return spvOpcodeTableValueLookup(target_env_, opcodeTable_, opcode, desc); } @@ -219,7 +214,7 @@ spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type, } spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name, - spv::Op* opcode) const { + SpvOp* opcode) const { const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; const auto* found = std::find_if(kOpSpecConstantOpcodes, last, @@ -231,7 +226,7 @@ spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name, return SPV_SUCCESS; } -spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(spv::Op opcode) const { +spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(SpvOp opcode) const { const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes; const auto* found = std::find_if(kOpSpecConstantOpcodes, last, diff --git a/source/assembly_grammar.h b/source/assembly_grammar.h index 36fdd08a..17c2bd3b 100644 --- a/source/assembly_grammar.h +++ b/source/assembly_grammar.h @@ -41,7 +41,7 @@ class AssemblyGrammar { // Removes capabilities not available in the current target environment and // returns the rest. - CapabilitySet filterCapsAgainstTargetEnv(const spv::Capability* cap_array, + CapabilitySet filterCapsAgainstTargetEnv(const SpvCapability* cap_array, uint32_t count) const; // Fills in the desc parameter with the information about the opcode @@ -52,7 +52,7 @@ class AssemblyGrammar { // Fills in the desc parameter with the information about the opcode // of the valid. Returns SPV_SUCCESS if the opcode was found, and // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist. - spv_result_t lookupOpcode(spv::Op opcode, spv_opcode_desc* desc) const; + spv_result_t lookupOpcode(SpvOp opcode, spv_opcode_desc* desc) const; // Fills in the desc parameter with the information about the given // operand. Returns SPV_SUCCESS if the operand was found, and @@ -82,12 +82,11 @@ class AssemblyGrammar { // the integer add opcode for OpSpecConstantOp. On success, returns // SPV_SUCCESS and sends the discovered operation code through the opcode // parameter. On failure, returns SPV_ERROR_INVALID_LOOKUP. - spv_result_t lookupSpecConstantOpcode(const char* name, - spv::Op* opcode) const; + spv_result_t lookupSpecConstantOpcode(const char* name, SpvOp* opcode) const; // Returns SPV_SUCCESS if the given opcode is valid as the opcode operand // to OpSpecConstantOp. - spv_result_t lookupSpecConstantOpcode(spv::Op opcode) const; + spv_result_t lookupSpecConstantOpcode(SpvOp opcode) const; // Parses a mask expression string for the given operand type. // diff --git a/source/binary.cpp b/source/binary.cpp index 3cfdee04..24d32f8c 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -156,7 +156,7 @@ class Parser { // Issues a diagnostic describing an exhaustion of input condition when // trying to decode an instruction operand, and returns // SPV_ERROR_INVALID_BINARY. - spv_result_t exhaustedInputDiagnostic(size_t inst_offset, spv::Op opcode, + spv_result_t exhaustedInputDiagnostic(size_t inst_offset, SpvOp opcode, spv_operand_type_t type) { return diagnostic() << "End of input reached while decoding Op" << spvOpcodeString(opcode) << " starting at word " @@ -318,7 +318,7 @@ spv_result_t Parser::parseInstruction() { << inst_word_count; } spv_opcode_desc opcode_desc; - if (grammar_.lookupOpcode(static_cast(inst.opcode), &opcode_desc)) + if (grammar_.lookupOpcode(static_cast(inst.opcode), &opcode_desc)) return diagnostic() << "Invalid opcode: " << inst.opcode; // Advance past the opcode word. But remember the of the start @@ -418,7 +418,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, std::vector* words, std::vector* operands, spv_operand_pattern_t* expected_operands) { - const spv::Op opcode = static_cast(inst->opcode); + const SpvOp opcode = static_cast(inst->opcode); // We'll fill in this result as we go along. spv_parsed_operand_t parsed_operand; parsed_operand.offset = uint16_t(_.word_index - inst_offset); @@ -473,7 +473,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0"; parsed_operand.type = SPV_OPERAND_TYPE_ID; - if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) { + if (opcode == SpvOpExtInst && parsed_operand.offset == 3) { // The current word is the extended instruction set Id. // Set the extended instruction set type for the current instruction. auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word); @@ -494,7 +494,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, break; case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { - assert(spv::Op::OpExtInst == opcode); + assert(SpvOpExtInst == opcode); assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE); spv_ext_inst_desc ext_inst; if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) == @@ -516,14 +516,14 @@ spv_result_t Parser::parseOperand(size_t inst_offset, } break; case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { - assert(spv::Op::OpSpecConstantOp == opcode); - if (word > static_cast(spv::Op::Max) || - grammar_.lookupSpecConstantOpcode(spv::Op(word))) { + assert(SpvOpSpecConstantOp == opcode); + if (word > static_cast(SpvOp::SpvOpMax) || + grammar_.lookupSpecConstantOpcode(SpvOp(word))) { return diagnostic() << "Invalid " << spvOperandTypeStr(type) << ": " << word; } spv_opcode_desc opcode_entry = nullptr; - if (grammar_.lookupOpcode(spv::Op(word), &opcode_entry)) { + if (grammar_.lookupOpcode(SpvOp(word), &opcode_entry)) { return diagnostic(SPV_ERROR_INTERNAL) << "OpSpecConstant opcode table out of sync"; } @@ -546,17 +546,10 @@ spv_result_t Parser::parseOperand(size_t inst_offset, parsed_operand.number_bit_width = 32; break; - case SPV_OPERAND_TYPE_LITERAL_FLOAT: - // These are regular single-word literal float operands. - parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_FLOAT; - parsed_operand.number_kind = SPV_NUMBER_FLOATING; - parsed_operand.number_bit_width = 32; - break; - case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER; - if (opcode == spv::Op::OpSwitch) { + if (opcode == SpvOpSwitch) { // The literal operands have the same type as the value // referenced by the selector Id. const uint32_t selector_id = peekAt(inst_offset + 1); @@ -582,8 +575,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, << " is not a scalar integer"; } } else { - assert(opcode == spv::Op::OpConstant || - opcode == spv::Op::OpSpecConstant); + assert(opcode == SpvOpConstant || opcode == SpvOpSpecConstant); // The literal number type is determined by the type Id for the // constant. assert(inst->type_id); @@ -615,7 +607,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, parsed_operand.num_words = uint16_t(string_num_words); parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING; - if (spv::Op::OpExtInstImport == opcode) { + if (SpvOpExtInstImport == opcode) { // Record the extended instruction type for the ID for this import. // There is only one string literal argument to OpExtInstImport, // so it's sufficient to guard this just on the opcode. @@ -633,6 +625,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, } break; case SPV_OPERAND_TYPE_CAPABILITY: + case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: case SPV_OPERAND_TYPE_EXECUTION_MODEL: case SPV_OPERAND_TYPE_ADDRESSING_MODEL: case SPV_OPERAND_TYPE_MEMORY_MODEL: @@ -689,21 +682,6 @@ spv_result_t Parser::parseOperand(size_t inst_offset, spvPushOperandTypes(entry->operandTypes, expected_operands); } break; - case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: { - spv_operand_desc entry; - if (grammar_.lookupOperand(type, word, &entry)) { - return diagnostic() - << "Invalid " << spvOperandTypeStr(parsed_operand.type) - << " operand: " << word - << ", if you are creating a new source language please use " - "value 0 " - "(Unknown) and when ready, add your source language to " - "SPRIV-Headers"; - } - // Prepare to accept operands to this operand, if needed. - spvPushOperandTypes(entry->operandTypes, expected_operands); - } break; - case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: case SPV_OPERAND_TYPE_FUNCTION_CONTROL: case SPV_OPERAND_TYPE_LOOP_CONTROL: @@ -712,9 +690,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: { // This operand is a mask. // Map an optional operand type to its corresponding concrete type. @@ -722,8 +698,6 @@ spv_result_t Parser::parseOperand(size_t inst_offset, parsed_operand.type = SPV_OPERAND_TYPE_IMAGE; else if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS) parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS; - if (type == SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS) - parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS; // Check validity of set mask bits. Also prepare for operands for those // masks if they have any. To get operand order correct, scan from @@ -815,14 +789,14 @@ spv_result_t Parser::setNumericTypeInfoForType( void Parser::recordNumberType(size_t inst_offset, const spv_parsed_instruction_t* inst) { - const spv::Op opcode = static_cast(inst->opcode); + const SpvOp opcode = static_cast(inst->opcode); if (spvOpcodeGeneratesType(opcode)) { NumberType info = {SPV_NUMBER_NONE, 0}; - if (spv::Op::OpTypeInt == opcode) { + if (SpvOpTypeInt == opcode) { const bool is_signed = peekAt(inst_offset + 3) != 0; info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT; info.bit_width = peekAt(inst_offset + 2); - } else if (spv::Op::OpTypeFloat == opcode) { + } else if (SpvOpTypeFloat == opcode) { info.type = SPV_NUMBER_FLOATING; info.bit_width = peekAt(inst_offset + 2); } diff --git a/source/cfa.h b/source/cfa.h index 9ae3e39a..2743ab40 100644 --- a/source/cfa.h +++ b/source/cfa.h @@ -275,16 +275,10 @@ std::vector> CFA::CalculateDominators( std::vector> out; for (auto idom : idoms) { - // At this point if there is no dominator for the node, just make it - // reflexive. - auto dominator = std::get<1>(idom).dominator; - if (dominator == undefined_dom) { - dominator = std::get<1>(idom).postorder_index; - } // NOTE: performing a const cast for convenient usage with // UpdateImmediateDominators out.push_back({const_cast(std::get<0>(idom)), - const_cast(postorder[dominator])}); + const_cast(postorder[std::get<1>(idom).dominator])}); } // Sort by postorder index to generate a deterministic ordering of edges. diff --git a/source/diff/CMakeLists.txt b/source/diff/CMakeLists.txt index 52f18f2d..1328699a 100644 --- a/source/diff/CMakeLists.txt +++ b/source/diff/CMakeLists.txt @@ -39,7 +39,10 @@ set_property(TARGET SPIRV-Tools-diff PROPERTY FOLDER "SPIRV-Tools libraries") spvtools_check_symbol_exports(SPIRV-Tools-diff) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-diff EXPORT SPIRV-Tools-diffTargets) + install(TARGETS SPIRV-Tools-diff EXPORT SPIRV-Tools-diffTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-diffTargets FILE SPIRV-Tools-diffTargets.cmake) spvtools_config_package_dir(SPIRV-Tools-diff PACKAGE_DIR) diff --git a/source/diff/diff.cpp b/source/diff/diff.cpp index 6269af50..7ed41de5 100644 --- a/source/diff/diff.cpp +++ b/source/diff/diff.cpp @@ -44,8 +44,8 @@ using IdGroup = std::vector; // different implementations produce identical results. using IdGroupMapByName = std::map; using IdGroupMapByTypeId = std::map; -using IdGroupMapByOp = std::map; -using IdGroupMapByStorageClass = std::map; +using IdGroupMapByOp = std::map; +using IdGroupMapByStorageClass = std::map; // A set of potential id mappings that haven't been resolved yet. Any id in src // may map in any id in dst. Note that ids are added in the same order as they @@ -101,12 +101,9 @@ class IdMap { return from < id_map_.size() && id_map_[from] != 0; } - bool IsMapped(const opt::Instruction* from_inst) const { - assert(from_inst != nullptr); - assert(!from_inst->HasResultId()); - - return inst_map_.find(from_inst) != inst_map_.end(); - } + // Map any ids in src and dst that have not been mapped to new ids in dst and + // src respectively. + void MapUnmatchedIds(IdMap& other_way); // Some instructions don't have result ids. Those are mapped by pointer. void MapInsts(const opt::Instruction* from_inst, @@ -120,12 +117,6 @@ class IdMap { uint32_t IdBound() const { return static_cast(id_map_.size()); } - // Generate a fresh id in this mapping's domain. - uint32_t MakeFreshId() { - id_map_.push_back(0); - return static_cast(id_map_.size()) - 1; - } - private: // Given an id, returns the corresponding id in the other module, or 0 if not // matched yet. @@ -159,16 +150,10 @@ class SrcDstIdMap { bool IsSrcMapped(uint32_t src) { return src_to_dst_.IsMapped(src); } bool IsDstMapped(uint32_t dst) { return dst_to_src_.IsMapped(dst); } - bool IsDstMapped(const opt::Instruction* dst_inst) { - return dst_to_src_.IsMapped(dst_inst); - } // Map any ids in src and dst that have not been mapped to new ids in dst and - // src respectively. Use src_insn_defined and dst_insn_defined to ignore ids - // that are simply never defined. (Since we assume the inputs are valid - // SPIR-V, this implies they are also never used.) - void MapUnmatchedIds(std::function src_insn_defined, - std::function dst_insn_defined); + // src respectively. + void MapUnmatchedIds(); // Some instructions don't have result ids. Those are mapped by pointer. void MapInsts(const opt::Instruction* src_inst, @@ -218,11 +203,6 @@ struct IdInstructions { void MapIdToInstruction(uint32_t id, const opt::Instruction* inst); - // Return true if id is mapped to any instruction, false otherwise. - bool IsDefined(uint32_t id) { - return id < inst_map_.size() && inst_map_[id] != nullptr; - } - void MapIdsToInstruction( opt::IteratorRange section); void MapIdsToInfos( @@ -321,10 +301,10 @@ class Differ { // Get various properties from an id. These Helper functions are passed to // `GroupIds` and `GroupIdsAndMatch` below (as the `get_group` argument). uint32_t GroupIdsHelperGetTypeId(const IdInstructions& id_to, uint32_t id); - spv::StorageClass GroupIdsHelperGetTypePointerStorageClass( + SpvStorageClass GroupIdsHelperGetTypePointerStorageClass( const IdInstructions& id_to, uint32_t id); - spv::Op GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, - uint32_t id); + SpvOp GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, + uint32_t id); // Given a list of ids, groups them based on some value. The `get_group` // function extracts a piece of information corresponding to each id, and the @@ -358,59 +338,6 @@ class Differ { std::function match_group); - // Bucket `src_ids` and `dst_ids` by the key ids returned by `get_group`, and - // then call `match_group` on pairs of buckets whose key ids are matched with - // each other. - // - // For example, suppose we want to pair up groups of instructions with the - // same type. Naturally, the source instructions refer to their types by their - // ids in the source, and the destination instructions use destination type - // ids, so simply comparing source and destination type ids as integers, as - // `GroupIdsAndMatch` would do, is meaningless. But if a prior call to - // `MatchTypeIds` has established type matches between the two modules, then - // we can consult those to pair source and destination buckets whose types are - // equivalent. - // - // Suppose our input groups are as follows: - // - // - src_ids: { 1 -> 100, 2 -> 300, 3 -> 100, 4 -> 200 } - // - dst_ids: { 5 -> 10, 6 -> 20, 7 -> 10, 8 -> 300 } - // - // Here, `X -> Y` means that the instruction with SPIR-V id `X` is a member of - // the group, and `Y` is the id of its type. If we use - // `Differ::GroupIdsHelperGetTypeId` for `get_group`, then - // `get_group(X) == Y`. - // - // These instructions are bucketed by type as follows: - // - // - source: [1, 3] -> 100 - // [4] -> 200 - // [2] -> 300 - // - // - destination: [5, 7] -> 10 - // [6] -> 20 - // [8] -> 300 - // - // Now suppose that we have previously matched up src type 100 with dst type - // 10, and src type 200 with dst type 20, but no other types are matched. - // - // Then `match_group` is called twice: - // - Once with ([1,3], [5, 7]), corresponding to 100/10 - // - Once with ([4],[6]), corresponding to 200/20 - // - // The source type 300 isn't matched with anything, so the fact that there's a - // destination type 300 is irrelevant, and thus 2 and 8 are never passed to - // `match_group`. - // - // This function isn't specific to types; it simply buckets by the ids - // returned from `get_group`, and consults existing matches to pair up the - // resulting buckets. - void GroupIdsAndMatchByMappedId( - const IdGroup& src_ids, const IdGroup& dst_ids, - uint32_t (Differ::*get_group)(const IdInstructions&, uint32_t), - std::function - match_group); - // Helper functions that determine if two instructions match bool DoIdsMatch(uint32_t src_id, uint32_t dst_id); bool DoesOperandMatch(const opt::Operand& src_operand, @@ -487,8 +414,8 @@ class Differ { // Helper functions to retrieve information pertaining to an id const opt::Instruction* GetInst(const IdInstructions& id_to, uint32_t id); uint32_t GetConstantUint(const IdInstructions& id_to, uint32_t constant_id); - spv::ExecutionModel GetExecutionModel(const opt::Module* module, - uint32_t entry_point_id); + SpvExecutionModel GetExecutionModel(const opt::Module* module, + uint32_t entry_point_id); bool HasName(const IdInstructions& id_to, uint32_t id); // Get the OpName associated with an id std::string GetName(const IdInstructions& id_to, uint32_t id, bool* has_name); @@ -497,21 +424,20 @@ class Differ { // string, and this improves diff between SPIR-V from those tools and others. std::string GetSanitizedName(const IdInstructions& id_to, uint32_t id); uint32_t GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, - spv::StorageClass* storage_class); + SpvStorageClass* storage_class); bool GetDecorationValue(const IdInstructions& id_to, uint32_t id, - spv::Decoration decoration, - uint32_t* decoration_value); + SpvDecoration decoration, uint32_t* decoration_value); const opt::Instruction* GetForwardPointerInst(const IdInstructions& id_to, uint32_t id); bool IsIntType(const IdInstructions& id_to, uint32_t type_id); bool IsFloatType(const IdInstructions& id_to, uint32_t type_id); bool IsConstantUint(const IdInstructions& id_to, uint32_t id); bool IsVariable(const IdInstructions& id_to, uint32_t pointer_id); - bool IsOp(const IdInstructions& id_to, uint32_t id, spv::Op opcode); + bool IsOp(const IdInstructions& id_to, uint32_t id, SpvOp opcode); bool IsPerVertexType(const IdInstructions& id_to, uint32_t type_id); bool IsPerVertexVariable(const IdInstructions& id_to, uint32_t type_id); - spv::StorageClass GetPerVertexStorageClass(const opt::Module* module, - uint32_t type_id); + SpvStorageClass GetPerVertexStorageClass(const opt::Module* module, + uint32_t type_id); spv_ext_inst_type_t GetExtInstType(const IdInstructions& id_to, uint32_t set_id); spv_number_kind_t GetNumberKind(const IdInstructions& id_to, @@ -577,27 +503,36 @@ class Differ { FunctionMap dst_funcs_; }; -void SrcDstIdMap::MapUnmatchedIds( - std::function src_insn_defined, - std::function dst_insn_defined) { - const uint32_t src_id_bound = static_cast(src_to_dst_.IdBound()); - const uint32_t dst_id_bound = static_cast(dst_to_src_.IdBound()); +void IdMap::MapUnmatchedIds(IdMap& other_way) { + const uint32_t src_id_bound = static_cast(id_map_.size()); + const uint32_t dst_id_bound = static_cast(other_way.id_map_.size()); + + uint32_t next_src_id = src_id_bound; + uint32_t next_dst_id = dst_id_bound; for (uint32_t src_id = 1; src_id < src_id_bound; ++src_id) { - if (!src_to_dst_.IsMapped(src_id) && src_insn_defined(src_id)) { - uint32_t fresh_dst_id = dst_to_src_.MakeFreshId(); - MapIds(src_id, fresh_dst_id); + if (!IsMapped(src_id)) { + MapIds(src_id, next_dst_id); + + other_way.id_map_.push_back(0); + other_way.MapIds(next_dst_id++, src_id); } } for (uint32_t dst_id = 1; dst_id < dst_id_bound; ++dst_id) { - if (!dst_to_src_.IsMapped(dst_id) && dst_insn_defined(dst_id)) { - uint32_t fresh_src_id = src_to_dst_.MakeFreshId(); - MapIds(fresh_src_id, dst_id); + if (!other_way.IsMapped(dst_id)) { + id_map_.push_back(0); + MapIds(next_src_id, dst_id); + + other_way.MapIds(dst_id, next_src_id++); } } } +void SrcDstIdMap::MapUnmatchedIds() { + src_to_dst_.MapUnmatchedIds(dst_to_src_); +} + void IdInstructions::MapIdToInstruction(uint32_t id, const opt::Instruction* inst) { assert(id != 0); @@ -626,19 +561,19 @@ void IdInstructions::MapIdsToInfos( uint32_t id_operand = 0; switch (inst.opcode()) { - case spv::Op::OpName: + case SpvOpName: info_map = &name_map_; break; - case spv::Op::OpMemberName: + case SpvOpMemberName: info_map = &name_map_; break; - case spv::Op::OpDecorate: + case SpvOpDecorate: info_map = &decoration_map_; break; - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: info_map = &decoration_map_; break; - case spv::Op::OpTypeForwardPointer: { + case SpvOpTypeForwardPointer: { uint32_t id = inst.GetSingleWordOperand(0); assert(id != 0); @@ -796,10 +731,10 @@ int Differ::ComparePreambleInstructions(const opt::Instruction* a, // Instead of comparing OpExecutionMode entry point ids as ids, compare them // through their corresponding execution model. This simplifies traversing // the sorted list of instructions between src and dst modules. - if (a->opcode() == spv::Op::OpExecutionMode) { - const spv::ExecutionModel src_model = + if (a->opcode() == SpvOpExecutionMode) { + const SpvExecutionModel src_model = GetExecutionModel(src_inst_module, a->GetSingleWordOperand(0)); - const spv::ExecutionModel dst_model = + const SpvExecutionModel dst_model = GetExecutionModel(dst_inst_module, b->GetSingleWordOperand(0)); if (src_model < dst_model) { @@ -883,17 +818,17 @@ uint32_t Differ::GroupIdsHelperGetTypeId(const IdInstructions& id_to, return GetInst(id_to, id)->type_id(); } -spv::StorageClass Differ::GroupIdsHelperGetTypePointerStorageClass( +SpvStorageClass Differ::GroupIdsHelperGetTypePointerStorageClass( const IdInstructions& id_to, uint32_t id) { const opt::Instruction* inst = GetInst(id_to, id); - assert(inst && inst->opcode() == spv::Op::OpTypePointer); - return spv::StorageClass(inst->GetSingleWordInOperand(0)); + assert(inst && inst->opcode() == SpvOpTypePointer); + return SpvStorageClass(inst->GetSingleWordInOperand(0)); } -spv::Op Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, - uint32_t id) { +SpvOp Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to, + uint32_t id) { const opt::Instruction* inst = GetInst(id_to, id); - assert(inst && inst->opcode() == spv::Op::OpTypePointer); + assert(inst && inst->opcode() == SpvOpTypePointer); const uint32_t type_id = inst->GetSingleWordInOperand(1); const opt::Instruction* type_inst = GetInst(id_to, type_id); @@ -953,37 +888,6 @@ void Differ::GroupIdsAndMatch( } } -void Differ::GroupIdsAndMatchByMappedId( - const IdGroup& src_ids, const IdGroup& dst_ids, - uint32_t (Differ::*get_group)(const IdInstructions&, uint32_t), - std::function - match_group) { - // Group the ids based on a key (get_group) - std::map src_groups; - std::map dst_groups; - - GroupIds(src_ids, true, &src_groups, get_group); - GroupIds(dst_ids, false, &dst_groups, get_group); - - // Iterate over pairs of groups whose keys map to each other. - for (const auto& iter : src_groups) { - const uint32_t& src_key = iter.first; - const IdGroup& src_group = iter.second; - - if (src_key == 0) { - continue; - } - - if (id_map_.IsSrcMapped(src_key)) { - const uint32_t& dst_key = id_map_.MappedDstId(src_key); - const IdGroup& dst_group = dst_groups[dst_key]; - - // Let the caller match the groups as appropriate. - match_group(src_group, dst_group); - } - } -} - bool Differ::DoIdsMatch(uint32_t src_id, uint32_t dst_id) { assert(dst_id != 0); return id_map_.MappedDstId(src_id) == dst_id; @@ -1116,7 +1020,7 @@ bool Differ::DoInstructionsMatchFuzzy(const opt::Instruction* src_inst, } // For external instructions, make sure the set and opcode of the external // instruction matches too. - if (src_inst->opcode() == spv::Op::OpExtInst) { + if (src_inst->opcode() == SpvOpExtInst) { if (!DoOperandsMatch(src_inst, dst_inst, 0, 2)) { return false; } @@ -1160,26 +1064,26 @@ bool Differ::DoDebugAndAnnotationInstructionsMatch( } switch (src_inst->opcode()) { - case spv::Op::OpString: - case spv::Op::OpSourceExtension: - case spv::Op::OpModuleProcessed: + case SpvOpString: + case SpvOpSourceExtension: + case SpvOpModuleProcessed: return DoesOperandMatch(src_inst->GetOperand(0), dst_inst->GetOperand(0)); - case spv::Op::OpSource: + case SpvOpSource: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case spv::Op::OpSourceContinued: + case SpvOpSourceContinued: return true; - case spv::Op::OpName: + case SpvOpName: return DoOperandsMatch(src_inst, dst_inst, 0, 1); - case spv::Op::OpMemberName: + case SpvOpMemberName: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case spv::Op::OpDecorate: + case SpvOpDecorate: return DoOperandsMatch(src_inst, dst_inst, 0, 2); - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: return DoOperandsMatch(src_inst, dst_inst, 0, 3); - case spv::Op::OpExtInst: - case spv::Op::OpDecorationGroup: - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: + case SpvOpExtInst: + case SpvOpDecorationGroup: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: return false; default: return false; @@ -1191,9 +1095,9 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, // Variables must match by their built-in decorations. uint32_t src_built_in_decoration = 0, dst_built_in_decoration = 0; const bool src_is_built_in = GetDecorationValue( - src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration); + src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration); const bool dst_is_built_in = GetDecorationValue( - dst_id_to_, dst_id, spv::Decoration::BuiltIn, &dst_built_in_decoration); + dst_id_to_, dst_id, SpvDecorationBuiltIn, &dst_built_in_decoration); if (src_is_built_in != dst_is_built_in) { return false; @@ -1203,7 +1107,7 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, } // Check their types and storage classes. - spv::StorageClass src_storage_class, dst_storage_class; + SpvStorageClass src_storage_class, dst_storage_class; const uint32_t src_type_id = GetVarTypeId(src_id_to_, src_id, &src_storage_class); const uint32_t dst_type_id = @@ -1223,14 +1127,12 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id, // Allow one of the two to be Private while the other is Input or // Output, this allows matching in/out variables that have been turned // global as part of linking two stages (as done in ANGLE). - const bool src_is_io = src_storage_class == spv::StorageClass::Input || - src_storage_class == spv::StorageClass::Output; - const bool dst_is_io = dst_storage_class == spv::StorageClass::Input || - dst_storage_class == spv::StorageClass::Output; - const bool src_is_private = - src_storage_class == spv::StorageClass::Private; - const bool dst_is_private = - dst_storage_class == spv::StorageClass::Private; + const bool src_is_io = src_storage_class == SpvStorageClassInput || + src_storage_class == SpvStorageClassOutput; + const bool dst_is_io = dst_storage_class == SpvStorageClassInput || + dst_storage_class == SpvStorageClassOutput; + const bool src_is_private = src_storage_class == SpvStorageClassPrivate; + const bool dst_is_private = dst_storage_class == SpvStorageClassPrivate; if (!((src_is_io && dst_is_private) || (src_is_private && dst_is_io))) { return false; @@ -1375,16 +1277,16 @@ bool Differ::MatchOpSpecConstant(const opt::Instruction* src_inst, // Otherwise, match them by SpecId. uint32_t src_spec_id, dst_spec_id; - if (GetDecorationValue(src_id_to_, src_id, spv::Decoration::SpecId, + if (GetDecorationValue(src_id_to_, src_id, SpvDecorationSpecId, &src_spec_id) && - GetDecorationValue(dst_id_to_, dst_id, spv::Decoration::SpecId, + GetDecorationValue(dst_id_to_, dst_id, SpvDecorationSpecId, &dst_spec_id)) { return src_spec_id == dst_spec_id; } // There is no SpecId decoration, while not practical, still valid. // SpecConstantOp don't have SpecId and can be matched by operands - if (src_inst->opcode() == spv::Op::OpSpecConstantOp) { + if (src_inst->opcode() == SpvOpSpecConstantOp) { if (src_inst->NumInOperandWords() == dst_inst->NumInOperandWords()) { return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); @@ -1425,13 +1327,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, // built-in decorations. uint32_t src_built_in_decoration; const bool src_is_built_in = GetDecorationValue( - src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration); + src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration); if (src_is_built_in && AreVariablesMatchable(src_id, dst_id, flexibility)) { return true; } - spv::StorageClass src_storage_class, dst_storage_class; + SpvStorageClass src_storage_class, dst_storage_class; GetVarTypeId(src_id_to_, src_id, &src_storage_class); GetVarTypeId(dst_id_to_, dst_id, &dst_storage_class); @@ -1446,13 +1348,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, uint32_t src_binding = 0, dst_binding = 0; const bool src_has_set = GetDecorationValue( - src_id_to_, src_id, spv::Decoration::DescriptorSet, &src_set); + src_id_to_, src_id, SpvDecorationDescriptorSet, &src_set); const bool dst_has_set = GetDecorationValue( - dst_id_to_, dst_id, spv::Decoration::DescriptorSet, &dst_set); - const bool src_has_binding = GetDecorationValue( - src_id_to_, src_id, spv::Decoration::Binding, &src_set); - const bool dst_has_binding = GetDecorationValue( - dst_id_to_, dst_id, spv::Decoration::Binding, &dst_set); + dst_id_to_, dst_id, SpvDecorationDescriptorSet, &dst_set); + const bool src_has_binding = + GetDecorationValue(src_id_to_, src_id, SpvDecorationBinding, &src_set); + const bool dst_has_binding = + GetDecorationValue(dst_id_to_, dst_id, SpvDecorationBinding, &dst_set); if (src_has_set && dst_has_set && src_has_binding && dst_has_binding) { return src_set == dst_set && src_binding == dst_binding; @@ -1465,9 +1367,9 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst, uint32_t src_location, dst_location; const bool src_has_location = GetDecorationValue( - src_id_to_, src_id, spv::Decoration::Location, &src_location); + src_id_to_, src_id, SpvDecorationLocation, &src_location); const bool dst_has_location = GetDecorationValue( - dst_id_to_, dst_id, spv::Decoration::Location, &dst_location); + dst_id_to_, dst_id, SpvDecorationLocation, &dst_location); if (src_has_location && dst_has_location) { return src_location == dst_location; @@ -1482,25 +1384,25 @@ bool Differ::MatchPerVertexType(uint32_t src_type_id, uint32_t dst_type_id) { // For gl_PerVertex, find the type pointer of this type (array) and make sure // the storage classes of src and dst match; geometry and tessellation shaders // have two instances of gl_PerVertex. - spv::StorageClass src_storage_class = + SpvStorageClass src_storage_class = GetPerVertexStorageClass(src_, src_type_id); - spv::StorageClass dst_storage_class = + SpvStorageClass dst_storage_class = GetPerVertexStorageClass(dst_, dst_type_id); - assert(src_storage_class == spv::StorageClass::Input || - src_storage_class == spv::StorageClass::Output); - assert(dst_storage_class == spv::StorageClass::Input || - dst_storage_class == spv::StorageClass::Output); + assert(src_storage_class == SpvStorageClassInput || + src_storage_class == SpvStorageClassOutput); + assert(dst_storage_class == SpvStorageClassInput || + dst_storage_class == SpvStorageClassOutput); return src_storage_class == dst_storage_class; } bool Differ::MatchPerVertexVariable(const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - spv::StorageClass src_storage_class = - spv::StorageClass(src_inst->GetSingleWordInOperand(0)); - spv::StorageClass dst_storage_class = - spv::StorageClass(dst_inst->GetSingleWordInOperand(0)); + SpvStorageClass src_storage_class = + SpvStorageClass(src_inst->GetSingleWordInOperand(0)); + SpvStorageClass dst_storage_class = + SpvStorageClass(dst_inst->GetSingleWordInOperand(0)); return src_storage_class == dst_storage_class; } @@ -1514,6 +1416,7 @@ void Differ::MatchTypeForwardPointersByName(const IdGroup& src, GroupIdsAndMatch( src, dst, "", &Differ::GetSanitizedName, [this](const IdGroup& src_group, const IdGroup& dst_group) { + // Match only if there's a unique forward declaration with this debug // name. if (src_group.size() == 1 && dst_group.size() == 1) { @@ -1576,7 +1479,7 @@ InstructionList Differ::GetFunctionHeader(const opt::Function& function) { InstructionList body; function.WhileEachInst( [&body](const opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpLabel) { + if (inst->opcode() == SpvOpLabel) { return false; } body.push_back(inst); @@ -1668,8 +1571,6 @@ void Differ::BestEffortMatchFunctions(const IdGroup& src_func_ids, id_map_.MapIds(match_result.src_id, match_result.dst_id); - MatchFunctionParamIds(src_funcs_[match_result.src_id], - dst_funcs_[match_result.dst_id]); MatchIdsInFunctionBodies(src_func_insts.at(match_result.src_id), dst_func_insts.at(match_result.dst_id), match_result.src_match, match_result.dst_match, 0); @@ -1694,6 +1595,7 @@ void Differ::MatchFunctionParamIds(const opt::Function* src_func, GroupIdsAndMatch( src_params, dst_params, "", &Differ::GetSanitizedName, [this](const IdGroup& src_group, const IdGroup& dst_group) { + // There shouldn't be two parameters with the same name, so the ids // should match. There is nothing restricting the SPIR-V however to have // two parameters with the same name, so be resilient against that. @@ -1704,17 +1606,17 @@ void Differ::MatchFunctionParamIds(const opt::Function* src_func, // Then match the parameters by their type. If there are multiple of them, // match them by their order. - GroupIdsAndMatchByMappedId( - src_params, dst_params, &Differ::GroupIdsHelperGetTypeId, + GroupIdsAndMatch( + src_params, dst_params, 0, &Differ::GroupIdsHelperGetTypeId, [this](const IdGroup& src_group_by_type_id, const IdGroup& dst_group_by_type_id) { + const size_t shared_param_count = std::min(src_group_by_type_id.size(), dst_group_by_type_id.size()); for (size_t param_index = 0; param_index < shared_param_count; ++param_index) { - id_map_.MapIds(src_group_by_type_id[param_index], - dst_group_by_type_id[param_index]); + id_map_.MapIds(src_group_by_type_id[0], dst_group_by_type_id[0]); } }); } @@ -1792,12 +1694,12 @@ void Differ::MatchVariablesUsedByMatchedInstructions( default: // TODO: match functions based on OpFunctionCall? break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: - case spv::Op::OpLoad: - case spv::Op::OpStore: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: + case SpvOpLoad: + case SpvOpStore: const uint32_t src_pointer_id = src_inst->GetSingleWordInOperand(0); const uint32_t dst_pointer_id = dst_inst->GetSingleWordInOperand(0); if (IsVariable(src_id_to_, src_pointer_id) && @@ -1825,24 +1727,23 @@ const opt::Instruction* Differ::GetInst(const IdInstructions& id_to, uint32_t Differ::GetConstantUint(const IdInstructions& id_to, uint32_t constant_id) { const opt::Instruction* constant_inst = GetInst(id_to, constant_id); - assert(constant_inst->opcode() == spv::Op::OpConstant); - assert(GetInst(id_to, constant_inst->type_id())->opcode() == - spv::Op::OpTypeInt); + assert(constant_inst->opcode() == SpvOpConstant); + assert(GetInst(id_to, constant_inst->type_id())->opcode() == SpvOpTypeInt); return constant_inst->GetSingleWordInOperand(0); } -spv::ExecutionModel Differ::GetExecutionModel(const opt::Module* module, - uint32_t entry_point_id) { +SpvExecutionModel Differ::GetExecutionModel(const opt::Module* module, + uint32_t entry_point_id) { for (const opt::Instruction& inst : module->entry_points()) { - assert(inst.opcode() == spv::Op::OpEntryPoint); + assert(inst.opcode() == SpvOpEntryPoint); if (inst.GetSingleWordOperand(1) == entry_point_id) { - return spv::ExecutionModel(inst.GetSingleWordOperand(0)); + return SpvExecutionModel(inst.GetSingleWordOperand(0)); } } assert(false && "Unreachable"); - return spv::ExecutionModel(0xFFF); + return SpvExecutionModel(0xFFF); } bool Differ::HasName(const IdInstructions& id_to, uint32_t id) { @@ -1850,7 +1751,7 @@ bool Differ::HasName(const IdInstructions& id_to, uint32_t id) { assert(id < id_to.name_map_.size()); for (const opt::Instruction* inst : id_to.name_map_[id]) { - if (inst->opcode() == spv::Op::OpName) { + if (inst->opcode() == SpvOpName) { return true; } } @@ -1864,7 +1765,7 @@ std::string Differ::GetName(const IdInstructions& id_to, uint32_t id, assert(id < id_to.name_map_.size()); for (const opt::Instruction* inst : id_to.name_map_[id]) { - if (inst->opcode() == spv::Op::OpName) { + if (inst->opcode() == SpvOpName) { *has_name = true; return inst->GetOperand(1).AsString(); } @@ -1887,11 +1788,11 @@ std::string Differ::GetSanitizedName(const IdInstructions& id_to, uint32_t id) { } uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, - spv::StorageClass* storage_class) { + SpvStorageClass* storage_class) { const opt::Instruction* var_inst = GetInst(id_to, var_id); - assert(var_inst->opcode() == spv::Op::OpVariable); + assert(var_inst->opcode() == SpvOpVariable); - *storage_class = spv::StorageClass(var_inst->GetSingleWordInOperand(0)); + *storage_class = SpvStorageClass(var_inst->GetSingleWordInOperand(0)); // Get the type pointer from the variable. const uint32_t type_pointer_id = var_inst->type_id(); @@ -1902,15 +1803,15 @@ uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id, } bool Differ::GetDecorationValue(const IdInstructions& id_to, uint32_t id, - spv::Decoration decoration, + SpvDecoration decoration, uint32_t* decoration_value) { assert(id != 0); assert(id < id_to.decoration_map_.size()); for (const opt::Instruction* inst : id_to.decoration_map_[id]) { - if (inst->opcode() == spv::Op::OpDecorate && + if (inst->opcode() == SpvOpDecorate && inst->GetSingleWordOperand(0) == id && - spv::Decoration(inst->GetSingleWordOperand(1)) == decoration) { + inst->GetSingleWordOperand(1) == decoration) { *decoration_value = inst->GetSingleWordOperand(2); return true; } @@ -1927,28 +1828,28 @@ const opt::Instruction* Differ::GetForwardPointerInst( } bool Differ::IsIntType(const IdInstructions& id_to, uint32_t type_id) { - return IsOp(id_to, type_id, spv::Op::OpTypeInt); + return IsOp(id_to, type_id, SpvOpTypeInt); } bool Differ::IsFloatType(const IdInstructions& id_to, uint32_t type_id) { - return IsOp(id_to, type_id, spv::Op::OpTypeFloat); + return IsOp(id_to, type_id, SpvOpTypeFloat); } bool Differ::IsConstantUint(const IdInstructions& id_to, uint32_t id) { const opt::Instruction* constant_inst = GetInst(id_to, id); - if (constant_inst->opcode() != spv::Op::OpConstant) { + if (constant_inst->opcode() != SpvOpConstant) { return false; } const opt::Instruction* type_inst = GetInst(id_to, constant_inst->type_id()); - return type_inst->opcode() == spv::Op::OpTypeInt; + return type_inst->opcode() == SpvOpTypeInt; } bool Differ::IsVariable(const IdInstructions& id_to, uint32_t pointer_id) { - return IsOp(id_to, pointer_id, spv::Op::OpVariable); + return IsOp(id_to, pointer_id, SpvOpVariable); } -bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, spv::Op op) { +bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, SpvOp op) { return GetInst(id_to, id)->opcode() == op; } @@ -1957,18 +1858,17 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) { assert(type_id < id_to.decoration_map_.size()); for (const opt::Instruction* inst : id_to.decoration_map_[type_id]) { - if (inst->opcode() == spv::Op::OpMemberDecorate && + if (inst->opcode() == SpvOpMemberDecorate && inst->GetSingleWordOperand(0) == type_id && - spv::Decoration(inst->GetSingleWordOperand(2)) == - spv::Decoration::BuiltIn) { - spv::BuiltIn built_in = spv::BuiltIn(inst->GetSingleWordOperand(3)); + inst->GetSingleWordOperand(2) == SpvDecorationBuiltIn) { + SpvBuiltIn built_in = SpvBuiltIn(inst->GetSingleWordOperand(3)); // Only gl_PerVertex can have, and it can only have, the following // built-in decorations. - return built_in == spv::BuiltIn::Position || - built_in == spv::BuiltIn::PointSize || - built_in == spv::BuiltIn::ClipDistance || - built_in == spv::BuiltIn::CullDistance; + return built_in == SpvBuiltInPosition || + built_in == SpvBuiltInPointSize || + built_in == SpvBuiltInClipDistance || + built_in == SpvBuiltInCullDistance; } } @@ -1977,12 +1877,12 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) { bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) { // Get the type from the type pointer. - spv::StorageClass storage_class; + SpvStorageClass storage_class; uint32_t type_id = GetVarTypeId(id_to, var_id, &storage_class); const opt::Instruction* type_inst = GetInst(id_to, type_id); // If array, get the element type. - if (type_inst->opcode() == spv::Op::OpTypeArray) { + if (type_inst->opcode() == SpvOpTypeArray) { type_id = type_inst->GetSingleWordInOperand(0); } @@ -1990,21 +1890,21 @@ bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) { return IsPerVertexType(id_to, type_id); } -spv::StorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, - uint32_t type_id) { +SpvStorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, + uint32_t type_id) { for (const opt::Instruction& inst : module->types_values()) { switch (inst.opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: // The gl_PerVertex instance could be an array, look for a variable of // the array type instead. if (inst.GetSingleWordInOperand(0) == type_id) { type_id = inst.result_id(); } break; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: // Find the storage class of the pointer to this type. if (inst.GetSingleWordInOperand(1) == type_id) { - return spv::StorageClass(inst.GetSingleWordInOperand(0)); + return SpvStorageClass(inst.GetSingleWordInOperand(0)); } break; default: @@ -2015,7 +1915,7 @@ spv::StorageClass Differ::GetPerVertexStorageClass(const opt::Module* module, // gl_PerVertex is declared, but is unused. Return either of Input or Output // classes just so it matches one in the other module. This should be highly // unlikely, perhaps except for ancient GS-used-to-emulate-CS scenarios. - return spv::StorageClass::Output; + return SpvStorageClassOutput; } spv_ext_inst_type_t Differ::GetExtInstType(const IdInstructions& id_to, @@ -2038,16 +1938,12 @@ spv_number_kind_t Differ::GetNumberKind(const IdInstructions& id_to, // Always unsigned integers. *number_bit_width = 32; return SPV_NUMBER_UNSIGNED_INT; - case SPV_OPERAND_TYPE_LITERAL_FLOAT: - // Always float. - *number_bit_width = 32; - return SPV_NUMBER_FLOATING; case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: switch (inst.opcode()) { - case spv::Op::OpSwitch: - case spv::Op::OpConstant: - case spv::Op::OpSpecConstant: + case SpvOpSwitch: + case SpvOpConstant: + case SpvOpSpecConstant: // Same kind of number as the selector (OpSwitch) or the type // (Op*Constant). return GetTypeNumberKind(id_to, inst.GetSingleWordOperand(0), @@ -2073,12 +1969,12 @@ spv_number_kind_t Differ::GetTypeNumberKind(const IdInstructions& id_to, } switch (type_inst->opcode()) { - case spv::Op::OpTypeInt: + case SpvOpTypeInt: *number_bit_width = type_inst->GetSingleWordOperand(1); return type_inst->GetSingleWordOperand(2) == 0 ? SPV_NUMBER_UNSIGNED_INT : SPV_NUMBER_SIGNED_INT; break; - case spv::Op::OpTypeFloat: + case SpvOpTypeFloat: *number_bit_width = type_inst->GetSingleWordOperand(1); return SPV_NUMBER_FLOATING; default: @@ -2163,10 +2059,9 @@ void Differ::MatchEntryPointIds() { } // Otherwise match them by name. + bool matched = false; for (const opt::Instruction* src_inst : src_insts) { for (const opt::Instruction* dst_inst : dst_insts) { - if (id_map_.IsDstMapped(dst_inst)) continue; - const opt::Operand& src_name = src_inst->GetOperand(2); const opt::Operand& dst_name = dst_inst->GetOperand(2); @@ -2175,9 +2070,13 @@ void Differ::MatchEntryPointIds() { uint32_t dst_id = dst_inst->GetSingleWordOperand(1); id_map_.MapIds(src_id, dst_id); id_map_.MapInsts(src_inst, dst_inst); + matched = true; break; } } + if (matched) { + break; + } } } } @@ -2193,7 +2092,7 @@ void Differ::MatchTypeForwardPointers() { return inst.GetSingleWordOperand(0); }; auto accept_type_forward_pointer_ops = [](const opt::Instruction& inst) { - return inst.opcode() == spv::Op::OpTypeForwardPointer; + return inst.opcode() == SpvOpTypeForwardPointer; }; PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true, @@ -2217,18 +2116,20 @@ void Differ::MatchTypeForwardPointers() { // - If leftover is unique, match // Group forwarded pointers by storage class first and loop over them. - GroupIdsAndMatch( - potential_id_map.src_ids, potential_id_map.dst_ids, - spv::StorageClass::Max, &Differ::GroupIdsHelperGetTypePointerStorageClass, + GroupIdsAndMatch( + potential_id_map.src_ids, potential_id_map.dst_ids, SpvStorageClassMax, + &Differ::GroupIdsHelperGetTypePointerStorageClass, [this](const IdGroup& src_group_by_storage_class, const IdGroup& dst_group_by_storage_class) { + // Group them further by the type they are pointing to and loop over // them. - GroupIdsAndMatch( - src_group_by_storage_class, dst_group_by_storage_class, - spv::Op::Max, &Differ::GroupIdsHelperGetTypePointerTypeOp, + GroupIdsAndMatch( + src_group_by_storage_class, dst_group_by_storage_class, SpvOpMax, + &Differ::GroupIdsHelperGetTypePointerTypeOp, [this](const IdGroup& src_group_by_type_op, const IdGroup& dst_group_by_type_op) { + // Group them even further by debug info, if possible and match by // debug name. MatchTypeForwardPointersByName(src_group_by_type_op, @@ -2281,8 +2182,8 @@ void Differ::MatchTypeIds() { MatchIds(potential_id_map, [this, flexibility]( const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - const spv::Op src_op = src_inst->opcode(); - const spv::Op dst_op = dst_inst->opcode(); + const SpvOp src_op = src_inst->opcode(); + const SpvOp dst_op = dst_inst->opcode(); // Don't match if the opcode is not the same. if (src_op != dst_op) { @@ -2290,28 +2191,26 @@ void Differ::MatchTypeIds() { } switch (src_op) { - case spv::Op::OpTypeVoid: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeAccelerationStructureNV: - case spv::Op::OpTypeRayQueryKHR: - // the above types have no operands and are unique, match them. + case SpvOpTypeVoid: + case SpvOpTypeBool: + case SpvOpTypeSampler: + // void, bool and sampler are unique, match them. return true; - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypePointer: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeSampledImage: + case SpvOpTypeRuntimeArray: + case SpvOpTypePointer: // Match these instructions when all operands match. assert(src_inst->NumInOperandWords() == dst_inst->NumInOperandWords()); return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case spv::Op::OpTypeFunction: - case spv::Op::OpTypeImage: + case SpvOpTypeFunction: + case SpvOpTypeImage: // Match function types only if they have the same number of operands, // and they all match. // Match image types similarly, expecting the optional final parameter @@ -2322,7 +2221,7 @@ void Differ::MatchTypeIds() { return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case spv::Op::OpTypeArray: + case SpvOpTypeArray: // Match arrays only if the element type and length match. The length // is an id of a constant, so the actual constant it's defining is // compared instead. @@ -2339,7 +2238,7 @@ void Differ::MatchTypeIds() { // example if a spec contant is used). return DoOperandsMatch(src_inst, dst_inst, 1, 1); - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: return MatchOpTypeStruct(src_inst, dst_inst, flexibility); default: @@ -2371,8 +2270,8 @@ void Differ::MatchConstants() { MatchIds(potential_id_map, [this, flexibility]( const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - const spv::Op src_op = src_inst->opcode(); - const spv::Op dst_op = dst_inst->opcode(); + const SpvOp src_op = src_inst->opcode(); + const SpvOp dst_op = dst_inst->opcode(); // Don't match if the opcode is not the same. if (src_op != dst_op) { @@ -2380,14 +2279,14 @@ void Differ::MatchConstants() { } switch (src_op) { - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: + case SpvOpConstantTrue: + case SpvOpConstantFalse: // true and false are unique, match them. return true; - case spv::Op::OpConstant: + case SpvOpConstant: return MatchOpConstant(src_inst, dst_inst, flexibility); - case spv::Op::OpConstantComposite: - case spv::Op::OpSpecConstantComposite: + case SpvOpConstantComposite: + case SpvOpSpecConstantComposite: // Composite constants must match in type and value. // // TODO: match OpConstantNull with OpConstantComposite with all zeros @@ -2400,7 +2299,7 @@ void Differ::MatchConstants() { dst_inst->GetOperand(0)) && DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case spv::Op::OpConstantSampler: + case SpvOpConstantSampler: // Match sampler constants exactly. // TODO: Allow flexibility in parameters to better diff shaders where // the sampler param has changed. @@ -2408,15 +2307,15 @@ void Differ::MatchConstants() { dst_inst->NumInOperandWords()); return DoOperandsMatch(src_inst, dst_inst, 0, src_inst->NumInOperandWords()); - case spv::Op::OpConstantNull: + case SpvOpConstantNull: // Match null constants as long as the type matches. return DoesOperandMatch(src_inst->GetOperand(0), dst_inst->GetOperand(0)); - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpSpecConstant: - case spv::Op::OpSpecConstantOp: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: + case SpvOpSpecConstantOp: // Match spec constants by name if available, then by the SpecId // decoration. return MatchOpSpecConstant(src_inst, dst_inst); @@ -2435,7 +2334,7 @@ void Differ::MatchVariableIds() { return inst.result_id(); }; auto accept_type_ops = [](const opt::Instruction& inst) { - return inst.opcode() == spv::Op::OpVariable; + return inst.opcode() == SpvOpVariable; }; PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true, @@ -2451,8 +2350,8 @@ void Differ::MatchVariableIds() { MatchIds(potential_id_map, [this, flexibility](const opt::Instruction* src_inst, const opt::Instruction* dst_inst) { - assert(src_inst->opcode() == spv::Op::OpVariable); - assert(dst_inst->opcode() == spv::Op::OpVariable); + assert(src_inst->opcode() == SpvOpVariable); + assert(dst_inst->opcode() == SpvOpVariable); return MatchOpVariable(src_inst, dst_inst, flexibility); }); @@ -2474,6 +2373,7 @@ void Differ::MatchFunctions() { GroupIdsAndMatch( src_func_ids, dst_func_ids, "", &Differ::GetSanitizedName, [this](const IdGroup& src_group, const IdGroup& dst_group) { + // If there is a single function with this name in src and dst, it's a // definite match. if (src_group.size() == 1 && dst_group.size() == 1) { @@ -2487,6 +2387,7 @@ void Differ::MatchFunctions() { &Differ::GroupIdsHelperGetTypeId, [this](const IdGroup& src_group_by_type_id, const IdGroup& dst_group_by_type_id) { + if (src_group_by_type_id.size() == 1 && dst_group_by_type_id.size() == 1) { id_map_.MapIds(src_group_by_type_id[0], @@ -2531,6 +2432,7 @@ void Differ::MatchFunctions() { src_func_ids, dst_func_ids, 0, &Differ::GroupIdsHelperGetTypeId, [this](const IdGroup& src_group_by_type_id, const IdGroup& dst_group_by_type_id) { + BestEffortMatchFunctions(src_group_by_type_id, dst_group_by_type_id, src_func_insts_, dst_func_insts_); }); @@ -2695,7 +2597,7 @@ void Differ::ToParsedInstruction( parsed_inst->num_words = static_cast(inst_binary.size()); parsed_inst->opcode = static_cast(inst.opcode()); parsed_inst->ext_inst_type = - inst.opcode() == spv::Op::OpExtInst + inst.opcode() == SpvOpExtInst ? GetExtInstType(id_to, original_inst.GetSingleWordInOperand(0)) : SPV_EXT_INST_TYPE_NONE; parsed_inst->type_id = @@ -2740,9 +2642,7 @@ opt::Instruction Differ::ToMappedSrcIds(const opt::Instruction& dst_inst) { } spv_result_t Differ::Output() { - id_map_.MapUnmatchedIds( - [this](uint32_t src_id) { return src_id_to_.IsDefined(src_id); }, - [this](uint32_t dst_id) { return dst_id_to_.IsDefined(dst_id); }); + id_map_.MapUnmatchedIds(); src_id_to_.inst_map_.resize(id_map_.SrcToDstMap().IdBound(), nullptr); dst_id_to_.inst_map_.resize(id_map_.DstToSrcMap().IdBound(), nullptr); diff --git a/source/disassemble.cpp b/source/disassemble.cpp index 5173fbf6..1d61b9f9 100644 --- a/source/disassemble.cpp +++ b/source/disassemble.cpp @@ -244,7 +244,7 @@ void InstructionDisassembler::EmitHeaderSchema(uint32_t schema) { void InstructionDisassembler::EmitInstruction( const spv_parsed_instruction_t& inst, size_t inst_byte_offset) { - auto opcode = static_cast(inst.opcode); + auto opcode = static_cast(inst.opcode); if (inst.result_id) { SetBlue(); @@ -268,7 +268,7 @@ void InstructionDisassembler::EmitInstruction( EmitOperand(inst, i); } - if (comment_ && opcode == spv::Op::OpName) { + if (comment_ && opcode == SpvOpName) { const spv_parsed_operand_t& operand = inst.operands[0]; const uint32_t word = inst.words[operand.offset]; stream_ << " ; id %" << word; @@ -290,8 +290,8 @@ void InstructionDisassembler::EmitInstruction( void InstructionDisassembler::EmitSectionComment( const spv_parsed_instruction_t& inst, bool& inserted_decoration_space, bool& inserted_debug_space, bool& inserted_type_space) { - auto opcode = static_cast(inst.opcode); - if (comment_ && opcode == spv::Op::OpFunction) { + auto opcode = static_cast(inst.opcode); + if (comment_ && opcode == SpvOpFunction) { stream_ << std::endl; stream_ << std::string(indent_, ' '); stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl; @@ -351,14 +351,13 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, } break; case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { spv_opcode_desc opcode_desc; - if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc)) + if (grammar_.lookupOpcode(SpvOp(word), &opcode_desc)) assert(false && "should have caught this earlier"); SetRed(); stream_ << opcode_desc->name; } break; case SPV_OPERAND_TYPE_LITERAL_INTEGER: - case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: - case SPV_OPERAND_TYPE_LITERAL_FLOAT: { + case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: { SetRed(); EmitNumericLiteral(&stream_, inst, operand); ResetColor(); diff --git a/source/enum_set.h b/source/enum_set.h index a3751388..d4d31e33 100644 --- a/source/enum_set.h +++ b/source/enum_set.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Google Inc. +// Copyright (c) 2016 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,457 +12,196 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include -#include -#include -#include -#include -#include -#include - #ifndef SOURCE_ENUM_SET_H_ #define SOURCE_ENUM_SET_H_ +#include +#include +#include +#include +#include + #include "source/latest_version_spirv_header.h" +#include "source/util/make_unique.h" namespace spvtools { -// This container is optimized to store and retrieve unsigned enum values. -// The base model for this implementation is an open-addressing hashtable with -// linear probing. For small enums (max index < 64), all operations are O(1). -// -// - Enums are stored in buckets (64 contiguous values max per bucket) -// - Buckets ranges don't overlap, but don't have to be contiguous. -// - Enums are packed into 64-bits buckets, using 1 bit per enum value. -// -// Example: -// - MyEnum { A = 0, B = 1, C = 64, D = 65 } -// - 2 buckets are required: -// - bucket 0, storing values in the range [ 0; 64[ -// - bucket 1, storing values in the range [64; 128[ -// -// - Buckets are stored in a sorted vector (sorted by bucket range). -// - Retrieval is done by computing the theoretical bucket index using the enum -// value, and -// doing a linear scan from this position. -// - Insertion is done by retrieving the bucket and either: -// - inserting a new bucket in the sorted vector when no buckets has a -// compatible range. -// - setting the corresponding bit in the bucket. -// This means insertion in the middle/beginning can cause a memmove when no -// bucket is available. In our case, this happens at most 23 times for the -// largest enum we have (Opcodes). -template +// A set of values of a 32-bit enum type. +// It is fast and compact for the common case, where enum values +// are at most 63. But it can represent enums with larger values, +// as may appear in extensions. +template class EnumSet { private: - using BucketType = uint64_t; - using ElementType = std::underlying_type_t; - static_assert(std::is_enum_v, "EnumSets only works with enums."); - static_assert(std::is_signed_v == false, - "EnumSet doesn't supports signed enums."); - - // Each bucket can hold up to `kBucketSize` distinct, contiguous enum values. - // The first value a bucket can hold must be aligned on `kBucketSize`. - struct Bucket { - // bit mask to store `kBucketSize` enums. - BucketType data; - // 1st enum this bucket can represent. - T start; - - friend bool operator==(const Bucket& lhs, const Bucket& rhs) { - return lhs.start == rhs.start && lhs.data == rhs.data; - } - }; - - // How many distinct values can a bucket hold? 1 bit per value. - static constexpr size_t kBucketSize = sizeof(BucketType) * 8ULL; + // The ForEach method will call the functor on enum values in + // enum value order (lowest to highest). To make that easier, use + // an ordered set for the overflow values. + using OverflowSetType = std::set; public: - class Iterator { - public: - typedef Iterator self_type; - typedef T value_type; - typedef T& reference; - typedef T* pointer; - typedef std::forward_iterator_tag iterator_category; - typedef size_t difference_type; - - Iterator(const Iterator& other) - : set_(other.set_), - bucketIndex_(other.bucketIndex_), - bucketOffset_(other.bucketOffset_) {} - - Iterator& operator++() { - do { - if (bucketIndex_ >= set_->buckets_.size()) { - bucketIndex_ = set_->buckets_.size(); - bucketOffset_ = 0; - break; - } - - if (bucketOffset_ + 1 == kBucketSize) { - bucketOffset_ = 0; - ++bucketIndex_; - } else { - ++bucketOffset_; - } - - } while (bucketIndex_ < set_->buckets_.size() && - !set_->HasEnumAt(bucketIndex_, bucketOffset_)); - return *this; - } - - Iterator operator++(int) { - Iterator old = *this; - operator++(); - return old; - } - - T operator*() const { - assert(set_->HasEnumAt(bucketIndex_, bucketOffset_) && - "operator*() called on an invalid iterator."); - return GetValueFromBucket(set_->buckets_[bucketIndex_], bucketOffset_); - } - - bool operator!=(const Iterator& other) const { - return set_ != other.set_ || bucketOffset_ != other.bucketOffset_ || - bucketIndex_ != other.bucketIndex_; - } - - bool operator==(const Iterator& other) const { - return !(operator!=(other)); - } - - Iterator& operator=(const Iterator& other) { - set_ = other.set_; - bucketIndex_ = other.bucketIndex_; - bucketOffset_ = other.bucketOffset_; - return *this; - } - - private: - Iterator(const EnumSet* set, size_t bucketIndex, ElementType bucketOffset) - : set_(set), bucketIndex_(bucketIndex), bucketOffset_(bucketOffset) {} - - private: - const EnumSet* set_ = nullptr; - // Index of the bucket in the vector. - size_t bucketIndex_ = 0; - // Offset in bits in the current bucket. - ElementType bucketOffset_ = 0; - - friend class EnumSet; - }; - - // Required to allow the use of std::inserter. - using value_type = T; - using const_iterator = Iterator; - using iterator = Iterator; - - public: - iterator cbegin() const noexcept { - auto it = iterator(this, /* bucketIndex= */ 0, /* bucketOffset= */ 0); - if (buckets_.size() == 0) { - return it; - } - - // The iterator has the logic to find the next valid bit. If the value 0 - // is not stored, use it to find the next valid bit. - if (!HasEnumAt(it.bucketIndex_, it.bucketOffset_)) { - ++it; - } - - return it; + // Construct an empty set. + EnumSet() {} + // Construct an set with just the given enum value. + explicit EnumSet(EnumType c) { Add(c); } + // Construct an set from an initializer list of enum values. + EnumSet(std::initializer_list cs) { + for (auto c : cs) Add(c); } - - iterator begin() const noexcept { return cbegin(); } - - iterator cend() const noexcept { - return iterator(this, buckets_.size(), /* bucketOffset= */ 0); + EnumSet(uint32_t count, const EnumType* ptr) { + for (uint32_t i = 0; i < count; ++i) Add(ptr[i]); } - - iterator end() const noexcept { return cend(); } - - // Creates an empty set. - EnumSet() : buckets_(0), size_(0) {} - - // Creates a set and store `value` in it. - EnumSet(T value) : EnumSet() { insert(value); } - - // Creates a set and stores each `values` in it. - EnumSet(std::initializer_list values) : EnumSet() { - for (auto item : values) { - insert(item); - } + // Copy constructor. + EnumSet(const EnumSet& other) { *this = other; } + // Move constructor. The moved-from set is emptied. + EnumSet(EnumSet&& other) { + mask_ = other.mask_; + overflow_ = std::move(other.overflow_); + other.mask_ = 0; + other.overflow_.reset(nullptr); } - - // Creates a set, and insert `count` enum values pointed by `array` in it. - EnumSet(ElementType count, const T* array) : EnumSet() { - for (ElementType i = 0; i < count; i++) { - insert(array[i]); - } - } - - // Creates a set initialized with the content of the range [begin; end[. - template - EnumSet(InputIt begin, InputIt end) : EnumSet() { - for (; begin != end; ++begin) { - insert(*begin); - } - } - - // Copies the EnumSet `other` into a new EnumSet. - EnumSet(const EnumSet& other) - : buckets_(other.buckets_), size_(other.size_) {} - - // Moves the EnumSet `other` into a new EnumSet. - EnumSet(EnumSet&& other) - : buckets_(std::move(other.buckets_)), size_(other.size_) {} - - // Deep-copies the EnumSet `other` into this EnumSet. + // Assignment operator. EnumSet& operator=(const EnumSet& other) { - buckets_ = other.buckets_; - size_ = other.size_; + if (&other != this) { + mask_ = other.mask_; + overflow_.reset(other.overflow_ ? new OverflowSetType(*other.overflow_) + : nullptr); + } return *this; } - // Matches std::unordered_set::insert behavior. - std::pair insert(const T& value) { - const size_t index = FindBucketForValue(value); - const ElementType offset = ComputeBucketOffset(value); - - if (index >= buckets_.size() || - buckets_[index].start != ComputeBucketStart(value)) { - size_ += 1; - InsertBucketFor(index, value); - return std::make_pair(Iterator(this, index, offset), true); - } - - auto& bucket = buckets_[index]; - const auto mask = ComputeMaskForValue(value); - if (bucket.data & mask) { - return std::make_pair(Iterator(this, index, offset), false); - } - - size_ += 1; - bucket.data |= ComputeMaskForValue(value); - return std::make_pair(Iterator(this, index, offset), true); - } - - // Inserts `value` in the set if possible. - // Similar to `std::unordered_set::insert`, except the hint is ignored. - // Returns an iterator to the inserted element, or the element preventing - // insertion. - iterator insert(const_iterator, const T& value) { - return insert(value).first; - } - - // Inserts `value` in the set if possible. - // Similar to `std::unordered_set::insert`, except the hint is ignored. - // Returns an iterator to the inserted element, or the element preventing - // insertion. - iterator insert(const_iterator, T&& value) { return insert(value).first; } - - // Inserts all the values in the range [`first`; `last[. - // Similar to `std::unordered_set::insert`. - template - void insert(InputIt first, InputIt last) { - for (auto it = first; it != last; ++it) { - insert(*it); - } - } - - // Removes the value `value` into the set. - // Similar to `std::unordered_set::erase`. - // Returns the number of erased elements. - size_t erase(const T& value) { - const size_t index = FindBucketForValue(value); - if (index >= buckets_.size() || - buckets_[index].start != ComputeBucketStart(value)) { - return 0; - } - - auto& bucket = buckets_[index]; - const auto mask = ComputeMaskForValue(value); - if (!(bucket.data & mask)) { - return 0; - } - - size_ -= 1; - bucket.data &= ~mask; - if (bucket.data == 0) { - buckets_.erase(buckets_.cbegin() + index); - } - return 1; - } - - // Returns true if `value` is present in the set. - bool contains(T value) const { - const size_t index = FindBucketForValue(value); - if (index >= buckets_.size() || - buckets_[index].start != ComputeBucketStart(value)) { + friend bool operator==(const EnumSet& a, const EnumSet& b) { + if (a.mask_ != b.mask_) { return false; } - auto& bucket = buckets_[index]; - return bucket.data & ComputeMaskForValue(value); - } - // Returns the 1 if `value` is present in the set, `0` otherwise. - inline size_t count(T value) const { return contains(value) ? 1 : 0; } - - // Returns true if the set is holds no values. - inline bool empty() const { return size_ == 0; } - - // Returns the number of enums stored in this set. - size_t size() const { return size_; } - - // Returns true if this set contains at least one value contained in `in_set`. - // Note: If `in_set` is empty, this function returns true. - bool HasAnyOf(const EnumSet& in_set) const { - if (in_set.empty()) { + if (a.overflow_ == nullptr && b.overflow_ == nullptr) { return true; } - auto lhs = buckets_.cbegin(); - auto rhs = in_set.buckets_.cbegin(); + if (a.overflow_ == nullptr || b.overflow_ == nullptr) { + return false; + } - while (lhs != buckets_.cend() && rhs != in_set.buckets_.cend()) { - if (lhs->start == rhs->start) { - if (lhs->data & rhs->data) { - // At least 1 bit is shared. Early return. - return true; - } + return *a.overflow_ == *b.overflow_; + } - lhs++; - rhs++; - continue; - } + friend bool operator!=(const EnumSet& a, const EnumSet& b) { + return !(a == b); + } - // LHS bucket is smaller than the current RHS bucket. Catching up on RHS. - if (lhs->start < rhs->start) { - lhs++; - continue; - } + // Adds the given enum value to the set. This has no effect if the + // enum value is already in the set. + void Add(EnumType c) { AddWord(ToWord(c)); } - // Otherwise, RHS needs to catch up on LHS. - rhs++; + // Removes the given enum value from the set. This has no effect if the + // enum value is not in the set. + void Remove(EnumType c) { RemoveWord(ToWord(c)); } + + // Returns true if this enum value is in the set. + bool Contains(EnumType c) const { return ContainsWord(ToWord(c)); } + + // Applies f to each enum in the set, in order from smallest enum + // value to largest. + void ForEach(std::function f) const { + for (uint32_t i = 0; i < 64; ++i) { + if (mask_ & AsMask(i)) f(static_cast(i)); + } + if (overflow_) { + for (uint32_t c : *overflow_) f(static_cast(c)); + } + } + + // Returns true if the set is empty. + bool IsEmpty() const { + if (mask_) return false; + if (overflow_ && !overflow_->empty()) return false; + return true; + } + + // Returns true if the set contains ANY of the elements of |in_set|, + // or if |in_set| is empty. + bool HasAnyOf(const EnumSet& in_set) const { + if (in_set.IsEmpty()) return true; + + if (mask_ & in_set.mask_) return true; + + if (!overflow_ || !in_set.overflow_) return false; + + for (uint32_t item : *in_set.overflow_) { + if (overflow_->find(item) != overflow_->end()) return true; } return false; } private: - // Returns the index of the last bucket in which `value` could be stored. - static constexpr inline size_t ComputeLargestPossibleBucketIndexFor(T value) { - return static_cast(value) / kBucketSize; - } - - // Returns the smallest enum value that could be contained in the same bucket - // as `value`. - static constexpr inline T ComputeBucketStart(T value) { - return static_cast(kBucketSize * - ComputeLargestPossibleBucketIndexFor(value)); - } - - // Returns the index of the bit that corresponds to `value` in the bucket. - static constexpr inline ElementType ComputeBucketOffset(T value) { - return static_cast(value) % kBucketSize; - } - - // Returns the bitmask used to represent the enum `value` in its bucket. - static constexpr inline BucketType ComputeMaskForValue(T value) { - return 1ULL << ComputeBucketOffset(value); - } - - // Returns the `enum` stored in `bucket` at `offset`. - // `offset` is the bit-offset in the bucket storage. - static constexpr inline T GetValueFromBucket(const Bucket& bucket, - BucketType offset) { - return static_cast(static_cast(bucket.start) + offset); - } - - // For a given enum `value`, finds the bucket index that could contain this - // value. If no such bucket is found, the index at which the new bucket should - // be inserted is returned. - size_t FindBucketForValue(T value) const { - // Set is empty, insert at 0. - if (buckets_.size() == 0) { - return 0; + // Adds the given enum value (as a 32-bit word) to the set. This has no + // effect if the enum value is already in the set. + void AddWord(uint32_t word) { + if (auto new_bits = AsMask(word)) { + mask_ |= new_bits; + } else { + Overflow().insert(word); } + } - const T wanted_start = ComputeBucketStart(value); - assert(buckets_.size() > 0 && - "Size must not be 0 here. Has the code above changed?"); - size_t index = std::min(buckets_.size() - 1, - ComputeLargestPossibleBucketIndexFor(value)); - - // This loops behaves like std::upper_bound with a reverse iterator. - // Buckets are sorted. 3 main cases: - // - The bucket matches - // => returns the bucket index. - // - The found bucket is larger - // => scans left until it finds the correct bucket, or insertion point. - // - The found bucket is smaller - // => We are at the end, so we return past-end index for insertion. - for (; buckets_[index].start >= wanted_start; index--) { - if (index == 0) { - return 0; - } + // Removes the given enum value (as a 32-bit word) from the set. This has no + // effect if the enum value is not in the set. + void RemoveWord(uint32_t word) { + if (auto new_bits = AsMask(word)) { + mask_ &= ~new_bits; + } else { + auto itr = Overflow().find(word); + if (itr != Overflow().end()) Overflow().erase(itr); } - - return index + 1; } - // Creates a new bucket to store `value` and inserts it at `index`. - // If the `index` is past the end, the bucket is inserted at the end of the - // vector. - void InsertBucketFor(size_t index, T value) { - const T bucket_start = ComputeBucketStart(value); - Bucket bucket = {1ULL << ComputeBucketOffset(value), bucket_start}; - auto it = buckets_.emplace(buckets_.begin() + index, std::move(bucket)); -#if defined(NDEBUG) - (void)it; // Silencing unused variable warning. -#else - assert(std::next(it) == buckets_.end() || - std::next(it)->start > bucket_start); - assert(it == buckets_.begin() || std::prev(it)->start < bucket_start); -#endif - } - - // Returns true if the bucket at `bucketIndex/ stores the enum at - // `bucketOffset`, false otherwise. - bool HasEnumAt(size_t bucketIndex, BucketType bucketOffset) const { - assert(bucketIndex < buckets_.size()); - assert(bucketOffset < kBucketSize); - return buckets_[bucketIndex].data & (1ULL << bucketOffset); - } - - // Returns true if `lhs` and `rhs` hold the exact same values. - friend bool operator==(const EnumSet& lhs, const EnumSet& rhs) { - if (lhs.size_ != rhs.size_) { - return false; + // Returns true if the enum represented as a 32-bit word is in the set. + bool ContainsWord(uint32_t word) const { + // We shouldn't call Overflow() since this is a const method. + if (auto bits = AsMask(word)) { + return (mask_ & bits) != 0; + } else if (auto overflow = overflow_.get()) { + return overflow->find(word) != overflow->end(); } + // The word is large, but the set doesn't have large members, so + // it doesn't have an overflow set. + return false; + } - if (lhs.buckets_.size() != rhs.buckets_.size()) { - return false; + // Returns the enum value as a uint32_t. + uint32_t ToWord(EnumType value) const { + static_assert(sizeof(EnumType) <= sizeof(uint32_t), + "EnumType must statically castable to uint32_t"); + return static_cast(value); + } + + // Determines whether the given enum value can be represented + // as a bit in a uint64_t mask. If so, then returns that mask bit. + // Otherwise, returns 0. + uint64_t AsMask(uint32_t word) const { + if (word > 63) return 0; + return uint64_t(1) << word; + } + + // Ensures that overflow_set_ references a set. A new empty set is + // allocated if one doesn't exist yet. Returns overflow_set_. + OverflowSetType& Overflow() { + if (overflow_.get() == nullptr) { + overflow_ = MakeUnique(); } - return lhs.buckets_ == rhs.buckets_; + return *overflow_; } - // Returns true if `lhs` and `rhs` hold at least 1 different value. - friend bool operator!=(const EnumSet& lhs, const EnumSet& rhs) { - return !(lhs == rhs); - } - - // Storage for the buckets. - std::vector buckets_; - // How many enums is this set storing. - size_t size_ = 0; + // Enums with values up to 63 are stored as bits in this mask. + uint64_t mask_ = 0; + // Enums with values larger than 63 are stored in this set. + // This set should normally be empty or very small. + std::unique_ptr overflow_ = {}; }; -// A set of spv::Capability. -using CapabilitySet = EnumSet; +// A set of SpvCapability, optimized for small capability values. +using CapabilitySet = EnumSet; } // namespace spvtools diff --git a/source/enum_string_mapping.h b/source/enum_string_mapping.h index b1365840..af8f56b8 100644 --- a/source/enum_string_mapping.h +++ b/source/enum_string_mapping.h @@ -29,7 +29,7 @@ bool GetExtensionFromString(const char* str, Extension* extension); const char* ExtensionToString(Extension extension); // Returns text string corresponding to |capability|. -const char* CapabilityToString(spv::Capability capability); +const char* CapabilityToString(SpvCapability capability); } // namespace spvtools diff --git a/source/extensions.cpp b/source/extensions.cpp index ac987fcc..049a3ad1 100644 --- a/source/extensions.cpp +++ b/source/extensions.cpp @@ -24,9 +24,7 @@ namespace spvtools { std::string GetExtensionString(const spv_parsed_instruction_t* inst) { - if (inst->opcode != static_cast(spv::Op::OpExtension)) { - return "ERROR_not_op_extension"; - } + if (inst->opcode != SpvOpExtension) return "ERROR_not_op_extension"; assert(inst->num_operands == 1); @@ -40,9 +38,8 @@ std::string GetExtensionString(const spv_parsed_instruction_t* inst) { std::string ExtensionSetToString(const ExtensionSet& extensions) { std::stringstream ss; - for (auto extension : extensions) { - ss << ExtensionToString(extension) << " "; - } + extensions.ForEach( + [&ss](Extension ext) { ss << ExtensionToString(ext) << " "; }); return ss.str(); } diff --git a/source/extensions.h b/source/extensions.h index cda4924a..8023444c 100644 --- a/source/extensions.h +++ b/source/extensions.h @@ -15,7 +15,6 @@ #ifndef SOURCE_EXTENSIONS_H_ #define SOURCE_EXTENSIONS_H_ -#include #include #include "source/enum_set.h" @@ -24,7 +23,7 @@ namespace spvtools { // The known SPIR-V extensions. -enum Extension : uint32_t { +enum Extension { #include "extension_enum.inc" }; diff --git a/source/fuzz/CMakeLists.txt b/source/fuzz/CMakeLists.txt index 86ee657a..dd674dd0 100644 --- a/source/fuzz/CMakeLists.txt +++ b/source/fuzz/CMakeLists.txt @@ -470,7 +470,10 @@ if(SPIRV_BUILD_FUZZER) spvtools_check_symbol_exports(SPIRV-Tools-fuzz) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-fuzz EXPORT SPIRV-Tools-fuzzTargets) + install(TARGETS SPIRV-Tools-fuzz EXPORT SPIRV-Tools-fuzzTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-fuzzTargets FILE SPIRV-Tools-fuzzTarget.cmake) spvtools_config_package_dir(SPIRV-Tools-fuzz PACKAGE_DIR) diff --git a/source/fuzz/added_function_reducer.cpp b/source/fuzz/added_function_reducer.cpp index 95cf9d6d..e7cb027b 100644 --- a/source/fuzz/added_function_reducer.cpp +++ b/source/fuzz/added_function_reducer.cpp @@ -130,7 +130,7 @@ bool AddedFunctionReducer::InterestingnessFunctionForReducingAddedFunction( binary_under_reduction.size()); assert(ir_context != nullptr && "The binary should be parsable."); for (auto& type_or_value : ir_context->module()->types_values()) { - if (type_or_value.opcode() != spv::Op::OpVariable) { + if (type_or_value.opcode() != SpvOpVariable) { continue; } if (irrelevant_pointee_global_variables.count(type_or_value.result_id())) { @@ -202,7 +202,7 @@ void AddedFunctionReducer::ReplayPrefixAndAddFunction( auto* ir_context = replay_result.transformed_module.get(); for (auto& type_or_value : ir_context->module()->types_values()) { - if (type_or_value.opcode() != spv::Op::OpVariable) { + if (type_or_value.opcode() != SpvOpVariable) { continue; } if (replay_result.transformation_context->GetFactManager() diff --git a/source/fuzz/call_graph.cpp b/source/fuzz/call_graph.cpp index d61a5f84..c52bc342 100644 --- a/source/fuzz/call_graph.cpp +++ b/source/fuzz/call_graph.cpp @@ -54,7 +54,7 @@ void CallGraph::BuildGraphAndGetDepthOfFunctionCalls( // Consider every function call instruction in every block. for (auto& block : function) { for (auto& instruction : block) { - if (instruction.opcode() != spv::Op::OpFunctionCall) { + if (instruction.opcode() != SpvOpFunctionCall) { continue; } // Get the id of the function being called. diff --git a/source/fuzz/fact_manager/constant_uniform_facts.cpp b/source/fuzz/fact_manager/constant_uniform_facts.cpp index 461859bd..a629c0d3 100644 --- a/source/fuzz/fact_manager/constant_uniform_facts.cpp +++ b/source/fuzz/fact_manager/constant_uniform_facts.cpp @@ -63,7 +63,7 @@ std::vector ConstantUniformFacts::GetConstantWords( bool ConstantUniformFacts::DataMatches( const opt::Instruction& constant_instruction, const protobufs::FactConstantUniform& constant_uniform_fact) { - assert(constant_instruction.opcode() == spv::Op::OpConstant); + assert(constant_instruction.opcode() == SpvOpConstant); std::vector data_in_constant; for (uint32_t i = 0; i < constant_instruction.NumInOperands(); i++) { data_in_constant.push_back(constant_instruction.GetSingleWordInOperand(i)); @@ -95,7 +95,7 @@ ConstantUniformFacts::GetUniformDescriptorsForConstant( uint32_t constant_id) const { std::vector result; auto constant_inst = ir_context_->get_def_use_mgr()->GetDef(constant_id); - assert(constant_inst->opcode() == spv::Op::OpConstant && + assert(constant_inst->opcode() == SpvOpConstant && "The given id must be that of a constant"); auto type_id = constant_inst->type_id(); for (auto& fact_and_type_id : facts_and_type_ids_) { @@ -175,9 +175,8 @@ bool ConstantUniformFacts::MaybeAddFact( return false; } - assert(spv::Op::OpVariable == uniform_variable->opcode()); - assert(spv::StorageClass::Uniform == - spv::StorageClass(uniform_variable->GetSingleWordInOperand(0))); + assert(SpvOpVariable == uniform_variable->opcode()); + assert(SpvStorageClassUniform == uniform_variable->GetSingleWordInOperand(0)); auto should_be_uniform_pointer_type = ir_context_->get_type_mgr()->GetType(uniform_variable->type_id()); @@ -185,7 +184,7 @@ bool ConstantUniformFacts::MaybeAddFact( return false; } if (should_be_uniform_pointer_type->AsPointer()->storage_class() != - spv::StorageClass::Uniform) { + SpvStorageClassUniform) { return false; } auto should_be_uniform_pointer_instruction = diff --git a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp index b43b8edf..a2c1f2ca 100644 --- a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp +++ b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.cpp @@ -23,7 +23,7 @@ namespace fact_manager { size_t DataSynonymAndIdEquationFacts::OperationHash::operator()( const Operation& operation) const { std::u32string hash; - hash.push_back(uint32_t(operation.opcode)); + hash.push_back(operation.opcode); for (auto operand : operation.operands) { hash.push_back(static_cast(DataDescriptorHash()(operand))); } @@ -104,8 +104,7 @@ bool DataSynonymAndIdEquationFacts::MaybeAddFact( } // Now add the fact. - AddEquationFactRecursive(lhs_dd, static_cast(fact.opcode()), - rhs_dds); + AddEquationFactRecursive(lhs_dd, static_cast(fact.opcode()), rhs_dds); return true; } @@ -120,7 +119,7 @@ DataSynonymAndIdEquationFacts::GetEquations( } void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( - const protobufs::DataDescriptor& lhs_dd, spv::Op opcode, + const protobufs::DataDescriptor& lhs_dd, SpvOp opcode, const std::vector& rhs_dds) { assert(synonymous_.Exists(lhs_dd) && "The LHS must be known to the equivalence relation."); @@ -156,21 +155,21 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( // Now try to work out corollaries implied by the new equation and existing // facts. switch (opcode) { - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: + case SpvOpConvertSToF: + case SpvOpConvertUToF: ComputeConversionDataSynonymFacts(*rhs_dds[0]); break; - case spv::Op::OpBitcast: { + case SpvOpBitcast: { assert(DataDescriptorsAreWellFormedAndComparable(lhs_dd, *rhs_dds[0]) && "Operands of OpBitcast equation fact must have compatible types"); if (!synonymous_.IsEquivalent(lhs_dd, *rhs_dds[0])) { AddDataSynonymFactRecursive(lhs_dd, *rhs_dds[0]); } } break; - case spv::Op::OpIAdd: { + case SpvOpIAdd: { // Equation form: "a = b + c" for (const auto& equation : GetEquations(rhs_dds[0])) { - if (equation.opcode == spv::Op::OpISub) { + if (equation.opcode == SpvOpISub) { // Equation form: "a = (d - e) + c" if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[1])) { // Equation form: "a = (d - c) + c" @@ -180,7 +179,7 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( } } for (const auto& equation : GetEquations(rhs_dds[1])) { - if (equation.opcode == spv::Op::OpISub) { + if (equation.opcode == SpvOpISub) { // Equation form: "a = b + (d - e)" if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[0])) { // Equation form: "a = b + (d - b)" @@ -191,10 +190,10 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( } break; } - case spv::Op::OpISub: { + case SpvOpISub: { // Equation form: "a = b - c" for (const auto& equation : GetEquations(rhs_dds[0])) { - if (equation.opcode == spv::Op::OpIAdd) { + if (equation.opcode == SpvOpIAdd) { // Equation form: "a = (d + e) - c" if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[1])) { // Equation form: "a = (c + e) - c" @@ -208,34 +207,34 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( } } - if (equation.opcode == spv::Op::OpISub) { + if (equation.opcode == SpvOpISub) { // Equation form: "a = (d - e) - c" if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[1])) { // Equation form: "a = (c - e) - c" // We can thus infer "a = -e" - AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate, + AddEquationFactRecursive(lhs_dd, SpvOpSNegate, {equation.operands[1]}); } } } for (const auto& equation : GetEquations(rhs_dds[1])) { - if (equation.opcode == spv::Op::OpIAdd) { + if (equation.opcode == SpvOpIAdd) { // Equation form: "a = b - (d + e)" if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[0])) { // Equation form: "a = b - (b + e)" // We can thus infer "a = -e" - AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate, + AddEquationFactRecursive(lhs_dd, SpvOpSNegate, {equation.operands[1]}); } if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[0])) { // Equation form: "a = b - (d + b)" // We can thus infer "a = -d" - AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate, + AddEquationFactRecursive(lhs_dd, SpvOpSNegate, {equation.operands[0]}); } } - if (equation.opcode == spv::Op::OpISub) { + if (equation.opcode == SpvOpISub) { // Equation form: "a = b - (d - e)" if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[0])) { // Equation form: "a = b - (b - e)" @@ -246,8 +245,8 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive( } break; } - case spv::Op::OpLogicalNot: - case spv::Op::OpSNegate: { + case SpvOpLogicalNot: + case SpvOpSNegate: { // Equation form: "a = !b" or "a = -b" for (const auto& equation : GetEquations(rhs_dds[0])) { if (equation.opcode == opcode) { @@ -322,9 +321,9 @@ void DataSynonymAndIdEquationFacts::ComputeConversionDataSynonymFacts( for (const auto& equation : fact.second) { if (synonymous_.IsEquivalent(*equation.operands[0], dd)) { - if (equation.opcode == spv::Op::OpConvertSToF) { + if (equation.opcode == SpvOpConvertSToF) { convert_s_to_f_lhs.push_back(*dd_it); - } else if (equation.opcode == spv::Op::OpConvertUToF) { + } else if (equation.opcode == SpvOpConvertUToF) { convert_u_to_f_lhs.push_back(*dd_it); } } @@ -809,9 +808,9 @@ bool DataSynonymAndIdEquationFacts::DataDescriptorsAreWellFormedAndComparable( } // Neither end type is allowed to be void. if (ir_context_->get_def_use_mgr()->GetDef(end_type_id_1)->opcode() == - spv::Op::OpTypeVoid || + SpvOpTypeVoid || ir_context_->get_def_use_mgr()->GetDef(end_type_id_2)->opcode() == - spv::Op::OpTypeVoid) { + SpvOpTypeVoid) { return false; } // If the end types are the same, the data descriptors are comparable. diff --git a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h index 36d92ca7..6652f30a 100644 --- a/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h +++ b/source/fuzz/fact_manager/data_synonym_and_id_equation_facts.h @@ -79,7 +79,7 @@ class DataSynonymAndIdEquationFacts { // This helper struct represents the right hand side of an equation as an // operator applied to a number of data descriptor operands. struct Operation { - spv::Op opcode; + SpvOp opcode; std::vector operands; }; @@ -144,7 +144,7 @@ class DataSynonymAndIdEquationFacts { // corollaries, in the form of data synonym or equation facts, that follow // from this and other known facts. void AddEquationFactRecursive( - const protobufs::DataDescriptor& lhs_dd, spv::Op opcode, + const protobufs::DataDescriptor& lhs_dd, SpvOp opcode, const std::vector& rhs_dds); // Returns true if and only if |dd.object()| still exists in the module. diff --git a/source/fuzz/fact_manager/fact_manager.cpp b/source/fuzz/fact_manager/fact_manager.cpp index c99f690d..40c0865f 100644 --- a/source/fuzz/fact_manager/fact_manager.cpp +++ b/source/fuzz/fact_manager/fact_manager.cpp @@ -64,7 +64,7 @@ std::string ToString(const protobufs::FactDataSynonym& fact) { std::string ToString(const protobufs::FactIdEquation& fact) { std::stringstream stream; stream << fact.lhs_id(); - stream << " " << fact.opcode(); + stream << " " << static_cast(fact.opcode()); for (auto rhs_id : fact.rhs_id()) { stream << " " << rhs_id; } @@ -255,11 +255,11 @@ void FactManager::AddFactIdIsIrrelevant(uint32_t result_id) { assert(success && "|result_id| is invalid"); } -void FactManager::AddFactIdEquation(uint32_t lhs_id, spv::Op opcode, +void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode, const std::vector& rhs_id) { protobufs::FactIdEquation fact; fact.set_lhs_id(lhs_id); - fact.set_opcode(uint32_t(opcode)); + fact.set_opcode(opcode); for (auto an_rhs_id : rhs_id) { fact.add_rhs_id(an_rhs_id); } diff --git a/source/fuzz/fact_manager/fact_manager.h b/source/fuzz/fact_manager/fact_manager.h index 4453e445..ce28ae4c 100644 --- a/source/fuzz/fact_manager/fact_manager.h +++ b/source/fuzz/fact_manager/fact_manager.h @@ -83,7 +83,7 @@ class FactManager { // |lhs_id| = |opcode| |rhs_id[0]| ... |rhs_id[N-1]| // // Neither |lhs_id| nor any of |rhs_id| may be irrelevant. - void AddFactIdEquation(uint32_t lhs_id, spv::Op opcode, + void AddFactIdEquation(uint32_t lhs_id, SpvOp opcode, const std::vector& rhs_id); // Inspects all known facts and adds corollary facts; e.g. if we know that diff --git a/source/fuzz/force_render_red.cpp b/source/fuzz/force_render_red.cpp index 191fd716..3267487a 100644 --- a/source/fuzz/force_render_red.cpp +++ b/source/fuzz/force_render_red.cpp @@ -36,9 +36,8 @@ opt::Function* FindFragmentShaderEntryPoint(opt::IRContext* ir_context, // Check that this is a fragment shader bool found_capability_shader = false; for (auto& capability : ir_context->capabilities()) { - assert(capability.opcode() == spv::Op::OpCapability); - if (spv::Capability(capability.GetSingleWordInOperand(0)) == - spv::Capability::Shader) { + assert(capability.opcode() == SpvOpCapability); + if (capability.GetSingleWordInOperand(0) == SpvCapabilityShader) { found_capability_shader = true; break; } @@ -52,8 +51,7 @@ opt::Function* FindFragmentShaderEntryPoint(opt::IRContext* ir_context, opt::Instruction* fragment_entry_point = nullptr; for (auto& entry_point : ir_context->module()->entry_points()) { - if (spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) == - spv::ExecutionModel::Fragment) { + if (entry_point.GetSingleWordInOperand(0) == SpvExecutionModelFragment) { fragment_entry_point = &entry_point; break; } @@ -83,9 +81,8 @@ opt::Instruction* FindVec4OutputVariable(opt::IRContext* ir_context, MessageConsumer message_consumer) { opt::Instruction* output_variable = nullptr; for (auto& inst : ir_context->types_values()) { - if (inst.opcode() == spv::Op::OpVariable && - spv::StorageClass(inst.GetSingleWordInOperand(0)) == - spv::StorageClass::Output) { + if (inst.opcode() == SpvOpVariable && + inst.GetSingleWordInOperand(0) == SpvStorageClassOutput) { if (output_variable != nullptr) { message_consumer(SPV_MSG_ERROR, nullptr, {}, "Only one output variable can be handled at present; " @@ -147,11 +144,10 @@ MakeConstantUniformReplacement(opt::IRContext* ir_context, uint32_t greater_than_instruction, uint32_t in_operand_index) { return MakeUnique( - MakeIdUseDescriptor( - constant_id, - MakeInstructionDescriptor(greater_than_instruction, - spv::Op::OpFOrdGreaterThan, 0), - in_operand_index), + MakeIdUseDescriptor(constant_id, + MakeInstructionDescriptor(greater_than_instruction, + SpvOpFOrdGreaterThan, 0), + in_operand_index), fact_manager.GetUniformDescriptorsForConstant(constant_id)[0], ir_context->TakeNextId(), ir_context->TakeNextId()); } @@ -208,21 +204,20 @@ bool ForceRenderRed( // Make the new exit block auto new_exit_block_id = ir_context->TakeNextId(); { - auto label = MakeUnique( - ir_context.get(), spv::Op::OpLabel, 0, new_exit_block_id, - opt::Instruction::OperandList()); + auto label = MakeUnique(ir_context.get(), SpvOpLabel, 0, + new_exit_block_id, + opt::Instruction::OperandList()); auto new_exit_block = MakeUnique(std::move(label)); - new_exit_block->AddInstruction( - MakeUnique(ir_context.get(), spv::Op::OpReturn, 0, 0, - opt::Instruction::OperandList())); + new_exit_block->AddInstruction(MakeUnique( + ir_context.get(), SpvOpReturn, 0, 0, opt::Instruction::OperandList())); entry_point_function->AddBasicBlock(std::move(new_exit_block)); } // Make the new entry block { - auto label = MakeUnique( - ir_context.get(), spv::Op::OpLabel, 0, ir_context->TakeNextId(), - opt::Instruction::OperandList()); + auto label = MakeUnique(ir_context.get(), SpvOpLabel, 0, + ir_context->TakeNextId(), + opt::Instruction::OperandList()); auto new_entry_block = MakeUnique(std::move(label)); // Make an instruction to construct vec4(1.0, 0.0, 0.0, 1.0), representing @@ -234,7 +229,7 @@ bool ForceRenderRed( auto temp_vec4 = opt::analysis::Vector(float_type, 4); auto vec4_id = ir_context->get_type_mgr()->GetId(&temp_vec4); auto red = MakeUnique( - ir_context.get(), spv::Op::OpCompositeConstruct, vec4_id, + ir_context.get(), SpvOpCompositeConstruct, vec4_id, ir_context->TakeNextId(), op_composite_construct_operands); auto red_id = red->result_id(); new_entry_block->AddInstruction(std::move(red)); @@ -246,7 +241,7 @@ bool ForceRenderRed( opt::Instruction::OperandList op_store_operands = {variable_to_store_into, value_to_be_stored}; new_entry_block->AddInstruction(MakeUnique( - ir_context.get(), spv::Op::OpStore, 0, 0, op_store_operands)); + ir_context.get(), SpvOpStore, 0, 0, op_store_operands)); // We are going to attempt to construct 'false' as an expression of the form // 'literal1 > literal2'. If we succeed, we will later replace each literal @@ -318,7 +313,7 @@ bool ForceRenderRed( {SPV_OPERAND_TYPE_ID, {smaller_constant}}, {SPV_OPERAND_TYPE_ID, {larger_constant}}}; new_entry_block->AddInstruction(MakeUnique( - ir_context.get(), spv::Op::OpFOrdGreaterThan, + ir_context.get(), SpvOpFOrdGreaterThan, ir_context->get_type_mgr()->GetId(registered_bool_type), id_guaranteed_to_be_false, greater_than_operands)); @@ -349,9 +344,9 @@ bool ForceRenderRed( opt::Operand else_block = {SPV_OPERAND_TYPE_ID, {new_exit_block_id}}; opt::Instruction::OperandList op_branch_conditional_operands = { false_condition, then_block, else_block}; - new_entry_block->AddInstruction(MakeUnique( - ir_context.get(), spv::Op::OpBranchConditional, 0, 0, - op_branch_conditional_operands)); + new_entry_block->AddInstruction( + MakeUnique(ir_context.get(), SpvOpBranchConditional, + 0, 0, op_branch_conditional_operands)); entry_point_function->InsertBasicBlockBefore( std::move(new_entry_block), entry_point_function->entry().get()); diff --git a/source/fuzz/fuzzer_pass.cpp b/source/fuzz/fuzzer_pass.cpp index 02d8aa1b..6a879851 100644 --- a/source/fuzz/fuzzer_pass.cpp +++ b/source/fuzz/fuzzer_pass.cpp @@ -131,15 +131,14 @@ void FuzzerPass::ForEachInstructionWithInstructionDescriptor( // should skip when searching from 'base' for the desired instruction. // (An instruction that has a result id is represented by its own opcode, // itself as 'base', and a skip-count of 0.) - std::vector> - base_opcode_skip_triples; + std::vector> base_opcode_skip_triples; // The initial base instruction is the block label. uint32_t base = block->id(); // Counts the number of times we have seen each opcode since we reset the // base instruction. - std::map skip_count; + std::map skip_count; // Consider every instruction in the block. The label is excluded: it is // only necessary to consider it as a base in case the first instruction @@ -152,7 +151,7 @@ void FuzzerPass::ForEachInstructionWithInstructionDescriptor( base = inst_it->result_id(); skip_count.clear(); } - const spv::Op opcode = inst_it->opcode(); + const SpvOp opcode = inst_it->opcode(); // Invoke the provided function, which might apply a transformation. action(block, inst_it, @@ -331,7 +330,7 @@ uint32_t FuzzerPass::FindOrCreateStructType( } uint32_t FuzzerPass::FindOrCreatePointerType(uint32_t base_type_id, - spv::StorageClass storage_class) { + SpvStorageClass storage_class) { // We do not use the type manager here, due to problems related to isomorphic // but distinct structs not being regarded as different. auto existing_id = fuzzerutil::MaybeGetPointerType( @@ -346,7 +345,7 @@ uint32_t FuzzerPass::FindOrCreatePointerType(uint32_t base_type_id, } uint32_t FuzzerPass::FindOrCreatePointerToIntegerType( - uint32_t width, bool is_signed, spv::StorageClass storage_class) { + uint32_t width, bool is_signed, SpvStorageClass storage_class) { return FindOrCreatePointerType(FindOrCreateIntegerType(width, is_signed), storage_class); } @@ -433,7 +432,7 @@ uint32_t FuzzerPass::FindOrCreateCompositeConstant( uint32_t FuzzerPass::FindOrCreateGlobalUndef(uint32_t type_id) { for (auto& inst : GetIRContext()->types_values()) { - if (inst.opcode() == spv::Op::OpUndef && inst.type_id() == type_id) { + if (inst.opcode() == SpvOpUndef && inst.type_id() == type_id) { return inst.result_id(); } } @@ -465,7 +464,7 @@ uint32_t FuzzerPass::FindOrCreateNullConstant(uint32_t type_id) { std::pair, std::map>> FuzzerPass::GetAvailableBasicTypesAndPointers( - spv::StorageClass storage_class) const { + SpvStorageClass storage_class) const { // Records all of the basic types available in the module. std::set basic_types; @@ -481,23 +480,23 @@ FuzzerPass::GetAvailableBasicTypesAndPointers( // For pointer types with basic pointee types, associate the pointer type // with the basic type. switch (inst.opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeMatrix: + case SpvOpTypeVector: // These are all basic types. basic_types.insert(inst.result_id()); basic_type_to_pointers.insert({inst.result_id(), {}}); break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: // An array type is basic if its base type is basic. if (basic_types.count(inst.GetSingleWordInOperand(0))) { basic_types.insert(inst.result_id()); basic_type_to_pointers.insert({inst.result_id(), {}}); } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // A struct type is basic if it does not have the Block/BufferBlock // decoration, and if all of its members are basic. if (!fuzzerutil::HasBlockOrBufferBlockDecoration(GetIRContext(), @@ -516,12 +515,11 @@ FuzzerPass::GetAvailableBasicTypesAndPointers( } break; } - case spv::Op::OpTypePointer: { + case SpvOpTypePointer: { // We are interested in the pointer if its pointee type is basic and it // has the right storage class. auto pointee_type = inst.GetSingleWordInOperand(1); - if (spv::StorageClass(inst.GetSingleWordInOperand(0)) == - storage_class && + if (inst.GetSingleWordInOperand(0) == storage_class && basic_types.count(pointee_type)) { // The pointer has the desired storage class, and its pointee type is // a basic type, so we are interested in it. Associate it with its @@ -543,22 +541,22 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant( GetIRContext()->get_def_use_mgr()->GetDef(scalar_or_composite_type_id); assert(type_instruction && "The type instruction must exist."); switch (type_instruction->opcode()) { - case spv::Op::OpTypeBool: + case SpvOpTypeBool: return FindOrCreateBoolConstant(false, is_irrelevant); - case spv::Op::OpTypeFloat: { + case SpvOpTypeFloat: { auto width = type_instruction->GetSingleWordInOperand(0); auto num_words = (width + 32 - 1) / 32; return FindOrCreateFloatConstant(std::vector(num_words, 0), width, is_irrelevant); } - case spv::Op::OpTypeInt: { + case SpvOpTypeInt: { auto width = type_instruction->GetSingleWordInOperand(0); auto num_words = (width + 32 - 1) / 32; return FindOrCreateIntegerConstant( std::vector(num_words, 0), width, type_instruction->GetSingleWordInOperand(1), is_irrelevant); } - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { auto component_type_id = type_instruction->GetSingleWordInOperand(0); auto num_components = fuzzerutil::GetArraySize(*type_instruction, GetIRContext()); @@ -568,8 +566,8 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant( FindOrCreateZeroConstant(component_type_id, is_irrelevant)), scalar_or_composite_type_id, is_irrelevant); } - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: { + case SpvOpTypeMatrix: + case SpvOpTypeVector: { auto component_type_id = type_instruction->GetSingleWordInOperand(0); auto num_components = type_instruction->GetSingleWordInOperand(1); return FindOrCreateCompositeConstant( @@ -578,7 +576,7 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant( FindOrCreateZeroConstant(component_type_id, is_irrelevant)), scalar_or_composite_type_id, is_irrelevant); } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { assert(!fuzzerutil::HasBlockOrBufferBlockDecoration( GetIRContext(), scalar_or_composite_type_id) && "We do not construct constants of struct types decorated with " @@ -648,7 +646,7 @@ opt::BasicBlock* FuzzerPass::GetOrCreateSimpleLoopPreheader( // |maybe_preheader| is a preheader if it branches unconditionally to // the header. We also require it not to be a loop header. - if (maybe_preheader->terminator()->opcode() == spv::Op::OpBranch && + if (maybe_preheader->terminator()->opcode() == SpvOpBranch && !maybe_preheader->IsLoopHeader()) { return maybe_preheader; } @@ -685,8 +683,8 @@ opt::BasicBlock* FuzzerPass::SplitBlockAfterOpPhiOrOpVariable( // Find the first non-OpPhi and non-OpVariable instruction. auto non_phi_or_var_inst = &*block->begin(); - while (non_phi_or_var_inst->opcode() == spv::Op::OpPhi || - non_phi_or_var_inst->opcode() == spv::Op::OpVariable) { + while (non_phi_or_var_inst->opcode() == SpvOpPhi || + non_phi_or_var_inst->opcode() == SpvOpVariable) { non_phi_or_var_inst = non_phi_or_var_inst->NextNode(); } @@ -708,7 +706,7 @@ uint32_t FuzzerPass::FindOrCreateLocalVariable( (void)pointer_type; assert(pointer_type && pointer_type->AsPointer() && pointer_type->AsPointer()->storage_class() == - spv::StorageClass::Function && + SpvStorageClassFunction && "The pointer_type_id must refer to a defined pointer type with " "storage class Function"); auto function = fuzzerutil::FindFunction(GetIRContext(), function_id); @@ -717,7 +715,7 @@ uint32_t FuzzerPass::FindOrCreateLocalVariable( // First we try to find a suitable existing variable. // All of the local variable declarations are located in the first block. for (auto& instruction : *function->begin()) { - if (instruction.opcode() != spv::Op::OpVariable) { + if (instruction.opcode() != SpvOpVariable) { continue; } // The existing OpVariable must have type |pointer_type_id|. @@ -751,16 +749,15 @@ uint32_t FuzzerPass::FindOrCreateGlobalVariable( (void)pointer_type; assert( pointer_type && pointer_type->AsPointer() && - (pointer_type->AsPointer()->storage_class() == - spv::StorageClass::Private || + (pointer_type->AsPointer()->storage_class() == SpvStorageClassPrivate || pointer_type->AsPointer()->storage_class() == - spv::StorageClass::Workgroup) && + SpvStorageClassWorkgroup) && "The pointer_type_id must refer to a defined pointer type with storage " "class Private or Workgroup"); // First we try to find a suitable existing variable. for (auto& instruction : GetIRContext()->module()->types_values()) { - if (instruction.opcode() != spv::Op::OpVariable) { + if (instruction.opcode() != SpvOpVariable) { continue; } // The existing OpVariable must have type |pointer_type_id|. @@ -784,13 +781,13 @@ uint32_t FuzzerPass::FindOrCreateGlobalVariable( uint32_t result_id = GetFuzzerContext()->GetFreshId(); // A variable with storage class Workgroup shouldn't have an initializer. - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { ApplyTransformation(TransformationAddGlobalVariable( - result_id, pointer_type_id, spv::StorageClass::Workgroup, 0, + result_id, pointer_type_id, SpvStorageClassWorkgroup, 0, pointee_value_is_irrelevant)); } else { ApplyTransformation(TransformationAddGlobalVariable( - result_id, pointer_type_id, spv::StorageClass::Private, + result_id, pointer_type_id, SpvStorageClassPrivate, FindOrCreateZeroConstant(pointee_type_id, pointee_value_is_irrelevant), pointee_value_is_irrelevant)); } diff --git a/source/fuzz/fuzzer_pass.h b/source/fuzz/fuzzer_pass.h index 5c76be1b..2655b540 100644 --- a/source/fuzz/fuzzer_pass.h +++ b/source/fuzz/fuzzer_pass.h @@ -159,14 +159,14 @@ class FuzzerPass { // already exist) and storage class |storage_class|. A transformation is // applied to add the pointer if it does not already exist. uint32_t FindOrCreatePointerType(uint32_t base_type_id, - spv::StorageClass storage_class); + SpvStorageClass storage_class); // Returns the id of an OpTypePointer instruction, with a integer base // type of width and signedness specified by |width| and |is_signed|, // respectively. If the pointer type or required integer base type do not // exist, transformations are applied to add them. uint32_t FindOrCreatePointerToIntegerType(uint32_t width, bool is_signed, - spv::StorageClass storage_class); + SpvStorageClass storage_class); // Returns the id of an OpConstant instruction, with a integer type of // width and signedness specified by |width| and |is_signed|, respectively, @@ -239,7 +239,7 @@ class FuzzerPass { // storage class, and the sequence will have multiple elements if there are // repeated pointer declarations for the same basic type and storage class. std::pair, std::map>> - GetAvailableBasicTypesAndPointers(spv::StorageClass storage_class) const; + GetAvailableBasicTypesAndPointers(SpvStorageClass storage_class) const; // Given a type id, |scalar_or_composite_type_id|, which must correspond to // some scalar or composite type, returns the result id of an instruction diff --git a/source/fuzz/fuzzer_pass_add_access_chains.cpp b/source/fuzz/fuzzer_pass_add_access_chains.cpp index 85ca57dc..39f193d9 100644 --- a/source/fuzz/fuzzer_pass_add_access_chains.cpp +++ b/source/fuzz/fuzzer_pass_add_access_chains.cpp @@ -34,16 +34,15 @@ void FuzzerPassAddAccessChains::Apply() { opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - inst_it->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(inst_it->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Check whether it is legitimate to insert an access chain // instruction before this instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpAccessChain, inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAccessChain, + inst_it)) { return; } @@ -65,8 +64,8 @@ void FuzzerPassAddAccessChains::Apply() { return false; } switch (instruction->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: // Do not allow making an access chain from a null or // undefined pointer. (We can eliminate these cases // before actually checking that the instruction is a @@ -79,7 +78,7 @@ void FuzzerPassAddAccessChains::Apply() { // make an access chain from it. return context->get_def_use_mgr() ->GetDef(instruction->type_id()) - ->opcode() == spv::Op::OpTypePointer; + ->opcode() == SpvOpTypePointer; }); // At this point, |relevant_instructions| contains all the pointers @@ -113,14 +112,14 @@ void FuzzerPassAddAccessChains::Apply() { } uint32_t bound; switch (subobject_type->opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: bound = fuzzerutil::GetArraySize(*subobject_type, GetIRContext()); break; - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: bound = subobject_type->GetSingleWordInOperand(1); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: bound = fuzzerutil::GetNumberOfStructMembers(*subobject_type); break; default: @@ -141,9 +140,9 @@ void FuzzerPassAddAccessChains::Apply() { GetFuzzerContext()->GetRandomIndexForAccessChain(bound); switch (subobject_type->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: { + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeVector: { // The index will be clamped bool is_signed = GetFuzzerContext()->ChooseEven(); @@ -165,7 +164,7 @@ void FuzzerPassAddAccessChains::Apply() { subobject_type_id = subobject_type->GetSingleWordInOperand(0); } break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: index_ids.push_back(FindOrCreateIntegerConstant( {index_value}, 32, GetFuzzerContext()->ChooseEven(), false)); subobject_type_id = @@ -179,7 +178,7 @@ void FuzzerPassAddAccessChains::Apply() { // pointer suitable for the access chain's result type exists, so we // create one if it does not. FindOrCreatePointerType(subobject_type_id, - static_cast( + static_cast( pointer_type->GetSingleWordInOperand(0))); // Apply the transformation to add an access chain. ApplyTransformation(TransformationAccessChain( diff --git a/source/fuzz/fuzzer_pass_add_composite_extract.cpp b/source/fuzz/fuzzer_pass_add_composite_extract.cpp index c33ae44c..dbbec0ca 100644 --- a/source/fuzz/fuzzer_pass_add_composite_extract.cpp +++ b/source/fuzz/fuzzer_pass_add_composite_extract.cpp @@ -53,8 +53,8 @@ void FuzzerPassAddCompositeExtract::Apply() { opt::Function* /*unused*/, opt::BasicBlock* /*unused*/, opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) { - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeExtract, inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract, + inst_it)) { return; } @@ -97,15 +97,15 @@ void FuzzerPassAddCompositeExtract::Apply() { assert(type_inst && "Composite instruction has invalid type id"); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: number_of_members = fuzzerutil::GetArraySize(*type_inst, GetIRContext()); break; - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeVector: + case SpvOpTypeMatrix: number_of_members = type_inst->GetSingleWordInOperand(1); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: number_of_members = type_inst->NumInOperands(); break; default: @@ -122,12 +122,12 @@ void FuzzerPassAddCompositeExtract::Apply() { number_of_members)); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: type_id = type_inst->GetSingleWordInOperand(indices.back()); break; default: diff --git a/source/fuzz/fuzzer_pass_add_composite_inserts.cpp b/source/fuzz/fuzzer_pass_add_composite_inserts.cpp index 048cdfde..2ac12de4 100644 --- a/source/fuzz/fuzzer_pass_add_composite_inserts.cpp +++ b/source/fuzz/fuzzer_pass_add_composite_inserts.cpp @@ -36,11 +36,10 @@ void FuzzerPassAddCompositeInserts::Apply() { opt::BasicBlock::iterator instruction_iterator, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - instruction_iterator->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(instruction_iterator->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Randomly decide whether to try adding an OpCompositeInsert // instruction. @@ -52,7 +51,7 @@ void FuzzerPassAddCompositeInserts::Apply() { // It must be possible to insert an OpCompositeInsert instruction // before |instruction_iterator|. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeInsert, instruction_iterator)) { + SpvOpCompositeInsert, instruction_iterator)) { return; } diff --git a/source/fuzz/fuzzer_pass_add_composite_types.cpp b/source/fuzz/fuzzer_pass_add_composite_types.cpp index bb909913..af36ad06 100644 --- a/source/fuzz/fuzzer_pass_add_composite_types.cpp +++ b/source/fuzz/fuzzer_pass_add_composite_types.cpp @@ -114,15 +114,15 @@ uint32_t FuzzerPassAddCompositeTypes::ChooseScalarOrCompositeType() { std::vector candidates; for (auto& inst : GetIRContext()->types_values()) { switch (inst.opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeMatrix: + case SpvOpTypeVector: candidates.push_back(inst.result_id()); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { if (!fuzzerutil::MembersHaveBuiltInDecoration(GetIRContext(), inst.result_id()) && !fuzzerutil::HasBlockOrBufferBlockDecoration(GetIRContext(), diff --git a/source/fuzz/fuzzer_pass_add_copy_memory.cpp b/source/fuzz/fuzzer_pass_add_copy_memory.cpp index d54d4ad8..6551f49f 100644 --- a/source/fuzz/fuzzer_pass_add_copy_memory.cpp +++ b/source/fuzz/fuzzer_pass_add_copy_memory.cpp @@ -36,7 +36,7 @@ void FuzzerPassAddCopyMemory::Apply() { opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) { // Check that we can insert an OpCopyMemory before this instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyMemory, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyMemory, inst_it)) { return; } @@ -61,8 +61,8 @@ void FuzzerPassAddCopyMemory::Apply() { // Decide whether to create global or local variable. auto storage_class = GetFuzzerContext()->ChooseEven() - ? spv::StorageClass::Private - : spv::StorageClass::Function; + ? SpvStorageClassPrivate + : SpvStorageClassFunction; auto pointee_type_id = fuzzerutil::GetPointeeTypeIdFromPointerType( GetIRContext(), inst->type_id()); diff --git a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp index e720c4ec..4bbded8e 100644 --- a/source/fuzz/fuzzer_pass_add_equation_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_equation_instructions.cpp @@ -29,14 +29,12 @@ bool IsBitWidthSupported(opt::IRContext* ir_context, uint32_t bit_width) { return true; case 64: return ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Float64) && - ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Int64); + SpvCapabilityFloat64) && + ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt64); case 16: return ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Float16) && - ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Int16); + SpvCapabilityFloat16) && + ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt16); default: return false; } @@ -68,8 +66,7 @@ void FuzzerPassAddEquationInstructions::Apply() { // as an example opcode for this check, to be representative of *some* // opcode that defines an equation, even though we may choose a // different opcode below. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpIAdd, - inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, inst_it)) { return; } @@ -81,7 +78,7 @@ void FuzzerPassAddEquationInstructions::Apply() { [this](opt::IRContext* /*unused*/, opt::Instruction* instruction) -> bool { return instruction->result_id() && instruction->type_id() && - instruction->opcode() != spv::Op::OpUndef && + instruction->opcode() != SpvOpUndef && !GetTransformationContext() ->GetFactManager() ->IdIsIrrelevant(instruction->result_id()); @@ -89,16 +86,15 @@ void FuzzerPassAddEquationInstructions::Apply() { // Try the opcodes for which we know how to make ids at random until // something works. - std::vector candidate_opcodes = { - spv::Op::OpIAdd, spv::Op::OpISub, spv::Op::OpLogicalNot, - spv::Op::OpSNegate, spv::Op::OpConvertUToF, spv::Op::OpConvertSToF, - spv::Op::OpBitcast}; + std::vector candidate_opcodes = { + SpvOpIAdd, SpvOpISub, SpvOpLogicalNot, SpvOpSNegate, + SpvOpConvertUToF, SpvOpConvertSToF, SpvOpBitcast}; do { auto opcode = GetFuzzerContext()->RemoveAtRandomIndex(&candidate_opcodes); switch (opcode) { - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: { + case SpvOpConvertSToF: + case SpvOpConvertUToF: { std::vector candidate_instructions; for (const auto* inst : GetIntegerInstructions(available_instructions)) { @@ -148,7 +144,7 @@ void FuzzerPassAddEquationInstructions::Apply() { {operand->result_id()}, instruction_descriptor)); return; } - case spv::Op::OpBitcast: { + case SpvOpBitcast: { const auto candidate_instructions = GetNumericalInstructions(available_instructions); @@ -201,8 +197,8 @@ void FuzzerPassAddEquationInstructions::Apply() { return; } } break; - case spv::Op::OpIAdd: - case spv::Op::OpISub: { + case SpvOpIAdd: + case SpvOpISub: { // Instructions of integer (scalar or vector) result type are // suitable for these opcodes. auto integer_instructions = @@ -255,7 +251,7 @@ void FuzzerPassAddEquationInstructions::Apply() { } break; } - case spv::Op::OpLogicalNot: { + case SpvOpLogicalNot: { // Choose any available instruction of boolean scalar/vector // result type and equate its negation with a fresh id. auto boolean_instructions = @@ -272,7 +268,7 @@ void FuzzerPassAddEquationInstructions::Apply() { } break; } - case spv::Op::OpSNegate: { + case SpvOpSNegate: { // Similar to OpLogicalNot, but for signed integer negation. auto integer_instructions = GetIntegerInstructions(available_instructions); diff --git a/source/fuzz/fuzzer_pass_add_function_calls.cpp b/source/fuzz/fuzzer_pass_add_function_calls.cpp index 70b86573..033f4a27 100644 --- a/source/fuzz/fuzzer_pass_add_function_calls.cpp +++ b/source/fuzz/fuzzer_pass_add_function_calls.cpp @@ -39,8 +39,8 @@ void FuzzerPassAddFunctionCalls::Apply() { -> void { // Check whether it is legitimate to insert a function call before the // instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpFunctionCall, inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpFunctionCall, + inst_it)) { return; } @@ -112,8 +112,8 @@ std::vector FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments( auto available_pointers = FindAvailableInstructions( caller_function, caller_block, caller_inst_it, [this, caller_block](opt::IRContext* /*unused*/, opt::Instruction* inst) { - if (inst->opcode() != spv::Op::OpVariable || - inst->opcode() != spv::Op::OpFunctionParameter) { + if (inst->opcode() != SpvOpVariable || + inst->opcode() != SpvOpFunctionParameter) { // Function parameters and variables are the only // kinds of pointer that can be used as actual // parameters. @@ -172,15 +172,15 @@ std::vector FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments( auto storage_class = param_type->AsPointer()->storage_class(); auto pointee_type_id = fuzzerutil::GetPointeeTypeIdFromPointerType( GetIRContext(), param->type_id()); - if (storage_class == spv::StorageClass::Function) { + if (storage_class == SpvStorageClassFunction) { // Add a new zero-initialized local variable to the current // function, noting that its pointee value is irrelevant. ApplyTransformation(TransformationAddLocalVariable( fresh_variable_id, param->type_id(), caller_function->result_id(), FindOrCreateZeroConstant(pointee_type_id, false), true)); } else { - assert((storage_class == spv::StorageClass::Private || - storage_class == spv::StorageClass::Workgroup) && + assert((storage_class == SpvStorageClassPrivate || + storage_class == SpvStorageClassWorkgroup) && "Only Function, Private and Workgroup storage classes are " "supported at present."); // Add a new global variable to the module, zero-initializing it if @@ -188,7 +188,7 @@ std::vector FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments( // irrelevant. ApplyTransformation(TransformationAddGlobalVariable( fresh_variable_id, param->type_id(), storage_class, - storage_class == spv::StorageClass::Private + storage_class == SpvStorageClassPrivate ? FindOrCreateZeroConstant(pointee_type_id, false) : 0, true)); diff --git a/source/fuzz/fuzzer_pass_add_global_variables.cpp b/source/fuzz/fuzzer_pass_add_global_variables.cpp index 41068565..061f44d0 100644 --- a/source/fuzz/fuzzer_pass_add_global_variables.cpp +++ b/source/fuzz/fuzzer_pass_add_global_variables.cpp @@ -29,17 +29,16 @@ FuzzerPassAddGlobalVariables::FuzzerPassAddGlobalVariables( transformations, ignore_inapplicable_transformations) {} void FuzzerPassAddGlobalVariables::Apply() { - spv::StorageClass variable_storage_class = spv::StorageClass::Private; + SpvStorageClass variable_storage_class = SpvStorageClassPrivate; for (auto& entry_point : GetIRContext()->module()->entry_points()) { // If the execution model of some entry point is GLCompute, // then the variable storage class may be Workgroup. - if (spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) == - spv::ExecutionModel::GLCompute) { + if (entry_point.GetSingleWordInOperand(0) == SpvExecutionModelGLCompute) { variable_storage_class = GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfChoosingWorkgroupStorageClass()) - ? spv::StorageClass::Workgroup - : spv::StorageClass::Private; + ? SpvStorageClassWorkgroup + : SpvStorageClassPrivate; break; } } @@ -88,7 +87,7 @@ void FuzzerPassAddGlobalVariables::Apply() { ApplyTransformation(TransformationAddGlobalVariable( GetFuzzerContext()->GetFreshId(), pointer_type_id, variable_storage_class, - variable_storage_class == spv::StorageClass::Private + variable_storage_class == SpvStorageClassPrivate ? FindOrCreateZeroConstant(basic_type, false) : 0, true)); diff --git a/source/fuzz/fuzzer_pass_add_loads.cpp b/source/fuzz/fuzzer_pass_add_loads.cpp index 36603284..ab91543b 100644 --- a/source/fuzz/fuzzer_pass_add_loads.cpp +++ b/source/fuzz/fuzzer_pass_add_loads.cpp @@ -34,11 +34,10 @@ void FuzzerPassAddLoads::Apply() { opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - inst_it->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(inst_it->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Randomly decide whether to try inserting a load here. if (!GetFuzzerContext()->ChoosePercentage( @@ -48,11 +47,10 @@ void FuzzerPassAddLoads::Apply() { // Check whether it is legitimate to insert a load or atomic load before // this instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, - inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, inst_it)) { return; } - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpAtomicLoad, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAtomicLoad, inst_it)) { return; } @@ -66,8 +64,8 @@ void FuzzerPassAddLoads::Apply() { return false; } switch (instruction->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: // Do not allow loading from a null or undefined pointer; // this might be OK if the block is dead, but for now we // conservatively avoid it. @@ -77,7 +75,7 @@ void FuzzerPassAddLoads::Apply() { } return context->get_def_use_mgr() ->GetDef(instruction->type_id()) - ->opcode() == spv::Op::OpTypePointer; + ->opcode() == SpvOpTypePointer; }); // At this point, |relevant_instructions| contains all the pointers @@ -94,25 +92,25 @@ void FuzzerPassAddLoads::Apply() { uint32_t memory_scope_id = 0; uint32_t memory_semantics_id = 0; - auto storage_class = static_cast( + auto storage_class = static_cast( GetIRContext() ->get_def_use_mgr() ->GetDef(chosen_instruction->type_id()) ->GetSingleWordInOperand(0)); switch (storage_class) { - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - case spv::StorageClass::Workgroup: - case spv::StorageClass::CrossWorkgroup: - case spv::StorageClass::AtomicCounter: - case spv::StorageClass::Image: + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassWorkgroup: + case SpvStorageClassCrossWorkgroup: + case SpvStorageClassAtomicCounter: + case SpvStorageClassImage: if (GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfAddingAtomicLoad())) { is_atomic_load = true; memory_scope_id = FindOrCreateConstant( - {uint32_t(spv::Scope::Invocation)}, + {SpvScopeInvocation}, FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()), false); diff --git a/source/fuzz/fuzzer_pass_add_local_variables.cpp b/source/fuzz/fuzzer_pass_add_local_variables.cpp index f467f46b..a4e739f8 100644 --- a/source/fuzz/fuzzer_pass_add_local_variables.cpp +++ b/source/fuzz/fuzzer_pass_add_local_variables.cpp @@ -31,7 +31,7 @@ FuzzerPassAddLocalVariables::FuzzerPassAddLocalVariables( void FuzzerPassAddLocalVariables::Apply() { auto basic_type_ids_and_pointers = - GetAvailableBasicTypesAndPointers(spv::StorageClass::Function); + GetAvailableBasicTypesAndPointers(SpvStorageClassFunction); // These are the basic types that are available to this fuzzer pass. auto& basic_types = basic_type_ids_and_pointers.first; @@ -64,7 +64,7 @@ void FuzzerPassAddLocalVariables::Apply() { // use it. pointer_type = GetFuzzerContext()->GetFreshId(); ApplyTransformation(TransformationAddTypePointer( - pointer_type, spv::StorageClass::Function, basic_type)); + pointer_type, SpvStorageClassFunction, basic_type)); available_pointers_to_basic_type.push_back(pointer_type); } else { // There is - grab one. diff --git a/source/fuzz/fuzzer_pass_add_opphi_synonyms.cpp b/source/fuzz/fuzzer_pass_add_opphi_synonyms.cpp index d0b1275b..73b6b0ac 100644 --- a/source/fuzz/fuzzer_pass_add_opphi_synonyms.cpp +++ b/source/fuzz/fuzzer_pass_add_opphi_synonyms.cpp @@ -176,8 +176,8 @@ FuzzerPassAddOpPhiSynonyms::GetIdEquivalenceClasses() { // - OpFunction does not yield a value; // - OpUndef yields an undefined value at each use, so it should never be a // synonym of another id. - if (pair.second->opcode() == spv::Op::OpFunction || - pair.second->opcode() == spv::Op::OpUndef) { + if (pair.second->opcode() == SpvOpFunction || + pair.second->opcode() == SpvOpUndef) { continue; } diff --git a/source/fuzz/fuzzer_pass_add_parameters.cpp b/source/fuzz/fuzzer_pass_add_parameters.cpp index e663d89b..1cb6a79d 100644 --- a/source/fuzz/fuzzer_pass_add_parameters.cpp +++ b/source/fuzz/fuzzer_pass_add_parameters.cpp @@ -79,7 +79,7 @@ void FuzzerPassAddParameters::Apply() { auto storage_class = fuzzerutil::GetStorageClassFromPointerType( GetIRContext(), current_type_id); switch (storage_class) { - case spv::StorageClass::Function: { + case SpvStorageClassFunction: { // In every caller find or create a local variable that has the // selected type. for (auto* instr : @@ -91,8 +91,8 @@ void FuzzerPassAddParameters::Apply() { call_parameter_ids[instr->result_id()] = variable_id; } } break; - case spv::StorageClass::Private: - case spv::StorageClass::Workgroup: { + case SpvStorageClassPrivate: + case SpvStorageClassWorkgroup: { // If there exists at least one caller, find or create a global // variable that has the selected type. std::vector callers = diff --git a/source/fuzz/fuzzer_pass_add_stores.cpp b/source/fuzz/fuzzer_pass_add_stores.cpp index 0de02a5b..606e4a63 100644 --- a/source/fuzz/fuzzer_pass_add_stores.cpp +++ b/source/fuzz/fuzzer_pass_add_stores.cpp @@ -34,11 +34,10 @@ void FuzzerPassAddStores::Apply() { opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - inst_it->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(inst_it->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Randomly decide whether to try inserting a store here. if (!GetFuzzerContext()->ChoosePercentage( @@ -48,12 +47,12 @@ void FuzzerPassAddStores::Apply() { // Check whether it is legitimate to insert a store before this // instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpStore, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore, inst_it)) { return; } - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpAtomicStore, inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAtomicStore, + inst_it)) { return; } @@ -68,7 +67,7 @@ void FuzzerPassAddStores::Apply() { } auto type_inst = context->get_def_use_mgr()->GetDef( instruction->type_id()); - if (type_inst->opcode() != spv::Op::OpTypePointer) { + if (type_inst->opcode() != SpvOpTypePointer) { // Not a pointer. return false; } @@ -77,8 +76,8 @@ void FuzzerPassAddStores::Apply() { return false; } switch (instruction->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: // Do not allow storing to a null or undefined pointer; // this might be OK if the block is dead, but for now we // conservatively avoid it. @@ -127,24 +126,24 @@ void FuzzerPassAddStores::Apply() { uint32_t memory_semantics_id = 0; auto storage_class = - static_cast(GetIRContext() - ->get_def_use_mgr() - ->GetDef(pointer->type_id()) - ->GetSingleWordInOperand(0)); + static_cast(GetIRContext() + ->get_def_use_mgr() + ->GetDef(pointer->type_id()) + ->GetSingleWordInOperand(0)); switch (storage_class) { - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - case spv::StorageClass::Workgroup: - case spv::StorageClass::CrossWorkgroup: - case spv::StorageClass::AtomicCounter: - case spv::StorageClass::Image: + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassWorkgroup: + case SpvStorageClassCrossWorkgroup: + case SpvStorageClassAtomicCounter: + case SpvStorageClassImage: if (GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfAddingAtomicStore())) { is_atomic_store = true; memory_scope_id = FindOrCreateConstant( - {uint32_t(spv::Scope::Invocation)}, + {SpvScopeInvocation}, FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()), false); diff --git a/source/fuzz/fuzzer_pass_add_synonyms.cpp b/source/fuzz/fuzzer_pass_add_synonyms.cpp index 5782732c..1d188deb 100644 --- a/source/fuzz/fuzzer_pass_add_synonyms.cpp +++ b/source/fuzz/fuzzer_pass_add_synonyms.cpp @@ -44,8 +44,7 @@ void FuzzerPassAddSynonyms::Apply() { // Skip |inst_it| if we can't insert anything above it. OpIAdd is just // a representative of some instruction that might be produced by the // transformation. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpIAdd, - inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, inst_it)) { return; } diff --git a/source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.cpp b/source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.cpp index 4cddf55e..a29d1d34 100644 --- a/source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.cpp +++ b/source/fuzz/fuzzer_pass_add_vector_shuffle_instructions.cpp @@ -35,11 +35,10 @@ void FuzzerPassAddVectorShuffleInstructions::Apply() { opt::BasicBlock::iterator instruction_iterator, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - instruction_iterator->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(instruction_iterator->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Randomly decide whether to try adding an OpVectorShuffle instruction. if (!GetFuzzerContext()->ChoosePercentage( @@ -50,7 +49,7 @@ void FuzzerPassAddVectorShuffleInstructions::Apply() { // It must be valid to insert an OpVectorShuffle instruction // before |instruction_iterator|. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpVectorShuffle, instruction_iterator)) { + SpvOpVectorShuffle, instruction_iterator)) { return; } diff --git a/source/fuzz/fuzzer_pass_adjust_branch_weights.cpp b/source/fuzz/fuzzer_pass_adjust_branch_weights.cpp index 6bf46e1b..94428f72 100644 --- a/source/fuzz/fuzzer_pass_adjust_branch_weights.cpp +++ b/source/fuzz/fuzzer_pass_adjust_branch_weights.cpp @@ -33,7 +33,7 @@ void FuzzerPassAdjustBranchWeights::Apply() { // For all OpBranchConditional instructions, // randomly applies the transformation. GetIRContext()->module()->ForEachInst([this](opt::Instruction* instruction) { - if (instruction->opcode() == spv::Op::OpBranchConditional && + if (instruction->opcode() == SpvOpBranchConditional && GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfAdjustingBranchWeights())) { ApplyTransformation(TransformationAdjustBranchWeights( diff --git a/source/fuzz/fuzzer_pass_adjust_function_controls.cpp b/source/fuzz/fuzzer_pass_adjust_function_controls.cpp index 363edc70..1c2bc8cf 100644 --- a/source/fuzz/fuzzer_pass_adjust_function_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_function_controls.cpp @@ -40,21 +40,21 @@ void FuzzerPassAdjustFunctionControls::Apply() { // For the new mask, we first randomly select one of three basic masks: // None, Inline or DontInline. These are always valid (and are mutually // exclusive). - std::vector basic_function_control_masks = { - spv::FunctionControlMask::MaskNone, spv::FunctionControlMask::Inline, - spv::FunctionControlMask::DontInline}; + std::vector basic_function_control_masks = { + SpvFunctionControlMaskNone, SpvFunctionControlInlineMask, + SpvFunctionControlDontInlineMask}; uint32_t new_function_control_mask = - uint32_t(basic_function_control_masks[GetFuzzerContext()->RandomIndex( - basic_function_control_masks)]); + basic_function_control_masks[GetFuzzerContext()->RandomIndex( + basic_function_control_masks)]; // We now consider the Pure and Const mask bits. If these are already // set on the function then it's OK to keep them, but also interesting // to consider dropping them, so we decide randomly in each case. for (auto mask_bit : - {spv::FunctionControlMask::Pure, spv::FunctionControlMask::Const}) { - if ((existing_function_control_mask & uint32_t(mask_bit)) && + {SpvFunctionControlPureMask, SpvFunctionControlConstMask}) { + if ((existing_function_control_mask & mask_bit) && GetFuzzerContext()->ChooseEven()) { - new_function_control_mask |= uint32_t(mask_bit); + new_function_control_mask |= mask_bit; } } diff --git a/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp b/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp index 53dbe540..fe855cad 100644 --- a/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_loop_controls.cpp @@ -34,7 +34,7 @@ void FuzzerPassAdjustLoopControls::Apply() { for (auto& block : function) { if (auto merge_inst = block.GetMergeInst()) { // Ignore the instruction if it is not a loop merge. - if (merge_inst->opcode() != spv::Op::OpLoopMerge) { + if (merge_inst->opcode() != SpvOpLoopMerge) { continue; } @@ -48,10 +48,9 @@ void FuzzerPassAdjustLoopControls::Apply() { TransformationSetLoopControl::kLoopControlMaskInOperandIndex); // First, set the new mask to one of None, Unroll or DontUnroll. - std::vector basic_masks = { - uint32_t(spv::LoopControlMask::MaskNone), - uint32_t(spv::LoopControlMask::Unroll), - uint32_t(spv::LoopControlMask::DontUnroll)}; + std::vector basic_masks = {SpvLoopControlMaskNone, + SpvLoopControlUnrollMask, + SpvLoopControlDontUnrollMask}; uint32_t new_mask = basic_masks[GetFuzzerContext()->RandomIndex(basic_masks)]; @@ -59,20 +58,19 @@ void FuzzerPassAdjustLoopControls::Apply() { // does, check which of these were present in the existing mask and // randomly decide whether to keep them. They are just hints, so // removing them should not change the semantics of the module. - for (auto mask_bit : {spv::LoopControlMask::DependencyInfinite, - spv::LoopControlMask::DependencyLength, - spv::LoopControlMask::MinIterations, - spv::LoopControlMask::MaxIterations, - spv::LoopControlMask::IterationMultiple}) { - if ((existing_mask & uint32_t(mask_bit)) && - GetFuzzerContext()->ChooseEven()) { + for (auto mask_bit : + {SpvLoopControlDependencyInfiniteMask, + SpvLoopControlDependencyLengthMask, + SpvLoopControlMinIterationsMask, SpvLoopControlMaxIterationsMask, + SpvLoopControlIterationMultipleMask}) { + if ((existing_mask & mask_bit) && GetFuzzerContext()->ChooseEven()) { // The mask bits we are considering are not available in all SPIR-V // versions. However, we only include a mask bit if it was present // in the original loop control mask, and we work under the // assumption that we are transforming a valid module, thus we don't // need to actually check whether the SPIR-V version being used // supports these loop control mask bits. - new_mask |= uint32_t(mask_bit); + new_mask |= mask_bit; } } @@ -83,14 +81,14 @@ void FuzzerPassAdjustLoopControls::Apply() { // PeelCount and PartialCount are not compatible with DontUnroll, so // we check whether DontUnroll is set. - if (!(new_mask & uint32_t(spv::LoopControlMask::DontUnroll))) { + if (!(new_mask & SpvLoopControlDontUnrollMask)) { // If PeelCount is supported by this SPIR-V version, randomly choose // whether to set it. If it was set in the original mask and is not // selected for setting here, that amounts to dropping it. if (TransformationSetLoopControl::PeelCountIsSupported( GetIRContext()) && GetFuzzerContext()->ChooseEven()) { - new_mask |= uint32_t(spv::LoopControlMask::PeelCount); + new_mask |= SpvLoopControlPeelCountMask; // The peel count is chosen randomly - if PeelCount was already set // this will overwrite whatever peel count was previously used. peel_count = GetFuzzerContext()->GetRandomLoopControlPeelCount(); @@ -99,7 +97,7 @@ void FuzzerPassAdjustLoopControls::Apply() { if (TransformationSetLoopControl::PartialCountIsSupported( GetIRContext()) && GetFuzzerContext()->ChooseEven()) { - new_mask |= uint32_t(spv::LoopControlMask::PartialCount); + new_mask |= SpvLoopControlPartialCountMask; partial_count = GetFuzzerContext()->GetRandomLoopControlPartialCount(); } diff --git a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp index efae7d66..d2ff40e6 100644 --- a/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp +++ b/source/fuzz/fuzzer_pass_adjust_memory_operands_masks.cpp @@ -47,8 +47,8 @@ void FuzzerPassAdjustMemoryOperandsMasks::Apply() { // From SPIR-V 1.4 onwards, OpCopyMemory and OpCopyMemorySized have a // second mask. switch (inst_it->opcode()) { - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: if (TransformationSetMemoryOperandsMask:: MultipleMemoryOperandMasksAreSupported(GetIRContext())) { indices_of_available_masks_to_adjust.push_back(1); @@ -75,26 +75,24 @@ void FuzzerPassAdjustMemoryOperandsMasks::Apply() { existing_mask_in_operand_index < inst_it->NumInOperands() ? inst_it->GetSingleWordInOperand( existing_mask_in_operand_index) - : static_cast(spv::MemoryAccessMask::MaskNone); + : static_cast(SpvMemoryAccessMaskNone); // There are two things we can do to a mask: // - add Volatile if not already present // - toggle Nontemporal // The following ensures that we do at least one of these - bool add_volatile = - !(existing_mask & uint32_t(spv::MemoryAccessMask::Volatile)) && - GetFuzzerContext()->ChooseEven(); + bool add_volatile = !(existing_mask & SpvMemoryAccessVolatileMask) && + GetFuzzerContext()->ChooseEven(); bool toggle_nontemporal = !add_volatile || GetFuzzerContext()->ChooseEven(); // These bitwise operations use '|' to add Volatile if desired, and // '^' to toggle Nontemporal if desired. uint32_t new_mask = - (existing_mask | - (add_volatile ? uint32_t(spv::MemoryAccessMask::Volatile) - : uint32_t(spv::MemoryAccessMask::MaskNone))) ^ - (toggle_nontemporal ? uint32_t(spv::MemoryAccessMask::Nontemporal) - : uint32_t(spv::MemoryAccessMask::MaskNone)); + (existing_mask | (add_volatile ? SpvMemoryAccessVolatileMask + : SpvMemoryAccessMaskNone)) ^ + (toggle_nontemporal ? SpvMemoryAccessNontemporalMask + : SpvMemoryAccessMaskNone); TransformationSetMemoryOperandsMask transformation( MakeInstructionDescriptor(block, inst_it), new_mask, mask_index); diff --git a/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp b/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp index fe0cf7af..7d8e6b57 100644 --- a/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp +++ b/source/fuzz/fuzzer_pass_adjust_selection_controls.cpp @@ -34,7 +34,7 @@ void FuzzerPassAdjustSelectionControls::Apply() { for (auto& block : function) { if (auto merge_inst = block.GetMergeInst()) { // Ignore the instruction if it is not a selection merge. - if (merge_inst->opcode() != spv::Op::OpSelectionMerge) { + if (merge_inst->opcode() != SpvOpSelectionMerge) { continue; } @@ -48,14 +48,13 @@ void FuzzerPassAdjustSelectionControls::Apply() { // The choices to change the selection control to are the set of valid // controls, minus the current control. std::vector choices; - for (auto control : {spv::SelectionControlMask::MaskNone, - spv::SelectionControlMask::Flatten, - spv::SelectionControlMask::DontFlatten}) { - if (control == - spv::SelectionControlMask(merge_inst->GetSingleWordOperand(1))) { + for (auto control : + {SpvSelectionControlMaskNone, SpvSelectionControlFlattenMask, + SpvSelectionControlDontFlattenMask}) { + if (control == merge_inst->GetSingleWordOperand(1)) { continue; } - choices.push_back(uint32_t(control)); + choices.push_back(control); } // Apply the transformation and add it to the output transformation diff --git a/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp b/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp index 0367a26b..5c3b86b9 100644 --- a/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp +++ b/source/fuzz/fuzzer_pass_apply_id_synonyms.cpp @@ -107,9 +107,9 @@ void FuzzerPassApplyIdSynonyms::Apply() { // which case we need to be able to add an extract instruction to get // that element out. if (synonym_to_try->index_size() > 0 && - !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeExtract, use_inst) && - use_inst->opcode() != spv::Op::OpPhi) { + !fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract, + use_inst) && + use_inst->opcode() != SpvOpPhi) { // We cannot insert an extract before this instruction, so this // synonym is no good. continue; @@ -132,7 +132,7 @@ void FuzzerPassApplyIdSynonyms::Apply() { id_with_which_to_replace_use = GetFuzzerContext()->GetFreshId(); opt::Instruction* instruction_to_insert_before = nullptr; - if (use_inst->opcode() != spv::Op::OpPhi) { + if (use_inst->opcode() != SpvOpPhi) { instruction_to_insert_before = use_inst; } else { auto parent_block_id = @@ -182,7 +182,7 @@ void FuzzerPassApplyIdSynonyms::Apply() { } bool FuzzerPassApplyIdSynonyms::DataDescriptorsHaveCompatibleTypes( - spv::Op opcode, uint32_t use_in_operand_index, + SpvOp opcode, uint32_t use_in_operand_index, const protobufs::DataDescriptor& dd1, const protobufs::DataDescriptor& dd2) { auto base_object_type_id_1 = diff --git a/source/fuzz/fuzzer_pass_apply_id_synonyms.h b/source/fuzz/fuzzer_pass_apply_id_synonyms.h index d1a0e1aa..3da9c5d6 100644 --- a/source/fuzz/fuzzer_pass_apply_id_synonyms.h +++ b/source/fuzz/fuzzer_pass_apply_id_synonyms.h @@ -38,7 +38,7 @@ class FuzzerPassApplyIdSynonyms : public FuzzerPass { // with respect to the type. Concretely, returns true if |dd1| and |dd2| have // the same type or both |dd1| and |dd2| are either a numerical or a vector // type of integral components with possibly different signedness. - bool DataDescriptorsHaveCompatibleTypes(spv::Op opcode, + bool DataDescriptorsHaveCompatibleTypes(SpvOp opcode, uint32_t use_in_operand_index, const protobufs::DataDescriptor& dd1, const protobufs::DataDescriptor& dd2); diff --git a/source/fuzz/fuzzer_pass_construct_composites.cpp b/source/fuzz/fuzzer_pass_construct_composites.cpp index 0ad630c1..ff022fcc 100644 --- a/source/fuzz/fuzzer_pass_construct_composites.cpp +++ b/source/fuzz/fuzzer_pass_construct_composites.cpp @@ -81,7 +81,7 @@ void FuzzerPassConstructComposites::Apply() { // Check whether it is legitimate to insert a composite construction // before the instruction. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeConstruct, inst_it)) { + SpvOpCompositeConstruct, inst_it)) { return; } @@ -121,19 +121,19 @@ void FuzzerPassConstructComposites::Apply() { auto composite_type_inst = GetIRContext()->get_def_use_mgr()->GetDef(chosen_composite_type); switch (composite_type_inst->opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: constructor_arguments = FindComponentsToConstructArray( *composite_type_inst, type_id_to_available_instructions); break; - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: constructor_arguments = FindComponentsToConstructMatrix( *composite_type_inst, type_id_to_available_instructions); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: constructor_arguments = FindComponentsToConstructStruct( *composite_type_inst, type_id_to_available_instructions); break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: constructor_arguments = FindComponentsToConstructVector( *composite_type_inst, type_id_to_available_instructions); break; @@ -156,7 +156,7 @@ std::vector FuzzerPassConstructComposites::FindComponentsToConstructArray( const opt::Instruction& array_type_instruction, const TypeIdToInstructions& type_id_to_available_instructions) { - assert(array_type_instruction.opcode() == spv::Op::OpTypeArray && + assert(array_type_instruction.opcode() == SpvOpTypeArray && "Precondition: instruction must be an array type."); // Get the element type for the array. @@ -191,7 +191,7 @@ std::vector FuzzerPassConstructComposites::FindComponentsToConstructMatrix( const opt::Instruction& matrix_type_instruction, const TypeIdToInstructions& type_id_to_available_instructions) { - assert(matrix_type_instruction.opcode() == spv::Op::OpTypeMatrix && + assert(matrix_type_instruction.opcode() == SpvOpTypeMatrix && "Precondition: instruction must be a matrix type."); // Get the element type for the matrix. @@ -221,7 +221,7 @@ std::vector FuzzerPassConstructComposites::FindComponentsToConstructStruct( const opt::Instruction& struct_type_instruction, const TypeIdToInstructions& type_id_to_available_instructions) { - assert(struct_type_instruction.opcode() == spv::Op::OpTypeStruct && + assert(struct_type_instruction.opcode() == SpvOpTypeStruct && "Precondition: instruction must be a struct type."); std::vector result; // Consider the type of each field of the struct. @@ -251,7 +251,7 @@ std::vector FuzzerPassConstructComposites::FindComponentsToConstructVector( const opt::Instruction& vector_type_instruction, const TypeIdToInstructions& type_id_to_available_instructions) { - assert(vector_type_instruction.opcode() == spv::Op::OpTypeVector && + assert(vector_type_instruction.opcode() == SpvOpTypeVector && "Precondition: instruction must be a vector type."); // Get details of the type underlying the vector, and the width of the vector, diff --git a/source/fuzz/fuzzer_pass_copy_objects.cpp b/source/fuzz/fuzzer_pass_copy_objects.cpp index 725c33e5..80cc2a57 100644 --- a/source/fuzz/fuzzer_pass_copy_objects.cpp +++ b/source/fuzz/fuzzer_pass_copy_objects.cpp @@ -35,11 +35,10 @@ void FuzzerPassCopyObjects::Apply() { opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - inst_it->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(inst_it->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); if (GetTransformationContext()->GetFactManager()->BlockIsDead( block->id())) { @@ -49,7 +48,7 @@ void FuzzerPassCopyObjects::Apply() { // Check whether it is legitimate to insert a copy before this // instruction. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyObject, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyObject, inst_it)) { return; } diff --git a/source/fuzz/fuzzer_pass_donate_modules.cpp b/source/fuzz/fuzzer_pass_donate_modules.cpp index 1696c74e..29ede58b 100644 --- a/source/fuzz/fuzzer_pass_donate_modules.cpp +++ b/source/fuzz/fuzzer_pass_donate_modules.cpp @@ -88,7 +88,7 @@ void FuzzerPassDonateModules::DonateSingleModule( // module. for (const auto& capability_inst : donor_ir_context->capabilities()) { auto capability = - static_cast(capability_inst.GetSingleWordInOperand(0)); + static_cast(capability_inst.GetSingleWordInOperand(0)); if (!GetIRContext()->get_feature_mgr()->HasCapability(capability)) { return; } @@ -122,27 +122,27 @@ void FuzzerPassDonateModules::DonateSingleModule( // kinds of decoration. } -spv::StorageClass FuzzerPassDonateModules::AdaptStorageClass( - spv::StorageClass donor_storage_class) { +SpvStorageClass FuzzerPassDonateModules::AdaptStorageClass( + SpvStorageClass donor_storage_class) { switch (donor_storage_class) { - case spv::StorageClass::Function: - case spv::StorageClass::Private: - case spv::StorageClass::Workgroup: + case SpvStorageClassFunction: + case SpvStorageClassPrivate: + case SpvStorageClassWorkgroup: // We leave these alone return donor_storage_class; - case spv::StorageClass::Input: - case spv::StorageClass::Output: - case spv::StorageClass::Uniform: - case spv::StorageClass::UniformConstant: - case spv::StorageClass::PushConstant: - case spv::StorageClass::Image: - case spv::StorageClass::StorageBuffer: + case SpvStorageClassInput: + case SpvStorageClassOutput: + case SpvStorageClassUniform: + case SpvStorageClassUniformConstant: + case SpvStorageClassPushConstant: + case SpvStorageClassImage: + case SpvStorageClassStorageBuffer: // We change these to Private - return spv::StorageClass::Private; + return SpvStorageClassPrivate; default: // Handle other cases on demand. assert(false && "Currently unsupported storage class."); - return spv::StorageClass::Max; + return SpvStorageClassMax; } } @@ -200,14 +200,14 @@ void FuzzerPassDonateModules::HandleTypeOrValue( // that its component types will have been considered previously, and that // |original_id_to_donated_id| will already contain an entry for them. switch (type_or_value.opcode()) { - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeSampler: + case SpvOpTypeImage: + case SpvOpTypeSampledImage: + case SpvOpTypeSampler: // We do not donate types and variables that relate to images and // samplers, so we skip these types and subsequently skip anything that // depends on them. return; - case spv::Op::OpTypeVoid: { + case SpvOpTypeVoid: { // Void has to exist already in order for us to have an entry point. // Get the existing id of void. opt::analysis::Void void_type; @@ -216,7 +216,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( "The module being transformed will always have 'void' type " "declared."); } break; - case spv::Op::OpTypeBool: { + case SpvOpTypeBool: { // Bool cannot be declared multiple times, so use its existing id if // present, or add a declaration of Bool with a fresh id if not. opt::analysis::Bool bool_type; @@ -228,7 +228,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( ApplyTransformation(TransformationAddTypeBoolean(new_result_id)); } } break; - case spv::Op::OpTypeInt: { + case SpvOpTypeInt: { // Int cannot be declared multiple times with the same width and // signedness, so check whether an existing identical Int type is // present and use its id if so. Otherwise add a declaration of the @@ -246,8 +246,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue( TransformationAddTypeInt(new_result_id, width, is_signed)); } } break; - case spv::Op::OpTypeFloat: { - // Similar to spv::Op::OpTypeInt. + case SpvOpTypeFloat: { + // Similar to SpvOpTypeInt. const uint32_t width = type_or_value.GetSingleWordInOperand(0); opt::analysis::Float float_type(width); auto float_type_id = GetIRContext()->get_type_mgr()->GetId(&float_type); @@ -258,7 +258,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( ApplyTransformation(TransformationAddTypeFloat(new_result_id, width)); } } break; - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { // It is not legal to have two Vector type declarations with identical // element types and element counts, so check whether an existing // identical Vector type is present and use its id if so. Otherwise add @@ -282,8 +282,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue( new_result_id, component_type_id, component_count)); } } break; - case spv::Op::OpTypeMatrix: { - // Similar to spv::Op::OpTypeVector. + case SpvOpTypeMatrix: { + // Similar to SpvOpTypeVector. uint32_t column_type_id = original_id_to_donated_id->at( type_or_value.GetSingleWordInOperand(0)); auto column_type = @@ -302,7 +302,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( } } break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { // It is OK to have multiple structurally identical array types, so // we go ahead and add a remapped version of the type declared by the // donor. @@ -318,7 +318,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( original_id_to_donated_id->at( type_or_value.GetSingleWordInOperand(1)))); } break; - case spv::Op::OpTypeRuntimeArray: { + case SpvOpTypeRuntimeArray: { // A runtime array is allowed as the final member of an SSBO. During // donation we turn runtime arrays into fixed-size arrays. For dead // code donations this is OK because the array is never indexed into at @@ -341,8 +341,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue( {GetFuzzerContext()->GetRandomSizeForNewArray()}, 32, false, false))); } break; - case spv::Op::OpTypeStruct: { - // Similar to spv::Op::OpTypeArray. + case SpvOpTypeStruct: { + // Similar to SpvOpTypeArray. std::vector member_type_ids; for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) { auto component_type_id = type_or_value.GetSingleWordInOperand(i); @@ -358,8 +358,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue( ApplyTransformation( TransformationAddTypeStruct(new_result_id, member_type_ids)); } break; - case spv::Op::OpTypePointer: { - // Similar to spv::Op::OpTypeArray. + case SpvOpTypePointer: { + // Similar to SpvOpTypeArray. uint32_t pointee_type_id = type_or_value.GetSingleWordInOperand(1); if (!original_id_to_donated_id->count(pointee_type_id)) { // We did not donate the pointee type for this pointer type, so we @@ -369,11 +369,11 @@ void FuzzerPassDonateModules::HandleTypeOrValue( new_result_id = GetFuzzerContext()->GetFreshId(); ApplyTransformation(TransformationAddTypePointer( new_result_id, - AdaptStorageClass(static_cast( + AdaptStorageClass(static_cast( type_or_value.GetSingleWordInOperand(0))), original_id_to_donated_id->at(pointee_type_id))); } break; - case spv::Op::OpTypeFunction: { + case SpvOpTypeFunction: { // It is not OK to have multiple function types that use identical ids // for their return and parameter types. We thus go through all // existing function types to look for a match. We do not use the @@ -425,11 +425,10 @@ void FuzzerPassDonateModules::HandleTypeOrValue( argument_type_ids)); } } break; - case spv::Op::OpSpecConstantOp: { + case SpvOpSpecConstantOp: { new_result_id = GetFuzzerContext()->GetFreshId(); auto type_id = original_id_to_donated_id->at(type_or_value.type_id()); - auto opcode = - static_cast(type_or_value.GetSingleWordInOperand(0)); + auto opcode = static_cast(type_or_value.GetSingleWordInOperand(0)); // Make sure we take into account |original_id_to_donated_id| when // computing operands for OpSpecConstantOp. @@ -448,20 +447,20 @@ void FuzzerPassDonateModules::HandleTypeOrValue( ApplyTransformation(TransformationAddSpecConstantOp( new_result_id, type_id, opcode, std::move(operands))); } break; - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: { + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpConstantTrue: + case SpvOpConstantFalse: { // It is OK to have duplicate definitions of True and False, so add // these to the module, using a remapped Bool type. new_result_id = GetFuzzerContext()->GetFreshId(); - auto value = type_or_value.opcode() == spv::Op::OpConstantTrue || - type_or_value.opcode() == spv::Op::OpSpecConstantTrue; + auto value = type_or_value.opcode() == SpvOpConstantTrue || + type_or_value.opcode() == SpvOpSpecConstantTrue; ApplyTransformation( TransformationAddConstantBoolean(new_result_id, value, false)); } break; - case spv::Op::OpSpecConstant: - case spv::Op::OpConstant: { + case SpvOpSpecConstant: + case SpvOpConstant: { // It is OK to have duplicate constant definitions, so add this to the // module using a remapped result type. new_result_id = GetFuzzerContext()->GetFreshId(); @@ -473,8 +472,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue( new_result_id, original_id_to_donated_id->at(type_or_value.type_id()), data_words, false)); } break; - case spv::Op::OpSpecConstantComposite: - case spv::Op::OpConstantComposite: { + case SpvOpSpecConstantComposite: + case SpvOpConstantComposite: { assert(original_id_to_donated_id->count(type_or_value.type_id()) && "Composite types for which it is possible to create a constant " "should have been donated."); @@ -496,7 +495,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( new_result_id, original_id_to_donated_id->at(type_or_value.type_id()), constituent_ids, false)); } break; - case spv::Op::OpConstantNull: { + case SpvOpConstantNull: { if (!original_id_to_donated_id->count(type_or_value.type_id())) { // We did not donate the type associated with this null constant, so // we cannot donate the null constant. @@ -510,7 +509,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( new_result_id, original_id_to_donated_id->at(type_or_value.type_id()))); } break; - case spv::Op::OpVariable: { + case SpvOpVariable: { if (!original_id_to_donated_id->count(type_or_value.type_id())) { // We did not donate the pointer type associated with this variable, // so we cannot donate the variable. @@ -537,11 +536,11 @@ void FuzzerPassDonateModules::HandleTypeOrValue( uint32_t remapped_pointer_type = original_id_to_donated_id->at(type_or_value.type_id()); uint32_t initializer_id; - spv::StorageClass storage_class = - static_cast(type_or_value.GetSingleWordInOperand( - 0)) == spv::StorageClass::Workgroup - ? spv::StorageClass::Workgroup - : spv::StorageClass::Private; + SpvStorageClass storage_class = + static_cast(type_or_value.GetSingleWordInOperand( + 0)) == SpvStorageClassWorkgroup + ? SpvStorageClassWorkgroup + : SpvStorageClassPrivate; if (type_or_value.NumInOperands() == 1) { // The variable did not have an initializer. Initialize it to zero // if it has Private storage class (to limit problems associated with @@ -552,7 +551,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( // could initialize Workgroup variables at the start of an entry // point, and should do so if their uninitialized nature proves // problematic. - initializer_id = storage_class == spv::StorageClass::Workgroup + initializer_id = storage_class == SpvStorageClassWorkgroup ? 0 : FindOrCreateZeroConstant( fuzzerutil::GetPointeeTypeIdFromPointerType( @@ -567,7 +566,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue( TransformationAddGlobalVariable(new_result_id, remapped_pointer_type, storage_class, initializer_id, true)); } break; - case spv::Op::OpUndef: { + case SpvOpUndef: { if (!original_id_to_donated_id->count(type_or_value.type_id())) { // We did not donate the type associated with this undef, so we cannot // donate the undef. @@ -639,7 +638,7 @@ void FuzzerPassDonateModules::HandleFunctions( [this, &donated_instructions, donor_ir_context, &original_id_to_donated_id, &skipped_instructions](const opt::Instruction* instruction) { - if (instruction->opcode() == spv::Op::OpArrayLength) { + if (instruction->opcode() == SpvOpArrayLength) { // We treat OpArrayLength specially. HandleOpArrayLength(*instruction, original_id_to_donated_id, &donated_instructions); @@ -683,70 +682,70 @@ bool FuzzerPassDonateModules::CanDonateInstruction( // Now consider instructions we specifically want to skip because we do not // yet support them. switch (instruction.opcode()) { - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: + case SpvOpAtomicLoad: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: // We conservatively ignore all atomic instructions at present. // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3276): Consider // being less conservative here. - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageFetch: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageRead: - case spv::Op::OpImageWrite: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageSparseRead: - case spv::Op::OpImageSampleFootprintNV: - case spv::Op::OpImage: - case spv::Op::OpImageQueryFormat: - case spv::Op::OpImageQueryLevels: - case spv::Op::OpImageQueryLod: - case spv::Op::OpImageQueryOrder: - case spv::Op::OpImageQuerySamples: - case spv::Op::OpImageQuerySize: - case spv::Op::OpImageQuerySizeLod: - case spv::Op::OpSampledImage: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageFetch: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageRead: + case SpvOpImageWrite: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpImageSparseRead: + case SpvOpImageSampleFootprintNV: + case SpvOpImage: + case SpvOpImageQueryFormat: + case SpvOpImageQueryLevels: + case SpvOpImageQueryLod: + case SpvOpImageQueryOrder: + case SpvOpImageQuerySamples: + case SpvOpImageQuerySize: + case SpvOpImageQuerySizeLod: + case SpvOpSampledImage: // We ignore all instructions related to accessing images, since we do not // donate images. return false; - case spv::Op::OpLoad: + case SpvOpLoad: switch (donor_ir_context->get_def_use_mgr() ->GetDef(instruction.type_id()) ->opcode()) { - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeSampler: + case SpvOpTypeImage: + case SpvOpTypeSampledImage: + case SpvOpTypeSampler: // Again, we ignore instructions that relate to accessing images. return false; default: @@ -784,13 +783,13 @@ bool FuzzerPassDonateModules::CanDonateInstruction( bool FuzzerPassDonateModules::IsBasicType( const opt::Instruction& instruction) const { switch (instruction.opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeStruct: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeMatrix: + case SpvOpTypeStruct: + case SpvOpTypeVector: return true; default: return false; @@ -801,7 +800,7 @@ void FuzzerPassDonateModules::HandleOpArrayLength( const opt::Instruction& instruction, std::map* original_id_to_donated_id, std::vector* donated_instructions) const { - assert(instruction.opcode() == spv::Op::OpArrayLength && + assert(instruction.opcode() == SpvOpArrayLength && "Precondition: instruction must be OpArrayLength."); uint32_t donated_variable_id = original_id_to_donated_id->at(instruction.GetSingleWordInOperand(0)); @@ -810,12 +809,12 @@ void FuzzerPassDonateModules::HandleOpArrayLength( auto pointer_to_struct_instruction = GetIRContext()->get_def_use_mgr()->GetDef( donated_variable_instruction->type_id()); - assert(pointer_to_struct_instruction->opcode() == spv::Op::OpTypePointer && + assert(pointer_to_struct_instruction->opcode() == SpvOpTypePointer && "Type of variable must be pointer."); auto donated_struct_type_instruction = GetIRContext()->get_def_use_mgr()->GetDef( pointer_to_struct_instruction->GetSingleWordInOperand(1)); - assert(donated_struct_type_instruction->opcode() == spv::Op::OpTypeStruct && + assert(donated_struct_type_instruction->opcode() == SpvOpTypeStruct && "Pointee type of pointer used by OpArrayLength must be struct."); assert(donated_struct_type_instruction->NumInOperands() == instruction.GetSingleWordInOperand(1) + 1 && @@ -826,7 +825,7 @@ void FuzzerPassDonateModules::HandleOpArrayLength( donated_struct_type_instruction->NumInOperands() - 1); auto fixed_size_array_type_instruction = GetIRContext()->get_def_use_mgr()->GetDef(fixed_size_array_type_id); - assert(fixed_size_array_type_instruction->opcode() == spv::Op::OpTypeArray && + assert(fixed_size_array_type_instruction->opcode() == SpvOpTypeArray && "The donated array type must be fixed-size."); auto array_size_id = fixed_size_array_type_instruction->GetSingleWordInOperand(1); @@ -838,8 +837,7 @@ void FuzzerPassDonateModules::HandleOpArrayLength( } donated_instructions->push_back(MakeInstructionMessage( - spv::Op::OpCopyObject, - original_id_to_donated_id->at(instruction.type_id()), + SpvOpCopyObject, original_id_to_donated_id->at(instruction.type_id()), original_id_to_donated_id->at(instruction.result_id()), opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {array_size_id}}}))); } @@ -894,7 +892,7 @@ void FuzzerPassDonateModules::HandleDifficultInstruction( // more interesting value later. auto zero_constant = FindOrCreateZeroConstant(remapped_type_id, true); donated_instructions->push_back(MakeInstructionMessage( - spv::Op::OpCopyObject, remapped_type_id, + SpvOpCopyObject, remapped_type_id, original_id_to_donated_id->at(instruction.result_id()), opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {zero_constant}}}))); } @@ -928,8 +926,8 @@ void FuzzerPassDonateModules::PrepareInstructionForDonation( (void)(donor_ir_context); assert((donor_ir_context->get_def_use_mgr() ->GetDef(operand_id) - ->opcode() == spv::Op::OpLabel || - instruction.opcode() == spv::Op::OpPhi) && + ->opcode() == SpvOpLabel || + instruction.opcode() == SpvOpPhi) && "Unsupported forward reference."); original_id_to_donated_id->insert( {operand_id, GetFuzzerContext()->GetFreshId()}); @@ -944,7 +942,7 @@ void FuzzerPassDonateModules::PrepareInstructionForDonation( input_operands.push_back({in_operand.type, operand_data}); } - if (instruction.opcode() == spv::Op::OpVariable && + if (instruction.opcode() == SpvOpVariable && instruction.NumInOperands() == 1) { // This is an uninitialized local variable. Initialize it to zero. input_operands.push_back( @@ -1019,7 +1017,7 @@ bool FuzzerPassDonateModules::CreateLoopLimiterInfo( // Adjust OpPhi instructions in the |merge_block|. for (const auto& inst : *merge_block) { - if (inst.opcode() != spv::Op::OpPhi) { + if (inst.opcode() != SpvOpPhi) { break; } @@ -1072,8 +1070,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( // live-safe. Add them if not already present. FindOrCreateBoolType(); // Needed for comparisons FindOrCreatePointerToIntegerType( - 32, false, - spv::StorageClass::Function); // Needed for adding loop limiters + 32, false, SpvStorageClassFunction); // Needed for adding loop limiters FindOrCreateIntegerConstant({0}, 32, false, false); // Needed for initializing loop limiters FindOrCreateIntegerConstant({1}, 32, false, @@ -1110,8 +1107,8 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( for (auto& block : function_to_donate) { for (auto& inst : block) { switch (inst.opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: { + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: { protobufs::AccessChainClampingInfo clamping_info; clamping_info.set_access_chain_id( original_id_to_donated_id.at(inst.result_id())); @@ -1121,8 +1118,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( assert(base_object && "The base object must exist."); auto pointer_type = donor_ir_context->get_def_use_mgr()->GetDef( base_object->type_id()); - assert(pointer_type && - pointer_type->opcode() == spv::Op::OpTypePointer && + assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer && "The base object must have pointer type."); auto should_be_composite_type = @@ -1142,8 +1138,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( // Get the bound for the component being indexed into. uint32_t bound; - if (should_be_composite_type->opcode() == - spv::Op::OpTypeRuntimeArray) { + if (should_be_composite_type->opcode() == SpvOpTypeRuntimeArray) { // The donor is indexing into a runtime array. We do not // donate runtime arrays. Instead, we donate a corresponding // fixed-size array for every runtime array. We should thus @@ -1153,7 +1148,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( GetIRContext()->get_def_use_mgr()->GetDef( original_id_to_donated_id.at( should_be_composite_type->result_id())); - assert(fixed_size_array_type->opcode() == spv::Op::OpTypeArray && + assert(fixed_size_array_type->opcode() == SpvOpTypeArray && "A runtime array type in the donor should have been " "replaced by a fixed-sized array in the recipient."); // The size of this fixed-size array is a suitable bound. @@ -1168,12 +1163,12 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( donor_ir_context->get_def_use_mgr()->GetDef(index_id); auto index_type_inst = donor_ir_context->get_def_use_mgr()->GetDef( index_inst->type_id()); - assert(index_type_inst->opcode() == spv::Op::OpTypeInt); + assert(index_type_inst->opcode() == SpvOpTypeInt); opt::analysis::Integer* index_int_type = donor_ir_context->get_type_mgr() ->GetType(index_type_inst->result_id()) ->AsInteger(); - if (index_inst->opcode() != spv::Op::OpConstant) { + if (index_inst->opcode() != SpvOpConstant) { // We will have to clamp this index, so we need a constant // whose value is one less than the bound, to compare // against and to use as the clamped value. @@ -1199,7 +1194,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction( uint32_t kill_unreachable_return_value_id = 0; auto function_return_type_inst = donor_ir_context->get_def_use_mgr()->GetDef(function_to_donate.type_id()); - if (function_return_type_inst->opcode() != spv::Op::OpTypeVoid && + if (function_return_type_inst->opcode() != SpvOpTypeVoid && fuzzerutil::FunctionContainsOpKillOrUnreachable(function_to_donate)) { kill_unreachable_return_value_id = FindOrCreateZeroConstant( original_id_to_donated_id.at(function_return_type_inst->result_id()), diff --git a/source/fuzz/fuzzer_pass_donate_modules.h b/source/fuzz/fuzzer_pass_donate_modules.h index 004f1587..924dd358 100644 --- a/source/fuzz/fuzzer_pass_donate_modules.h +++ b/source/fuzz/fuzzer_pass_donate_modules.h @@ -45,8 +45,7 @@ class FuzzerPassDonateModules : public FuzzerPass { private: // Adapts a storage class coming from a donor module so that it will work // in a recipient module, e.g. by changing Uniform to Private. - static spv::StorageClass AdaptStorageClass( - spv::StorageClass donor_storage_class); + static SpvStorageClass AdaptStorageClass(SpvStorageClass donor_storage_class); // Identifies all external instruction set imports in |donor_ir_context| and // populates |original_id_to_donated_id| with a mapping from the donor's id diff --git a/source/fuzz/fuzzer_pass_expand_vector_reductions.cpp b/source/fuzz/fuzzer_pass_expand_vector_reductions.cpp index fecd82e4..5bf0461d 100644 --- a/source/fuzz/fuzzer_pass_expand_vector_reductions.cpp +++ b/source/fuzz/fuzzer_pass_expand_vector_reductions.cpp @@ -40,8 +40,8 @@ void FuzzerPassExpandVectorReductions::Apply() { } // |instruction| must be OpAny or OpAll. - if (instruction.opcode() != spv::Op::OpAny && - instruction.opcode() != spv::Op::OpAll) { + if (instruction.opcode() != SpvOpAny && + instruction.opcode() != SpvOpAll) { continue; } diff --git a/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp b/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp index 86ffff45..70fa6a12 100644 --- a/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp +++ b/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp @@ -48,8 +48,8 @@ void FuzzerPassFlattenConditionalBranches::Apply() { // Only consider this block if it is the header of a conditional, with a // non-irrelevant condition. if (block.GetMergeInst() && - block.GetMergeInst()->opcode() == spv::Op::OpSelectionMerge && - block.terminator()->opcode() == spv::Op::OpBranchConditional && + block.GetMergeInst()->opcode() == SpvOpSelectionMerge && + block.terminator()->opcode() == SpvOpBranchConditional && !GetTransformationContext()->GetFactManager()->IdIsIrrelevant( block.terminator()->GetSingleWordInOperand(0))) { selection_headers.emplace_back(&block); @@ -94,11 +94,11 @@ void FuzzerPassFlattenConditionalBranches::Apply() { ->get_def_use_mgr() ->GetDef(phi_instruction->type_id()) ->opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypePointer: - case spv::Op::OpTypeVector: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypePointer: + case SpvOpTypeVector: return true; default: return false; @@ -143,7 +143,7 @@ void FuzzerPassFlattenConditionalBranches::Apply() { GetIRContext()->get_def_use_mgr()->GetDef( phi_instruction->type_id()); switch (type_instruction->opcode()) { - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { uint32_t dimension = type_instruction->GetSingleWordInOperand(1); switch (dimension) { diff --git a/source/fuzz/fuzzer_pass_inline_functions.cpp b/source/fuzz/fuzzer_pass_inline_functions.cpp index 6839bbe2..4024096f 100644 --- a/source/fuzz/fuzzer_pass_inline_functions.cpp +++ b/source/fuzz/fuzzer_pass_inline_functions.cpp @@ -64,7 +64,7 @@ void FuzzerPassInlineFunctions::Apply() { auto* function_call_block = GetIRContext()->get_instr_block(function_call_instruction); if ((function_call_instruction != &*--function_call_block->tail() || - function_call_block->terminator()->opcode() != spv::Op::OpBranch) && + function_call_block->terminator()->opcode() != SpvOpBranch) && !MaybeApplyTransformation(TransformationSplitBlock( MakeInstructionDescriptor(GetIRContext(), function_call_instruction->NextNode()), diff --git a/source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp b/source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp index ec5fc4b7..b755d235 100644 --- a/source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp +++ b/source/fuzz/fuzzer_pass_make_vector_operations_dynamic.cpp @@ -47,20 +47,18 @@ void FuzzerPassMakeVectorOperationsDynamic::Apply() { } // Make sure |instruction| has only one indexing operand. - assert( - instruction.NumInOperands() == - (instruction.opcode() == spv::Op::OpCompositeExtract ? 2 : 3) && - "FuzzerPassMakeVectorOperationsDynamic: the composite " - "instruction must have " - "only one indexing operand."); + assert(instruction.NumInOperands() == + (instruction.opcode() == SpvOpCompositeExtract ? 2 : 3) && + "FuzzerPassMakeVectorOperationsDynamic: the composite " + "instruction must have " + "only one indexing operand."); // Applies the make vector operation dynamic transformation. ApplyTransformation(TransformationMakeVectorOperationDynamic( instruction.result_id(), FindOrCreateIntegerConstant( {instruction.GetSingleWordInOperand( - instruction.opcode() == spv::Op::OpCompositeExtract ? 1 - : 2)}, + instruction.opcode() == SpvOpCompositeExtract ? 1 : 2)}, 32, GetFuzzerContext()->ChooseEven(), false))); } } diff --git a/source/fuzz/fuzzer_pass_merge_function_returns.cpp b/source/fuzz/fuzzer_pass_merge_function_returns.cpp index 48c18618..220f707b 100644 --- a/source/fuzz/fuzzer_pass_merge_function_returns.cpp +++ b/source/fuzz/fuzzer_pass_merge_function_returns.cpp @@ -64,11 +64,11 @@ void FuzzerPassMergeFunctionReturns::Apply() { [this, function]( opt::BasicBlock* /*unused*/, opt::BasicBlock::iterator inst_it, const protobufs::InstructionDescriptor& instruction_descriptor) { - const spv::Op opcode = inst_it->opcode(); + const SpvOp opcode = inst_it->opcode(); switch (opcode) { - case spv::Op::OpKill: - case spv::Op::OpUnreachable: - case spv::Op::OpTerminateInvocation: { + case SpvOpKill: + case SpvOpUnreachable: + case SpvOpTerminateInvocation: { // This is an early termination instruction - we need to wrap it // so that it becomes a return. if (TransformationWrapEarlyTerminatorInFunction:: @@ -85,7 +85,7 @@ void FuzzerPassMergeFunctionReturns::Apply() { GetIRContext()->get_def_use_mgr()->GetDef( function->type_id()); uint32_t returned_value_id; - if (function_return_type->opcode() == spv::Op::OpTypeVoid) { + if (function_return_type->opcode() == SpvOpTypeVoid) { // No value is needed. returned_value_id = 0; } else if (fuzzerutil::CanCreateConstant( @@ -130,7 +130,7 @@ void FuzzerPassMergeFunctionReturns::Apply() { // If the entry block does not branch unconditionally to another block, // split it. - if (function->entry()->terminator()->opcode() != spv::Op::OpBranch) { + if (function->entry()->terminator()->opcode() != SpvOpBranch) { SplitBlockAfterOpPhiOrOpVariable(function->entry()->id()); } @@ -149,9 +149,9 @@ void FuzzerPassMergeFunctionReturns::Apply() { if (GetIRContext() ->get_instr_block(merge_block) ->WhileEachInst([](opt::Instruction* inst) { - return inst->opcode() == spv::Op::OpLabel || - inst->opcode() == spv::Op::OpPhi || - inst->opcode() == spv::Op::OpBranch; + return inst->opcode() == SpvOpLabel || + inst->opcode() == SpvOpPhi || + inst->opcode() == SpvOpBranch; })) { actual_merge_blocks.emplace_back(merge_block); continue; @@ -324,8 +324,7 @@ FuzzerPassMergeFunctionReturns::GetInfoNeededForMergeBlocks( bool FuzzerPassMergeFunctionReturns::IsEarlyTerminatorWrapper( const opt::Function& function) const { - for (spv::Op opcode : {spv::Op::OpKill, spv::Op::OpUnreachable, - spv::Op::OpTerminateInvocation}) { + for (SpvOp opcode : {SpvOpKill, SpvOpUnreachable, SpvOpTerminateInvocation}) { if (TransformationWrapEarlyTerminatorInFunction::MaybeGetWrapperFunction( GetIRContext(), opcode) == &function) { return true; diff --git a/source/fuzz/fuzzer_pass_mutate_pointers.cpp b/source/fuzz/fuzzer_pass_mutate_pointers.cpp index a7e9fdc3..bbe05409 100644 --- a/source/fuzz/fuzzer_pass_mutate_pointers.cpp +++ b/source/fuzz/fuzzer_pass_mutate_pointers.cpp @@ -39,8 +39,7 @@ void FuzzerPassMutatePointers::Apply() { return; } - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, - inst_it)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, inst_it)) { return; } diff --git a/source/fuzz/fuzzer_pass_obfuscate_constants.cpp b/source/fuzz/fuzzer_pass_obfuscate_constants.cpp index 48ac589e..f60c1b4c 100644 --- a/source/fuzz/fuzzer_pass_obfuscate_constants.cpp +++ b/source/fuzz/fuzzer_pass_obfuscate_constants.cpp @@ -37,21 +37,21 @@ FuzzerPassObfuscateConstants::FuzzerPassObfuscateConstants( void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair( uint32_t depth, const protobufs::IdUseDescriptor& bool_constant_use, - const std::vector& greater_than_opcodes, - const std::vector& less_than_opcodes, uint32_t constant_id_1, + const std::vector& greater_than_opcodes, + const std::vector& less_than_opcodes, uint32_t constant_id_1, uint32_t constant_id_2, bool first_constant_is_larger) { auto bool_constant_opcode = GetIRContext() ->get_def_use_mgr() ->GetDef(bool_constant_use.id_of_interest()) ->opcode(); - assert((bool_constant_opcode == spv::Op::OpConstantFalse || - bool_constant_opcode == spv::Op::OpConstantTrue) && + assert((bool_constant_opcode == SpvOpConstantFalse || + bool_constant_opcode == SpvOpConstantTrue) && "Precondition: this must be a usage of a boolean constant."); // Pick an opcode at random. First randomly decide whether to generate // a 'greater than' or 'less than' kind of opcode, and then select a // random opcode from the resulting subset. - spv::Op comparison_opcode; + SpvOp comparison_opcode; if (GetFuzzerContext()->ChooseEven()) { comparison_opcode = greater_than_opcodes[GetFuzzerContext()->RandomIndex( greater_than_opcodes)]; @@ -68,9 +68,9 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair( comparison_opcode) != greater_than_opcodes.end(); uint32_t lhs_id; uint32_t rhs_id; - if ((bool_constant_opcode == spv::Op::OpConstantTrue && + if ((bool_constant_opcode == SpvOpConstantTrue && first_constant_is_larger == is_greater_than_opcode) || - (bool_constant_opcode == spv::Op::OpConstantFalse && + (bool_constant_opcode == SpvOpConstantFalse && first_constant_is_larger != is_greater_than_opcode)) { lhs_id = constant_id_1; rhs_id = constant_id_2; @@ -147,12 +147,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaFloatConstantPair( first_constant_is_larger = float_constant_1->GetDouble() > float_constant_2->GetDouble(); } - std::vector greater_than_opcodes{ - spv::Op::OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThanEqual, - spv::Op::OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThanEqual}; - std::vector less_than_opcodes{ - spv::Op::OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThanEqual, - spv::Op::OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThanEqual}; + std::vector greater_than_opcodes{ + SpvOpFOrdGreaterThan, SpvOpFOrdGreaterThanEqual, SpvOpFUnordGreaterThan, + SpvOpFUnordGreaterThanEqual}; + std::vector less_than_opcodes{ + SpvOpFOrdGreaterThan, SpvOpFOrdGreaterThanEqual, SpvOpFUnordGreaterThan, + SpvOpFUnordGreaterThanEqual}; ObfuscateBoolConstantViaConstantPair( depth, bool_constant_use, greater_than_opcodes, less_than_opcodes, @@ -190,10 +190,9 @@ void FuzzerPassObfuscateConstants:: first_constant_is_larger = signed_int_constant_1->GetS64() > signed_int_constant_2->GetS64(); } - std::vector greater_than_opcodes{spv::Op::OpSGreaterThan, - spv::Op::OpSGreaterThanEqual}; - std::vector less_than_opcodes{spv::Op::OpSLessThan, - spv::Op::OpSLessThanEqual}; + std::vector greater_than_opcodes{SpvOpSGreaterThan, + SpvOpSGreaterThanEqual}; + std::vector less_than_opcodes{SpvOpSLessThan, SpvOpSLessThanEqual}; ObfuscateBoolConstantViaConstantPair( depth, bool_constant_use, greater_than_opcodes, less_than_opcodes, @@ -233,10 +232,9 @@ void FuzzerPassObfuscateConstants:: first_constant_is_larger = unsigned_int_constant_1->GetU64() > unsigned_int_constant_2->GetU64(); } - std::vector greater_than_opcodes{spv::Op::OpUGreaterThan, - spv::Op::OpUGreaterThanEqual}; - std::vector less_than_opcodes{spv::Op::OpULessThan, - spv::Op::OpULessThanEqual}; + std::vector greater_than_opcodes{SpvOpUGreaterThan, + SpvOpUGreaterThanEqual}; + std::vector less_than_opcodes{SpvOpULessThan, SpvOpULessThanEqual}; ObfuscateBoolConstantViaConstantPair( depth, bool_constant_use, greater_than_opcodes, less_than_opcodes, @@ -381,7 +379,7 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant( uniform_descriptor.index()); assert(element_type_id && "Type of uniform variable is invalid"); - FindOrCreatePointerType(element_type_id, spv::StorageClass::Uniform); + FindOrCreatePointerType(element_type_id, SpvStorageClassUniform); // Create, apply and record a transformation to replace the constant use with // the result of a load from the chosen uniform. @@ -396,11 +394,11 @@ void FuzzerPassObfuscateConstants::ObfuscateConstant( ->get_def_use_mgr() ->GetDef(constant_use.id_of_interest()) ->opcode()) { - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: + case SpvOpConstantTrue: + case SpvOpConstantFalse: ObfuscateBoolConstant(depth, constant_use); break; - case spv::Op::OpConstant: + case SpvOpConstant: ObfuscateScalarConstant(depth, constant_use); break; default: @@ -412,7 +410,7 @@ void FuzzerPassObfuscateConstants::ObfuscateConstant( void FuzzerPassObfuscateConstants::MaybeAddConstantIdUse( const opt::Instruction& inst, uint32_t in_operand_index, uint32_t base_instruction_result_id, - const std::map& skipped_opcode_count, + const std::map& skipped_opcode_count, std::vector* constant_uses) { if (inst.GetInOperand(in_operand_index).type != SPV_OPERAND_TYPE_ID) { // The operand is not an id, so it cannot be a constant id. @@ -422,15 +420,15 @@ void FuzzerPassObfuscateConstants::MaybeAddConstantIdUse( auto operand_definition = GetIRContext()->get_def_use_mgr()->GetDef(operand_id); switch (operand_definition->opcode()) { - case spv::Op::OpConstantFalse: - case spv::Op::OpConstantTrue: - case spv::Op::OpConstant: { + case SpvOpConstantFalse: + case SpvOpConstantTrue: + case SpvOpConstant: { // The operand is a constant id, so make an id use descriptor and record // it. protobufs::IdUseDescriptor id_use_descriptor; id_use_descriptor.set_id_of_interest(operand_id); id_use_descriptor.mutable_enclosing_instruction() - ->set_target_instruction_opcode(uint32_t(inst.opcode())); + ->set_target_instruction_opcode(inst.opcode()); id_use_descriptor.mutable_enclosing_instruction() ->set_base_instruction_result_id(base_instruction_result_id); id_use_descriptor.mutable_enclosing_instruction() @@ -463,7 +461,7 @@ void FuzzerPassObfuscateConstants::Apply() { // opcode need to be skipped in order to find the instruction of interest // from the base instruction. We maintain a mapping that records a skip // count for each relevant opcode. - std::map skipped_opcode_count; + std::map skipped_opcode_count; // Go through each instruction in the block. for (auto& inst : block) { @@ -480,7 +478,7 @@ void FuzzerPassObfuscateConstants::Apply() { // The instruction must not be an OpVariable, the only id that an // OpVariable uses is an initializer id, which has to remain // constant. - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { // Consider each operand of the instruction, and add a constant id // use for the operand if relevant. for (uint32_t in_operand_index = 0; diff --git a/source/fuzz/fuzzer_pass_obfuscate_constants.h b/source/fuzz/fuzzer_pass_obfuscate_constants.h index bfef597c..30e64d28 100644 --- a/source/fuzz/fuzzer_pass_obfuscate_constants.h +++ b/source/fuzz/fuzzer_pass_obfuscate_constants.h @@ -85,8 +85,8 @@ class FuzzerPassObfuscateConstants : public FuzzerPass { // (similar for |less_than_opcodes|). void ObfuscateBoolConstantViaConstantPair( uint32_t depth, const protobufs::IdUseDescriptor& bool_constant_use, - const std::vector& greater_than_opcodes, - const std::vector& less_than_opcodes, uint32_t constant_id_1, + const std::vector& greater_than_opcodes, + const std::vector& less_than_opcodes, uint32_t constant_id_1, uint32_t constant_id_2, bool first_constant_is_larger); // A helper method to determine whether input operand |in_operand_index| of @@ -96,7 +96,7 @@ class FuzzerPassObfuscateConstants : public FuzzerPass { void MaybeAddConstantIdUse( const opt::Instruction& inst, uint32_t in_operand_index, uint32_t base_instruction_result_id, - const std::map& skipped_opcode_count, + const std::map& skipped_opcode_count, std::vector* constant_uses); // Returns a vector of unique words that denote constants. Every such constant diff --git a/source/fuzz/fuzzer_pass_outline_functions.cpp b/source/fuzz/fuzzer_pass_outline_functions.cpp index e64373a4..b90c12dc 100644 --- a/source/fuzz/fuzzer_pass_outline_functions.cpp +++ b/source/fuzz/fuzzer_pass_outline_functions.cpp @@ -137,12 +137,12 @@ FuzzerPassOutlineFunctions::MaybeGetEntryBlockSuitableForOutlining( "The entry block cannot be a loop header at this point."); // If the entry block starts with OpPhi or OpVariable, try to split it. - if (entry_block->begin()->opcode() == spv::Op::OpPhi || - entry_block->begin()->opcode() == spv::Op::OpVariable) { + if (entry_block->begin()->opcode() == SpvOpPhi || + entry_block->begin()->opcode() == SpvOpVariable) { // Find the first non-OpPhi and non-OpVariable instruction. auto non_phi_or_var_inst = &*entry_block->begin(); - while (non_phi_or_var_inst->opcode() == spv::Op::OpPhi || - non_phi_or_var_inst->opcode() == spv::Op::OpVariable) { + while (non_phi_or_var_inst->opcode() == SpvOpPhi || + non_phi_or_var_inst->opcode() == SpvOpVariable) { non_phi_or_var_inst = non_phi_or_var_inst->NextNode(); } @@ -175,7 +175,7 @@ FuzzerPassOutlineFunctions::MaybeGetExitBlockSuitableForOutlining( // Find the first non-OpPhi instruction, after which to split. auto split_before = &*exit_block->begin(); - while (split_before->opcode() == spv::Op::OpPhi) { + while (split_before->opcode() == SpvOpPhi) { split_before = split_before->NextNode(); } diff --git a/source/fuzz/fuzzer_pass_permute_function_variables.cpp b/source/fuzz/fuzzer_pass_permute_function_variables.cpp index 2313f420..f8b9b450 100644 --- a/source/fuzz/fuzzer_pass_permute_function_variables.cpp +++ b/source/fuzz/fuzzer_pass_permute_function_variables.cpp @@ -47,7 +47,7 @@ void FuzzerPassPermuteFunctionVariables::Apply() { std::vector variables; for (auto& instruction : *first_block) { - if (instruction.opcode() == spv::Op::OpVariable) { + if (instruction.opcode() == SpvOpVariable) { variables.push_back(&instruction); } } diff --git a/source/fuzz/fuzzer_pass_permute_phi_operands.cpp b/source/fuzz/fuzzer_pass_permute_phi_operands.cpp index 7fbdd3b2..5fac9816 100644 --- a/source/fuzz/fuzzer_pass_permute_phi_operands.cpp +++ b/source/fuzz/fuzzer_pass_permute_phi_operands.cpp @@ -40,7 +40,7 @@ void FuzzerPassPermutePhiOperands::Apply() { const protobufs::InstructionDescriptor& /*unused*/) { const auto& inst = *inst_it; - if (inst.opcode() != spv::Op::OpPhi) { + if (inst.opcode() != SpvOpPhi) { return; } diff --git a/source/fuzz/fuzzer_pass_push_ids_through_variables.cpp b/source/fuzz/fuzzer_pass_push_ids_through_variables.cpp index c0397e18..a6c07b4b 100644 --- a/source/fuzz/fuzzer_pass_push_ids_through_variables.cpp +++ b/source/fuzz/fuzzer_pass_push_ids_through_variables.cpp @@ -35,11 +35,10 @@ void FuzzerPassPushIdsThroughVariables::Apply() { opt::BasicBlock::iterator instruction_iterator, const protobufs::InstructionDescriptor& instruction_descriptor) -> void { - assert( - instruction_iterator->opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode()) && - "The opcode of the instruction we might insert before must be " - "the same as the opcode in the descriptor for the instruction"); + assert(instruction_iterator->opcode() == + instruction_descriptor.target_instruction_opcode() && + "The opcode of the instruction we might insert before must be " + "the same as the opcode in the descriptor for the instruction"); // Randomly decide whether to try pushing an id through a variable. if (!GetFuzzerContext()->ChoosePercentage( @@ -56,16 +55,16 @@ void FuzzerPassPushIdsThroughVariables::Apply() { // It must be valid to insert OpStore and OpLoad instructions // before the instruction to insert before. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpStore, instruction_iterator) || + SpvOpStore, instruction_iterator) || !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpLoad, instruction_iterator)) { + SpvOpLoad, instruction_iterator)) { return; } // Randomly decides whether a global or local variable will be added. auto variable_storage_class = GetFuzzerContext()->ChooseEven() - ? spv::StorageClass::Private - : spv::StorageClass::Function; + ? SpvStorageClassPrivate + : SpvStorageClassFunction; // Gets the available basic and pointer types. auto basic_type_ids_and_pointers = @@ -128,13 +127,13 @@ void FuzzerPassPushIdsThroughVariables::Apply() { GetIRContext()->get_def_use_mgr()->GetDef(basic_type_id); assert(type_inst); switch (type_inst->opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeStruct: + case SpvOpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeVector: + case SpvOpTypeStruct: break; default: return; @@ -151,8 +150,7 @@ void FuzzerPassPushIdsThroughVariables::Apply() { value_instructions)] ->result_id(), GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId(), - uint32_t(variable_storage_class), initializer_id, - instruction_descriptor)); + variable_storage_class, initializer_id, instruction_descriptor)); }); } diff --git a/source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.cpp b/source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.cpp index 52c03818..995657cc 100644 --- a/source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.cpp +++ b/source/fuzz/fuzzer_pass_replace_branches_from_dead_blocks_with_exits.cpp @@ -38,13 +38,13 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() { // to be executed with the Fragment execution model. We conservatively only // allow OpKill if every entry point in the module has the Fragment execution // model. - auto fragment_execution_model_guaranteed = std::all_of( - GetIRContext()->module()->entry_points().begin(), - GetIRContext()->module()->entry_points().end(), - [](const opt::Instruction& entry_point) -> bool { - return spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) == - spv::ExecutionModel::Fragment; - }); + auto fragment_execution_model_guaranteed = + std::all_of(GetIRContext()->module()->entry_points().begin(), + GetIRContext()->module()->entry_points().end(), + [](const opt::Instruction& entry_point) -> bool { + return entry_point.GetSingleWordInOperand(0) == + SpvExecutionModelFragment; + }); // Transformations of this type can disable one another. To avoid ordering // bias, we therefore build a set of candidate transformations to apply, and @@ -71,20 +71,20 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() { // Whether we can use OpKill depends on the execution model, and which of // OpReturn and OpReturnValue we can use depends on the return type of the // enclosing function. - std::vector opcodes = {spv::Op::OpUnreachable}; + std::vector opcodes = {SpvOpUnreachable}; if (fragment_execution_model_guaranteed) { - opcodes.emplace_back(spv::Op::OpKill); + opcodes.emplace_back(SpvOpKill); } auto function_return_type = GetIRContext()->get_type_mgr()->GetType(function.type_id()); if (function_return_type->AsVoid()) { - opcodes.emplace_back(spv::Op::OpReturn); + opcodes.emplace_back(SpvOpReturn); } else if (fuzzerutil::CanCreateConstant(GetIRContext(), function.type_id())) { // For simplicity we only allow OpReturnValue if the function return // type is a type for which we can create a constant. This allows us a // zero of the given type as a default return value. - opcodes.emplace_back(spv::Op::OpReturnValue); + opcodes.emplace_back(SpvOpReturnValue); } // Choose one of the available terminator opcodes at random and create a // candidate transformation. @@ -92,7 +92,7 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() { candidate_transformations.emplace_back( TransformationReplaceBranchFromDeadBlockWithExit( block.id(), opcode, - opcode == spv::Op::OpReturnValue + opcode == SpvOpReturnValue ? FindOrCreateZeroConstant(function.type_id(), true) : 0)); } diff --git a/source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.cpp b/source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.cpp index aabc6bc3..af1aacee 100644 --- a/source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.cpp +++ b/source/fuzz/fuzzer_pass_replace_copy_memories_with_loads_stores.cpp @@ -41,7 +41,7 @@ void FuzzerPassReplaceCopyMemoriesWithLoadsStores::Apply() { } // The instruction must be OpCopyMemory. - if (instruction->opcode() != spv::Op::OpCopyMemory) { + if (instruction->opcode() != SpvOpCopyMemory) { return; } diff --git a/source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.cpp b/source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.cpp index c1892be1..d0992a3f 100644 --- a/source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.cpp +++ b/source/fuzz/fuzzer_pass_replace_copy_objects_with_stores_loads.cpp @@ -40,7 +40,7 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() { return; } // The instruction must be OpCopyObject. - if (instruction->opcode() != spv::Op::OpCopyObject) { + if (instruction->opcode() != SpvOpCopyObject) { return; } // The opcode of the type_id instruction cannot be a OpTypePointer, @@ -48,22 +48,21 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() { if (GetIRContext() ->get_def_use_mgr() ->GetDef(instruction->type_id()) - ->opcode() == spv::Op::OpTypePointer) { + ->opcode() == SpvOpTypePointer) { return; } // It must be valid to insert OpStore and OpLoad instructions // before the instruction OpCopyObject. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpStore, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore, instruction) || - !fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, - instruction)) { + !fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, instruction)) { return; } // Randomly decides whether a global or local variable will be added. auto variable_storage_class = GetFuzzerContext()->ChooseEven() - ? spv::StorageClass::Private - : spv::StorageClass::Function; + ? SpvStorageClassPrivate + : SpvStorageClassFunction; // Find or create a constant to initialize the variable from. The type of // |instruction| must be such that the function FindOrCreateConstant can be @@ -80,7 +79,7 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() { // Apply the transformation replacing OpCopyObject with Store and Load. ApplyTransformation(TransformationReplaceCopyObjectWithStoreLoad( instruction->result_id(), GetFuzzerContext()->GetFreshId(), - uint32_t(variable_storage_class), variable_initializer_id)); + variable_storage_class, variable_initializer_id)); }); } diff --git a/source/fuzz/fuzzer_pass_replace_irrelevant_ids.cpp b/source/fuzz/fuzzer_pass_replace_irrelevant_ids.cpp index 4c0bd859..4d55ae84 100644 --- a/source/fuzz/fuzzer_pass_replace_irrelevant_ids.cpp +++ b/source/fuzz/fuzzer_pass_replace_irrelevant_ids.cpp @@ -73,7 +73,7 @@ void FuzzerPassReplaceIrrelevantIds::Apply() { // we cannot use these as replacements. for (const auto& pair : GetIRContext()->get_def_use_mgr()->id_to_defs()) { uint32_t type_id = pair.second->type_id(); - if (pair.second->opcode() != spv::Op::OpFunction && type_id && + if (pair.second->opcode() != SpvOpFunction && type_id && types_to_ids.count(type_id)) { types_to_ids[type_id].push_back(pair.first); } diff --git a/source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.cpp b/source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.cpp index 8d292ac3..38ac048b 100644 --- a/source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.cpp +++ b/source/fuzz/fuzzer_pass_replace_loads_stores_with_copy_memories.cpp @@ -50,9 +50,9 @@ void FuzzerPassReplaceLoadsStoresWithCopyMemories::Apply() { std::unordered_map current_op_loads; for (auto& instruction : block) { // Add a potential OpLoad instruction. - if (instruction.opcode() == spv::Op::OpLoad) { + if (instruction.opcode() == SpvOpLoad) { current_op_loads[instruction.result_id()] = &instruction; - } else if (instruction.opcode() == spv::Op::OpStore) { + } else if (instruction.opcode() == SpvOpStore) { if (current_op_loads.find(instruction.GetSingleWordOperand(1)) != current_op_loads.end()) { // We have found the matching OpLoad instruction to the current @@ -73,7 +73,7 @@ void FuzzerPassReplaceLoadsStoresWithCopyMemories::Apply() { opt::Instruction* source_id = GetIRContext()->get_def_use_mgr()->GetDef( it->second->GetSingleWordOperand(2)); - spv::StorageClass storage_class = + SpvStorageClass storage_class = fuzzerutil::GetStorageClassFromPointerType( GetIRContext(), source_id->type_id()); if (!TransformationReplaceLoadStoreWithCopyMemory:: diff --git a/source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.cpp b/source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.cpp index 26475ab2..ea90a7ac 100644 --- a/source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.cpp +++ b/source/fuzz/fuzzer_pass_replace_opphi_ids_from_dead_predecessors.cpp @@ -50,7 +50,7 @@ void FuzzerPassReplaceOpPhiIdsFromDeadPredecessors::Apply() { block->id(), [this, &function, block, &transformations]( opt::Instruction* instruction, uint32_t) { // Only consider OpPhi instructions. - if (instruction->opcode() != spv::Op::OpPhi) { + if (instruction->opcode() != SpvOpPhi) { return; } diff --git a/source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.cpp b/source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.cpp index 4691e0a8..72ed0936 100644 --- a/source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.cpp +++ b/source/fuzz/fuzzer_pass_replace_opselects_with_conditional_branches.cpp @@ -52,7 +52,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() { for (auto& instruction : block) { // We only care about OpSelect instructions. - if (instruction.opcode() != spv::Op::OpSelect) { + if (instruction.opcode() != SpvOpSelect) { continue; } @@ -69,7 +69,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() { ->get_def_use_mgr() ->GetDef(fuzzerutil::GetTypeId( GetIRContext(), instruction.GetSingleWordInOperand(0))) - ->opcode() != spv::Op::OpTypeBool) { + ->opcode() != SpvOpTypeBool) { continue; } @@ -136,7 +136,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() { bool FuzzerPassReplaceOpSelectsWithConditionalBranches:: InstructionNeedsSplitBefore(opt::Instruction* instruction) { - assert(instruction && instruction->opcode() == spv::Op::OpSelect && + assert(instruction && instruction->opcode() == SpvOpSelect && "The instruction must be OpSelect."); auto block = GetIRContext()->get_instr_block(instruction); @@ -163,7 +163,7 @@ bool FuzzerPassReplaceOpSelectsWithConditionalBranches:: auto predecessor = GetIRContext()->get_instr_block( GetIRContext()->cfg()->preds(block->id())[0]); return predecessor->MergeBlockIdIfAny() || - predecessor->terminator()->opcode() != spv::Op::OpBranch; + predecessor->terminator()->opcode() != SpvOpBranch; } } // namespace fuzz diff --git a/source/fuzz/fuzzer_pass_replace_parameter_with_global.cpp b/source/fuzz/fuzzer_pass_replace_parameter_with_global.cpp index d7eddca1..7fb7b0d2 100644 --- a/source/fuzz/fuzzer_pass_replace_parameter_with_global.cpp +++ b/source/fuzz/fuzzer_pass_replace_parameter_with_global.cpp @@ -72,8 +72,7 @@ void FuzzerPassReplaceParameterWithGlobal::Apply() { assert(replaced_param && "Unable to find a parameter to replace"); // Make sure type id for the global variable exists in the module. - FindOrCreatePointerType(replaced_param->type_id(), - spv::StorageClass::Private); + FindOrCreatePointerType(replaced_param->type_id(), SpvStorageClassPrivate); // Make sure initializer for the global variable exists in the module. FindOrCreateZeroConstant(replaced_param->type_id(), false); diff --git a/source/fuzz/fuzzer_pass_split_blocks.cpp b/source/fuzz/fuzzer_pass_split_blocks.cpp index 5b4afcc5..40a4151d 100644 --- a/source/fuzz/fuzzer_pass_split_blocks.cpp +++ b/source/fuzz/fuzzer_pass_split_blocks.cpp @@ -65,7 +65,7 @@ void FuzzerPassSplitBlocks::Apply() { // Counts the number of times we have seen each opcode since we reset the // base instruction. - std::map skip_count; + std::map skip_count; // Consider every instruction in the block. The label is excluded: it is // only necessary to consider it as a base in case the first instruction @@ -78,7 +78,7 @@ void FuzzerPassSplitBlocks::Apply() { base = inst.result_id(); skip_count.clear(); } - const spv::Op opcode = inst.opcode(); + const SpvOp opcode = inst.opcode(); instruction_descriptors.emplace_back(MakeInstructionDescriptor( base, opcode, skip_count.count(opcode) ? skip_count.at(opcode) : 0)); if (!inst.HasResultId()) { diff --git a/source/fuzz/fuzzer_pass_swap_conditional_branch_operands.cpp b/source/fuzz/fuzzer_pass_swap_conditional_branch_operands.cpp index 72c8358a..f8bf111d 100644 --- a/source/fuzz/fuzzer_pass_swap_conditional_branch_operands.cpp +++ b/source/fuzz/fuzzer_pass_swap_conditional_branch_operands.cpp @@ -39,7 +39,7 @@ void FuzzerPassSwapBranchConditionalOperands::Apply() { const protobufs::InstructionDescriptor& instruction_descriptor) { const auto& inst = *inst_it; - if (inst.opcode() != spv::Op::OpBranchConditional) { + if (inst.opcode() != SpvOpBranchConditional) { return; } diff --git a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp index 2a1ad6e5..ac2b1565 100644 --- a/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp +++ b/source/fuzz/fuzzer_pass_toggle_access_chain_instruction.cpp @@ -36,9 +36,8 @@ void FuzzerPassToggleAccessChainInstruction::Apply() { // probabilistically applied. context->module()->ForEachInst([this, context](opt::Instruction* instruction) { - spv::Op opcode = instruction->opcode(); - if ((opcode == spv::Op::OpAccessChain || - opcode == spv::Op::OpInBoundsAccessChain) && + SpvOp opcode = instruction->opcode(); + if ((opcode == SpvOpAccessChain || opcode == SpvOpInBoundsAccessChain) && GetFuzzerContext()->ChoosePercentage( GetFuzzerContext()->GetChanceOfTogglingAccessChainInstruction())) { auto instructionDescriptor = diff --git a/source/fuzz/fuzzer_pass_wrap_vector_synonym.cpp b/source/fuzz/fuzzer_pass_wrap_vector_synonym.cpp index 55fbe2c2..35adcfec 100644 --- a/source/fuzz/fuzzer_pass_wrap_vector_synonym.cpp +++ b/source/fuzz/fuzzer_pass_wrap_vector_synonym.cpp @@ -52,7 +52,7 @@ void FuzzerPassWrapVectorSynonym::Apply() { // It must be valid to insert an OpCompositeConstruct instruction // before |instruction_iterator|. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeConstruct, instruction_iterator)) { + SpvOpCompositeConstruct, instruction_iterator)) { return; } diff --git a/source/fuzz/fuzzer_util.cpp b/source/fuzz/fuzzer_util.cpp index e85ff2fb..1d368a9f 100644 --- a/source/fuzz/fuzzer_util.cpp +++ b/source/fuzz/fuzzer_util.cpp @@ -49,7 +49,7 @@ uint32_t MaybeGetOpConstant(opt::IRContext* ir_context, const std::vector& words, uint32_t type_id, bool is_irrelevant) { for (const auto& inst : ir_context->types_values()) { - if (inst.opcode() == spv::Op::OpConstant && inst.type_id() == type_id && + if (inst.opcode() == SpvOpConstant && inst.type_id() == type_id && inst.GetInOperand(0).words == words && transformation_context.GetFactManager()->IdIsIrrelevant( inst.result_id()) == is_irrelevant) { @@ -112,7 +112,7 @@ opt::BasicBlock* MaybeFindBlock(opt::IRContext* context, // No instruction defining this id was found. return nullptr; } - if (inst->opcode() != spv::Op::OpLabel) { + if (inst->opcode() != SpvOpLabel) { // The instruction defining the id is not a label, so it cannot be a block // id. return nullptr; @@ -138,7 +138,7 @@ bool PhiIdsOkForNewEdge( // makes sense here because we need to increment |phi_index| for each OpPhi // instruction. for (auto& inst : *bb_to) { - if (inst.opcode() != spv::Op::OpPhi) { + if (inst.opcode() != SpvOpPhi) { // The OpPhi instructions all occur at the start of the block; if we find // a non-OpPhi then we have seen them all. break; @@ -189,24 +189,24 @@ opt::Instruction CreateUnreachableEdgeInstruction(opt::IRContext* ir_context, const auto* bb_from = MaybeFindBlock(ir_context, bb_from_id); assert(bb_from && "|bb_from_id| is invalid"); assert(MaybeFindBlock(ir_context, bb_to_id) && "|bb_to_id| is invalid"); - assert(bb_from->terminator()->opcode() == spv::Op::OpBranch && + assert(bb_from->terminator()->opcode() == SpvOpBranch && "Precondition on terminator of bb_from is not satisfied"); // Get the id of the boolean constant to be used as the condition. auto condition_inst = ir_context->get_def_use_mgr()->GetDef(bool_id); assert(condition_inst && - (condition_inst->opcode() == spv::Op::OpConstantTrue || - condition_inst->opcode() == spv::Op::OpConstantFalse) && + (condition_inst->opcode() == SpvOpConstantTrue || + condition_inst->opcode() == SpvOpConstantFalse) && "|bool_id| is invalid"); - auto condition_value = condition_inst->opcode() == spv::Op::OpConstantTrue; + auto condition_value = condition_inst->opcode() == SpvOpConstantTrue; auto successor_id = bb_from->terminator()->GetSingleWordInOperand(0); // Add the dead branch, by turning OpBranch into OpBranchConditional, and // ordering the targets depending on whether the given boolean corresponds to // true or false. return opt::Instruction( - ir_context, spv::Op::OpBranchConditional, 0, 0, + ir_context, SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {bool_id}}, {SPV_OPERAND_TYPE_ID, {condition_value ? successor_id : bb_to_id}}, {SPV_OPERAND_TYPE_ID, {condition_value ? bb_to_id : successor_id}}}); @@ -228,7 +228,7 @@ void AddUnreachableEdgeAndUpdateOpPhis( if (!from_to_edge_already_exists) { uint32_t phi_index = 0; for (auto& inst : *bb_to) { - if (inst.opcode() != spv::Op::OpPhi) { + if (inst.opcode() != SpvOpPhi) { break; } assert(phi_index < static_cast(phi_ids.size()) && @@ -285,30 +285,28 @@ opt::BasicBlock::iterator GetIteratorForInstruction( } bool CanInsertOpcodeBeforeInstruction( - spv::Op opcode, const opt::BasicBlock::iterator& instruction_in_block) { + SpvOp opcode, const opt::BasicBlock::iterator& instruction_in_block) { if (instruction_in_block->PreviousNode() && - (instruction_in_block->PreviousNode()->opcode() == spv::Op::OpLoopMerge || - instruction_in_block->PreviousNode()->opcode() == - spv::Op::OpSelectionMerge)) { + (instruction_in_block->PreviousNode()->opcode() == SpvOpLoopMerge || + instruction_in_block->PreviousNode()->opcode() == SpvOpSelectionMerge)) { // We cannot insert directly after a merge instruction. return false; } - if (opcode != spv::Op::OpVariable && - instruction_in_block->opcode() == spv::Op::OpVariable) { + if (opcode != SpvOpVariable && + instruction_in_block->opcode() == SpvOpVariable) { // We cannot insert a non-OpVariable instruction directly before a // variable; variables in a function must be contiguous in the entry block. return false; } // We cannot insert a non-OpPhi instruction directly before an OpPhi, because // OpPhi instructions need to be contiguous at the start of a block. - return opcode == spv::Op::OpPhi || - instruction_in_block->opcode() != spv::Op::OpPhi; + return opcode == SpvOpPhi || instruction_in_block->opcode() != SpvOpPhi; } bool CanMakeSynonymOf(opt::IRContext* ir_context, const TransformationContext& transformation_context, const opt::Instruction& inst) { - if (inst.opcode() == spv::Op::OpSampledImage) { + if (inst.opcode() == SpvOpSampledImage) { // The SPIR-V data rules say that only very specific instructions may // may consume the result id of an OpSampledImage, and this excludes the // instructions that are used for making synonyms. @@ -328,15 +326,15 @@ bool CanMakeSynonymOf(opt::IRContext* ir_context, return false; } auto type_inst = ir_context->get_def_use_mgr()->GetDef(inst.type_id()); - if (type_inst->opcode() == spv::Op::OpTypeVoid) { + if (type_inst->opcode() == SpvOpTypeVoid) { // We only make synonyms of instructions that define objects, and an object // cannot have void type. return false; } - if (type_inst->opcode() == spv::Op::OpTypePointer) { + if (type_inst->opcode() == SpvOpTypePointer) { switch (inst.opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: // We disallow making synonyms of null or undefined pointers. This is // to provide the property that if the original shader exhibited no bad // pointer accesses, the transformed shader will not either. @@ -375,22 +373,22 @@ uint32_t WalkOneCompositeTypeIndex(opt::IRContext* context, context->get_def_use_mgr()->GetDef(base_object_type_id); assert(should_be_composite_type && "The type should exist."); switch (should_be_composite_type->opcode()) { - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { auto array_length = GetArraySize(*should_be_composite_type, context); if (array_length == 0 || index >= array_length) { return 0; } return should_be_composite_type->GetSingleWordInOperand(0); } - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: { + case SpvOpTypeMatrix: + case SpvOpTypeVector: { auto count = should_be_composite_type->GetSingleWordInOperand(1); if (index >= count) { return 0; } return should_be_composite_type->GetSingleWordInOperand(0); } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { if (index >= GetNumberOfStructMembers(*should_be_composite_type)) { return 0; } @@ -417,7 +415,7 @@ uint32_t WalkCompositeTypeIndices( uint32_t GetNumberOfStructMembers( const opt::Instruction& struct_type_instruction) { - assert(struct_type_instruction.opcode() == spv::Op::OpTypeStruct && + assert(struct_type_instruction.opcode() == SpvOpTypeStruct && "An OpTypeStruct instruction is required here."); return struct_type_instruction.NumInOperands(); } @@ -438,15 +436,15 @@ uint32_t GetArraySize(const opt::Instruction& array_type_instruction, uint32_t GetBoundForCompositeIndex(const opt::Instruction& composite_type_inst, opt::IRContext* ir_context) { switch (composite_type_inst.opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: return fuzzerutil::GetArraySize(composite_type_inst, ir_context); - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: return composite_type_inst.GetSingleWordInOperand(1); - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { return fuzzerutil::GetNumberOfStructMembers(composite_type_inst); } - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: assert(false && "GetBoundForCompositeIndex should not be invoked with an " "OpTypeRuntimeArray, which does not have a static bound."); @@ -457,27 +455,27 @@ uint32_t GetBoundForCompositeIndex(const opt::Instruction& composite_type_inst, } } -spv::MemorySemanticsMask GetMemorySemanticsForStorageClass( - spv::StorageClass storage_class) { +SpvMemorySemanticsMask GetMemorySemanticsForStorageClass( + SpvStorageClass storage_class) { switch (storage_class) { - case spv::StorageClass::Workgroup: - return spv::MemorySemanticsMask::WorkgroupMemory; + case SpvStorageClassWorkgroup: + return SpvMemorySemanticsWorkgroupMemoryMask; - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - return spv::MemorySemanticsMask::UniformMemory; + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + return SpvMemorySemanticsUniformMemoryMask; - case spv::StorageClass::CrossWorkgroup: - return spv::MemorySemanticsMask::CrossWorkgroupMemory; + case SpvStorageClassCrossWorkgroup: + return SpvMemorySemanticsCrossWorkgroupMemoryMask; - case spv::StorageClass::AtomicCounter: - return spv::MemorySemanticsMask::AtomicCounterMemory; + case SpvStorageClassAtomicCounter: + return SpvMemorySemanticsAtomicCounterMemoryMask; - case spv::StorageClass::Image: - return spv::MemorySemanticsMask::ImageMemory; + case SpvStorageClassImage: + return SpvMemorySemanticsImageMemoryMask; default: - return spv::MemorySemanticsMask::MaskNone; + return SpvMemorySemanticsMaskNone; } } @@ -564,8 +562,8 @@ bool IsMergeOrContinue(opt::IRContext* ir_context, uint32_t block_id) { [&result](const opt::Instruction* use_instruction, uint32_t /*unused*/) -> bool { switch (use_instruction->opcode()) { - case spv::Op::OpLoopMerge: - case spv::Op::OpSelectionMerge: + case SpvOpLoopMerge: + case SpvOpSelectionMerge: result = true; return false; default: @@ -583,7 +581,7 @@ uint32_t GetLoopFromMergeBlock(opt::IRContext* ir_context, [ir_context, &result](opt::Instruction* use_instruction, uint32_t use_index) -> bool { switch (use_instruction->opcode()) { - case spv::Op::OpLoopMerge: + case SpvOpLoopMerge: // The merge block operand is the first operand in OpLoopMerge. if (use_index == 0) { result = ir_context->get_instr_block(use_instruction)->id(); @@ -601,7 +599,7 @@ uint32_t FindFunctionType(opt::IRContext* ir_context, const std::vector& type_ids) { // Look through the existing types for a match. for (auto& type_or_value : ir_context->types_values()) { - if (type_or_value.opcode() != spv::Op::OpTypeFunction) { + if (type_or_value.opcode() != SpvOpTypeFunction) { // We are only interested in function types. continue; } @@ -643,8 +641,8 @@ opt::Function* FindFunction(opt::IRContext* ir_context, uint32_t function_id) { bool FunctionContainsOpKillOrUnreachable(const opt::Function& function) { for (auto& block : function) { - if (block.terminator()->opcode() == spv::Op::OpKill || - block.terminator()->opcode() == spv::Op::OpUnreachable) { + if (block.terminator()->opcode() == SpvOpKill || + block.terminator()->opcode() == SpvOpUnreachable) { return true; } } @@ -671,7 +669,7 @@ bool IdIsAvailableAtUse(opt::IRContext* context, context->get_instr_block(use_instruction)->GetParent(); // If the id a function parameter, it needs to be associated with the // function containing the use. - if (defining_instruction->opcode() == spv::Op::OpFunctionParameter) { + if (defining_instruction->opcode() == SpvOpFunctionParameter) { return InstructionIsFunctionParameter(defining_instruction, enclosing_function); } @@ -689,7 +687,7 @@ bool IdIsAvailableAtUse(opt::IRContext* context, return false; } auto dominator_analysis = context->GetDominatorAnalysis(enclosing_function); - if (use_instruction->opcode() == spv::Op::OpPhi) { + if (use_instruction->opcode() == SpvOpPhi) { // In the case where the use is an operand to OpPhi, it is actually the // *parent* block associated with the operand that must be dominated by // the synonym. @@ -712,7 +710,7 @@ bool IdIsAvailableBeforeInstruction(opt::IRContext* context, context->get_instr_block(instruction)->GetParent(); // If the id a function parameter, it needs to be associated with the // function containing the instruction. - if (id_definition->opcode() == spv::Op::OpFunctionParameter) { + if (id_definition->opcode() == SpvOpFunctionParameter) { return InstructionIsFunctionParameter(id_definition, function_enclosing_instruction); } @@ -734,7 +732,7 @@ bool IdIsAvailableBeforeInstruction(opt::IRContext* context, // the instruction. return true; } - if (id_definition->opcode() == spv::Op::OpVariable && + if (id_definition->opcode() == SpvOpVariable && function_enclosing_instruction == context->get_instr_block(id)->GetParent()) { assert(!context->IsReachable(*context->get_instr_block(instruction)) && @@ -749,7 +747,7 @@ bool IdIsAvailableBeforeInstruction(opt::IRContext* context, bool InstructionIsFunctionParameter(opt::Instruction* instruction, opt::Function* function) { - if (instruction->opcode() != spv::Op::OpFunctionParameter) { + if (instruction->opcode() != SpvOpFunctionParameter) { return false; } bool found_parameter = false; @@ -769,8 +767,7 @@ uint32_t GetTypeId(opt::IRContext* context, uint32_t result_id) { } uint32_t GetPointeeTypeIdFromPointerType(opt::Instruction* pointer_type_inst) { - assert(pointer_type_inst && - pointer_type_inst->opcode() == spv::Op::OpTypePointer && + assert(pointer_type_inst && pointer_type_inst->opcode() == SpvOpTypePointer && "Precondition: |pointer_type_inst| must be OpTypePointer."); return pointer_type_inst->GetSingleWordInOperand(1); } @@ -781,28 +778,26 @@ uint32_t GetPointeeTypeIdFromPointerType(opt::IRContext* context, context->get_def_use_mgr()->GetDef(pointer_type_id)); } -spv::StorageClass GetStorageClassFromPointerType( +SpvStorageClass GetStorageClassFromPointerType( opt::Instruction* pointer_type_inst) { - assert(pointer_type_inst && - pointer_type_inst->opcode() == spv::Op::OpTypePointer && + assert(pointer_type_inst && pointer_type_inst->opcode() == SpvOpTypePointer && "Precondition: |pointer_type_inst| must be OpTypePointer."); - return static_cast( + return static_cast( pointer_type_inst->GetSingleWordInOperand(0)); } -spv::StorageClass GetStorageClassFromPointerType(opt::IRContext* context, - uint32_t pointer_type_id) { +SpvStorageClass GetStorageClassFromPointerType(opt::IRContext* context, + uint32_t pointer_type_id) { return GetStorageClassFromPointerType( context->get_def_use_mgr()->GetDef(pointer_type_id)); } uint32_t MaybeGetPointerType(opt::IRContext* context, uint32_t pointee_type_id, - spv::StorageClass storage_class) { + SpvStorageClass storage_class) { for (auto& inst : context->types_values()) { switch (inst.opcode()) { - case spv::Op::OpTypePointer: - if (spv::StorageClass(inst.GetSingleWordInOperand(0)) == - storage_class && + case SpvOpTypePointer: + if (inst.GetSingleWordInOperand(0) == storage_class && inst.GetSingleWordInOperand(1) == pointee_type_id) { return inst.result_id(); } @@ -823,30 +818,30 @@ uint32_t InOperandIndexFromOperandIndex(const opt::Instruction& inst, bool IsNullConstantSupported(opt::IRContext* ir_context, const opt::Instruction& type_inst) { switch (type_inst.opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeDeviceEvent: - case spv::Op::OpTypeEvent: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeQueue: - case spv::Op::OpTypeReserveId: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeStruct: + case SpvOpTypeArray: + case SpvOpTypeBool: + case SpvOpTypeDeviceEvent: + case SpvOpTypeEvent: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeMatrix: + case SpvOpTypeQueue: + case SpvOpTypeReserveId: + case SpvOpTypeVector: + case SpvOpTypeStruct: return true; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: // Null pointers are allowed if the VariablePointers capability is // enabled, or if the VariablePointersStorageBuffer capability is enabled // and the pointer type has StorageBuffer as its storage class. if (ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointers)) { + SpvCapabilityVariablePointers)) { return true; } if (ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)) { - return spv::StorageClass(type_inst.GetSingleWordInOperand(0)) == - spv::StorageClass::StorageBuffer; + SpvCapabilityVariablePointersStorageBuffer)) { + return type_inst.GetSingleWordInOperand(0) == + SpvStorageClassStorageBuffer; } return false; default: @@ -890,22 +885,22 @@ void AddVariableIdToEntryPointInterfaces(opt::IRContext* context, uint32_t id) { opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id, uint32_t type_id, - spv::StorageClass storage_class, + SpvStorageClass storage_class, uint32_t initializer_id) { // Check various preconditions. assert(result_id != 0 && "Result id can't be 0"); - assert((storage_class == spv::StorageClass::Private || - storage_class == spv::StorageClass::Workgroup) && + assert((storage_class == SpvStorageClassPrivate || + storage_class == SpvStorageClassWorkgroup) && "Variable's storage class must be either Private or Workgroup"); auto* type_inst = context->get_def_use_mgr()->GetDef(type_id); (void)type_inst; // Variable becomes unused in release mode. - assert(type_inst && type_inst->opcode() == spv::Op::OpTypePointer && + assert(type_inst && type_inst->opcode() == SpvOpTypePointer && GetStorageClassFromPointerType(type_inst) == storage_class && "Variable's type is invalid"); - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { assert(initializer_id == 0); } @@ -927,7 +922,7 @@ opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id, } auto new_instruction = MakeUnique( - context, spv::Op::OpVariable, type_id, result_id, std::move(operands)); + context, SpvOpVariable, type_id, result_id, std::move(operands)); auto result = new_instruction.get(); context->module()->AddGlobalValue(std::move(new_instruction)); @@ -945,9 +940,8 @@ opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id, auto* type_inst = context->get_def_use_mgr()->GetDef(type_id); (void)type_inst; // Variable becomes unused in release mode. - assert(type_inst && type_inst->opcode() == spv::Op::OpTypePointer && - GetStorageClassFromPointerType(type_inst) == - spv::StorageClass::Function && + assert(type_inst && type_inst->opcode() == SpvOpTypePointer && + GetStorageClassFromPointerType(type_inst) == SpvStorageClassFunction && "Variable's type is invalid"); const auto* constant_inst = @@ -962,10 +956,10 @@ opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id, assert(function && "Function id is invalid"); auto new_instruction = MakeUnique( - context, spv::Op::OpVariable, type_id, result_id, - opt::Instruction::OperandList{{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}, - {SPV_OPERAND_TYPE_ID, {initializer_id}}}); + context, SpvOpVariable, type_id, result_id, + opt::Instruction::OperandList{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, + {SPV_OPERAND_TYPE_ID, {initializer_id}}}); auto result = new_instruction.get(); function->begin()->begin()->InsertBefore(std::move(new_instruction)); @@ -1028,7 +1022,7 @@ std::vector GetCallers(opt::IRContext* ir_context, std::vector result; ir_context->get_def_use_mgr()->ForEachUser( function_id, [&result, function_id](opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpFunctionCall && + if (inst->opcode() == SpvOpFunctionCall && inst->GetSingleWordInOperand(0) == function_id) { result.push_back(inst); } @@ -1143,7 +1137,7 @@ void AddFunctionType(opt::IRContext* ir_context, uint32_t result_id, } ir_context->AddType(MakeUnique( - ir_context, spv::Op::OpTypeFunction, 0, result_id, std::move(operands))); + ir_context, SpvOpTypeFunction, 0, result_id, std::move(operands))); UpdateModuleIdBound(ir_context, result_id); } @@ -1192,7 +1186,7 @@ uint32_t MaybeGetVectorType(opt::IRContext* ir_context, uint32_t MaybeGetStructType(opt::IRContext* ir_context, const std::vector& component_type_ids) { for (auto& type_or_value : ir_context->types_values()) { - if (type_or_value.opcode() != spv::Op::OpTypeStruct || + if (type_or_value.opcode() != SpvOpTypeStruct || type_or_value.NumInOperands() != static_cast(component_type_ids.size())) { continue; @@ -1225,11 +1219,11 @@ uint32_t MaybeGetZeroConstant( assert(type_inst && "|scalar_or_composite_type_id| is invalid"); switch (type_inst->opcode()) { - case spv::Op::OpTypeBool: + case SpvOpTypeBool: return MaybeGetBoolConstant(ir_context, transformation_context, false, is_irrelevant); - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: { + case SpvOpTypeFloat: + case SpvOpTypeInt: { const auto width = type_inst->GetSingleWordInOperand(0); std::vector words = {0}; if (width > 32) { @@ -1239,7 +1233,7 @@ uint32_t MaybeGetZeroConstant( return MaybeGetScalarConstant(ir_context, transformation_context, words, scalar_or_composite_type_id, is_irrelevant); } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { std::vector component_ids; for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { const auto component_type_id = type_inst->GetSingleWordInOperand(i); @@ -1266,8 +1260,8 @@ uint32_t MaybeGetZeroConstant( ir_context, transformation_context, component_ids, scalar_or_composite_type_id, is_irrelevant); } - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: { + case SpvOpTypeMatrix: + case SpvOpTypeVector: { const auto component_type_id = type_inst->GetSingleWordInOperand(0); auto component_id = MaybeGetZeroConstant( @@ -1290,7 +1284,7 @@ uint32_t MaybeGetZeroConstant( std::vector(component_count, component_id), scalar_or_composite_type_id, is_irrelevant); } - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { const auto component_type_id = type_inst->GetSingleWordInOperand(0); auto component_id = MaybeGetZeroConstant( @@ -1325,16 +1319,16 @@ bool CanCreateConstant(opt::IRContext* ir_context, uint32_t type_id) { assert(spvOpcodeGeneratesType(type_instr->opcode()) && "A type-generating opcode was expected."); switch (type_instr->opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeMatrix: + case SpvOpTypeVector: return true; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: return CanCreateConstant(ir_context, type_instr->GetSingleWordInOperand(0)); - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: if (HasBlockOrBufferBlockDecoration(ir_context, type_id)) { return false; } @@ -1383,7 +1377,7 @@ uint32_t MaybeGetCompositeConstant( assert(IsCompositeType(type) && "|composite_type_id| is invalid"); for (const auto& inst : ir_context->types_values()) { - if (inst.opcode() == spv::Op::OpConstantComposite && + if (inst.opcode() == SpvOpConstantComposite && inst.type_id() == composite_type_id && transformation_context.GetFactManager()->IdIsIrrelevant( inst.result_id()) == is_irrelevant && @@ -1463,8 +1457,7 @@ uint32_t MaybeGetBoolConstant( bool is_irrelevant) { if (auto type_id = MaybeGetBoolType(ir_context)) { for (const auto& inst : ir_context->types_values()) { - if (inst.opcode() == - (value ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse) && + if (inst.opcode() == (value ? SpvOpConstantTrue : SpvOpConstantFalse) && inst.type_id() == type_id && transformation_context.GetFactManager()->IdIsIrrelevant( inst.result_id()) == is_irrelevant) { @@ -1559,13 +1552,13 @@ MapToRepeatedUInt32Pair(const std::map& data) { opt::Instruction* GetLastInsertBeforeInstruction(opt::IRContext* ir_context, uint32_t block_id, - spv::Op opcode) { + SpvOp opcode) { // CFG::block uses std::map::at which throws an exception when |block_id| is // invalid. The error message is unhelpful, though. Thus, we test that // |block_id| is valid here. const auto* label_inst = ir_context->get_def_use_mgr()->GetDef(block_id); (void)label_inst; // Make compilers happy in release mode. - assert(label_inst && label_inst->opcode() == spv::Op::OpLabel && + assert(label_inst && label_inst->opcode() == SpvOpLabel && "|block_id| is invalid"); auto* block = ir_context->cfg()->block(block_id); @@ -1631,7 +1624,7 @@ bool IdUseCanBeReplaced(opt::IRContext* ir_context, assert(composite_type_being_accessed->AsStruct()); auto constant_index_instruction = ir_context->get_def_use_mgr()->GetDef( use_instruction->GetSingleWordInOperand(index_in_operand)); - assert(constant_index_instruction->opcode() == spv::Op::OpConstant); + assert(constant_index_instruction->opcode() == SpvOpConstant); uint32_t member_index = constant_index_instruction->GetSingleWordInOperand(0); composite_type_being_accessed = @@ -1648,7 +1641,7 @@ bool IdUseCanBeReplaced(opt::IRContext* ir_context, } } - if (use_instruction->opcode() == spv::Op::OpFunctionCall && + if (use_instruction->opcode() == SpvOpFunctionCall && use_in_operand_index > 0) { // This is a function call argument. It is not allowed to have pointer // type. @@ -1670,7 +1663,7 @@ bool IdUseCanBeReplaced(opt::IRContext* ir_context, } } - if (use_instruction->opcode() == spv::Op::OpImageTexelPointer && + if (use_instruction->opcode() == SpvOpImageTexelPointer && use_in_operand_index == 2) { // The OpImageTexelPointer instruction has a Sample parameter that in some // situations must be an id for the value 0. To guard against disrupting @@ -1678,38 +1671,38 @@ bool IdUseCanBeReplaced(opt::IRContext* ir_context, return false; } - if (ir_context->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + if (ir_context->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { // With the Shader capability, memory scope and memory semantics operands // are required to be constants, so they cannot be replaced arbitrarily. switch (use_instruction->opcode()) { - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: + case SpvOpAtomicLoad: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: if (use_in_operand_index == 1 || use_in_operand_index == 2) { return false; } break; - case spv::Op::OpAtomicCompareExchange: + case SpvOpAtomicCompareExchange: if (use_in_operand_index == 1 || use_in_operand_index == 2 || use_in_operand_index == 3) { return false; } break; - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicFlagTestAndSet: - case spv::Op::OpAtomicFlagClear: - case spv::Op::OpAtomicFAddEXT: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicFlagTestAndSet: + case SpvOpAtomicFlagClear: + case SpvOpAtomicFAddEXT: assert(false && "Not allowed with the Shader capability."); default: break; @@ -1722,17 +1715,17 @@ bool IdUseCanBeReplaced(opt::IRContext* ir_context, bool MembersHaveBuiltInDecoration(opt::IRContext* ir_context, uint32_t struct_type_id) { const auto* type_inst = ir_context->get_def_use_mgr()->GetDef(struct_type_id); - assert(type_inst && type_inst->opcode() == spv::Op::OpTypeStruct && + assert(type_inst && type_inst->opcode() == SpvOpTypeStruct && "|struct_type_id| is not a result id of an OpTypeStruct"); uint32_t builtin_count = 0; ir_context->get_def_use_mgr()->ForEachUser( type_inst, [struct_type_id, &builtin_count](const opt::Instruction* user) { - if (user->opcode() == spv::Op::OpMemberDecorate && + if (user->opcode() == SpvOpMemberDecorate && user->GetSingleWordInOperand(0) == struct_type_id && - static_cast(user->GetSingleWordInOperand(2)) == - spv::Decoration::BuiltIn) { + static_cast(user->GetSingleWordInOperand(2)) == + SpvDecorationBuiltIn) { ++builtin_count; } }); @@ -1745,11 +1738,9 @@ bool MembersHaveBuiltInDecoration(opt::IRContext* ir_context, } bool HasBlockOrBufferBlockDecoration(opt::IRContext* ir_context, uint32_t id) { - for (auto decoration : - {spv::Decoration::Block, spv::Decoration::BufferBlock}) { + for (auto decoration : {SpvDecorationBlock, SpvDecorationBufferBlock}) { if (!ir_context->get_decoration_mgr()->WhileEachDecoration( - id, uint32_t(decoration), - [](const opt::Instruction & /*unused*/) -> bool { + id, decoration, [](const opt::Instruction & /*unused*/) -> bool { return false; })) { return true; @@ -1771,7 +1762,7 @@ bool SplittingBeforeInstructionSeparatesOpSampledImageDefinitionFromUse( if (before_split) { // If the instruction comes before the split and its opcode is // OpSampledImage, record its result id. - if (instruction.opcode() == spv::Op::OpSampledImage) { + if (instruction.opcode() == SpvOpSampledImage) { sampled_image_result_ids.insert(instruction.result_id()); } } else { @@ -1793,110 +1784,110 @@ bool SplittingBeforeInstructionSeparatesOpSampledImageDefinitionFromUse( bool InstructionHasNoSideEffects(const opt::Instruction& instruction) { switch (instruction.opcode()) { - case spv::Op::OpUndef: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpArrayLength: - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCopyObject: - case spv::Op::OpTranspose: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: - case spv::Op::OpBitcast: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpCopyLogical: - case spv::Op::OpPhi: - case spv::Op::OpPtrEqual: - case spv::Op::OpPtrNotEqual: + case SpvOpUndef: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpArrayLength: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: + case SpvOpCopyObject: + case SpvOpTranspose: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: + case SpvOpBitcast: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpCopyLogical: + case SpvOpPhi: + case SpvOpPtrEqual: + case SpvOpPtrNotEqual: return true; default: return false; @@ -1984,7 +1975,7 @@ bool NewTerminatorPreservesDominationRules(opt::IRContext* ir_context, for (const auto& inst : block) { for (uint32_t i = 0; i < inst.NumInOperands(); - i += inst.opcode() == spv::Op::OpPhi ? 2 : 1) { + i += inst.opcode() == SpvOpPhi ? 2 : 1) { const auto& operand = inst.GetInOperand(i); if (!spvIsInIdType(operand.type)) { continue; @@ -2003,7 +1994,7 @@ bool NewTerminatorPreservesDominationRules(opt::IRContext* ir_context, continue; } - auto domination_target_id = inst.opcode() == spv::Op::OpPhi + auto domination_target_id = inst.opcode() == SpvOpPhi ? inst.GetSingleWordInOperand(i + 1) : block.id(); @@ -2030,68 +2021,68 @@ opt::Module::iterator GetFunctionIterator(opt::IRContext* ir_context, // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3582): Add all // opcodes that are agnostic to signedness of operands to function. // This is not exhaustive yet. -bool IsAgnosticToSignednessOfOperand(spv::Op opcode, +bool IsAgnosticToSignednessOfOperand(SpvOp opcode, uint32_t use_in_operand_index) { switch (opcode) { - case spv::Op::OpSNegate: - case spv::Op::OpNot: - case spv::Op::OpIAdd: - case spv::Op::OpISub: - case spv::Op::OpIMul: - case spv::Op::OpSDiv: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: + case SpvOpSNegate: + case SpvOpNot: + case SpvOpIAdd: + case SpvOpISub: + case SpvOpIMul: + case SpvOpSDiv: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: return true; - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFAddEXT: // Capability AtomicFloat32AddEXT, + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFAddEXT: // Capability AtomicFloat32AddEXT, // AtomicFloat64AddEXT. assert(use_in_operand_index != 0 && "Signedness check should not occur on a pointer operand."); return use_in_operand_index == 1 || use_in_operand_index == 2; - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: // Capability Kernel. + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: // Capability Kernel. assert(use_in_operand_index != 0 && "Signedness check should not occur on a pointer operand."); return use_in_operand_index >= 1 && use_in_operand_index <= 3; - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicFlagTestAndSet: // Capability Kernel. - case spv::Op::OpAtomicFlagClear: // Capability Kernel. + case SpvOpAtomicLoad: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicFlagTestAndSet: // Capability Kernel. + case SpvOpAtomicFlagClear: // Capability Kernel. assert(use_in_operand_index != 0 && "Signedness check should not occur on a pointer operand."); return use_in_operand_index >= 1; - case spv::Op::OpAccessChain: + case SpvOpAccessChain: // The signedness of indices does not matter. return use_in_operand_index > 0; @@ -2102,7 +2093,7 @@ bool IsAgnosticToSignednessOfOperand(spv::Op opcode, } } -bool TypesAreCompatible(opt::IRContext* ir_context, spv::Op opcode, +bool TypesAreCompatible(opt::IRContext* ir_context, SpvOp opcode, uint32_t use_in_operand_index, uint32_t type_id_1, uint32_t type_id_2) { assert(ir_context->get_type_mgr()->GetType(type_id_1) && diff --git a/source/fuzz/fuzzer_util.h b/source/fuzz/fuzzer_util.h index 374e32e1..54aa14a2 100644 --- a/source/fuzz/fuzzer_util.h +++ b/source/fuzz/fuzzer_util.h @@ -111,7 +111,7 @@ opt::BasicBlock::iterator GetIteratorForInstruction( // Determines whether it is OK to insert an instruction with opcode |opcode| // before |instruction_in_block|. bool CanInsertOpcodeBeforeInstruction( - spv::Op opcode, const opt::BasicBlock::iterator& instruction_in_block); + SpvOp opcode, const opt::BasicBlock::iterator& instruction_in_block); // Determines whether it is OK to make a synonym of |inst|. // |transformation_context| is used to verify that the result id of |inst| @@ -170,8 +170,8 @@ uint32_t GetBoundForCompositeIndex(const opt::Instruction& composite_type_inst, opt::IRContext* ir_context); // Returns memory semantics mask for specific storage class. -spv::MemorySemanticsMask GetMemorySemanticsForStorageClass( - spv::StorageClass storage_class); +SpvMemorySemanticsMask GetMemorySemanticsForStorageClass( + SpvStorageClass storage_class); // Returns true if and only if |context| is valid, according to the validator // instantiated with |validator_options|. |consumer| is used for error @@ -258,18 +258,18 @@ uint32_t GetPointeeTypeIdFromPointerType(opt::IRContext* context, // Given |pointer_type_inst|, which must be an OpTypePointer instruction, // returns the associated storage class. -spv::StorageClass GetStorageClassFromPointerType( +SpvStorageClass GetStorageClassFromPointerType( opt::Instruction* pointer_type_inst); // Given |pointer_type_id|, which must be the id of a pointer type, returns the // associated storage class. -spv::StorageClass GetStorageClassFromPointerType(opt::IRContext* context, - uint32_t pointer_type_id); +SpvStorageClass GetStorageClassFromPointerType(opt::IRContext* context, + uint32_t pointer_type_id); // Returns the id of a pointer with pointee type |pointee_type_id| and storage // class |storage_class|, if it exists, and 0 otherwise. uint32_t MaybeGetPointerType(opt::IRContext* context, uint32_t pointee_type_id, - spv::StorageClass storage_class); + SpvStorageClass storage_class); // Given an instruction |inst| and an operand absolute index |absolute_index|, // returns the index of the operand restricted to the input operands. @@ -309,7 +309,7 @@ void AddVariableIdToEntryPointInterfaces(opt::IRContext* context, uint32_t id); // Returns a pointer to the new global variable instruction. opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id, uint32_t type_id, - spv::StorageClass storage_class, + SpvStorageClass storage_class, uint32_t initializer_id); // Adds an instruction to the start of |function_id|, of the form: @@ -541,7 +541,7 @@ MapToRepeatedUInt32Pair(const std::map& data); // opcode |opcode| can be inserted, or nullptr if there is no such instruction. opt::Instruction* GetLastInsertBeforeInstruction(opt::IRContext* ir_context, uint32_t block_id, - spv::Op opcode); + SpvOp opcode); // Checks whether various conditions hold related to the acceptability of // replacing the id use at |use_in_operand_index| of |use_instruction| with a @@ -608,14 +608,14 @@ opt::Module::iterator GetFunctionIterator(opt::IRContext* ir_context, // behaviour depending on the signedness of the operand at // |use_in_operand_index|. // Assumes that the operand must be the id of an integer scalar or vector. -bool IsAgnosticToSignednessOfOperand(spv::Op opcode, +bool IsAgnosticToSignednessOfOperand(SpvOp opcode, uint32_t use_in_operand_index); // Returns true if |type_id_1| and |type_id_2| represent compatible types // given the context of the instruction with |opcode| (i.e. we can replace // an operand of |opcode| of the first type with an id of the second type // and vice-versa). -bool TypesAreCompatible(opt::IRContext* ir_context, spv::Op opcode, +bool TypesAreCompatible(opt::IRContext* ir_context, SpvOp opcode, uint32_t use_in_operand_index, uint32_t type_id_1, uint32_t type_id_2); diff --git a/source/fuzz/instruction_descriptor.cpp b/source/fuzz/instruction_descriptor.cpp index 120d8f87..fb1ff765 100644 --- a/source/fuzz/instruction_descriptor.cpp +++ b/source/fuzz/instruction_descriptor.cpp @@ -40,9 +40,8 @@ opt::Instruction* FindInstruction( "The skipped instruction count should only be incremented " "after the instruction base has been found."); } - if (found_base && - instruction.opcode() == - spv::Op(instruction_descriptor.target_instruction_opcode())) { + if (found_base && instruction.opcode() == + instruction_descriptor.target_instruction_opcode()) { if (num_ignored == instruction_descriptor.num_opcodes_to_ignore()) { return &instruction; } @@ -53,11 +52,11 @@ opt::Instruction* FindInstruction( } protobufs::InstructionDescriptor MakeInstructionDescriptor( - uint32_t base_instruction_result_id, spv::Op target_instruction_opcode, + uint32_t base_instruction_result_id, SpvOp target_instruction_opcode, uint32_t num_opcodes_to_ignore) { protobufs::InstructionDescriptor result; result.set_base_instruction_result_id(base_instruction_result_id); - result.set_target_instruction_opcode(uint32_t(target_instruction_opcode)); + result.set_target_instruction_opcode(target_instruction_opcode); result.set_num_opcodes_to_ignore(num_opcodes_to_ignore); return result; } @@ -65,7 +64,7 @@ protobufs::InstructionDescriptor MakeInstructionDescriptor( protobufs::InstructionDescriptor MakeInstructionDescriptor( const opt::BasicBlock& block, const opt::BasicBlock::const_iterator& inst_it) { - const spv::Op opcode = + const SpvOp opcode = inst_it->opcode(); // The opcode of the instruction being described. uint32_t skip_count = 0; // The number of these opcodes we have skipped when // searching backwards. diff --git a/source/fuzz/instruction_descriptor.h b/source/fuzz/instruction_descriptor.h index 063cad47..2ccd15a2 100644 --- a/source/fuzz/instruction_descriptor.h +++ b/source/fuzz/instruction_descriptor.h @@ -32,7 +32,7 @@ opt::Instruction* FindInstruction( // components. See the protobuf definition for details of what these // components mean. protobufs::InstructionDescriptor MakeInstructionDescriptor( - uint32_t base_instruction_result_id, spv::Op target_instruction_opcode, + uint32_t base_instruction_result_id, SpvOp target_instruction_opcode, uint32_t num_opcodes_to_ignore); // Returns an instruction descriptor that describing the instruction at diff --git a/source/fuzz/instruction_message.cpp b/source/fuzz/instruction_message.cpp index 7e8ac71b..95039327 100644 --- a/source/fuzz/instruction_message.cpp +++ b/source/fuzz/instruction_message.cpp @@ -20,10 +20,10 @@ namespace spvtools { namespace fuzz { protobufs::Instruction MakeInstructionMessage( - spv::Op opcode, uint32_t result_type_id, uint32_t result_id, + SpvOp opcode, uint32_t result_type_id, uint32_t result_id, const opt::Instruction::OperandList& input_operands) { protobufs::Instruction result; - result.set_opcode(uint32_t(opcode)); + result.set_opcode(opcode); result.set_result_type_id(result_type_id); result.set_result_id(result_id); for (auto& operand : input_operands) { @@ -71,7 +71,7 @@ std::unique_ptr InstructionFromMessage( } // Create and return the instruction. return MakeUnique( - ir_context, static_cast(instruction_message.opcode()), + ir_context, static_cast(instruction_message.opcode()), instruction_message.result_type_id(), instruction_message.result_id(), in_operands); } diff --git a/source/fuzz/instruction_message.h b/source/fuzz/instruction_message.h index e1312f45..fcbb4c76 100644 --- a/source/fuzz/instruction_message.h +++ b/source/fuzz/instruction_message.h @@ -26,7 +26,7 @@ namespace fuzz { // Creates an Instruction protobuf message from its component parts. protobufs::Instruction MakeInstructionMessage( - spv::Op opcode, uint32_t result_type_id, uint32_t result_id, + SpvOp opcode, uint32_t result_type_id, uint32_t result_id, const opt::Instruction::OperandList& input_operands); // Creates an Instruction protobuf message from a parsed instruction. diff --git a/source/fuzz/protobufs/spirvfuzz_protobufs.h b/source/fuzz/protobufs/spirvfuzz_protobufs.h index 44aecfd6..46c21881 100644 --- a/source/fuzz/protobufs/spirvfuzz_protobufs.h +++ b/source/fuzz/protobufs/spirvfuzz_protobufs.h @@ -21,10 +21,6 @@ // of these header files without having to compromise on freedom from warnings // in the rest of the project. -#ifndef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE -#define GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE 1 -#endif - #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" // Must come first @@ -32,8 +28,6 @@ #pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wsuggest-destructor-override" #pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" -#pragma clang diagnostic ignored "-Wshorten-64-to-32" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" diff --git a/source/fuzz/transformation_access_chain.cpp b/source/fuzz/transformation_access_chain.cpp index 1e7f87bd..3fe9e656 100644 --- a/source/fuzz/transformation_access_chain.cpp +++ b/source/fuzz/transformation_access_chain.cpp @@ -63,7 +63,7 @@ bool TransformationAccessChain::IsApplicable( } // The type must indeed be a pointer. auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); - if (pointer_type->opcode() != spv::Op::OpTypePointer) { + if (pointer_type->opcode() != SpvOpTypePointer) { return false; } @@ -75,7 +75,7 @@ bool TransformationAccessChain::IsApplicable( return false; } if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpAccessChain, instruction_to_insert_before)) { + SpvOpAccessChain, instruction_to_insert_before)) { return false; } @@ -83,8 +83,8 @@ bool TransformationAccessChain::IsApplicable( // we do not want to allow accessing such pointers. This might be acceptable // in dead blocks, but we conservatively avoid it. switch (pointer->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: assert( false && "Access chains should not be created from null/undefined pointers"); @@ -117,7 +117,7 @@ bool TransformationAccessChain::IsApplicable( // Check whether the object is a struct. if (ir_context->get_def_use_mgr()->GetDef(subobject_type_id)->opcode() == - spv::Op::OpTypeStruct) { + SpvOpTypeStruct) { // It is a struct: we need to retrieve the integer value. bool successful; @@ -202,7 +202,7 @@ bool TransformationAccessChain::IsApplicable( // associated with pointers to isomorphic structs being regarded as the same. return fuzzerutil::MaybeGetPointerType( ir_context, subobject_type_id, - static_cast( + static_cast( pointer_type->GetSingleWordInOperand(0))) != 0; } @@ -243,7 +243,7 @@ void TransformationAccessChain::Apply( // Check whether the object is a struct. if (ir_context->get_def_use_mgr()->GetDef(subobject_type_id)->opcode() == - spv::Op::OpTypeStruct) { + SpvOpTypeStruct) { // It is a struct: we need to retrieve the integer value. index_value = @@ -290,8 +290,7 @@ void TransformationAccessChain::Apply( // %fresh_ids.first = OpULessThanEqual %bool %int_id %bound_minus_one. fuzzerutil::UpdateModuleIdBound(ir_context, fresh_ids.first()); auto comparison_instruction = MakeUnique( - ir_context, spv::Op::OpULessThanEqual, bool_type_id, - fresh_ids.first(), + ir_context, SpvOpULessThanEqual, bool_type_id, fresh_ids.first(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {index_instruction->result_id()}}, {SPV_OPERAND_TYPE_ID, {bound_minus_one_id}}})); @@ -307,7 +306,7 @@ void TransformationAccessChain::Apply( // %bound_minus_one fuzzerutil::UpdateModuleIdBound(ir_context, fresh_ids.second()); auto select_instruction = MakeUnique( - ir_context, spv::Op::OpSelect, int_type_inst->result_id(), + ir_context, SpvOpSelect, int_type_inst->result_id(), fresh_ids.second(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {fresh_ids.first()}}, @@ -335,14 +334,13 @@ void TransformationAccessChain::Apply( // of the original pointer. uint32_t result_type = fuzzerutil::MaybeGetPointerType( ir_context, subobject_type_id, - static_cast(pointer_type->GetSingleWordInOperand(0))); + static_cast(pointer_type->GetSingleWordInOperand(0))); // Add the access chain instruction to the module, and update the module's // id bound. fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); - auto access_chain_instruction = - MakeUnique(ir_context, spv::Op::OpAccessChain, - result_type, message_.fresh_id(), operands); + auto access_chain_instruction = MakeUnique( + ir_context, SpvOpAccessChain, result_type, message_.fresh_id(), operands); auto access_chain_instruction_ptr = access_chain_instruction.get(); instruction_to_insert_before->InsertBefore( std::move(access_chain_instruction)); @@ -369,7 +367,7 @@ std::pair TransformationAccessChain::GetStructIndexValue( opt::IRContext* ir_context, uint32_t index_id, uint32_t object_type_id) const { assert(ir_context->get_def_use_mgr()->GetDef(object_type_id)->opcode() == - spv::Op::OpTypeStruct && + SpvOpTypeStruct && "Precondition: the type must be a struct type."); if (!ValidIndexToComposite(ir_context, index_id, object_type_id)) { return {false, 0}; @@ -410,14 +408,14 @@ bool TransformationAccessChain::ValidIndexToComposite( // The index type must be 32-bit integer. auto index_type = ir_context->get_def_use_mgr()->GetDef(index_instruction->type_id()); - if (index_type->opcode() != spv::Op::OpTypeInt || + if (index_type->opcode() != SpvOpTypeInt || index_type->GetSingleWordInOperand(0) != 32) { return false; } // If the object being traversed is a struct, the id must correspond to an // in-bound constant. - if (object_type_def->opcode() == spv::Op::OpTypeStruct) { + if (object_type_def->opcode() == SpvOpTypeStruct) { if (!spvOpcodeIsConstant(index_instruction->opcode())) { return false; } diff --git a/source/fuzz/transformation_add_bit_instruction_synonym.cpp b/source/fuzz/transformation_add_bit_instruction_synonym.cpp index 4b26c2b5..636c0a38 100644 --- a/source/fuzz/transformation_add_bit_instruction_synonym.cpp +++ b/source/fuzz/transformation_add_bit_instruction_synonym.cpp @@ -87,10 +87,10 @@ void TransformationAddBitInstructionSynonym::Apply( // synonym fact. The helper function should take care of invalidating // analyses before adding facts. switch (bit_instruction->opcode()) { - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: AddOpBitwiseOrOpNotSynonym(ir_context, transformation_context, bit_instruction); break; @@ -106,10 +106,10 @@ bool TransformationAddBitInstructionSynonym::IsInstructionSupported( // Right now we only support certain operations. When this issue is addressed // the following conditional can use the function |spvOpcodeIsBit|. // |instruction| must be defined and must be a supported bit instruction. - if (!instruction || (instruction->opcode() != spv::Op::OpBitwiseOr && - instruction->opcode() != spv::Op::OpBitwiseXor && - instruction->opcode() != spv::Op::OpBitwiseAnd && - instruction->opcode() != spv::Op::OpNot)) { + if (!instruction || (instruction->opcode() != SpvOpBitwiseOr && + instruction->opcode() != SpvOpBitwiseXor && + instruction->opcode() != SpvOpBitwiseAnd && + instruction->opcode() != SpvOpNot)) { return false; } @@ -119,7 +119,7 @@ bool TransformationAddBitInstructionSynonym::IsInstructionSupported( return false; } - if (instruction->opcode() == spv::Op::OpNot) { + if (instruction->opcode() == SpvOpNot) { auto operand = instruction->GetInOperand(0).words[0]; auto operand_inst = ir_context->get_def_use_mgr()->GetDef(operand); auto operand_type = @@ -171,10 +171,10 @@ uint32_t TransformationAddBitInstructionSynonym::GetRequiredFreshIdCount( // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3557): // Right now, only certain operations are supported. switch (bit_instruction->opcode()) { - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: return (2 + bit_instruction->NumInOperands()) * ir_context->get_type_mgr() ->GetType(bit_instruction->type_id()) @@ -220,7 +220,7 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym( for (auto operand = bit_instruction->begin() + 2; operand != bit_instruction->end(); operand++) { auto bit_extract = - opt::Instruction(ir_context, spv::Op::OpBitFieldUExtract, + opt::Instruction(ir_context, SpvOpBitFieldUExtract, bit_instruction->type_id(), *fresh_id++, {{SPV_OPERAND_TYPE_ID, operand->words}, {SPV_OPERAND_TYPE_ID, {offset}}, @@ -246,13 +246,12 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym( // first two bits of the result. uint32_t offset = fuzzerutil::MaybeGetIntegerConstant( ir_context, *transformation_context, {1}, 32, false, false); - auto bit_insert = - opt::Instruction(ir_context, spv::Op::OpBitFieldInsert, - bit_instruction->type_id(), *fresh_id++, - {{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[0]}}, - {SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[1]}}, - {SPV_OPERAND_TYPE_ID, {offset}}, - {SPV_OPERAND_TYPE_ID, {count}}}); + auto bit_insert = opt::Instruction( + ir_context, SpvOpBitFieldInsert, bit_instruction->type_id(), *fresh_id++, + {{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[0]}}, + {SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[1]}}, + {SPV_OPERAND_TYPE_ID, {offset}}, + {SPV_OPERAND_TYPE_ID, {count}}}); bit_instruction->InsertBefore(MakeUnique(bit_insert)); fuzzerutil::UpdateModuleIdBound(ir_context, bit_insert.result_id()); @@ -261,7 +260,7 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym( offset = fuzzerutil::MaybeGetIntegerConstant( ir_context, *transformation_context, {i}, 32, false, false); bit_insert = opt::Instruction( - ir_context, spv::Op::OpBitFieldInsert, bit_instruction->type_id(), + ir_context, SpvOpBitFieldInsert, bit_instruction->type_id(), *fresh_id++, {{SPV_OPERAND_TYPE_ID, {bit_insert.result_id()}}, {SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[i]}}, diff --git a/source/fuzz/transformation_add_constant_boolean.cpp b/source/fuzz/transformation_add_constant_boolean.cpp index 89c2e579..39354325 100644 --- a/source/fuzz/transformation_add_constant_boolean.cpp +++ b/source/fuzz/transformation_add_constant_boolean.cpp @@ -43,8 +43,7 @@ void TransformationAddConstantBoolean::Apply( // Add the boolean constant to the module, ensuring the module's id bound is // high enough. auto new_instruction = MakeUnique( - ir_context, - message_.is_true() ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse, + ir_context, message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse, fuzzerutil::MaybeGetBoolType(ir_context), message_.fresh_id(), opt::Instruction::OperandList()); auto new_instruction_ptr = new_instruction.get(); diff --git a/source/fuzz/transformation_add_constant_composite.cpp b/source/fuzz/transformation_add_constant_composite.cpp index b8ee8be7..89007ab6 100644 --- a/source/fuzz/transformation_add_constant_composite.cpp +++ b/source/fuzz/transformation_add_constant_composite.cpp @@ -53,7 +53,7 @@ bool TransformationAddConstantComposite::IsApplicable( // struct - whether its decorations are OK. std::vector constituent_type_ids; switch (composite_type_instruction->opcode()) { - case spv::Op::OpTypeArray: + case SpvOpTypeArray: for (uint32_t index = 0; index < fuzzerutil::GetArraySize(*composite_type_instruction, ir_context); @@ -62,8 +62,8 @@ bool TransformationAddConstantComposite::IsApplicable( composite_type_instruction->GetSingleWordInOperand(0)); } break; - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: for (uint32_t index = 0; index < composite_type_instruction->GetSingleWordInOperand(1); index++) { @@ -71,7 +71,7 @@ bool TransformationAddConstantComposite::IsApplicable( composite_type_instruction->GetSingleWordInOperand(0)); } break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // We do not create constants of structs decorated with Block nor // BufferBlock. The SPIR-V spec does not explicitly disallow this, but it // seems like a strange thing to do, so we disallow it to avoid triggering @@ -120,7 +120,7 @@ void TransformationAddConstantComposite::Apply( in_operands.push_back({SPV_OPERAND_TYPE_ID, {constituent_id}}); } auto new_instruction = MakeUnique( - ir_context, spv::Op::OpConstantComposite, message_.type_id(), + ir_context, SpvOpConstantComposite, message_.type_id(), message_.fresh_id(), in_operands); auto new_instruction_ptr = new_instruction.get(); ir_context->module()->AddGlobalValue(std::move(new_instruction)); diff --git a/source/fuzz/transformation_add_constant_null.cpp b/source/fuzz/transformation_add_constant_null.cpp index 7b83baea..c0f73670 100644 --- a/source/fuzz/transformation_add_constant_null.cpp +++ b/source/fuzz/transformation_add_constant_null.cpp @@ -48,8 +48,8 @@ bool TransformationAddConstantNull::IsApplicable( void TransformationAddConstantNull::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto new_instruction = MakeUnique( - ir_context, spv::Op::OpConstantNull, message_.type_id(), - message_.fresh_id(), opt::Instruction::OperandList()); + ir_context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(), + opt::Instruction::OperandList()); auto new_instruction_ptr = new_instruction.get(); ir_context->module()->AddGlobalValue(std::move(new_instruction)); fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); diff --git a/source/fuzz/transformation_add_constant_scalar.cpp b/source/fuzz/transformation_add_constant_scalar.cpp index 45989d45..a2d95fb6 100644 --- a/source/fuzz/transformation_add_constant_scalar.cpp +++ b/source/fuzz/transformation_add_constant_scalar.cpp @@ -65,7 +65,7 @@ void TransformationAddConstantScalar::Apply( opt::IRContext* ir_context, TransformationContext* transformation_context) const { auto new_instruction = MakeUnique( - ir_context, spv::Op::OpConstant, message_.type_id(), message_.fresh_id(), + ir_context, SpvOpConstant, message_.type_id(), message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_LITERAL_INTEGER, std::vector(message_.word().begin(), diff --git a/source/fuzz/transformation_add_copy_memory.cpp b/source/fuzz/transformation_add_copy_memory.cpp index 9d1f3256..5eb4bdc0 100644 --- a/source/fuzz/transformation_add_copy_memory.cpp +++ b/source/fuzz/transformation_add_copy_memory.cpp @@ -27,12 +27,12 @@ TransformationAddCopyMemory::TransformationAddCopyMemory( TransformationAddCopyMemory::TransformationAddCopyMemory( const protobufs::InstructionDescriptor& instruction_descriptor, - uint32_t fresh_id, uint32_t source_id, spv::StorageClass storage_class, + uint32_t fresh_id, uint32_t source_id, SpvStorageClass storage_class, uint32_t initializer_id) { *message_.mutable_instruction_descriptor() = instruction_descriptor; message_.set_fresh_id(fresh_id); message_.set_source_id(source_id); - message_.set_storage_class(uint32_t(storage_class)); + message_.set_storage_class(storage_class); message_.set_initializer_id(initializer_id); } @@ -53,8 +53,7 @@ bool TransformationAddCopyMemory::IsApplicable( // Check that we can insert OpCopyMemory before |instruction_descriptor|. auto iter = fuzzerutil::GetIteratorForInstruction( ir_context->get_instr_block(inst), inst); - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyMemory, - iter)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyMemory, iter)) { return false; } @@ -66,10 +65,8 @@ bool TransformationAddCopyMemory::IsApplicable( } // |storage_class| is either Function or Private. - if (spv::StorageClass(message_.storage_class()) != - spv::StorageClass::Function && - spv::StorageClass(message_.storage_class()) != - spv::StorageClass::Private) { + if (message_.storage_class() != SpvStorageClassFunction && + message_.storage_class() != SpvStorageClassPrivate) { return false; } @@ -79,7 +76,7 @@ bool TransformationAddCopyMemory::IsApplicable( // OpTypePointer with |message_.storage_class| exists. if (!fuzzerutil::MaybeGetPointerType( ir_context, pointee_type_id, - static_cast(message_.storage_class()))) { + static_cast(message_.storage_class()))) { return false; } @@ -106,20 +103,20 @@ void TransformationAddCopyMemory::Apply( ir_context->get_instr_block(insert_before_inst); // Add global or local variable to copy memory into. - auto storage_class = static_cast(message_.storage_class()); + auto storage_class = static_cast(message_.storage_class()); auto type_id = fuzzerutil::MaybeGetPointerType( ir_context, fuzzerutil::GetPointeeTypeIdFromPointerType( ir_context, fuzzerutil::GetTypeId(ir_context, message_.source_id())), storage_class); - if (storage_class == spv::StorageClass::Private) { + if (storage_class == SpvStorageClassPrivate) { opt::Instruction* new_global = fuzzerutil::AddGlobalVariable(ir_context, message_.fresh_id(), type_id, storage_class, message_.initializer_id()); ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_global); } else { - assert(storage_class == spv::StorageClass::Function && + assert(storage_class == SpvStorageClassFunction && "Storage class can be either Private or Function"); opt::Function* enclosing_function = enclosing_block->GetParent(); opt::Instruction* new_local = fuzzerutil::AddLocalVariable( @@ -133,7 +130,7 @@ void TransformationAddCopyMemory::Apply( enclosing_block, insert_before_inst); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpCopyMemory, 0, 0, + ir_context, SpvOpCopyMemory, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.fresh_id()}}, {SPV_OPERAND_TYPE_ID, {message_.source_id()}}}); @@ -163,8 +160,7 @@ protobufs::Transformation TransformationAddCopyMemory::ToMessage() const { bool TransformationAddCopyMemory::IsInstructionSupported( opt::IRContext* ir_context, opt::Instruction* inst) { if (!inst->result_id() || !inst->type_id() || - inst->opcode() == spv::Op::OpConstantNull || - inst->opcode() == spv::Op::OpUndef) { + inst->opcode() == SpvOpConstantNull || inst->opcode() == SpvOpUndef) { return false; } diff --git a/source/fuzz/transformation_add_copy_memory.h b/source/fuzz/transformation_add_copy_memory.h index 053b6291..b25652fd 100644 --- a/source/fuzz/transformation_add_copy_memory.h +++ b/source/fuzz/transformation_add_copy_memory.h @@ -30,7 +30,7 @@ class TransformationAddCopyMemory : public Transformation { TransformationAddCopyMemory( const protobufs::InstructionDescriptor& instruction_descriptor, - uint32_t fresh_id, uint32_t source_id, spv::StorageClass storage_class, + uint32_t fresh_id, uint32_t source_id, SpvStorageClass storage_class, uint32_t initializer_id); // - |instruction_descriptor| must point to a valid instruction in the module. diff --git a/source/fuzz/transformation_add_dead_block.cpp b/source/fuzz/transformation_add_dead_block.cpp index 930adc10..df700ce5 100644 --- a/source/fuzz/transformation_add_dead_block.cpp +++ b/source/fuzz/transformation_add_dead_block.cpp @@ -61,7 +61,7 @@ bool TransformationAddDeadBlock::IsApplicable( } // It must end with OpBranch. - if (existing_block->terminator()->opcode() != spv::Op::OpBranch) { + if (existing_block->terminator()->opcode() != SpvOpBranch) { return false; } @@ -122,27 +122,27 @@ void TransformationAddDeadBlock::Apply( auto enclosing_function = existing_block->GetParent(); std::unique_ptr new_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.fresh_id(), + ir_context, SpvOpLabel, 0, message_.fresh_id(), opt::Instruction::OperandList())); new_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {successor_block_id}}}))); // Turn the original block into a selection merge, with its original successor // as the merge block. existing_block->terminator()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpSelectionMerge, 0, 0, + ir_context, SpvOpSelectionMerge, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {successor_block_id}}, {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}}))); + {SpvSelectionControlMaskNone}}}))); // Change the original block's terminator to be a conditional branch on the // given boolean, with the original successor and the new successor as branch // targets, and such that at runtime control will always transfer to the // original successor. - existing_block->terminator()->SetOpcode(spv::Op::OpBranchConditional); + existing_block->terminator()->SetOpcode(SpvOpBranchConditional); existing_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {bool_id}}, {SPV_OPERAND_TYPE_ID, diff --git a/source/fuzz/transformation_add_dead_break.cpp b/source/fuzz/transformation_add_dead_break.cpp index 07ed4dc5..32080ca4 100644 --- a/source/fuzz/transformation_add_dead_break.cpp +++ b/source/fuzz/transformation_add_dead_break.cpp @@ -142,7 +142,7 @@ bool TransformationAddDeadBreak::IsApplicable( } // Check that |message_.from_block| ends with an unconditional branch. - if (bb_from->terminator()->opcode() != spv::Op::OpBranch) { + if (bb_from->terminator()->opcode() != SpvOpBranch) { // The block associated with the id does not end with an unconditional // branch. return false; diff --git a/source/fuzz/transformation_add_dead_continue.cpp b/source/fuzz/transformation_add_dead_continue.cpp index c534801b..f2b9ab3f 100644 --- a/source/fuzz/transformation_add_dead_continue.cpp +++ b/source/fuzz/transformation_add_dead_continue.cpp @@ -55,7 +55,7 @@ bool TransformationAddDeadContinue::IsApplicable( } // Check that |message_.from_block| ends with an unconditional branch. - if (bb_from->terminator()->opcode() != spv::Op::OpBranch) { + if (bb_from->terminator()->opcode() != SpvOpBranch) { // The block associated with the id does not end with an unconditional // branch. return false; diff --git a/source/fuzz/transformation_add_early_terminator_wrapper.cpp b/source/fuzz/transformation_add_early_terminator_wrapper.cpp index 28e0186d..547398aa 100644 --- a/source/fuzz/transformation_add_early_terminator_wrapper.cpp +++ b/source/fuzz/transformation_add_early_terminator_wrapper.cpp @@ -28,17 +28,17 @@ TransformationAddEarlyTerminatorWrapper:: TransformationAddEarlyTerminatorWrapper:: TransformationAddEarlyTerminatorWrapper(uint32_t function_fresh_id, uint32_t label_fresh_id, - spv::Op opcode) { + SpvOp opcode) { message_.set_function_fresh_id(function_fresh_id); message_.set_label_fresh_id(label_fresh_id); - message_.set_opcode(uint32_t(opcode)); + message_.set_opcode(opcode); } bool TransformationAddEarlyTerminatorWrapper::IsApplicable( opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { - assert((spv::Op(message_.opcode()) == spv::Op::OpKill || - spv::Op(message_.opcode()) == spv::Op::OpUnreachable || - spv::Op(message_.opcode()) == spv::Op::OpTerminateInvocation) && + assert((message_.opcode() == SpvOpKill || + message_.opcode() == SpvOpUnreachable || + message_.opcode() == SpvOpTerminateInvocation) && "Invalid opcode."); if (!fuzzerutil::IsFreshId(ir_context, message_.function_fresh_id())) { @@ -66,29 +66,26 @@ void TransformationAddEarlyTerminatorWrapper::Apply( // %label_fresh_id = OpLabel // OpKill|Unreachable|TerminateInvocation auto basic_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.label_fresh_id(), + ir_context, SpvOpLabel, 0, message_.label_fresh_id(), opt::Instruction::OperandList())); basic_block->AddInstruction(MakeUnique( - ir_context, static_cast(message_.opcode()), 0, 0, + ir_context, static_cast(message_.opcode()), 0, 0, opt::Instruction::OperandList())); // Create a zero-argument void function. auto void_type_id = fuzzerutil::MaybeGetVoidType(ir_context); auto function = MakeUnique(MakeUnique( - ir_context, spv::Op::OpFunction, void_type_id, - message_.function_fresh_id(), + ir_context, SpvOpFunction, void_type_id, message_.function_fresh_id(), opt::Instruction::OperandList( - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, {SPV_OPERAND_TYPE_TYPE_ID, {fuzzerutil::FindFunctionType(ir_context, {void_type_id})}}}))); // Add the basic block to the function as the sole block, and add the function // to the module. function->AddBasicBlock(std::move(basic_block)); - function->SetFunctionEnd( - MakeUnique(ir_context, spv::Op::OpFunctionEnd, 0, 0, - opt::Instruction::OperandList())); + function->SetFunctionEnd(MakeUnique( + ir_context, SpvOpFunctionEnd, 0, 0, opt::Instruction::OperandList())); ir_context->module()->AddFunction(std::move(function)); ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); diff --git a/source/fuzz/transformation_add_early_terminator_wrapper.h b/source/fuzz/transformation_add_early_terminator_wrapper.h index 5d0201dd..97cc527c 100644 --- a/source/fuzz/transformation_add_early_terminator_wrapper.h +++ b/source/fuzz/transformation_add_early_terminator_wrapper.h @@ -30,7 +30,7 @@ class TransformationAddEarlyTerminatorWrapper : public Transformation { TransformationAddEarlyTerminatorWrapper(uint32_t function_fresh_id, uint32_t label_fresh_id, - spv::Op opcode); + SpvOp opcode); // - |message_.function_fresh_id| and |message_.label_fresh_id| must be fresh // and distinct. diff --git a/source/fuzz/transformation_add_function.cpp b/source/fuzz/transformation_add_function.cpp index 1f61ede7..06cd6572 100644 --- a/source/fuzz/transformation_add_function.cpp +++ b/source/fuzz/transformation_add_function.cpp @@ -178,7 +178,7 @@ void TransformationAddFunction::Apply( } ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); - assert(spv::Op(message_.instruction(0).opcode()) == spv::Op::OpFunction && + assert(message_.instruction(0).opcode() == SpvOpFunction && "The first instruction of an 'add function' transformation must be " "OpFunction."); @@ -189,7 +189,7 @@ void TransformationAddFunction::Apply( } else { // Inform the fact manager that all blocks in the function are dead. for (auto& inst : message_.instruction()) { - if (spv::Op(inst.opcode()) == spv::Op::OpLabel) { + if (inst.opcode() == SpvOpLabel) { transformation_context->GetFactManager()->AddFactBlockIsDead( inst.result_id()); } @@ -202,16 +202,16 @@ void TransformationAddFunction::Apply( // parameters to other functions knowing that it is OK if they get // over-written. for (auto& instruction : message_.instruction()) { - switch (spv::Op(instruction.opcode())) { - case spv::Op::OpFunctionParameter: + switch (instruction.opcode()) { + case SpvOpFunctionParameter: if (ir_context->get_def_use_mgr() ->GetDef(instruction.result_type_id()) - ->opcode() == spv::Op::OpTypePointer) { + ->opcode() == SpvOpTypePointer) { transformation_context->GetFactManager() ->AddFactValueOfPointeeIsIrrelevant(instruction.result_id()); } break; - case spv::Op::OpVariable: + case SpvOpVariable: transformation_context->GetFactManager() ->AddFactValueOfPointeeIsIrrelevant(instruction.result_id()); break; @@ -239,7 +239,7 @@ bool TransformationAddFunction::TryToAddFunction( // A function must start with OpFunction. auto function_begin = message_.instruction(0); - if (spv::Op(function_begin.opcode()) != spv::Op::OpFunction) { + if (function_begin.opcode() != SpvOpFunction) { return false; } @@ -256,8 +256,8 @@ bool TransformationAddFunction::TryToAddFunction( // Iterate through all function parameter instructions, adding parameters to // the new function. while (instruction_index < num_instructions && - spv::Op(message_.instruction(instruction_index).opcode()) == - spv::Op::OpFunctionParameter) { + message_.instruction(instruction_index).opcode() == + SpvOpFunctionParameter) { new_function->AddParameter(InstructionFromMessage( ir_context, message_.instruction(instruction_index))); instruction_index++; @@ -265,19 +265,16 @@ bool TransformationAddFunction::TryToAddFunction( // After the parameters, there needs to be a label. if (instruction_index == num_instructions || - spv::Op(message_.instruction(instruction_index).opcode()) != - spv::Op::OpLabel) { + message_.instruction(instruction_index).opcode() != SpvOpLabel) { return false; } // Iterate through the instructions block by block until the end of the // function is reached. while (instruction_index < num_instructions && - spv::Op(message_.instruction(instruction_index).opcode()) != - spv::Op::OpFunctionEnd) { + message_.instruction(instruction_index).opcode() != SpvOpFunctionEnd) { // Invariant: we should always be at a label instruction at this point. - assert(spv::Op(message_.instruction(instruction_index).opcode()) == - spv::Op::OpLabel); + assert(message_.instruction(instruction_index).opcode() == SpvOpLabel); // Make a basic block using the label instruction. std::unique_ptr block = @@ -288,10 +285,9 @@ bool TransformationAddFunction::TryToAddFunction( // of the function, adding each such instruction to the block. instruction_index++; while (instruction_index < num_instructions && - spv::Op(message_.instruction(instruction_index).opcode()) != - spv::Op::OpFunctionEnd && - spv::Op(message_.instruction(instruction_index).opcode()) != - spv::Op::OpLabel) { + message_.instruction(instruction_index).opcode() != + SpvOpFunctionEnd && + message_.instruction(instruction_index).opcode() != SpvOpLabel) { block->AddInstruction(InstructionFromMessage( ir_context, message_.instruction(instruction_index))); instruction_index++; @@ -302,8 +298,7 @@ bool TransformationAddFunction::TryToAddFunction( // Having considered all the blocks, we should be at the last instruction and // it needs to be OpFunctionEnd. if (instruction_index != num_instructions - 1 || - spv::Op(message_.instruction(instruction_index).opcode()) != - spv::Op::OpFunctionEnd) { + message_.instruction(instruction_index).opcode() != SpvOpFunctionEnd) { return false; } // Set the function's final instruction, add the function to the module and @@ -344,20 +339,20 @@ bool TransformationAddFunction::TryToMakeFunctionLivesafe( for (auto& block : *added_function) { for (auto& inst : block) { switch (inst.opcode()) { - case spv::Op::OpKill: - case spv::Op::OpUnreachable: + case SpvOpKill: + case SpvOpUnreachable: if (!TryToTurnKillOrUnreachableIntoReturn(ir_context, added_function, &inst)) { return false; } break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: if (!TryToClampAccessChainIndices(ir_context, &inst)) { return false; } break; - case spv::Op::OpFunctionCall: + case SpvOpFunctionCall: // A livesafe function my only call other livesafe functions. if (!transformation_context.GetFactManager()->FunctionIsLivesafe( inst.GetSingleWordInOperand(0))) { @@ -409,7 +404,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( auto loop_limit_constant_id_instr = ir_context->get_def_use_mgr()->GetDef(message_.loop_limit_constant_id()); if (!loop_limit_constant_id_instr || - loop_limit_constant_id_instr->opcode() != spv::Op::OpConstant) { + loop_limit_constant_id_instr->opcode() != SpvOpConstant) { // The loop limit constant id instruction must exist and have an // appropriate opcode. return false; @@ -417,7 +412,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( auto loop_limit_type = ir_context->get_def_use_mgr()->GetDef( loop_limit_constant_id_instr->type_id()); - if (loop_limit_type->opcode() != spv::Op::OpTypeInt || + if (loop_limit_type->opcode() != SpvOpTypeInt || loop_limit_type->GetSingleWordInOperand(0) != 32) { // The type of the loop limit constant must be 32-bit integer. It // doesn't actually matter whether the integer is signed or not. @@ -462,7 +457,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Look for pointer-to-unsigned int type. opt::analysis::Pointer pointer_to_unsigned_int_type( - registered_unsigned_int_type, spv::StorageClass::Function); + registered_unsigned_int_type, SpvStorageClassFunction); uint32_t pointer_to_unsigned_int_type_id = ir_context->get_type_mgr()->GetId(&pointer_to_unsigned_int_type); if (!pointer_to_unsigned_int_type_id) { @@ -482,13 +477,13 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Declare the loop limiter variable at the start of the function's entry // block, via an instruction of the form: - // %loop_limiter_var = spv::Op::OpVariable %ptr_to_uint Function %zero + // %loop_limiter_var = SpvOpVariable %ptr_to_uint Function %zero added_function->begin()->begin()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpVariable, pointer_to_unsigned_int_type_id, + ir_context, SpvOpVariable, pointer_to_unsigned_int_type_id, message_.loop_limiter_variable_id(), - opt::Instruction::OperandList({{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}, - {SPV_OPERAND_TYPE_ID, {zero_id}}}))); + opt::Instruction::OperandList( + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, + {SPV_OPERAND_TYPE_ID, {zero_id}}}))); // Update the module's id bound since we have added the loop limiter // variable id. fuzzerutil::UpdateModuleIdBound(ir_context, @@ -594,11 +589,10 @@ bool TransformationAddFunction::TryToAddLoopLimiters( auto back_edge_block = ir_context->cfg()->block(back_edge_block_id); auto back_edge_block_terminator = back_edge_block->terminator(); bool compare_using_greater_than_equal; - if (back_edge_block_terminator->opcode() == spv::Op::OpBranch) { + if (back_edge_block_terminator->opcode() == SpvOpBranch) { compare_using_greater_than_equal = true; } else { - assert(back_edge_block_terminator->opcode() == - spv::Op::OpBranchConditional); + assert(back_edge_block_terminator->opcode() == SpvOpBranchConditional); assert(((back_edge_block_terminator->GetSingleWordInOperand(1) == loop_header->id() && back_edge_block_terminator->GetSingleWordInOperand(2) == @@ -619,7 +613,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Add a load from the loop limiter variable, of the form: // %t1 = OpLoad %uint32 %loop_limiter new_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpLoad, unsigned_int_type_id, + ir_context, SpvOpLoad, unsigned_int_type_id, loop_limiter_info.load_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}}}))); @@ -627,7 +621,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Increment the loaded value: // %t2 = OpIAdd %uint32 %t1 %one new_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpIAdd, unsigned_int_type_id, + ir_context, SpvOpIAdd, unsigned_int_type_id, loop_limiter_info.increment_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {loop_limiter_info.load_id()}}, @@ -636,7 +630,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Store the incremented value back to the loop limiter variable: // OpStore %loop_limiter %t2 new_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}}, {SPV_OPERAND_TYPE_ID, {loop_limiter_info.increment_id()}}}))); @@ -647,18 +641,17 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // %t3 = OpULessThan %bool %t1 %loop_limit new_instructions.push_back(MakeUnique( ir_context, - compare_using_greater_than_equal ? spv::Op::OpUGreaterThanEqual - : spv::Op::OpULessThan, + compare_using_greater_than_equal ? SpvOpUGreaterThanEqual + : SpvOpULessThan, bool_type_id, loop_limiter_info.compare_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {loop_limiter_info.load_id()}}, {SPV_OPERAND_TYPE_ID, {message_.loop_limit_constant_id()}}}))); - if (back_edge_block_terminator->opcode() == spv::Op::OpBranchConditional) { + if (back_edge_block_terminator->opcode() == SpvOpBranchConditional) { new_instructions.push_back(MakeUnique( ir_context, - compare_using_greater_than_equal ? spv::Op::OpLogicalOr - : spv::Op::OpLogicalAnd, + compare_using_greater_than_equal ? SpvOpLogicalOr : SpvOpLogicalAnd, bool_type_id, loop_limiter_info.logical_op_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, @@ -676,11 +669,11 @@ bool TransformationAddFunction::TryToAddLoopLimiters( back_edge_block_terminator->InsertBefore(std::move(new_instructions)); } - if (back_edge_block_terminator->opcode() == spv::Op::OpBranchConditional) { + if (back_edge_block_terminator->opcode() == SpvOpBranchConditional) { back_edge_block_terminator->SetInOperand( 0, {loop_limiter_info.logical_op_id()}); } else { - assert(back_edge_block_terminator->opcode() == spv::Op::OpBranch && + assert(back_edge_block_terminator->opcode() == SpvOpBranch && "Back-edge terminator must be OpBranch or OpBranchConditional"); // Check that, if the merge block starts with OpPhi instructions, suitable @@ -696,7 +689,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( // Augment OpPhi instructions at the loop merge with the given ids. uint32_t phi_index = 0; for (auto& inst : *merge_block) { - if (inst.opcode() != spv::Op::OpPhi) { + if (inst.opcode() != SpvOpPhi) { break; } assert(phi_index < @@ -709,7 +702,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters( } // Add the new edge, by changing OpBranch to OpBranchConditional. - back_edge_block_terminator->SetOpcode(spv::Op::OpBranchConditional); + back_edge_block_terminator->SetOpcode(SpvOpBranchConditional); back_edge_block_terminator->SetInOperands(opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {loop_limiter_info.compare_id()}}, {SPV_OPERAND_TYPE_ID, {loop_header->MergeBlockId()}}, @@ -731,18 +724,18 @@ bool TransformationAddFunction::TryToAddLoopLimiters( bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( opt::IRContext* ir_context, opt::Function* added_function, opt::Instruction* kill_or_unreachable_inst) const { - assert((kill_or_unreachable_inst->opcode() == spv::Op::OpKill || - kill_or_unreachable_inst->opcode() == spv::Op::OpUnreachable) && + assert((kill_or_unreachable_inst->opcode() == SpvOpKill || + kill_or_unreachable_inst->opcode() == SpvOpUnreachable) && "Precondition: instruction must be OpKill or OpUnreachable."); // Get the function's return type. auto function_return_type_inst = ir_context->get_def_use_mgr()->GetDef(added_function->type_id()); - if (function_return_type_inst->opcode() == spv::Op::OpTypeVoid) { + if (function_return_type_inst->opcode() == SpvOpTypeVoid) { // The function has void return type, so change this instruction to // OpReturn. - kill_or_unreachable_inst->SetOpcode(spv::Op::OpReturn); + kill_or_unreachable_inst->SetOpcode(SpvOpReturn); } else { // The function has non-void return type, so change this instruction // to OpReturnValue, using the value id provided with the @@ -756,7 +749,7 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( ->type_id() != function_return_type_inst->result_id()) { return false; } - kill_or_unreachable_inst->SetOpcode(spv::Op::OpReturnValue); + kill_or_unreachable_inst->SetOpcode(SpvOpReturnValue); kill_or_unreachable_inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {message_.kill_unreachable_return_value_id()}}}); } @@ -765,8 +758,8 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn( bool TransformationAddFunction::TryToClampAccessChainIndices( opt::IRContext* ir_context, opt::Instruction* access_chain_inst) const { - assert((access_chain_inst->opcode() == spv::Op::OpAccessChain || - access_chain_inst->opcode() == spv::Op::OpInBoundsAccessChain) && + assert((access_chain_inst->opcode() == SpvOpAccessChain || + access_chain_inst->opcode() == SpvOpInBoundsAccessChain) && "Precondition: instruction must be OpAccessChain or " "OpInBoundsAccessChain."); @@ -800,7 +793,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( assert(base_object && "The base object must exist."); auto pointer_type = ir_context->get_def_use_mgr()->GetDef(base_object->type_id()); - assert(pointer_type && pointer_type->opcode() == spv::Op::OpTypePointer && + assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer && "The base object must have pointer type."); auto should_be_composite_type = ir_context->get_def_use_mgr()->GetDef( pointer_type->GetSingleWordInOperand(1)); @@ -831,18 +824,18 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id); auto index_type_inst = ir_context->get_def_use_mgr()->GetDef(index_inst->type_id()); - assert(index_type_inst->opcode() == spv::Op::OpTypeInt); + assert(index_type_inst->opcode() == SpvOpTypeInt); assert(index_type_inst->GetSingleWordInOperand(0) == 32); opt::analysis::Integer* index_int_type = ir_context->get_type_mgr() ->GetType(index_type_inst->result_id()) ->AsInteger(); - if (index_inst->opcode() != spv::Op::OpConstant || + if (index_inst->opcode() != SpvOpConstant || index_inst->GetSingleWordInOperand(0) >= bound) { // The index is either non-constant or an out-of-bounds constant, so we // need to clamp it. - assert(should_be_composite_type->opcode() != spv::Op::OpTypeStruct && + assert(should_be_composite_type->opcode() != SpvOpTypeStruct && "Access chain indices into structures are required to be " "constants."); opt::analysis::IntConstant bound_minus_one(index_int_type, {bound - 1}); @@ -873,7 +866,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Compare the index with the bound via an instruction of the form: // %t1 = OpULessThanEqual %bool %index %bound_minus_one new_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpULessThanEqual, bool_type_id, compare_id, + ir_context, SpvOpULessThanEqual, bool_type_id, compare_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {index_inst->result_id()}}, {SPV_OPERAND_TYPE_ID, {bound_minus_one_id}}}))); @@ -881,8 +874,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices( // Select the index if in-bounds, otherwise one less than the bound: // %t2 = OpSelect %int_type %t1 %index %bound_minus_one new_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpSelect, index_type_inst->result_id(), - select_id, + ir_context, SpvOpSelect, index_type_inst->result_id(), select_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {compare_id}}, {SPV_OPERAND_TYPE_ID, {index_inst->result_id()}}, @@ -907,20 +899,20 @@ opt::Instruction* TransformationAddFunction::FollowCompositeIndex( uint32_t index_id) { uint32_t sub_object_type_id; switch (composite_type_inst.opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: sub_object_type_id = composite_type_inst.GetSingleWordInOperand(0); break; - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: sub_object_type_id = composite_type_inst.GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id); - assert(index_inst->opcode() == spv::Op::OpConstant); + assert(index_inst->opcode() == SpvOpConstant); assert(ir_context->get_def_use_mgr() ->GetDef(index_inst->type_id()) - ->opcode() == spv::Op::OpTypeInt); + ->opcode() == SpvOpTypeInt); assert(ir_context->get_def_use_mgr() ->GetDef(index_inst->type_id()) ->GetSingleWordInOperand(0) == 32); diff --git a/source/fuzz/transformation_add_global_undef.cpp b/source/fuzz/transformation_add_global_undef.cpp index 5aca19d9..ec0574a4 100644 --- a/source/fuzz/transformation_add_global_undef.cpp +++ b/source/fuzz/transformation_add_global_undef.cpp @@ -39,14 +39,14 @@ bool TransformationAddGlobalUndef::IsApplicable( auto type = ir_context->get_def_use_mgr()->GetDef(message_.type_id()); // The type must exist, and must not be a function or pointer type. return type != nullptr && opt::IsTypeInst(type->opcode()) && - type->opcode() != spv::Op::OpTypeFunction && - type->opcode() != spv::Op::OpTypePointer; + type->opcode() != SpvOpTypeFunction && + type->opcode() != SpvOpTypePointer; } void TransformationAddGlobalUndef::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto new_instruction = MakeUnique( - ir_context, spv::Op::OpUndef, message_.type_id(), message_.fresh_id(), + ir_context, SpvOpUndef, message_.type_id(), message_.fresh_id(), opt::Instruction::OperandList()); auto new_instruction_ptr = new_instruction.get(); ir_context->module()->AddGlobalValue(std::move(new_instruction)); diff --git a/source/fuzz/transformation_add_global_variable.cpp b/source/fuzz/transformation_add_global_variable.cpp index 6e82d594..814d01b3 100644 --- a/source/fuzz/transformation_add_global_variable.cpp +++ b/source/fuzz/transformation_add_global_variable.cpp @@ -24,11 +24,11 @@ TransformationAddGlobalVariable::TransformationAddGlobalVariable( : message_(std::move(message)) {} TransformationAddGlobalVariable::TransformationAddGlobalVariable( - uint32_t fresh_id, uint32_t type_id, spv::StorageClass storage_class, + uint32_t fresh_id, uint32_t type_id, SpvStorageClass storage_class, uint32_t initializer_id, bool value_is_irrelevant) { message_.set_fresh_id(fresh_id); message_.set_type_id(type_id); - message_.set_storage_class(uint32_t(storage_class)); + message_.set_storage_class(storage_class); message_.set_initializer_id(initializer_id); message_.set_value_is_irrelevant(value_is_irrelevant); } @@ -41,10 +41,10 @@ bool TransformationAddGlobalVariable::IsApplicable( } // The storage class must be Private or Workgroup. - auto storage_class = static_cast(message_.storage_class()); + auto storage_class = static_cast(message_.storage_class()); switch (storage_class) { - case spv::StorageClass::Private: - case spv::StorageClass::Workgroup: + case SpvStorageClassPrivate: + case SpvStorageClassWorkgroup: break; default: assert(false && "Unsupported storage class."); @@ -66,7 +66,7 @@ bool TransformationAddGlobalVariable::IsApplicable( } if (message_.initializer_id()) { // An initializer is not allowed if the storage class is Workgroup. - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { assert(false && "By construction this transformation should not have an " "initializer when Workgroup storage class is used."); @@ -95,7 +95,7 @@ void TransformationAddGlobalVariable::Apply( TransformationContext* transformation_context) const { opt::Instruction* new_instruction = fuzzerutil::AddGlobalVariable( ir_context, message_.fresh_id(), message_.type_id(), - static_cast(message_.storage_class()), + static_cast(message_.storage_class()), message_.initializer_id()); // Inform the def-use manager about the new instruction. diff --git a/source/fuzz/transformation_add_global_variable.h b/source/fuzz/transformation_add_global_variable.h index 01782198..d74d48a2 100644 --- a/source/fuzz/transformation_add_global_variable.h +++ b/source/fuzz/transformation_add_global_variable.h @@ -29,7 +29,7 @@ class TransformationAddGlobalVariable : public Transformation { protobufs::TransformationAddGlobalVariable message); TransformationAddGlobalVariable(uint32_t fresh_id, uint32_t type_id, - spv::StorageClass storage_class, + SpvStorageClass storage_class, uint32_t initializer_id, bool value_is_irrelevant); diff --git a/source/fuzz/transformation_add_image_sample_unused_components.cpp b/source/fuzz/transformation_add_image_sample_unused_components.cpp index 018fed4c..1ead82bc 100644 --- a/source/fuzz/transformation_add_image_sample_unused_components.cpp +++ b/source/fuzz/transformation_add_image_sample_unused_components.cpp @@ -73,7 +73,7 @@ bool TransformationAddImageSampleUnusedComponents::IsApplicable( // It must be an OpCompositeConstruct instruction such that it can be checked // that the original components are present. if (coordinate_with_unused_components_instruction->opcode() != - spv::Op::OpCompositeConstruct) { + SpvOpCompositeConstruct) { return false; } diff --git a/source/fuzz/transformation_add_local_variable.cpp b/source/fuzz/transformation_add_local_variable.cpp index 9ee210cb..21768d22 100644 --- a/source/fuzz/transformation_add_local_variable.cpp +++ b/source/fuzz/transformation_add_local_variable.cpp @@ -43,10 +43,8 @@ bool TransformationAddLocalVariable::IsApplicable( // function storage class. auto type_instruction = ir_context->get_def_use_mgr()->GetDef(message_.type_id()); - if (!type_instruction || - type_instruction->opcode() != spv::Op::OpTypePointer || - spv::StorageClass(type_instruction->GetSingleWordInOperand(0)) != - spv::StorageClass::Function) { + if (!type_instruction || type_instruction->opcode() != SpvOpTypePointer || + type_instruction->GetSingleWordInOperand(0) != SpvStorageClassFunction) { return false; } // The initializer must... diff --git a/source/fuzz/transformation_add_loop_preheader.cpp b/source/fuzz/transformation_add_loop_preheader.cpp index 4b66b69f..71ab18da 100644 --- a/source/fuzz/transformation_add_loop_preheader.cpp +++ b/source/fuzz/transformation_add_loop_preheader.cpp @@ -120,8 +120,8 @@ void TransformationAddLoopPreheader::Apply( // If |use_inst| is not a branch or merge instruction, it should not be // changed. if (!use_inst->IsBranch() && - use_inst->opcode() != spv::Op::OpSelectionMerge && - use_inst->opcode() != spv::Op::OpLoopMerge) { + use_inst->opcode() != SpvOpSelectionMerge && + use_inst->opcode() != SpvOpLoopMerge) { return; } @@ -134,7 +134,7 @@ void TransformationAddLoopPreheader::Apply( // Make a new block for the preheader. std::unique_ptr preheader = MakeUnique( std::unique_ptr(new opt::Instruction( - ir_context, spv::Op::OpLabel, 0, message_.fresh_id(), {}))); + ir_context, SpvOpLabel, 0, message_.fresh_id(), {}))); uint32_t phi_ids_used = 0; @@ -183,7 +183,7 @@ void TransformationAddLoopPreheader::Apply( fuzzerutil::UpdateModuleIdBound(ir_context, fresh_phi_id); preheader->AddInstruction(std::unique_ptr( - new opt::Instruction(ir_context, spv::Op::OpPhi, phi_inst->type_id(), + new opt::Instruction(ir_context, SpvOpPhi, phi_inst->type_id(), fresh_phi_id, preheader_in_operands))); // Update the OpPhi instruction in the header so that it refers to the @@ -202,7 +202,7 @@ void TransformationAddLoopPreheader::Apply( // Add an unconditional branch from the preheader to the header. preheader->AddInstruction( std::unique_ptr(new opt::Instruction( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, std::initializer_list{opt::Operand( spv_operand_type_t::SPV_OPERAND_TYPE_ID, {loop_header->id()})}))); diff --git a/source/fuzz/transformation_add_loop_to_create_int_constant_synonym.cpp b/source/fuzz/transformation_add_loop_to_create_int_constant_synonym.cpp index 00030e79..657fafa4 100644 --- a/source/fuzz/transformation_add_loop_to_create_int_constant_synonym.cpp +++ b/source/fuzz/transformation_add_loop_to_create_int_constant_synonym.cpp @@ -262,13 +262,13 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // Create the loop header block. std::unique_ptr loop_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.loop_id(), + ir_context, SpvOpLabel, 0, message_.loop_id(), opt::Instruction::OperandList{})); // Add OpPhi instructions to retrieve the current value of the counter and of // the temporary variable that will be decreased at each operation. loop_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpPhi, const_0_def->type_id(), message_.ctr_id(), + ir_context, SpvOpPhi, const_0_def->type_id(), message_.ctr_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {const_0_id}}, {SPV_OPERAND_TYPE_ID, {pred_id}}, @@ -276,8 +276,7 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( {SPV_OPERAND_TYPE_ID, {last_loop_block_id}}})); loop_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpPhi, initial_val_def->type_id(), - message_.temp_id(), + ir_context, SpvOpPhi, initial_val_def->type_id(), message_.temp_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.initial_val_id()}}, {SPV_OPERAND_TYPE_ID, {pred_id}}, @@ -292,7 +291,7 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // Add an instruction to subtract the step value from the temporary value. // The value of this id will converge to the constant in the last iteration. other_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpISub, initial_val_def->type_id(), + ir_context, SpvOpISub, initial_val_def->type_id(), message_.eventual_syn_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.temp_id()}}, @@ -300,15 +299,15 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // Add an instruction to increment the counter. other_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpIAdd, const_0_def->type_id(), + ir_context, SpvOpIAdd, const_0_def->type_id(), message_.incremented_ctr_id(), opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {message_.ctr_id()}}, {SPV_OPERAND_TYPE_ID, {const_1_id}}})); // Add an instruction to decide whether the condition holds. other_instructions.push_back(MakeUnique( - ir_context, spv::Op::OpSLessThan, - fuzzerutil::MaybeGetBoolType(ir_context), message_.cond_id(), + ir_context, SpvOpSLessThan, fuzzerutil::MaybeGetBoolType(ir_context), + message_.cond_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.incremented_ctr_id()}}, {SPV_OPERAND_TYPE_ID, {message_.num_iterations_id()}}})); @@ -317,19 +316,18 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // the existing block, the continue block is the last block in the loop // (either the loop itself or the additional block). std::unique_ptr merge_inst = MakeUnique( - ir_context, spv::Op::OpLoopMerge, 0, 0, + ir_context, SpvOpLoopMerge, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.block_after_loop_id()}}, {SPV_OPERAND_TYPE_ID, {last_loop_block_id}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}}); + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}}); // Define a conditional branch instruction, branching to the loop header if // the condition holds, and to the existing block otherwise. This instruction // will be added to the last block in the loop. std::unique_ptr conditional_branch = MakeUnique( - ir_context, spv::Op::OpBranchConditional, 0, 0, + ir_context, SpvOpBranchConditional, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.cond_id()}}, {SPV_OPERAND_TYPE_ID, {message_.loop_id()}}, @@ -342,7 +340,7 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( std::unique_ptr additional_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.additional_block_id(), + ir_context, SpvOpLabel, 0, message_.additional_block_id(), opt::Instruction::OperandList{})); for (auto& instruction : other_instructions) { @@ -356,7 +354,7 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // Add an unconditional branch from the header to the additional block. loop_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.additional_block_id()}}})); @@ -386,14 +384,14 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( ir_context->get_def_use_mgr()->ForEachUse( message_.block_after_loop_id(), [this](opt::Instruction* instruction, uint32_t operand_index) { - assert(instruction->opcode() != spv::Op::OpLoopMerge && - instruction->opcode() != spv::Op::OpSelectionMerge && + assert(instruction->opcode() != SpvOpLoopMerge && + instruction->opcode() != SpvOpSelectionMerge && "The block should not be referenced by OpLoopMerge or " "OpSelectionMerge, by construction."); // Replace all uses of the label inside branch instructions. - if (instruction->opcode() == spv::Op::OpBranch || - instruction->opcode() == spv::Op::OpBranchConditional || - instruction->opcode() == spv::Op::OpSwitch) { + if (instruction->opcode() == SpvOpBranch || + instruction->opcode() == SpvOpBranchConditional || + instruction->opcode() == SpvOpSwitch) { instruction->SetOperand(operand_index, {message_.loop_id()}); } }); @@ -412,7 +410,7 @@ void TransformationAddLoopToCreateIntConstantSynonym::Apply( // |message_.initial_value_id|, since this is the value that is decremented in // the loop. block_after_loop->begin()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpPhi, initial_val_def->type_id(), message_.syn_id(), + ir_context, SpvOpPhi, initial_val_def->type_id(), message_.syn_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.eventual_syn_id()}}, {SPV_OPERAND_TYPE_ID, {last_loop_block_id}}})); diff --git a/source/fuzz/transformation_add_no_contraction_decoration.cpp b/source/fuzz/transformation_add_no_contraction_decoration.cpp index 07a31e5c..992a216b 100644 --- a/source/fuzz/transformation_add_no_contraction_decoration.cpp +++ b/source/fuzz/transformation_add_no_contraction_decoration.cpp @@ -43,8 +43,8 @@ bool TransformationAddNoContractionDecoration::IsApplicable( void TransformationAddNoContractionDecoration::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Add a NoContraction decoration targeting |message_.result_id|. - ir_context->get_decoration_mgr()->AddDecoration( - message_.result_id(), uint32_t(spv::Decoration::NoContraction)); + ir_context->get_decoration_mgr()->AddDecoration(message_.result_id(), + SpvDecorationNoContraction); } protobufs::Transformation TransformationAddNoContractionDecoration::ToMessage() @@ -54,50 +54,50 @@ protobufs::Transformation TransformationAddNoContractionDecoration::ToMessage() return result; } -bool TransformationAddNoContractionDecoration::IsArithmetic(spv::Op opcode) { +bool TransformationAddNoContractionDecoration::IsArithmetic(uint32_t opcode) { switch (opcode) { - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: return true; default: return false; diff --git a/source/fuzz/transformation_add_no_contraction_decoration.h b/source/fuzz/transformation_add_no_contraction_decoration.h index 4235dc10..2f78d429 100644 --- a/source/fuzz/transformation_add_no_contraction_decoration.h +++ b/source/fuzz/transformation_add_no_contraction_decoration.h @@ -50,7 +50,7 @@ class TransformationAddNoContractionDecoration : public Transformation { // Returns true if and only if |opcode| is the opcode of an arithmetic // instruction, as defined by the SPIR-V specification. - static bool IsArithmetic(spv::Op opcode); + static bool IsArithmetic(uint32_t opcode); private: protobufs::TransformationAddNoContractionDecoration message_; diff --git a/source/fuzz/transformation_add_opphi_synonym.cpp b/source/fuzz/transformation_add_opphi_synonym.cpp index 31c56b66..3c4698a7 100644 --- a/source/fuzz/transformation_add_opphi_synonym.cpp +++ b/source/fuzz/transformation_add_opphi_synonym.cpp @@ -142,8 +142,8 @@ void TransformationAddOpPhiSynonym::Apply( // Add a new OpPhi instructions at the beginning of the block. ir_context->get_instr_block(message_.block_id()) ->begin() - .InsertBefore(MakeUnique(ir_context, spv::Op::OpPhi, - type_id, message_.fresh_id(), + .InsertBefore(MakeUnique(ir_context, SpvOpPhi, type_id, + message_.fresh_id(), std::move(operand_list))); // Update the module id bound. @@ -186,9 +186,9 @@ bool TransformationAddOpPhiSynonym::CheckTypeIsAllowed( if (type->AsPointer()) { auto storage_class = type->AsPointer()->storage_class(); return ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointers) && - (storage_class == spv::StorageClass::Workgroup || - storage_class == spv::StorageClass::StorageBuffer); + SpvCapabilityVariablePointers) && + (storage_class == SpvStorageClassWorkgroup || + storage_class == SpvStorageClassStorageBuffer); } // We do not allow other types. diff --git a/source/fuzz/transformation_add_parameter.cpp b/source/fuzz/transformation_add_parameter.cpp index 8bd2ed78..48de3e83 100644 --- a/source/fuzz/transformation_add_parameter.cpp +++ b/source/fuzz/transformation_add_parameter.cpp @@ -112,7 +112,7 @@ void TransformationAddParameter::Apply( // Add new parameters to the function. function->AddParameter(MakeUnique( - ir_context, spv::Op::OpFunctionParameter, new_parameter_type_id, + ir_context, SpvOpFunctionParameter, new_parameter_type_id, message_.parameter_fresh_id(), opt::Instruction::OperandList())); fuzzerutil::UpdateModuleIdBound(ir_context, message_.parameter_fresh_id()); @@ -178,16 +178,16 @@ bool TransformationAddParameter::IsParameterTypeSupported( // Think about other type instructions we can add here. opt::Instruction* type_inst = ir_context->get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeMatrix: + case SpvOpTypeVector: return true; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: return IsParameterTypeSupported(ir_context, type_inst->GetSingleWordInOperand(0)); - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: if (fuzzerutil::HasBlockOrBufferBlockDecoration(ir_context, type_id)) { return false; } @@ -198,13 +198,13 @@ bool TransformationAddParameter::IsParameterTypeSupported( } } return true; - case spv::Op::OpTypePointer: { - spv::StorageClass storage_class = - static_cast(type_inst->GetSingleWordInOperand(0)); + case SpvOpTypePointer: { + SpvStorageClass storage_class = + static_cast(type_inst->GetSingleWordInOperand(0)); switch (storage_class) { - case spv::StorageClass::Private: - case spv::StorageClass::Function: - case spv::StorageClass::Workgroup: { + case SpvStorageClassPrivate: + case SpvStorageClassFunction: + case SpvStorageClassWorkgroup: { return IsParameterTypeSupported(ir_context, type_inst->GetSingleWordInOperand(1)); } diff --git a/source/fuzz/transformation_add_relaxed_decoration.cpp b/source/fuzz/transformation_add_relaxed_decoration.cpp index 6cd4ecbb..b66a1a83 100644 --- a/source/fuzz/transformation_add_relaxed_decoration.cpp +++ b/source/fuzz/transformation_add_relaxed_decoration.cpp @@ -54,7 +54,7 @@ void TransformationAddRelaxedDecoration::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { // Add a RelaxedPrecision decoration targeting |message_.result_id|. ir_context->get_decoration_mgr()->AddDecoration( - message_.result_id(), uint32_t(spv::Decoration::RelaxedPrecision)); + message_.result_id(), SpvDecorationRelaxedPrecision); } protobufs::Transformation TransformationAddRelaxedDecoration::ToMessage() @@ -64,77 +64,77 @@ protobufs::Transformation TransformationAddRelaxedDecoration::ToMessage() return result; } -bool TransformationAddRelaxedDecoration::IsNumeric(spv::Op opcode) { +bool TransformationAddRelaxedDecoration::IsNumeric(uint32_t opcode) { switch (opcode) { - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpConvertPtrToU: - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpTranspose: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpConvertPtrToU: + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpTranspose: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpAtomicLoad: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: return true; default: return false; @@ -147,4 +147,4 @@ std::unordered_set TransformationAddRelaxedDecoration::GetFreshIds() } } // namespace fuzz -} // namespace spvtools +} // namespace spvtools \ No newline at end of file diff --git a/source/fuzz/transformation_add_relaxed_decoration.h b/source/fuzz/transformation_add_relaxed_decoration.h index e13594e8..c0163497 100644 --- a/source/fuzz/transformation_add_relaxed_decoration.h +++ b/source/fuzz/transformation_add_relaxed_decoration.h @@ -52,7 +52,7 @@ class TransformationAddRelaxedDecoration : public Transformation { // Returns true if and only if |opcode| is the opcode of an instruction // that operates on 32-bit integers and 32-bit floats // as defined by the SPIR-V specification. - static bool IsNumeric(spv::Op opcode); + static bool IsNumeric(uint32_t opcode); private: protobufs::TransformationAddRelaxedDecoration message_; diff --git a/source/fuzz/transformation_add_spec_constant_op.cpp b/source/fuzz/transformation_add_spec_constant_op.cpp index 685f0a4a..19c5e855 100644 --- a/source/fuzz/transformation_add_spec_constant_op.cpp +++ b/source/fuzz/transformation_add_spec_constant_op.cpp @@ -26,11 +26,11 @@ TransformationAddSpecConstantOp::TransformationAddSpecConstantOp( : message_(std::move(message)) {} TransformationAddSpecConstantOp::TransformationAddSpecConstantOp( - uint32_t fresh_id, uint32_t type_id, spv::Op opcode, + uint32_t fresh_id, uint32_t type_id, SpvOp opcode, const opt::Instruction::OperandList& operands) { message_.set_fresh_id(fresh_id); message_.set_type_id(type_id); - message_.set_opcode(uint32_t(opcode)); + message_.set_opcode(opcode); for (const auto& operand : operands) { auto* op = message_.add_operand(); op->set_operand_type(operand.type); @@ -70,8 +70,8 @@ void TransformationAddSpecConstantOp::ApplyImpl( } ir_context->AddGlobalValue(MakeUnique( - ir_context, spv::Op::OpSpecConstantOp, message_.type_id(), - message_.fresh_id(), std::move(operands))); + ir_context, SpvOpSpecConstantOp, message_.type_id(), message_.fresh_id(), + std::move(operands))); fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); } diff --git a/source/fuzz/transformation_add_spec_constant_op.h b/source/fuzz/transformation_add_spec_constant_op.h index 665f66a0..29851fde 100644 --- a/source/fuzz/transformation_add_spec_constant_op.h +++ b/source/fuzz/transformation_add_spec_constant_op.h @@ -29,7 +29,7 @@ class TransformationAddSpecConstantOp : public Transformation { protobufs::TransformationAddSpecConstantOp message); TransformationAddSpecConstantOp( - uint32_t fresh_id, uint32_t type_id, spv::Op opcode, + uint32_t fresh_id, uint32_t type_id, SpvOp opcode, const opt::Instruction::OperandList& operands); // - |fresh_id| is a fresh result id in the module. diff --git a/source/fuzz/transformation_add_synonym.cpp b/source/fuzz/transformation_add_synonym.cpp index 00df9cf2..69269e5e 100644 --- a/source/fuzz/transformation_add_synonym.cpp +++ b/source/fuzz/transformation_add_synonym.cpp @@ -82,7 +82,7 @@ bool TransformationAddSynonym::IsApplicable( // Check that we can insert |message._synonymous_instruction| before // |message_.insert_before| instruction. We use OpIAdd to represent some // instruction that can produce a synonym. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpIAdd, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, insert_before_inst)) { return false; } @@ -147,8 +147,7 @@ bool TransformationAddSynonym::IsInstructionValid( // Instruction must have a result id, type id. We skip OpUndef and // OpConstantNull. if (!inst || !inst->result_id() || !inst->type_id() || - inst->opcode() == spv::Op::OpUndef || - inst->opcode() == spv::Op::OpConstantNull) { + inst->opcode() == SpvOpUndef || inst->opcode() == SpvOpConstantNull) { return false; } @@ -209,7 +208,7 @@ TransformationAddSynonym::MakeSynonymousInstruction( auto synonym_type_id = fuzzerutil::GetTypeId(ir_context, message_.result_id()); assert(synonym_type_id && "Synonym has invalid type id"); - auto opcode = spv::Op::OpNop; + auto opcode = SpvOpNop; const auto* synonym_type = ir_context->get_type_mgr()->GetType(synonym_type_id); assert(synonym_type && "Synonym has invalid type"); @@ -220,30 +219,30 @@ TransformationAddSynonym::MakeSynonymousInstruction( switch (message_.synonym_type()) { case protobufs::TransformationAddSynonym::SUB_ZERO: - opcode = is_integral ? spv::Op::OpISub : spv::Op::OpFSub; + opcode = is_integral ? SpvOpISub : SpvOpFSub; break; case protobufs::TransformationAddSynonym::MUL_ONE: - opcode = is_integral ? spv::Op::OpIMul : spv::Op::OpFMul; + opcode = is_integral ? SpvOpIMul : SpvOpFMul; break; case protobufs::TransformationAddSynonym::ADD_ZERO: - opcode = is_integral ? spv::Op::OpIAdd : spv::Op::OpFAdd; + opcode = is_integral ? SpvOpIAdd : SpvOpFAdd; break; case protobufs::TransformationAddSynonym::LOGICAL_OR: - opcode = spv::Op::OpLogicalOr; + opcode = SpvOpLogicalOr; break; case protobufs::TransformationAddSynonym::LOGICAL_AND: - opcode = spv::Op::OpLogicalAnd; + opcode = SpvOpLogicalAnd; break; case protobufs::TransformationAddSynonym::BITWISE_OR: - opcode = spv::Op::OpBitwiseOr; + opcode = SpvOpBitwiseOr; break; case protobufs::TransformationAddSynonym::BITWISE_XOR: - opcode = spv::Op::OpBitwiseXor; + opcode = SpvOpBitwiseXor; break; case protobufs::TransformationAddSynonym::COPY_OBJECT: return MakeUnique( - ir_context, spv::Op::OpCopyObject, synonym_type_id, + ir_context, SpvOpCopyObject, synonym_type_id, message_.synonym_fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.result_id()}}}); diff --git a/source/fuzz/transformation_add_type_array.cpp b/source/fuzz/transformation_add_type_array.cpp index d00d0e43..45bc8dfe 100644 --- a/source/fuzz/transformation_add_type_array.cpp +++ b/source/fuzz/transformation_add_type_array.cpp @@ -72,7 +72,7 @@ void TransformationAddTypeArray::Apply( in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.element_type_id()}}); in_operands.push_back({SPV_OPERAND_TYPE_ID, {message_.size_id()}}); auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeArray, 0, message_.fresh_id(), in_operands); + ir_context, SpvOpTypeArray, 0, message_.fresh_id(), in_operands); auto type_instruction_ptr = type_instruction.get(); ir_context->module()->AddType(std::move(type_instruction)); diff --git a/source/fuzz/transformation_add_type_boolean.cpp b/source/fuzz/transformation_add_type_boolean.cpp index 47fc744f..30ff43e2 100644 --- a/source/fuzz/transformation_add_type_boolean.cpp +++ b/source/fuzz/transformation_add_type_boolean.cpp @@ -43,7 +43,7 @@ void TransformationAddTypeBoolean::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { opt::Instruction::OperandList empty_operands; auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeBool, 0, message_.fresh_id(), empty_operands); + ir_context, SpvOpTypeBool, 0, message_.fresh_id(), empty_operands); auto type_instruction_ptr = type_instruction.get(); ir_context->module()->AddType(std::move(type_instruction)); diff --git a/source/fuzz/transformation_add_type_float.cpp b/source/fuzz/transformation_add_type_float.cpp index 1943ffa5..1b88b25c 100644 --- a/source/fuzz/transformation_add_type_float.cpp +++ b/source/fuzz/transformation_add_type_float.cpp @@ -40,8 +40,7 @@ bool TransformationAddTypeFloat::IsApplicable( switch (message_.width()) { case 16: // The Float16 capability must be present. - if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Float16)) { + if (!ir_context->get_feature_mgr()->HasCapability(SpvCapabilityFloat16)) { return false; } break; @@ -50,8 +49,7 @@ bool TransformationAddTypeFloat::IsApplicable( break; case 64: // The Float64 capability must be present. - if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Float64)) { + if (!ir_context->get_feature_mgr()->HasCapability(SpvCapabilityFloat64)) { return false; } break; @@ -68,7 +66,7 @@ bool TransformationAddTypeFloat::IsApplicable( void TransformationAddTypeFloat::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeFloat, 0, message_.fresh_id(), + ir_context, SpvOpTypeFloat, 0, message_.fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}}}); auto type_instruction_ptr = type_instruction.get(); diff --git a/source/fuzz/transformation_add_type_int.cpp b/source/fuzz/transformation_add_type_int.cpp index 35663f96..d4ef9819 100644 --- a/source/fuzz/transformation_add_type_int.cpp +++ b/source/fuzz/transformation_add_type_int.cpp @@ -42,15 +42,13 @@ bool TransformationAddTypeInt::IsApplicable( switch (message_.width()) { case 8: // The Int8 capability must be present. - if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Int8)) { + if (!ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt8)) { return false; } break; case 16: // The Int16 capability must be present. - if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Int16)) { + if (!ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt16)) { return false; } break; @@ -59,8 +57,7 @@ bool TransformationAddTypeInt::IsApplicable( break; case 64: // The Int64 capability must be present. - if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::Int64)) { + if (!ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt64)) { return false; } break; @@ -78,7 +75,7 @@ bool TransformationAddTypeInt::IsApplicable( void TransformationAddTypeInt::Apply(opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeInt, 0, message_.fresh_id(), + ir_context, SpvOpTypeInt, 0, message_.fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.width()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, diff --git a/source/fuzz/transformation_add_type_matrix.cpp b/source/fuzz/transformation_add_type_matrix.cpp index e3f1786b..b574b01b 100644 --- a/source/fuzz/transformation_add_type_matrix.cpp +++ b/source/fuzz/transformation_add_type_matrix.cpp @@ -53,7 +53,7 @@ void TransformationAddTypeMatrix::Apply( in_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.column_count()}}); auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeMatrix, 0, message_.fresh_id(), in_operands); + ir_context, SpvOpTypeMatrix, 0, message_.fresh_id(), in_operands); auto type_instruction_ptr = type_instruction.get(); ir_context->module()->AddType(std::move(type_instruction)); diff --git a/source/fuzz/transformation_add_type_pointer.cpp b/source/fuzz/transformation_add_type_pointer.cpp index c1126154..c6c3945b 100644 --- a/source/fuzz/transformation_add_type_pointer.cpp +++ b/source/fuzz/transformation_add_type_pointer.cpp @@ -24,9 +24,9 @@ TransformationAddTypePointer::TransformationAddTypePointer( : message_(std::move(message)) {} TransformationAddTypePointer::TransformationAddTypePointer( - uint32_t fresh_id, spv::StorageClass storage_class, uint32_t base_type_id) { + uint32_t fresh_id, SpvStorageClass storage_class, uint32_t base_type_id) { message_.set_fresh_id(fresh_id); - message_.set_storage_class(uint32_t(storage_class)); + message_.set_storage_class(storage_class); message_.set_base_type_id(base_type_id); } @@ -48,7 +48,7 @@ void TransformationAddTypePointer::Apply( {SPV_OPERAND_TYPE_STORAGE_CLASS, {message_.storage_class()}}, {SPV_OPERAND_TYPE_ID, {message_.base_type_id()}}}; auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypePointer, 0, message_.fresh_id(), in_operands); + ir_context, SpvOpTypePointer, 0, message_.fresh_id(), in_operands); auto type_instruction_ptr = type_instruction.get(); ir_context->module()->AddType(std::move(type_instruction)); diff --git a/source/fuzz/transformation_add_type_pointer.h b/source/fuzz/transformation_add_type_pointer.h index e4ef9d88..8468c14d 100644 --- a/source/fuzz/transformation_add_type_pointer.h +++ b/source/fuzz/transformation_add_type_pointer.h @@ -28,8 +28,7 @@ class TransformationAddTypePointer : public Transformation { explicit TransformationAddTypePointer( protobufs::TransformationAddTypePointer message); - TransformationAddTypePointer(uint32_t fresh_id, - spv::StorageClass storage_class, + TransformationAddTypePointer(uint32_t fresh_id, SpvStorageClass storage_class, uint32_t base_type_id); // - |message_.fresh_id| must not be used by the module diff --git a/source/fuzz/transformation_add_type_struct.cpp b/source/fuzz/transformation_add_type_struct.cpp index 95fbbbab..d7f0711e 100644 --- a/source/fuzz/transformation_add_type_struct.cpp +++ b/source/fuzz/transformation_add_type_struct.cpp @@ -79,9 +79,8 @@ void TransformationAddTypeStruct::Apply( operands.push_back({SPV_OPERAND_TYPE_ID, {type_id}}); } - auto type_instruction = - MakeUnique(ir_context, spv::Op::OpTypeStruct, 0, - message_.fresh_id(), std::move(operands)); + auto type_instruction = MakeUnique( + ir_context, SpvOpTypeStruct, 0, message_.fresh_id(), std::move(operands)); auto type_instruction_ptr = type_instruction.get(); ir_context->AddType(std::move(type_instruction)); diff --git a/source/fuzz/transformation_add_type_vector.cpp b/source/fuzz/transformation_add_type_vector.cpp index a7b0fa7a..4da0ff01 100644 --- a/source/fuzz/transformation_add_type_vector.cpp +++ b/source/fuzz/transformation_add_type_vector.cpp @@ -57,7 +57,7 @@ void TransformationAddTypeVector::Apply( "Precondition: component count must be in range [2, 4]."); auto type_instruction = MakeUnique( - ir_context, spv::Op::OpTypeVector, 0, message_.fresh_id(), + ir_context, SpvOpTypeVector, 0, message_.fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.component_type_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.component_count()}}}); diff --git a/source/fuzz/transformation_adjust_branch_weights.cpp b/source/fuzz/transformation_adjust_branch_weights.cpp index 26519389..21fef258 100644 --- a/source/fuzz/transformation_adjust_branch_weights.cpp +++ b/source/fuzz/transformation_adjust_branch_weights.cpp @@ -47,7 +47,7 @@ bool TransformationAdjustBranchWeights::IsApplicable( return false; } - spv::Op opcode = static_cast( + SpvOp opcode = static_cast( message_.instruction_descriptor().target_instruction_opcode()); assert(instruction->opcode() == opcode && @@ -55,7 +55,7 @@ bool TransformationAdjustBranchWeights::IsApplicable( "descriptor."); // Must be an OpBranchConditional instruction. - if (opcode != spv::Op::OpBranchConditional) { + if (opcode != SpvOpBranchConditional) { return false; } diff --git a/source/fuzz/transformation_composite_construct.cpp b/source/fuzz/transformation_composite_construct.cpp index 075b33d4..2d8e5991 100644 --- a/source/fuzz/transformation_composite_construct.cpp +++ b/source/fuzz/transformation_composite_construct.cpp @@ -121,7 +121,7 @@ void TransformationCompositeConstruct::Apply( // Insert an OpCompositeConstruct instruction. auto new_instruction = MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, message_.composite_type_id(), + ir_context, SpvOpCompositeConstruct, message_.composite_type_id(), message_.fresh_id(), in_operands); auto new_instruction_ptr = new_instruction.get(); insert_before.InsertBefore(std::move(new_instruction)); diff --git a/source/fuzz/transformation_composite_extract.cpp b/source/fuzz/transformation_composite_extract.cpp index 7118432f..0fbd4e1b 100644 --- a/source/fuzz/transformation_composite_extract.cpp +++ b/source/fuzz/transformation_composite_extract.cpp @@ -67,7 +67,7 @@ bool TransformationCompositeExtract::IsApplicable( } if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeExtract, instruction_to_insert_before)) { + SpvOpCompositeExtract, instruction_to_insert_before)) { return false; } @@ -93,7 +93,7 @@ void TransformationCompositeExtract::Apply( FindInstruction(message_.instruction_to_insert_before(), ir_context); opt::Instruction* new_instruction = insert_before->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, extracted_type, + ir_context, SpvOpCompositeExtract, extracted_type, message_.fresh_id(), extract_operands)); ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction); ir_context->set_instr_block(new_instruction, diff --git a/source/fuzz/transformation_composite_insert.cpp b/source/fuzz/transformation_composite_insert.cpp index 2f69c959..60fa5628 100644 --- a/source/fuzz/transformation_composite_insert.cpp +++ b/source/fuzz/transformation_composite_insert.cpp @@ -102,7 +102,7 @@ bool TransformationCompositeInsert::IsApplicable( // It must be possible to insert an OpCompositeInsert before this // instruction. return fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeInsert, instruction_to_insert_before); + SpvOpCompositeInsert, instruction_to_insert_before); } void TransformationCompositeInsert::Apply( @@ -126,8 +126,8 @@ void TransformationCompositeInsert::Apply( auto insert_before = FindInstruction(message_.instruction_to_insert_before(), ir_context); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpCompositeInsert, composite_type_id, - message_.fresh_id(), std::move(in_operands)); + ir_context, SpvOpCompositeInsert, composite_type_id, message_.fresh_id(), + std::move(in_operands)); auto new_instruction_ptr = new_instruction.get(); insert_before->InsertBefore(std::move(new_instruction)); diff --git a/source/fuzz/transformation_duplicate_region_with_selection.cpp b/source/fuzz/transformation_duplicate_region_with_selection.cpp index 9176bf75..db88610f 100644 --- a/source/fuzz/transformation_duplicate_region_with_selection.cpp +++ b/source/fuzz/transformation_duplicate_region_with_selection.cpp @@ -77,7 +77,7 @@ bool TransformationDuplicateRegionWithSelection::IsApplicable( // The entry and exit block ids must refer to blocks. for (auto block_id : {message_.entry_block_id(), message_.exit_block_id()}) { auto block_label = ir_context->get_def_use_mgr()->GetDef(block_id); - if (!block_label || block_label->opcode() != spv::Op::OpLabel) { + if (!block_label || block_label->opcode() != SpvOpLabel) { return false; } } @@ -297,7 +297,7 @@ void TransformationDuplicateRegionWithSelection::Apply( // in the same function. std::unique_ptr new_entry_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.new_entry_fresh_id(), + ir_context, SpvOpLabel, 0, message_.new_entry_fresh_id(), opt::Instruction::OperandList())); auto entry_block = ir_context->cfg()->block(message_.entry_block_id()); auto enclosing_function = entry_block->GetParent(); @@ -310,7 +310,7 @@ void TransformationDuplicateRegionWithSelection::Apply( // Construct the merge block. std::unique_ptr merge_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.merge_label_fresh_id(), + ir_context, SpvOpLabel, 0, message_.merge_label_fresh_id(), opt::Instruction::OperandList())); // Get the maps from the protobuf. @@ -361,7 +361,7 @@ void TransformationDuplicateRegionWithSelection::Apply( exit_block->ForEachSuccessorLabel([this, ir_context](uint32_t label_id) { auto block = ir_context->cfg()->block(label_id); for (auto& instr : *block) { - if (instr.opcode() == spv::Op::OpPhi) { + if (instr.opcode() == SpvOpPhi) { instr.ForEachId([this](uint32_t* id) { if (*id == message_.exit_block_id()) { *id = message_.merge_label_fresh_id(); @@ -390,7 +390,7 @@ void TransformationDuplicateRegionWithSelection::Apply( // occurrence of |entry_block_pred_id| to the id of |new_entry|, because we // will insert |new_entry| before |entry_block|. for (auto& instr : *entry_block) { - if (instr.opcode() == spv::Op::OpPhi) { + if (instr.opcode() == SpvOpPhi) { instr.ForEachId([this, entry_block_pred_id](uint32_t* id) { if (*id == entry_block_pred_id) { *id = message_.new_entry_fresh_id(); @@ -421,7 +421,7 @@ void TransformationDuplicateRegionWithSelection::Apply( std::unique_ptr duplicated_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, + ir_context, SpvOpLabel, 0, original_label_to_duplicate_label.at(block->id()), opt::Instruction::OperandList())); @@ -430,12 +430,12 @@ void TransformationDuplicateRegionWithSelection::Apply( // handled separately. if (block == exit_block && instr.IsBlockTerminator()) { switch (instr.opcode()) { - case spv::Op::OpBranch: - case spv::Op::OpBranchConditional: - case spv::Op::OpReturn: - case spv::Op::OpReturnValue: - case spv::Op::OpUnreachable: - case spv::Op::OpKill: + case SpvOpBranch: + case SpvOpBranchConditional: + case SpvOpReturn: + case SpvOpReturnValue: + case SpvOpUnreachable: + case SpvOpKill: continue; default: assert(false && @@ -497,7 +497,7 @@ void TransformationDuplicateRegionWithSelection::Apply( // the end of the region, as long as the result id is valid for use // with OpPhi. merge_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpPhi, instr.type_id(), + ir_context, SpvOpPhi, instr.type_id(), original_id_to_phi_id.at(instr.result_id()), opt::Instruction::OperandList({ {SPV_OPERAND_TYPE_ID, {instr.result_id()}}, @@ -537,14 +537,14 @@ void TransformationDuplicateRegionWithSelection::Apply( // false, the execution proceeds in the first block of the // duplicated region. new_entry_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpSelectionMerge, 0, 0, + ir_context, SpvOpSelectionMerge, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.merge_label_fresh_id()}}, {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}}))); + {SpvSelectionControlMaskNone}}}))); new_entry_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranchConditional, 0, 0, + ir_context, SpvOpBranchConditional, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.condition_id()}}, {SPV_OPERAND_TYPE_ID, {message_.entry_block_id()}}, @@ -563,7 +563,7 @@ void TransformationDuplicateRegionWithSelection::Apply( // |exit_block| and at the end of |duplicated_exit_block|, so that // the execution proceeds in the |merge_block|. opt::Instruction merge_branch_instr = opt::Instruction( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.merge_label_fresh_id()}}})); exit_block->AddInstruction(MakeUnique(merge_branch_instr)); @@ -584,14 +584,14 @@ void TransformationDuplicateRegionWithSelection::Apply( return; } switch (user->opcode()) { - case spv::Op::OpSwitch: - case spv::Op::OpBranch: - case spv::Op::OpBranchConditional: - case spv::Op::OpLoopMerge: - case spv::Op::OpSelectionMerge: { + case SpvOpSwitch: + case SpvOpBranch: + case SpvOpBranchConditional: + case SpvOpLoopMerge: + case SpvOpSelectionMerge: { user->SetOperand(operand_index, {message_.new_entry_fresh_id()}); } break; - case spv::Op::OpName: + case SpvOpName: break; default: assert(false && @@ -605,8 +605,8 @@ void TransformationDuplicateRegionWithSelection::Apply( opt::Instruction* merge_block_terminator = merge_block->terminator(); switch (merge_block_terminator->opcode()) { - case spv::Op::OpReturnValue: - case spv::Op::OpBranchConditional: { + case SpvOpReturnValue: + case SpvOpBranchConditional: { uint32_t operand = merge_block_terminator->GetSingleWordInOperand(0); if (original_id_to_phi_id.count(operand)) { merge_block_terminator->SetInOperand( @@ -699,19 +699,19 @@ bool TransformationDuplicateRegionWithSelection::ValidOpPhiArgument( ir_context->get_def_use_mgr()->GetDef(instr.type_id()); // It is invalid to apply OpPhi to void-typed values. - if (instr_type->opcode() == spv::Op::OpTypeVoid) { + if (instr_type->opcode() == SpvOpTypeVoid) { return false; } // Using pointers with OpPhi requires capability VariablePointers. - if (instr_type->opcode() == spv::Op::OpTypePointer && + if (instr_type->opcode() == SpvOpTypePointer && !ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointers)) { + SpvCapabilityVariablePointers)) { return false; } // OpTypeSampledImage cannot be the result type of an OpPhi instruction. - if (instr_type->opcode() == spv::Op::OpTypeSampledImage) { + if (instr_type->opcode() == SpvOpTypeSampledImage) { return false; } return true; diff --git a/source/fuzz/transformation_equation_instruction.cpp b/source/fuzz/transformation_equation_instruction.cpp index 72487a8e..1e5dae97 100644 --- a/source/fuzz/transformation_equation_instruction.cpp +++ b/source/fuzz/transformation_equation_instruction.cpp @@ -25,11 +25,10 @@ TransformationEquationInstruction::TransformationEquationInstruction( : message_(std::move(message)) {} TransformationEquationInstruction::TransformationEquationInstruction( - uint32_t fresh_id, spv::Op opcode, - const std::vector& in_operand_id, + uint32_t fresh_id, SpvOp opcode, const std::vector& in_operand_id, const protobufs::InstructionDescriptor& instruction_to_insert_before) { message_.set_fresh_id(fresh_id); - message_.set_opcode(uint32_t(opcode)); + message_.set_opcode(opcode); for (auto id : in_operand_id) { message_.add_in_operand_id(id); } @@ -58,7 +57,7 @@ bool TransformationEquationInstruction::IsApplicable( if (!inst) { return false; } - if (inst->opcode() == spv::Op::OpUndef) { + if (inst->opcode() == SpvOpUndef) { return false; } if (transformation_context.GetFactManager()->IdIsIrrelevant(id)) { @@ -89,7 +88,7 @@ void TransformationEquationInstruction::Apply( FindInstruction(message_.instruction_to_insert_before(), ir_context); opt::Instruction* new_instruction = insert_before->InsertBefore(MakeUnique( - ir_context, static_cast(message_.opcode()), + ir_context, static_cast(message_.opcode()), MaybeGetResultTypeId(ir_context), message_.fresh_id(), std::move(in_operands))); @@ -102,7 +101,7 @@ void TransformationEquationInstruction::Apply( if (!transformation_context->GetFactManager()->IdIsIrrelevant( message_.fresh_id())) { transformation_context->GetFactManager()->AddFactIdEquation( - message_.fresh_id(), static_cast(message_.opcode()), rhs_id); + message_.fresh_id(), static_cast(message_.opcode()), rhs_id); } } @@ -114,10 +113,10 @@ protobufs::Transformation TransformationEquationInstruction::ToMessage() const { uint32_t TransformationEquationInstruction::MaybeGetResultTypeId( opt::IRContext* ir_context) const { - auto opcode = static_cast(message_.opcode()); + auto opcode = static_cast(message_.opcode()); switch (opcode) { - case spv::Op::OpConvertUToF: - case spv::Op::OpConvertSToF: { + case SpvOpConvertUToF: + case SpvOpConvertSToF: { if (message_.in_operand_id_size() != 1) { return 0; } @@ -149,7 +148,7 @@ uint32_t TransformationEquationInstruction::MaybeGetResultTypeId( type->AsInteger()->width()); } } - case spv::Op::OpBitcast: { + case SpvOpBitcast: { if (message_.in_operand_id_size() != 1) { return 0; } @@ -211,8 +210,8 @@ uint32_t TransformationEquationInstruction::MaybeGetResultTypeId( return 0; } } - case spv::Op::OpIAdd: - case spv::Op::OpISub: { + case SpvOpIAdd: + case SpvOpISub: { if (message_.in_operand_id_size() != 2) { return 0; } @@ -250,7 +249,7 @@ uint32_t TransformationEquationInstruction::MaybeGetResultTypeId( "A type must have been found for the first operand."); return first_operand_type_id; } - case spv::Op::OpLogicalNot: { + case SpvOpLogicalNot: { if (message_.in_operand_id().size() != 1) { return 0; } @@ -268,7 +267,7 @@ uint32_t TransformationEquationInstruction::MaybeGetResultTypeId( } return operand_inst->type_id(); } - case spv::Op::OpSNegate: { + case SpvOpSNegate: { if (message_.in_operand_id().size() != 1) { return 0; } diff --git a/source/fuzz/transformation_equation_instruction.h b/source/fuzz/transformation_equation_instruction.h index 40118d91..ae32a1a2 100644 --- a/source/fuzz/transformation_equation_instruction.h +++ b/source/fuzz/transformation_equation_instruction.h @@ -31,7 +31,7 @@ class TransformationEquationInstruction : public Transformation { protobufs::TransformationEquationInstruction message); TransformationEquationInstruction( - uint32_t fresh_id, spv::Op opcode, + uint32_t fresh_id, SpvOp opcode, const std::vector& in_operand_id, const protobufs::InstructionDescriptor& instruction_to_insert_before); diff --git a/source/fuzz/transformation_expand_vector_reduction.cpp b/source/fuzz/transformation_expand_vector_reduction.cpp index 4c13ec1f..bafcf929 100644 --- a/source/fuzz/transformation_expand_vector_reduction.cpp +++ b/source/fuzz/transformation_expand_vector_reduction.cpp @@ -44,8 +44,7 @@ bool TransformationExpandVectorReduction::IsApplicable( } // |instruction| must be OpAny or OpAll. - if (instruction->opcode() != spv::Op::OpAny && - instruction->opcode() != spv::Op::OpAll) { + if (instruction->opcode() != SpvOpAny && instruction->opcode() != SpvOpAll) { return false; } @@ -93,11 +92,10 @@ void TransformationExpandVectorReduction::Apply( for (uint32_t i = 0; i < vector_component_count; i++) { // Extracts the i-th |vector| component. - auto vector_component = - opt::Instruction(ir_context, spv::Op::OpCompositeExtract, - instruction->type_id(), *fresh_id++, - {{SPV_OPERAND_TYPE_ID, {vector->result_id()}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}}); + auto vector_component = opt::Instruction( + ir_context, SpvOpCompositeExtract, instruction->type_id(), *fresh_id++, + {{SPV_OPERAND_TYPE_ID, {vector->result_id()}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}}); instruction->InsertBefore(MakeUnique(vector_component)); fuzzerutil::UpdateModuleIdBound(ir_context, vector_component.result_id()); vector_components.push_back(vector_component.result_id()); @@ -106,8 +104,7 @@ void TransformationExpandVectorReduction::Apply( // The first two |vector| components are used in the first logical operation. auto logical_instruction = opt::Instruction( ir_context, - instruction->opcode() == spv::Op::OpAny ? spv::Op::OpLogicalOr - : spv::Op::OpLogicalAnd, + instruction->opcode() == SpvOpAny ? SpvOpLogicalOr : SpvOpLogicalAnd, instruction->type_id(), *fresh_id++, {{SPV_OPERAND_TYPE_ID, {vector_components[0]}}, {SPV_OPERAND_TYPE_ID, {vector_components[1]}}}); diff --git a/source/fuzz/transformation_flatten_conditional_branch.cpp b/source/fuzz/transformation_flatten_conditional_branch.cpp index f8d1c338..127e7628 100644 --- a/source/fuzz/transformation_flatten_conditional_branch.cpp +++ b/source/fuzz/transformation_flatten_conditional_branch.cpp @@ -48,12 +48,12 @@ bool TransformationFlattenConditionalBranch::IsApplicable( // The block must have been found and it must be a selection header. if (!header_block || !header_block->GetMergeInst() || - header_block->GetMergeInst()->opcode() != spv::Op::OpSelectionMerge) { + header_block->GetMergeInst()->opcode() != SpvOpSelectionMerge) { return false; } // The header block must end with an OpBranchConditional instruction. - if (header_block->terminator()->opcode() != spv::Op::OpBranchConditional) { + if (header_block->terminator()->opcode() != SpvOpBranchConditional) { return false; } @@ -164,14 +164,14 @@ bool TransformationFlattenConditionalBranch::IsApplicable( opt::Instruction* phi_result_type = ir_context->get_def_use_mgr()->GetDef(inst->type_id()); switch (phi_result_type->opcode()) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypePointer: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypePointer: // Fine: OpSelect can work directly on scalar and pointer // types. return true; - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { // In its restricted form, OpSelect can only select between // vectors if the condition of the select is a boolean // boolean vector. We thus require the appropriate boolean @@ -288,8 +288,8 @@ void TransformationFlattenConditionalBranch::Apply( current_block->ForEachInst( [&problematic_instructions](opt::Instruction* instruction) { - if (instruction->opcode() != spv::Op::OpLabel && - instruction->opcode() != spv::Op::OpBranch && + if (instruction->opcode() != SpvOpLabel && + instruction->opcode() != SpvOpBranch && !fuzzerutil::InstructionHasNoSideEffects(*instruction)) { problematic_instructions.push_back(instruction); } @@ -381,7 +381,7 @@ void TransformationFlattenConditionalBranch::Apply( // Add a new, unconditional, branch instruction from the current header to // |after_header|. header_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {after_header}}})); // If the first branch to be laid out exists, change the branch instruction so @@ -437,8 +437,8 @@ bool TransformationFlattenConditionalBranch:: std::set* instructions_that_need_ids) { uint32_t merge_block_id = header->MergeBlockIdIfAny(); assert(merge_block_id && - header->GetMergeInst()->opcode() == spv::Op::OpSelectionMerge && - header->terminator()->opcode() == spv::Op::OpBranchConditional && + header->GetMergeInst()->opcode() == SpvOpSelectionMerge && + header->terminator()->opcode() == SpvOpBranchConditional && "|header| must be the header of a conditional."); // |header| must be reachable. @@ -508,7 +508,7 @@ bool TransformationFlattenConditionalBranch:: } // The terminator instruction for the block must be OpBranch. - if (block->terminator()->opcode() != spv::Op::OpBranch) { + if (block->terminator()->opcode() != SpvOpBranch) { return false; } @@ -524,7 +524,7 @@ bool TransformationFlattenConditionalBranch:: [ir_context, instructions_that_need_ids, &synonym_base_objects](opt::Instruction* instruction) { // We can ignore OpLabel instructions. - if (instruction->opcode() == spv::Op::OpLabel) { + if (instruction->opcode() == SpvOpLabel) { return true; } @@ -539,7 +539,7 @@ bool TransformationFlattenConditionalBranch:: // If the instruction is a branch, it must be an unconditional branch. if (instruction->IsBranch()) { - return instruction->opcode() == spv::Op::OpBranch; + return instruction->opcode() == SpvOpBranch; } // We cannot go ahead if we encounter an instruction that cannot be @@ -644,7 +644,7 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( // Add an unconditional branch from |execute_block| to |merge_block|. execute_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {merge_block->id()}}})); @@ -668,10 +668,10 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( } // Create a new block using |fresh_ids.alternative_block_id| for its label. - auto alternative_block_temp = MakeUnique( - MakeUnique(ir_context, spv::Op::OpLabel, 0, - wrapper_info.alternative_block_id(), - opt::Instruction::OperandList{})); + auto alternative_block_temp = + MakeUnique(MakeUnique( + ir_context, SpvOpLabel, 0, wrapper_info.alternative_block_id(), + opt::Instruction::OperandList{})); // Keep the original result id of the instruction in a variable. uint32_t original_result_id = instruction->result_id(); @@ -685,14 +685,14 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( // If there is an available id to copy from, the placeholder instruction // will be %placeholder_result_id = OpCopyObject %type %value_to_copy_id alternative_block_temp->AddInstruction(MakeUnique( - ir_context, spv::Op::OpCopyObject, instruction->type_id(), + ir_context, SpvOpCopyObject, instruction->type_id(), wrapper_info.placeholder_result_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {wrapper_info.value_to_copy_id()}}})); } else { // If there is no such id, use an OpUndef instruction. alternative_block_temp->AddInstruction(MakeUnique( - ir_context, spv::Op::OpUndef, instruction->type_id(), + ir_context, SpvOpUndef, instruction->type_id(), wrapper_info.placeholder_result_id(), opt::Instruction::OperandList{})); } @@ -702,7 +702,7 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( // Add an unconditional branch from the new block to the merge block. alternative_block_temp->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {merge_block->id()}}})); @@ -714,7 +714,7 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( // merge block, which will either take the value of the result of the // instruction or the placeholder value defined in the alternative block. merge_block->begin().InsertBefore(MakeUnique( - ir_context, spv::Op::OpPhi, instruction->type_id(), original_result_id, + ir_context, SpvOpPhi, instruction->type_id(), original_result_id, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {instruction->result_id()}}, {SPV_OPERAND_TYPE_ID, {execute_block->id()}}, @@ -738,17 +738,16 @@ TransformationFlattenConditionalBranch::EncloseInstructionInConditional( // Add an OpSelectionMerge instruction to the block. block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpSelectionMerge, 0, 0, - opt::Instruction::OperandList{ - {SPV_OPERAND_TYPE_ID, {merge_block->id()}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}})); + ir_context, SpvOpSelectionMerge, 0, 0, + opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {merge_block->id()}}, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, + {SpvSelectionControlMaskNone}}})); // Add an OpBranchConditional, to the block, using |condition_id| as the // condition and branching to |if_block_id| if the condition is true and to // |else_block_id| if the condition is false. block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranchConditional, 0, 0, + ir_context, SpvOpBranchConditional, 0, 0, opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {condition_id}}, {SPV_OPERAND_TYPE_ID, {if_block_id}}, {SPV_OPERAND_TYPE_ID, {else_block_id}}})); @@ -765,26 +764,26 @@ bool TransformationFlattenConditionalBranch::InstructionCanBeHandled( // We cannot handle barrier instructions, while we should be able to handle // all other instructions by enclosing them inside a conditional. - if (instruction.opcode() == spv::Op::OpControlBarrier || - instruction.opcode() == spv::Op::OpMemoryBarrier || - instruction.opcode() == spv::Op::OpNamedBarrierInitialize || - instruction.opcode() == spv::Op::OpMemoryNamedBarrier || - instruction.opcode() == spv::Op::OpTypeNamedBarrier) { + if (instruction.opcode() == SpvOpControlBarrier || + instruction.opcode() == SpvOpMemoryBarrier || + instruction.opcode() == SpvOpNamedBarrierInitialize || + instruction.opcode() == SpvOpMemoryNamedBarrier || + instruction.opcode() == SpvOpTypeNamedBarrier) { return false; } // We cannot handle OpSampledImage instructions, as they need to be in the // same block as their use. - if (instruction.opcode() == spv::Op::OpSampledImage) { + if (instruction.opcode() == SpvOpSampledImage) { return false; } // We cannot handle a sampled image load, because we re-work loads using // conditional branches and OpPhi instructions, and the result type of OpPhi // cannot be OpTypeSampledImage. - if (instruction.opcode() == spv::Op::OpLoad && + if (instruction.opcode() == SpvOpLoad && ir_context->get_def_use_mgr()->GetDef(instruction.type_id())->opcode() == - spv::Op::OpTypeSampledImage) { + SpvOpTypeSampledImage) { return false; } @@ -864,7 +863,7 @@ void TransformationFlattenConditionalBranch::AddBooleanVectorConstructorToBlock( in_operands.emplace_back(branch_condition_operand); } block->begin()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, fuzzerutil::MaybeGetVectorType( ir_context, fuzzerutil::MaybeGetBoolType(ir_context), dimension), fresh_id, in_operands)); @@ -907,7 +906,7 @@ void TransformationFlattenConditionalBranch:: opt::Operand selector_operand = branch_condition_operand; opt::Instruction* type_inst = ir_context->get_def_use_mgr()->GetDef(phi_inst->type_id()); - if (type_inst->opcode() == spv::Op::OpTypeVector) { + if (type_inst->opcode() == SpvOpTypeVector) { uint32_t dimension = type_inst->GetSingleWordInOperand(1); switch (dimension) { case 2: @@ -1013,7 +1012,7 @@ void TransformationFlattenConditionalBranch:: operands.emplace_back(phi_inst->GetInOperand(2)); operands.emplace_back(phi_inst->GetInOperand(0)); } - phi_inst->SetOpcode(spv::Op::OpSelect); + phi_inst->SetOpcode(SpvOpSelect); phi_inst->SetInOperands(std::move(operands)); }); diff --git a/source/fuzz/transformation_function_call.cpp b/source/fuzz/transformation_function_call.cpp index e96a230c..0f88ce51 100644 --- a/source/fuzz/transformation_function_call.cpp +++ b/source/fuzz/transformation_function_call.cpp @@ -49,7 +49,7 @@ bool TransformationFunctionCall::IsApplicable( // The function must exist auto callee_inst = ir_context->get_def_use_mgr()->GetDef(message_.callee_id()); - if (!callee_inst || callee_inst->opcode() != spv::Op::OpFunction) { + if (!callee_inst || callee_inst->opcode() != SpvOpFunction) { return false; } @@ -60,7 +60,7 @@ bool TransformationFunctionCall::IsApplicable( auto callee_type_inst = ir_context->get_def_use_mgr()->GetDef( callee_inst->GetSingleWordInOperand(1)); - assert(callee_type_inst->opcode() == spv::Op::OpTypeFunction && + assert(callee_type_inst->opcode() == SpvOpTypeFunction && "Bad function type."); // The number of expected function arguments must match the number of given @@ -78,7 +78,7 @@ bool TransformationFunctionCall::IsApplicable( if (!insert_before) { return false; } - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpFunctionCall, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpFunctionCall, insert_before)) { return false; } @@ -116,10 +116,10 @@ bool TransformationFunctionCall::IsApplicable( } opt::Instruction* arg_type_inst = ir_context->get_def_use_mgr()->GetDef(arg_inst->type_id()); - if (arg_type_inst->opcode() == spv::Op::OpTypePointer) { + if (arg_type_inst->opcode() == SpvOpTypePointer) { switch (arg_inst->opcode()) { - case spv::Op::OpFunctionParameter: - case spv::Op::OpVariable: + case SpvOpFunctionParameter: + case SpvOpVariable: // These are OK break; default: @@ -173,7 +173,7 @@ void TransformationFunctionCall::Apply( // Insert the function call before the instruction specified in the message. FindInstruction(message_.instruction_to_insert_before(), ir_context) ->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFunctionCall, return_type, message_.fresh_id(), + ir_context, SpvOpFunctionCall, return_type, message_.fresh_id(), operands)); // Invalidate all analyses since we have changed the module. ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); diff --git a/source/fuzz/transformation_inline_function.cpp b/source/fuzz/transformation_inline_function.cpp index 69e88fd5..a48b8179 100644 --- a/source/fuzz/transformation_inline_function.cpp +++ b/source/fuzz/transformation_inline_function.cpp @@ -62,8 +62,7 @@ bool TransformationInlineFunction::IsApplicable( ir_context->get_instr_block(function_call_instruction); if (function_call_instruction != &*--function_call_instruction_block->tail() || - function_call_instruction_block->terminator()->opcode() != - spv::Op::OpBranch) { + function_call_instruction_block->terminator()->opcode() != SpvOpBranch) { return false; } @@ -144,7 +143,7 @@ void TransformationInlineFunction::Apply( for (auto& entry_block_instruction : *called_function->entry()) { opt::Instruction* inlined_instruction; - if (entry_block_instruction.opcode() == spv::Op::OpVariable) { + if (entry_block_instruction.opcode() == SpvOpVariable) { // All OpVariable instructions in a function must be in the first block // in the function. inlined_instruction = caller_function->begin()->begin()->InsertBefore( @@ -207,7 +206,7 @@ void TransformationInlineFunction::Apply( block_containing_function_call->id(), [ir_context, new_return_block_id, successor_block]( opt::Instruction* use_instruction, uint32_t operand_index) { - if (use_instruction->opcode() == spv::Op::OpPhi && + if (use_instruction->opcode() == SpvOpPhi && ir_context->get_instr_block(use_instruction) == successor_block) { use_instruction->SetOperand(operand_index, {new_return_block_id}); } @@ -235,7 +234,7 @@ bool TransformationInlineFunction::IsSuitableForInlining( // |function_call_instruction| must be defined and must be an OpFunctionCall // instruction. if (!function_call_instruction || - function_call_instruction->opcode() != spv::Op::OpFunctionCall) { + function_call_instruction->opcode() != SpvOpFunctionCall) { return false; } @@ -332,14 +331,13 @@ void TransformationInlineFunction::AdaptInlinedInstruction( ->terminator() ->GetSingleWordInOperand(0); switch (instruction_to_be_inlined->opcode()) { - case spv::Op::OpReturn: + case SpvOpReturn: instruction_to_be_inlined->AddOperand( {SPV_OPERAND_TYPE_ID, {successor_block_id}}); break; - case spv::Op::OpReturnValue: { + case SpvOpReturnValue: { instruction_to_be_inlined->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCopyObject, - function_call_instruction->type_id(), + ir_context, SpvOpCopyObject, function_call_instruction->type_id(), function_call_instruction->result_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, @@ -350,7 +348,7 @@ void TransformationInlineFunction::AdaptInlinedInstruction( default: break; } - instruction_to_be_inlined->SetOpcode(spv::Op::OpBranch); + instruction_to_be_inlined->SetOpcode(SpvOpBranch); } } diff --git a/source/fuzz/transformation_invert_comparison_operator.cpp b/source/fuzz/transformation_invert_comparison_operator.cpp index 49801e39..ed7358fa 100644 --- a/source/fuzz/transformation_invert_comparison_operator.cpp +++ b/source/fuzz/transformation_invert_comparison_operator.cpp @@ -47,8 +47,7 @@ bool TransformationInvertComparisonOperator::IsApplicable( auto iter = fuzzerutil::GetIteratorForInstruction(block, inst); ++iter; assert(iter != block->end() && "Instruction can't be the last in the block"); - assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLogicalNot, - iter) && + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLogicalNot, iter) && "Can't insert negation after comparison operator"); // |message_.fresh_id| must be fresh. @@ -66,7 +65,7 @@ void TransformationInvertComparisonOperator::Apply( ++iter; iter.InsertBefore(MakeUnique( - ir_context, spv::Op::OpLogicalNot, inst->type_id(), inst->result_id(), + ir_context, SpvOpLogicalNot, inst->type_id(), inst->result_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.fresh_id()}}})); @@ -83,88 +82,88 @@ void TransformationInvertComparisonOperator::Apply( } bool TransformationInvertComparisonOperator::IsInversionSupported( - spv::Op opcode) { + SpvOp opcode) { switch (opcode) { - case spv::Op::OpSGreaterThan: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpSLessThan: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: + case SpvOpSGreaterThan: + case SpvOpSGreaterThanEqual: + case SpvOpSLessThan: + case SpvOpSLessThanEqual: + case SpvOpUGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpULessThan: + case SpvOpULessThanEqual: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: return true; default: return false; } } -spv::Op TransformationInvertComparisonOperator::InvertOpcode(spv::Op opcode) { +SpvOp TransformationInvertComparisonOperator::InvertOpcode(SpvOp opcode) { assert(IsInversionSupported(opcode) && "Inversion must be supported"); switch (opcode) { - case spv::Op::OpSGreaterThan: - return spv::Op::OpSLessThanEqual; - case spv::Op::OpSGreaterThanEqual: - return spv::Op::OpSLessThan; - case spv::Op::OpSLessThan: - return spv::Op::OpSGreaterThanEqual; - case spv::Op::OpSLessThanEqual: - return spv::Op::OpSGreaterThan; - case spv::Op::OpUGreaterThan: - return spv::Op::OpULessThanEqual; - case spv::Op::OpUGreaterThanEqual: - return spv::Op::OpULessThan; - case spv::Op::OpULessThan: - return spv::Op::OpUGreaterThanEqual; - case spv::Op::OpULessThanEqual: - return spv::Op::OpUGreaterThan; - case spv::Op::OpIEqual: - return spv::Op::OpINotEqual; - case spv::Op::OpINotEqual: - return spv::Op::OpIEqual; - case spv::Op::OpFOrdEqual: - return spv::Op::OpFUnordNotEqual; - case spv::Op::OpFUnordEqual: - return spv::Op::OpFOrdNotEqual; - case spv::Op::OpFOrdNotEqual: - return spv::Op::OpFUnordEqual; - case spv::Op::OpFUnordNotEqual: - return spv::Op::OpFOrdEqual; - case spv::Op::OpFOrdLessThan: - return spv::Op::OpFUnordGreaterThanEqual; - case spv::Op::OpFUnordLessThan: - return spv::Op::OpFOrdGreaterThanEqual; - case spv::Op::OpFOrdLessThanEqual: - return spv::Op::OpFUnordGreaterThan; - case spv::Op::OpFUnordLessThanEqual: - return spv::Op::OpFOrdGreaterThan; - case spv::Op::OpFOrdGreaterThan: - return spv::Op::OpFUnordLessThanEqual; - case spv::Op::OpFUnordGreaterThan: - return spv::Op::OpFOrdLessThanEqual; - case spv::Op::OpFOrdGreaterThanEqual: - return spv::Op::OpFUnordLessThan; - case spv::Op::OpFUnordGreaterThanEqual: - return spv::Op::OpFOrdLessThan; + case SpvOpSGreaterThan: + return SpvOpSLessThanEqual; + case SpvOpSGreaterThanEqual: + return SpvOpSLessThan; + case SpvOpSLessThan: + return SpvOpSGreaterThanEqual; + case SpvOpSLessThanEqual: + return SpvOpSGreaterThan; + case SpvOpUGreaterThan: + return SpvOpULessThanEqual; + case SpvOpUGreaterThanEqual: + return SpvOpULessThan; + case SpvOpULessThan: + return SpvOpUGreaterThanEqual; + case SpvOpULessThanEqual: + return SpvOpUGreaterThan; + case SpvOpIEqual: + return SpvOpINotEqual; + case SpvOpINotEqual: + return SpvOpIEqual; + case SpvOpFOrdEqual: + return SpvOpFUnordNotEqual; + case SpvOpFUnordEqual: + return SpvOpFOrdNotEqual; + case SpvOpFOrdNotEqual: + return SpvOpFUnordEqual; + case SpvOpFUnordNotEqual: + return SpvOpFOrdEqual; + case SpvOpFOrdLessThan: + return SpvOpFUnordGreaterThanEqual; + case SpvOpFUnordLessThan: + return SpvOpFOrdGreaterThanEqual; + case SpvOpFOrdLessThanEqual: + return SpvOpFUnordGreaterThan; + case SpvOpFUnordLessThanEqual: + return SpvOpFOrdGreaterThan; + case SpvOpFOrdGreaterThan: + return SpvOpFUnordLessThanEqual; + case SpvOpFUnordGreaterThan: + return SpvOpFOrdLessThanEqual; + case SpvOpFOrdGreaterThanEqual: + return SpvOpFUnordLessThan; + case SpvOpFUnordGreaterThanEqual: + return SpvOpFOrdLessThan; default: // The program will fail in the debug mode because of the assertion // at the beginning of the function. - return spv::Op::OpNop; + return SpvOpNop; } } diff --git a/source/fuzz/transformation_invert_comparison_operator.h b/source/fuzz/transformation_invert_comparison_operator.h index 39c2fe0f..f00f62b1 100644 --- a/source/fuzz/transformation_invert_comparison_operator.h +++ b/source/fuzz/transformation_invert_comparison_operator.h @@ -50,11 +50,11 @@ class TransformationInvertComparisonOperator : public Transformation { protobufs::Transformation ToMessage() const override; // Returns true if |opcode| is supported by this transformation. - static bool IsInversionSupported(spv::Op opcode); + static bool IsInversionSupported(SpvOp opcode); private: // Returns an inverted |opcode| (e.g. < becomes >=, == becomes != etc.) - static spv::Op InvertOpcode(spv::Op opcode); + static SpvOp InvertOpcode(SpvOp opcode); protobufs::TransformationInvertComparisonOperator message_; }; diff --git a/source/fuzz/transformation_load.cpp b/source/fuzz/transformation_load.cpp index 1cfde770..bf48d996 100644 --- a/source/fuzz/transformation_load.cpp +++ b/source/fuzz/transformation_load.cpp @@ -52,15 +52,15 @@ bool TransformationLoad::IsApplicable( // The type must indeed be a pointer type. auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); assert(pointer_type && "Type id must be defined."); - if (pointer_type->opcode() != spv::Op::OpTypePointer) { + if (pointer_type->opcode() != SpvOpTypePointer) { return false; } // We do not want to allow loading from null or undefined pointers, as it is // not clear how punishing the consequences of doing so are from a semantics // point of view. switch (pointer->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: return false; default: break; @@ -74,13 +74,13 @@ bool TransformationLoad::IsApplicable( return false; } // ... and it must be legitimate to insert a load before it. - if (!message_.is_atomic() && !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpLoad, insert_before)) { + if (!message_.is_atomic() && + !fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, insert_before)) { return false; } if (message_.is_atomic() && !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpAtomicLoad, insert_before)) { + SpvOpAtomicLoad, insert_before)) { return false; } @@ -99,10 +99,10 @@ bool TransformationLoad::IsApplicable( } // The memory scope and memory semantics instructions must have the // 'OpConstant' opcode. - if (memory_scope_instruction->opcode() != spv::Op::OpConstant) { + if (memory_scope_instruction->opcode() != SpvOpConstant) { return false; } - if (memory_semantics_instruction->opcode() != spv::Op::OpConstant) { + if (memory_semantics_instruction->opcode() != SpvOpConstant) { return false; } // The memory scope and memory semantics need to be available before @@ -119,12 +119,12 @@ bool TransformationLoad::IsApplicable( // operand type with signedness does not matters. if (ir_context->get_def_use_mgr() ->GetDef(memory_scope_instruction->type_id()) - ->opcode() != spv::Op::OpTypeInt) { + ->opcode() != SpvOpTypeInt) { return false; } if (ir_context->get_def_use_mgr() ->GetDef(memory_semantics_instruction->type_id()) - ->opcode() != spv::Op::OpTypeInt) { + ->opcode() != SpvOpTypeInt) { return false; } @@ -146,20 +146,20 @@ bool TransformationLoad::IsApplicable( return false; } - // The memory scope constant value must be that of spv::Scope::Invocation. + // The memory scope constant value must be that of SpvScopeInvocation. auto memory_scope_const_value = - spv::Scope(memory_scope_instruction->GetSingleWordInOperand(0)); - if (memory_scope_const_value != spv::Scope::Invocation) { + memory_scope_instruction->GetSingleWordInOperand(0); + if (memory_scope_const_value != SpvScopeInvocation) { return false; } // The memory semantics constant value must match the storage class of the // pointer being loaded from. - auto memory_semantics_const_value = static_cast( + auto memory_semantics_const_value = static_cast( memory_semantics_instruction->GetSingleWordInOperand(0)); if (memory_semantics_const_value != fuzzerutil::GetMemorySemanticsForStorageClass( - static_cast( + static_cast( pointer_type->GetSingleWordInOperand(0)))) { return false; } @@ -180,7 +180,7 @@ void TransformationLoad::Apply(opt::IRContext* ir_context, auto insert_before = FindInstruction(message_.instruction_to_insert_before(), ir_context); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpAtomicLoad, result_type, message_.fresh_id(), + ir_context, SpvOpAtomicLoad, result_type, message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_SCOPE_ID, {message_.memory_scope_id()}}, @@ -201,7 +201,7 @@ void TransformationLoad::Apply(opt::IRContext* ir_context, auto insert_before = FindInstruction(message_.instruction_to_insert_before(), ir_context); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpLoad, result_type, message_.fresh_id(), + ir_context, SpvOpLoad, result_type, message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}})); auto new_instruction_ptr = new_instruction.get(); diff --git a/source/fuzz/transformation_load.h b/source/fuzz/transformation_load.h index 66229185..57b4a535 100644 --- a/source/fuzz/transformation_load.h +++ b/source/fuzz/transformation_load.h @@ -37,7 +37,7 @@ class TransformationLoad : public Transformation { // - |message_.is_atomic| must be true if want to work with OpAtomicLoad // - If |is_atomic| is true then |message_memory_scope_id| must be the id of // an OpConstant 32 bit integer instruction with the value - // spv::Scope::Invocation. + // SpvScopeInvocation. // - If |is_atomic| is true then |message_.memory_semantics_id| must be the id // of an OpConstant 32 bit integer instruction with the values // SpvMemorySemanticsWorkgroupMemoryMask or diff --git a/source/fuzz/transformation_make_vector_operation_dynamic.cpp b/source/fuzz/transformation_make_vector_operation_dynamic.cpp index ecc8dcac..bd0664c0 100644 --- a/source/fuzz/transformation_make_vector_operation_dynamic.cpp +++ b/source/fuzz/transformation_make_vector_operation_dynamic.cpp @@ -62,19 +62,19 @@ void TransformationMakeVectorOperationDynamic::Apply( // The OpVectorInsertDynamic instruction has the vector and component operands // in reverse order in relation to the OpCompositeInsert corresponding // operands. - if (instruction->opcode() == spv::Op::OpCompositeInsert) { + if (instruction->opcode() == SpvOpCompositeInsert) { std::swap(instruction->GetInOperand(0), instruction->GetInOperand(1)); } // Sets the literal operand to the equivalent constant. instruction->SetInOperand( - instruction->opcode() == spv::Op::OpCompositeExtract ? 1 : 2, + instruction->opcode() == SpvOpCompositeExtract ? 1 : 2, {message_.constant_index_id()}); // Sets the |instruction| opcode to the corresponding vector dynamic opcode. - instruction->SetOpcode(instruction->opcode() == spv::Op::OpCompositeExtract - ? spv::Op::OpVectorExtractDynamic - : spv::Op::OpVectorInsertDynamic); + instruction->SetOpcode(instruction->opcode() == SpvOpCompositeExtract + ? SpvOpVectorExtractDynamic + : SpvOpVectorInsertDynamic); } protobufs::Transformation TransformationMakeVectorOperationDynamic::ToMessage() @@ -88,15 +88,15 @@ bool TransformationMakeVectorOperationDynamic::IsVectorOperation( opt::IRContext* ir_context, opt::Instruction* instruction) { // |instruction| must be defined and must be an OpCompositeExtract/Insert // instruction. - if (!instruction || (instruction->opcode() != spv::Op::OpCompositeExtract && - instruction->opcode() != spv::Op::OpCompositeInsert)) { + if (!instruction || (instruction->opcode() != SpvOpCompositeExtract && + instruction->opcode() != SpvOpCompositeInsert)) { return false; } // The composite must be a vector. auto composite_instruction = ir_context->get_def_use_mgr()->GetDef(instruction->GetSingleWordInOperand( - instruction->opcode() == spv::Op::OpCompositeExtract ? 0 : 1)); + instruction->opcode() == SpvOpCompositeExtract ? 0 : 1)); if (!ir_context->get_type_mgr() ->GetType(composite_instruction->type_id()) ->AsVector()) { diff --git a/source/fuzz/transformation_merge_function_returns.cpp b/source/fuzz/transformation_merge_function_returns.cpp index b35e358d..022e1b6d 100644 --- a/source/fuzz/transformation_merge_function_returns.cpp +++ b/source/fuzz/transformation_merge_function_returns.cpp @@ -50,7 +50,7 @@ bool TransformationMergeFunctionReturns::IsApplicable( } // The entry block must end in an unconditional branch. - if (function->entry()->terminator()->opcode() != spv::Op::OpBranch) { + if (function->entry()->terminator()->opcode() != SpvOpBranch) { return false; } @@ -134,9 +134,9 @@ bool TransformationMergeFunctionReturns::IsApplicable( bool all_instructions_allowed = ir_context->get_instr_block(merge_block) ->WhileEachInst([](opt::Instruction* inst) { - return inst->opcode() == spv::Op::OpLabel || - inst->opcode() == spv::Op::OpPhi || - inst->opcode() == spv::Op::OpBranch; + return inst->opcode() == SpvOpLabel || + inst->opcode() == SpvOpPhi || + inst->opcode() == SpvOpBranch; }); if (!all_instructions_allowed) { return false; @@ -286,7 +286,7 @@ void TransformationMergeFunctionReturns::Apply( } // Replace the return instruction with an unconditional branch. - ret_block->terminator()->SetOpcode(spv::Op::OpBranch); + ret_block->terminator()->SetOpcode(SpvOpBranch); ret_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {merge_block_id}}}); } @@ -410,7 +410,7 @@ void TransformationMergeFunctionReturns::Apply( // Insert the instruction. merge_block->begin()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpPhi, function->type_id(), maybe_return_val_id, + ir_context, SpvOpPhi, function->type_id(), maybe_return_val_id, std::move(operand_list))); fuzzerutil::UpdateModuleIdBound(ir_context, maybe_return_val_id); @@ -448,14 +448,14 @@ void TransformationMergeFunctionReturns::Apply( // Insert the instruction. merge_block->begin()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpPhi, bool_type, is_returning_id, + ir_context, SpvOpPhi, bool_type, is_returning_id, std::move(operand_list))); fuzzerutil::UpdateModuleIdBound(ir_context, is_returning_id); } // Change the branching instruction of the block. - assert(merge_block->terminator()->opcode() == spv::Op::OpBranch && + assert(merge_block->terminator()->opcode() == SpvOpBranch && "Each block should branch unconditionally to the next."); // Add a new entry to the map corresponding to the merge block of the @@ -483,14 +483,14 @@ void TransformationMergeFunctionReturns::Apply( // The block should branch to |enclosing_merge| if |is_returning_id| is // true, to |original_succ| otherwise. - merge_block->terminator()->SetOpcode(spv::Op::OpBranchConditional); + merge_block->terminator()->SetOpcode(SpvOpBranchConditional); merge_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {is_returning_id}}, {SPV_OPERAND_TYPE_ID, {enclosing_merge}}, {SPV_OPERAND_TYPE_ID, {original_succ}}}); } - assert(function->entry()->terminator()->opcode() == spv::Op::OpBranch && + assert(function->entry()->terminator()->opcode() == SpvOpBranch && "The entry block should branch unconditionally to another block."); uint32_t block_after_entry = function->entry()->terminator()->GetSingleWordInOperand(0); @@ -498,7 +498,7 @@ void TransformationMergeFunctionReturns::Apply( // Create the header for the new outer loop. auto outer_loop_header = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.outer_header_id(), + ir_context, SpvOpLabel, 0, message_.outer_header_id(), opt::Instruction::OperandList())); fuzzerutil::UpdateModuleIdBound(ir_context, message_.outer_header_id()); @@ -506,16 +506,15 @@ void TransformationMergeFunctionReturns::Apply( // Add the instruction: // OpLoopMerge %outer_return_id %unreachable_continue_id None outer_loop_header->AddInstruction(MakeUnique( - ir_context, spv::Op::OpLoopMerge, 0, 0, + ir_context, SpvOpLoopMerge, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.outer_return_id()}}, {SPV_OPERAND_TYPE_ID, {message_.unreachable_continue_id()}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}})); + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}})); // Add unconditional branch to %block_after_entry. outer_loop_header->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {block_after_entry}}})); @@ -532,7 +531,7 @@ void TransformationMergeFunctionReturns::Apply( ir_context->get_def_use_mgr()->ForEachUse( function->entry()->id(), [this](opt::Instruction* use_instruction, uint32_t use_operand_index) { - if (use_instruction->opcode() == spv::Op::OpPhi) { + if (use_instruction->opcode() == SpvOpPhi) { use_instruction->SetOperand(use_operand_index, {message_.outer_header_id()}); } @@ -541,7 +540,7 @@ void TransformationMergeFunctionReturns::Apply( // Create the merge block for the loop (and return block for the function). auto outer_return_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.outer_return_id(), + ir_context, SpvOpLabel, 0, message_.outer_return_id(), opt::Instruction::OperandList())); fuzzerutil::UpdateModuleIdBound(ir_context, message_.outer_return_id()); @@ -562,20 +561,20 @@ void TransformationMergeFunctionReturns::Apply( // Insert the OpPhi instruction. outer_return_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpPhi, function->type_id(), - message_.return_val_id(), std::move(operand_list))); + ir_context, SpvOpPhi, function->type_id(), message_.return_val_id(), + std::move(operand_list))); fuzzerutil::UpdateModuleIdBound(ir_context, message_.return_val_id()); // Insert the OpReturnValue instruction. outer_return_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpReturnValue, 0, 0, + ir_context, SpvOpReturnValue, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.return_val_id()}}})); } else { // Insert an OpReturn instruction (the function is void). outer_return_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpReturn, 0, 0, opt::Instruction::OperandList{})); + ir_context, SpvOpReturn, 0, 0, opt::Instruction::OperandList{})); } // Insert the new return block at the end of the function. @@ -584,7 +583,7 @@ void TransformationMergeFunctionReturns::Apply( // Create the unreachable continue block associated with the enclosing loop. auto unreachable_continue_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, message_.unreachable_continue_id(), + ir_context, SpvOpLabel, 0, message_.unreachable_continue_id(), opt::Instruction::OperandList())); fuzzerutil::UpdateModuleIdBound(ir_context, @@ -592,7 +591,7 @@ void TransformationMergeFunctionReturns::Apply( // Insert an branch back to the loop header, to create a back edge. unreachable_continue_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.outer_header_id()}}})); @@ -752,7 +751,7 @@ bool TransformationMergeFunctionReturns:: // The usage is OK if it is inside an OpPhi instruction in the // merge block. return block_use == merge_block && - inst_use->opcode() == spv::Op::OpPhi; + inst_use->opcode() == SpvOpPhi; }); }); diff --git a/source/fuzz/transformation_move_instruction_down.cpp b/source/fuzz/transformation_move_instruction_down.cpp index 4d5d9f0c..c8139e72 100644 --- a/source/fuzz/transformation_move_instruction_down.cpp +++ b/source/fuzz/transformation_move_instruction_down.cpp @@ -26,7 +26,7 @@ const char* const kExtensionSetName = "GLSL.std.450"; std::string GetExtensionSet(opt::IRContext* ir_context, const opt::Instruction& op_ext_inst) { - assert(op_ext_inst.opcode() == spv::Op::OpExtInst && "Wrong opcode"); + assert(op_ext_inst.opcode() == SpvOpExtInst && "Wrong opcode"); const auto* ext_inst_import = ir_context->get_def_use_mgr()->GetDef( op_ext_inst.GetSingleWordInOperand(0)); @@ -142,112 +142,112 @@ bool TransformationMoveInstructionDown::IsInstructionSupported( bool TransformationMoveInstructionDown::IsSimpleInstruction( opt::IRContext* ir_context, const opt::Instruction& inst) { switch (inst.opcode()) { - case spv::Op::OpNop: - case spv::Op::OpUndef: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpNop: + case SpvOpUndef: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: // OpAccessChain and OpInBoundsAccessChain are considered simple // instructions since they result in a pointer to the object in memory, // not the object itself. - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCopyObject: - case spv::Op::OpTranspose: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: - case spv::Op::OpBitcast: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpCopyLogical: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: + case SpvOpCopyObject: + case SpvOpTranspose: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: + case SpvOpBitcast: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpCopyLogical: return true; - case spv::Op::OpExtInst: { + case SpvOpExtInst: { const auto* ext_inst_import = ir_context->get_def_use_mgr()->GetDef(inst.GetSingleWordInOperand(0)); @@ -346,53 +346,53 @@ bool TransformationMoveInstructionDown::IsMemoryReadInstruction( opt::IRContext* ir_context, const opt::Instruction& inst) { switch (inst.opcode()) { // Some simple instructions. - case spv::Op::OpLoad: - case spv::Op::OpCopyMemory: + case SpvOpLoad: + case SpvOpCopyMemory: // Image instructions. - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageFetch: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageSparseRead: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageFetch: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageRead: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpImageSparseRead: // Atomic instructions. - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: + case SpvOpAtomicLoad: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: return true; // Extensions. - case spv::Op::OpExtInst: { + case SpvOpExtInst: { if (GetExtensionSet(ir_context, inst) != kExtensionSetName) { return false; } @@ -419,53 +419,53 @@ uint32_t TransformationMoveInstructionDown::GetMemoryReadTarget( switch (inst.opcode()) { // Simple instructions. - case spv::Op::OpLoad: + case SpvOpLoad: // Image instructions. - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageFetch: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageSparseRead: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageFetch: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageRead: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpImageSparseRead: // Atomic instructions. - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: + case SpvOpAtomicLoad: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: return inst.GetSingleWordInOperand(0); - case spv::Op::OpCopyMemory: + case SpvOpCopyMemory: return inst.GetSingleWordInOperand(1); - case spv::Op::OpExtInst: { + case SpvOpExtInst: { assert(GetExtensionSet(ir_context, inst) == kExtensionSetName && "Extension set is not supported"); @@ -493,31 +493,31 @@ bool TransformationMoveInstructionDown::IsMemoryWriteInstruction( opt::IRContext* ir_context, const opt::Instruction& inst) { switch (inst.opcode()) { // Simple Instructions. - case spv::Op::OpStore: - case spv::Op::OpCopyMemory: + case SpvOpStore: + case SpvOpCopyMemory: // Image instructions. - case spv::Op::OpImageWrite: + case SpvOpImageWrite: // Atomic instructions. - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: - case spv::Op::OpAtomicFlagClear: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: + case SpvOpAtomicFlagClear: return true; // Extensions. - case spv::Op::OpExtInst: { + case SpvOpExtInst: { if (GetExtensionSet(ir_context, inst) != kExtensionSetName) { return false; } @@ -537,28 +537,28 @@ uint32_t TransformationMoveInstructionDown::GetMemoryWriteTarget( "|inst| is not a memory write instruction"); switch (inst.opcode()) { - case spv::Op::OpStore: - case spv::Op::OpCopyMemory: - case spv::Op::OpImageWrite: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: - case spv::Op::OpAtomicFlagClear: + case SpvOpStore: + case SpvOpCopyMemory: + case SpvOpImageWrite: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: + case SpvOpAtomicFlagClear: return inst.GetSingleWordInOperand(0); - case spv::Op::OpExtInst: { + case SpvOpExtInst: { assert(GetExtensionSet(ir_context, inst) == kExtensionSetName && "Extension set is not supported"); @@ -590,9 +590,9 @@ bool TransformationMoveInstructionDown::IsMemoryInstruction( bool TransformationMoveInstructionDown::IsBarrierInstruction( const opt::Instruction& inst) { switch (inst.opcode()) { - case spv::Op::OpMemoryBarrier: - case spv::Op::OpControlBarrier: - case spv::Op::OpMemoryNamedBarrier: + case SpvOpMemoryBarrier: + case SpvOpControlBarrier: + case SpvOpMemoryNamedBarrier: return true; default: return false; diff --git a/source/fuzz/transformation_mutate_pointer.cpp b/source/fuzz/transformation_mutate_pointer.cpp index a1620cca..516a0d61 100644 --- a/source/fuzz/transformation_mutate_pointer.cpp +++ b/source/fuzz/transformation_mutate_pointer.cpp @@ -51,7 +51,7 @@ bool TransformationMutatePointer::IsApplicable( // Check that it is possible to insert OpLoad and OpStore before // |insert_before_inst|. We are only using OpLoad here since the result does // not depend on the opcode. - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, insert_before_inst)) { return false; } @@ -100,7 +100,7 @@ void TransformationMutatePointer::Apply( // Back up the original value. auto backup_instruction = MakeUnique( - ir_context, spv::Op::OpLoad, pointee_type_id, message_.fresh_id(), + ir_context, SpvOpLoad, pointee_type_id, message_.fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}}); auto backup_instruction_ptr = backup_instruction.get(); @@ -110,7 +110,7 @@ void TransformationMutatePointer::Apply( // Insert a new value. auto new_value_instruction = MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_ID, @@ -123,7 +123,7 @@ void TransformationMutatePointer::Apply( // Restore the original value. auto restore_instruction = MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_ID, {message_.fresh_id()}}}); @@ -145,9 +145,8 @@ bool TransformationMutatePointer::IsValidPointerInstruction( opt::IRContext* ir_context, const opt::Instruction& inst) { // |inst| must have both result id and type id and it may not cause undefined // behaviour. - if (!inst.result_id() || !inst.type_id() || - inst.opcode() == spv::Op::OpUndef || - inst.opcode() == spv::Op::OpConstantNull) { + if (!inst.result_id() || !inst.type_id() || inst.opcode() == SpvOpUndef || + inst.opcode() == SpvOpConstantNull) { return false; } @@ -156,16 +155,15 @@ bool TransformationMutatePointer::IsValidPointerInstruction( assert(type_inst != nullptr && "|inst| has invalid type id"); // |inst| must be a pointer. - if (type_inst->opcode() != spv::Op::OpTypePointer) { + if (type_inst->opcode() != SpvOpTypePointer) { return false; } // |inst| must have a supported storage class. - switch ( - static_cast(type_inst->GetSingleWordInOperand(0))) { - case spv::StorageClass::Function: - case spv::StorageClass::Private: - case spv::StorageClass::Workgroup: + switch (static_cast(type_inst->GetSingleWordInOperand(0))) { + case SpvStorageClassFunction: + case SpvStorageClassPrivate: + case SpvStorageClassWorkgroup: break; default: return false; diff --git a/source/fuzz/transformation_outline_function.cpp b/source/fuzz/transformation_outline_function.cpp index 4ab68d07..3140fa6b 100644 --- a/source/fuzz/transformation_outline_function.cpp +++ b/source/fuzz/transformation_outline_function.cpp @@ -107,7 +107,7 @@ bool TransformationOutlineFunction::IsApplicable( // The entry and exit block ids must indeed refer to blocks. for (auto block_id : {message_.entry_block(), message_.exit_block()}) { auto block_label = ir_context->get_def_use_mgr()->GetDef(block_id); - if (!block_label || block_label->opcode() != spv::Op::OpLabel) { + if (!block_label || block_label->opcode() != SpvOpLabel) { return false; } } @@ -118,7 +118,7 @@ bool TransformationOutlineFunction::IsApplicable( // The entry block cannot start with OpVariable - this would mean that // outlining would remove a variable from the function containing the region // being outlined. - if (entry_block->begin()->opcode() == spv::Op::OpVariable) { + if (entry_block->begin()->opcode() == SpvOpVariable) { return false; } @@ -136,7 +136,7 @@ bool TransformationOutlineFunction::IsApplicable( // The entry block cannot start with OpPhi. This is to keep the // transformation logic simple. (Another transformation to split the OpPhis // from a block could be applied to avoid this scenario.) - if (entry_block->begin()->opcode() == spv::Op::OpPhi) { + if (entry_block->begin()->opcode() == SpvOpPhi) { return false; } @@ -257,10 +257,10 @@ bool TransformationOutlineFunction::IsApplicable( auto input_id_inst = ir_context->get_def_use_mgr()->GetDef(id); if (ir_context->get_def_use_mgr() ->GetDef(input_id_inst->type_id()) - ->opcode() == spv::Op::OpTypePointer) { + ->opcode() == SpvOpTypePointer) { switch (input_id_inst->opcode()) { - case spv::Op::OpFunctionParameter: - case spv::Op::OpVariable: + case SpvOpFunctionParameter: + case SpvOpVariable: // These are OK. break; default: @@ -286,7 +286,7 @@ bool TransformationOutlineFunction::IsApplicable( // function) || ir_context->get_def_use_mgr() ->GetDef(fuzzerutil::GetTypeId(ir_context, id)) - ->opcode() == spv::Op::OpTypePointer) { + ->opcode() == SpvOpTypePointer) { return false; } } @@ -608,7 +608,7 @@ TransformationOutlineFunction::PrepareFunctionPrototype( auto output_id_type = ir_context->get_def_use_mgr()->GetDef(output_id)->type_id(); if (ir_context->get_def_use_mgr()->GetDef(output_id_type)->opcode() == - spv::Op::OpTypeVoid) { + SpvOpTypeVoid) { // We cannot add a void field to a struct. We instead use OpUndef to // handle void output ids. continue; @@ -617,7 +617,7 @@ TransformationOutlineFunction::PrepareFunctionPrototype( } // Add a new struct type to the module. ir_context->module()->AddType(MakeUnique( - ir_context, spv::Op::OpTypeStruct, 0, + ir_context, SpvOpTypeStruct, 0, message_.new_function_struct_return_type_id(), std::move(struct_member_types))); // The return type for the function is the newly-created struct. @@ -638,7 +638,7 @@ TransformationOutlineFunction::PrepareFunctionPrototype( // Add a new function type to the module, and record that this is the type // id for the new function. ir_context->module()->AddType(MakeUnique( - ir_context, spv::Op::OpTypeFunction, 0, message_.new_function_type_id(), + ir_context, SpvOpTypeFunction, 0, message_.new_function_type_id(), function_type_operands)); function_type_id = message_.new_function_type_id(); } @@ -647,11 +647,10 @@ TransformationOutlineFunction::PrepareFunctionPrototype( // and the return type and function type prepared above. std::unique_ptr outlined_function = MakeUnique(MakeUnique( - ir_context, spv::Op::OpFunction, return_type_id, - message_.new_function_id(), + ir_context, SpvOpFunction, return_type_id, message_.new_function_id(), opt::Instruction::OperandList( {{spv_operand_type_t ::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, + {SpvFunctionControlMaskNone}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {function_type_id}}}))); @@ -660,7 +659,7 @@ TransformationOutlineFunction::PrepareFunctionPrototype( for (auto id : region_input_ids) { uint32_t fresh_id = input_id_to_fresh_id_map.at(id); outlined_function->AddParameter(MakeUnique( - ir_context, spv::Op::OpFunctionParameter, + ir_context, SpvOpFunctionParameter, ir_context->get_def_use_mgr()->GetDef(id)->type_id(), fresh_id, opt::Instruction::OperandList())); @@ -789,8 +788,7 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( // |message_.new_function_region_entry_block| as its id. std::unique_ptr outlined_region_entry_block = MakeUnique(MakeUnique( - ir_context, spv::Op::OpLabel, 0, - message_.new_function_region_entry_block(), + ir_context, SpvOpLabel, 0, message_.new_function_region_entry_block(), opt::Instruction::OperandList())); if (&original_region_entry_block == &original_region_exit_block) { @@ -856,8 +854,8 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( // the cloned exit block. for (auto inst_it = outlined_region_exit_block->begin(); inst_it != outlined_region_exit_block->end();) { - if (inst_it->opcode() == spv::Op::OpLoopMerge || - inst_it->opcode() == spv::Op::OpSelectionMerge) { + if (inst_it->opcode() == SpvOpLoopMerge || + inst_it->opcode() == SpvOpSelectionMerge) { inst_it = inst_it.Erase(); } else if (inst_it->IsBlockTerminator()) { inst_it = inst_it.Erase(); @@ -872,7 +870,7 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( // The case where there are no region output ids is simple: we just add // OpReturn. outlined_region_exit_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpReturn, 0, 0, opt::Instruction::OperandList())); + ir_context, SpvOpReturn, 0, 0, opt::Instruction::OperandList())); } else { // In the case where there are output ids, we add an OpCompositeConstruct // instruction to pack all the non-void output values into a struct, and @@ -881,24 +879,23 @@ void TransformationOutlineFunction::PopulateOutlinedFunction( for (uint32_t id : region_output_ids) { if (ir_context->get_def_use_mgr() ->GetDef(output_id_to_type_id.at(id)) - ->opcode() != spv::Op::OpTypeVoid) { + ->opcode() != SpvOpTypeVoid) { struct_member_operands.push_back( {SPV_OPERAND_TYPE_ID, {output_id_to_fresh_id_map.at(id)}}); } } outlined_region_exit_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, message_.new_function_struct_return_type_id(), message_.new_callee_result_id(), struct_member_operands)); outlined_region_exit_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpReturnValue, 0, 0, + ir_context, SpvOpReturnValue, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.new_callee_result_id()}}}))); } - outlined_function->SetFunctionEnd( - MakeUnique(ir_context, spv::Op::OpFunctionEnd, 0, 0, - opt::Instruction::OperandList())); + outlined_function->SetFunctionEnd(MakeUnique( + ir_context, SpvOpFunctionEnd, 0, 0, opt::Instruction::OperandList())); } void TransformationOutlineFunction::ShrinkOriginalRegion( @@ -966,7 +963,7 @@ void TransformationOutlineFunction::ShrinkOriginalRegion( } original_region_entry_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpFunctionCall, return_type_id, + ir_context, SpvOpFunctionCall, return_type_id, message_.new_caller_result_id(), function_call_operands)); // If there are output ids, the function call will return a struct. For each @@ -978,15 +975,15 @@ void TransformationOutlineFunction::ShrinkOriginalRegion( for (uint32_t output_id : region_output_ids) { uint32_t output_type_id = output_id_to_type_id.at(output_id); if (ir_context->get_def_use_mgr()->GetDef(output_type_id)->opcode() == - spv::Op::OpTypeVoid) { + SpvOpTypeVoid) { original_region_entry_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpUndef, output_type_id, output_id, + ir_context, SpvOpUndef, output_type_id, output_id, opt::Instruction::OperandList())); // struct_member_index is not incremented since there was no struct member // associated with this void-typed output id. } else { original_region_entry_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, output_type_id, output_id, + ir_context, SpvOpCompositeExtract, output_type_id, output_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.new_caller_result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {struct_member_index}}}))); diff --git a/source/fuzz/transformation_permute_function_parameters.cpp b/source/fuzz/transformation_permute_function_parameters.cpp index b666cdfe..5663d72f 100644 --- a/source/fuzz/transformation_permute_function_parameters.cpp +++ b/source/fuzz/transformation_permute_function_parameters.cpp @@ -43,7 +43,7 @@ bool TransformationPermuteFunctionParameters::IsApplicable( // Check that function exists const auto* function = fuzzerutil::FindFunction(ir_context, message_.function_id()); - if (!function || function->DefInst().opcode() != spv::Op::OpFunction || + if (!function || function->DefInst().opcode() != SpvOpFunction || fuzzerutil::FunctionIsEntryPoint(ir_context, function->result_id())) { return false; } diff --git a/source/fuzz/transformation_permute_phi_operands.cpp b/source/fuzz/transformation_permute_phi_operands.cpp index f2f40570..7ee7a82f 100644 --- a/source/fuzz/transformation_permute_phi_operands.cpp +++ b/source/fuzz/transformation_permute_phi_operands.cpp @@ -39,7 +39,7 @@ bool TransformationPermutePhiOperands::IsApplicable( // Check that |message_.result_id| is valid. const auto* inst = ir_context->get_def_use_mgr()->GetDef(message_.result_id()); - if (!inst || inst->opcode() != spv::Op::OpPhi) { + if (!inst || inst->opcode() != SpvOpPhi) { return false; } diff --git a/source/fuzz/transformation_propagate_instruction_down.cpp b/source/fuzz/transformation_propagate_instruction_down.cpp index 4b987842..c3b7c4d9 100644 --- a/source/fuzz/transformation_propagate_instruction_down.cpp +++ b/source/fuzz/transformation_propagate_instruction_down.cpp @@ -144,7 +144,7 @@ void TransformationPropagateInstructionDown::Apply( ->block(merge_block_id) ->begin() ->InsertBefore(MakeUnique( - ir_context, spv::Op::OpPhi, inst_to_propagate->type_id(), + ir_context, SpvOpPhi, inst_to_propagate->type_id(), message_.phi_fresh_id(), std::move(in_operands))); fuzzerutil::UpdateModuleIdBound(ir_context, message_.phi_fresh_id()); @@ -234,115 +234,115 @@ protobufs::Transformation TransformationPropagateInstructionDown::ToMessage() return result; } -bool TransformationPropagateInstructionDown::IsOpcodeSupported(spv::Op opcode) { +bool TransformationPropagateInstructionDown::IsOpcodeSupported(SpvOp opcode) { // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3605): // We only support "simple" instructions that don't work with memory. // We should extend this so that we support the ones that modify the memory // too. switch (opcode) { - case spv::Op::OpUndef: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpArrayLength: - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCopyObject: - case spv::Op::OpTranspose: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: - case spv::Op::OpBitcast: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpCopyLogical: - case spv::Op::OpPtrEqual: - case spv::Op::OpPtrNotEqual: + case SpvOpUndef: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpArrayLength: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: + case SpvOpCopyObject: + case SpvOpTranspose: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: + case SpvOpBitcast: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpCopyLogical: + case SpvOpPtrEqual: + case SpvOpPtrNotEqual: return true; default: return false; @@ -408,7 +408,7 @@ bool TransformationPropagateInstructionDown::IsApplicableToBlock( // use |inst|. for (auto successor_id : successor_ids) { for (const auto& maybe_phi_inst : *ir_context->cfg()->block(successor_id)) { - if (maybe_phi_inst.opcode() != spv::Op::OpPhi) { + if (maybe_phi_inst.opcode() != SpvOpPhi) { // OpPhis can be intermixed with OpLine and OpNoLine. continue; } @@ -446,7 +446,7 @@ bool TransformationPropagateInstructionDown::IsApplicableToBlock( // |phi_block_id| dominates |user|'s block (or its predecessor if the // user is an OpPhi). We can't use fuzzerutil::IdIsAvailableAtUse since // the id in question hasn't yet been created in the module. - auto block_id_to_dominate = user->opcode() == spv::Op::OpPhi + auto block_id_to_dominate = user->opcode() == SpvOpPhi ? user->GetSingleWordOperand(index + 1) : user_block->id(); @@ -465,7 +465,7 @@ bool TransformationPropagateInstructionDown::IsApplicableToBlock( opt::Instruction* TransformationPropagateInstructionDown::GetFirstInsertBeforeInstruction( - opt::IRContext* ir_context, uint32_t block_id, spv::Op opcode) { + opt::IRContext* ir_context, uint32_t block_id, SpvOp opcode) { auto* block = ir_context->cfg()->block(block_id); auto it = block->begin(); @@ -572,7 +572,7 @@ uint32_t TransformationPropagateInstructionDown::GetOpPhiBlockId( // OpPhi instructions cannot have operands of pointer types. if (propagate_type->AsPointer() && !ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)) { + SpvCapabilityVariablePointersStorageBuffer)) { return 0; } diff --git a/source/fuzz/transformation_propagate_instruction_down.h b/source/fuzz/transformation_propagate_instruction_down.h index 91339285..560d7dc5 100644 --- a/source/fuzz/transformation_propagate_instruction_down.h +++ b/source/fuzz/transformation_propagate_instruction_down.h @@ -120,12 +120,12 @@ class TransformationPropagateInstructionDown : public Transformation { uint32_t block_id); // Returns true if |opcode| is supported by this transformation. - static bool IsOpcodeSupported(spv::Op opcode); + static bool IsOpcodeSupported(SpvOp opcode); // Returns the first instruction in the |block| that allows us to insert // |opcode| above itself. Returns nullptr is no such instruction exists. static opt::Instruction* GetFirstInsertBeforeInstruction( - opt::IRContext* ir_context, uint32_t block_id, spv::Op opcode); + opt::IRContext* ir_context, uint32_t block_id, SpvOp opcode); // Returns a result id of a basic block, where an OpPhi instruction can be // inserted. Returns nullptr if it's not possible to create an OpPhi. The diff --git a/source/fuzz/transformation_propagate_instruction_up.cpp b/source/fuzz/transformation_propagate_instruction_up.cpp index f9674fa9..bf0e6630 100644 --- a/source/fuzz/transformation_propagate_instruction_up.cpp +++ b/source/fuzz/transformation_propagate_instruction_up.cpp @@ -23,7 +23,7 @@ namespace { uint32_t GetResultIdFromLabelId(const opt::Instruction& phi_inst, uint32_t label_id) { - assert(phi_inst.opcode() == spv::Op::OpPhi && "|phi_inst| is not an OpPhi"); + assert(phi_inst.opcode() == SpvOpPhi && "|phi_inst| is not an OpPhi"); for (uint32_t i = 1; i < phi_inst.NumInOperands(); i += 2) { if (phi_inst.GetSingleWordInOperand(i) == label_id) { @@ -66,7 +66,7 @@ bool HasValidDependencies(opt::IRContext* ir_context, opt::Instruction* inst) { assert(dependency && "Operand has invalid id"); if (ir_context->get_instr_block(dependency) == inst_block && - dependency->opcode() != spv::Op::OpPhi) { + dependency->opcode() != SpvOpPhi) { // |dependency| is "valid" if it's an OpPhi from the same basic block or // an instruction from a different basic block. return false; @@ -173,7 +173,7 @@ void TransformationPropagateInstructionUp::Apply( continue; } - assert(dependency_inst->opcode() == spv::Op::OpPhi && + assert(dependency_inst->opcode() == SpvOpPhi && "Propagated instruction can depend only on OpPhis from the same " "basic block or instructions from different basic blocks"); @@ -191,7 +191,7 @@ void TransformationPropagateInstructionUp::Apply( // Insert an OpPhi instruction into the basic block of |inst|. ir_context->get_instr_block(inst)->begin()->InsertBefore( - MakeUnique(ir_context, spv::Op::OpPhi, inst->type_id(), + MakeUnique(ir_context, SpvOpPhi, inst->type_id(), inst->result_id(), std::move(op_phi_operands))); @@ -210,115 +210,115 @@ protobufs::Transformation TransformationPropagateInstructionUp::ToMessage() return result; } -bool TransformationPropagateInstructionUp::IsOpcodeSupported(spv::Op opcode) { +bool TransformationPropagateInstructionUp::IsOpcodeSupported(SpvOp opcode) { // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3605): // We only support "simple" instructions that don't work with memory. // We should extend this so that we support the ones that modify the memory // too. switch (opcode) { - case spv::Op::OpUndef: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpArrayLength: - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCopyObject: - case spv::Op::OpTranspose: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: - case spv::Op::OpBitcast: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpCopyLogical: - case spv::Op::OpPtrEqual: - case spv::Op::OpPtrNotEqual: + case SpvOpUndef: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpArrayLength: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: + case SpvOpCopyObject: + case SpvOpTranspose: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: + case SpvOpBitcast: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpCopyLogical: + case SpvOpPtrEqual: + case SpvOpPtrNotEqual: return true; default: return false; @@ -338,7 +338,7 @@ TransformationPropagateInstructionUp::GetInstructionToPropagate( // - it must be supported by this transformation // - it may depend only on instructions from different basic blocks or on // OpPhi instructions from the same basic block. - if (inst.opcode() == spv::Op::OpPhi || !IsOpcodeSupported(inst.opcode()) || + if (inst.opcode() == SpvOpPhi || !IsOpcodeSupported(inst.opcode()) || !inst.type_id() || !inst.result_id()) { continue; } @@ -353,7 +353,7 @@ TransformationPropagateInstructionUp::GetInstructionToPropagate( } if (!ir_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer) && + SpvCapabilityVariablePointersStorageBuffer) && ContainsPointers(*inst_type)) { // OpPhi supports pointer operands only with VariablePointers or // VariablePointersStorageBuffer capabilities. @@ -377,7 +377,7 @@ bool TransformationPropagateInstructionUp::IsApplicableToBlock( opt::IRContext* ir_context, uint32_t block_id) { // Check that |block_id| is valid. const auto* label_inst = ir_context->get_def_use_mgr()->GetDef(block_id); - if (!label_inst || label_inst->opcode() != spv::Op::OpLabel) { + if (!label_inst || label_inst->opcode() != SpvOpLabel) { return false; } diff --git a/source/fuzz/transformation_propagate_instruction_up.h b/source/fuzz/transformation_propagate_instruction_up.h index 93aa365a..0ca051bf 100644 --- a/source/fuzz/transformation_propagate_instruction_up.h +++ b/source/fuzz/transformation_propagate_instruction_up.h @@ -80,7 +80,7 @@ class TransformationPropagateInstructionUp : public Transformation { uint32_t block_id); // Returns true if |opcode| is supported by this transformation. - static bool IsOpcodeSupported(spv::Op opcode); + static bool IsOpcodeSupported(SpvOp opcode); protobufs::TransformationPropagateInstructionUp message_; }; diff --git a/source/fuzz/transformation_push_id_through_variable.cpp b/source/fuzz/transformation_push_id_through_variable.cpp index 2372d70c..55a57a15 100644 --- a/source/fuzz/transformation_push_id_through_variable.cpp +++ b/source/fuzz/transformation_push_id_through_variable.cpp @@ -53,9 +53,9 @@ bool TransformationPushIdThroughVariable::IsApplicable( // It must be valid to insert the OpStore and OpLoad instruction before it. if (!fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpStore, instruction_to_insert_before) || + SpvOpStore, instruction_to_insert_before) || !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpLoad, instruction_to_insert_before)) { + SpvOpLoad, instruction_to_insert_before)) { return false; } @@ -75,16 +75,14 @@ bool TransformationPushIdThroughVariable::IsApplicable( // A pointer type instruction pointing to the value type must be defined. auto pointer_type_id = fuzzerutil::MaybeGetPointerType( ir_context, value_instruction->type_id(), - static_cast(message_.variable_storage_class())); + static_cast(message_.variable_storage_class())); if (!pointer_type_id) { return false; } // |message_.variable_storage_class| must be private or function. - assert((message_.variable_storage_class() == - (uint32_t)spv::StorageClass::Private || - message_.variable_storage_class() == - (uint32_t)spv::StorageClass::Function) && + assert((message_.variable_storage_class() == SpvStorageClassPrivate || + message_.variable_storage_class() == SpvStorageClassFunction) && "The variable storage class must be private or function."); // Check that initializer is valid. @@ -113,15 +111,14 @@ void TransformationPushIdThroughVariable::Apply( // A pointer type instruction pointing to the value type must be defined. auto pointer_type_id = fuzzerutil::MaybeGetPointerType( ir_context, value_instruction->type_id(), - static_cast(message_.variable_storage_class())); + static_cast(message_.variable_storage_class())); assert(pointer_type_id && "The required pointer type must be available."); // Adds whether a global or local variable. - if (spv::StorageClass(message_.variable_storage_class()) == - spv::StorageClass::Private) { + if (message_.variable_storage_class() == SpvStorageClassPrivate) { opt::Instruction* global_variable = fuzzerutil::AddGlobalVariable( ir_context, message_.variable_id(), pointer_type_id, - spv::StorageClass::Private, message_.initializer_id()); + SpvStorageClassPrivate, message_.initializer_id()); ir_context->get_def_use_mgr()->AnalyzeInstDefUse(global_variable); } else { opt::Function* function = @@ -141,13 +138,13 @@ void TransformationPushIdThroughVariable::Apply( fuzzerutil::UpdateModuleIdBound(ir_context, message_.value_synonym_id()); opt::Instruction* load_instruction = insert_before->InsertBefore(MakeUnique( - ir_context, spv::Op::OpLoad, value_instruction->type_id(), + ir_context, SpvOpLoad, value_instruction->type_id(), message_.value_synonym_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.variable_id()}}}))); opt::Instruction* store_instruction = load_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.variable_id()}}, {SPV_OPERAND_TYPE_ID, {message_.value_id()}}}))); diff --git a/source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.cpp b/source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.cpp index 03e97375..e1977a64 100644 --- a/source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.cpp +++ b/source/fuzz/transformation_replace_add_sub_mul_with_carrying_extended.cpp @@ -97,20 +97,20 @@ void TransformationReplaceAddSubMulWithCarryingExtended::Apply( // Determine the opcode of the new instruction that computes the result into a // struct. - spv::Op new_instruction_opcode; + SpvOp new_instruction_opcode; switch (original_instruction->opcode()) { - case spv::Op::OpIAdd: - new_instruction_opcode = spv::Op::OpIAddCarry; + case SpvOpIAdd: + new_instruction_opcode = SpvOpIAddCarry; break; - case spv::Op::OpISub: - new_instruction_opcode = spv::Op::OpISubBorrow; + case SpvOpISub: + new_instruction_opcode = SpvOpISubBorrow; break; - case spv::Op::OpIMul: + case SpvOpIMul: if (!operand_is_signed) { - new_instruction_opcode = spv::Op::OpUMulExtended; + new_instruction_opcode = SpvOpUMulExtended; } else { - new_instruction_opcode = spv::Op::OpSMulExtended; + new_instruction_opcode = SpvOpSMulExtended; } break; default: @@ -148,7 +148,7 @@ void TransformationReplaceAddSubMulWithCarryingExtended::Apply( // takes the first component of the struct which represents low-order bits of // the operation. This is the original result. original_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, original_instruction->type_id(), + ir_context, SpvOpCompositeExtract, original_instruction->type_id(), message_.result_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.struct_fresh_id()}}, @@ -168,9 +168,9 @@ bool TransformationReplaceAddSubMulWithCarryingExtended::IsInstructionSuitable( // Only instructions OpIAdd, OpISub, OpIMul are supported. switch (instruction_opcode) { - case spv::Op::OpIAdd: - case spv::Op::OpISub: - case spv::Op::OpIMul: + case SpvOpIAdd: + case SpvOpISub: + case SpvOpIMul: break; default: return false; @@ -201,8 +201,8 @@ bool TransformationReplaceAddSubMulWithCarryingExtended::IsInstructionSuitable( auto type = ir_context->get_type_mgr()->GetType(instruction.type_id()); switch (instruction_opcode) { - case spv::Op::OpIAdd: - case spv::Op::OpISub: { + case SpvOpIAdd: + case SpvOpISub: { // In case of OpIAdd and OpISub if the operand is a vector, the component // type must be unsigned. Otherwise (if the operand is an int), the // operand must be unsigned. diff --git a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp index efd15551..24293516 100644 --- a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp +++ b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.cpp @@ -28,8 +28,7 @@ namespace { // operator |binop|, returns true if it is certain that 'lhs binop rhs' // evaluates to |required_value|. template -bool float_binop_evaluates_to(T lhs, T rhs, spv::Op binop, - bool required_value) { +bool float_binop_evaluates_to(T lhs, T rhs, SpvOp binop, bool required_value) { // Infinity and NaN values are conservatively treated as out of scope. if (!std::isfinite(lhs) || !std::isfinite(rhs)) { return false; @@ -38,20 +37,20 @@ bool float_binop_evaluates_to(T lhs, T rhs, spv::Op binop, // The following captures the binary operators that spirv-fuzz can actually // generate when turning a boolean constant into a binary expression. switch (binop) { - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: binop_result = (lhs >= rhs); break; - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: binop_result = (lhs > rhs); break; - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: binop_result = (lhs <= rhs); break; - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: binop_result = (lhs < rhs); break; default: @@ -62,20 +61,20 @@ bool float_binop_evaluates_to(T lhs, T rhs, spv::Op binop, // Analogous to 'float_binop_evaluates_to', but for signed int values. template -bool signed_int_binop_evaluates_to(T lhs, T rhs, spv::Op binop, +bool signed_int_binop_evaluates_to(T lhs, T rhs, SpvOp binop, bool required_value) { bool binop_result; switch (binop) { - case spv::Op::OpSGreaterThanEqual: + case SpvOpSGreaterThanEqual: binop_result = (lhs >= rhs); break; - case spv::Op::OpSGreaterThan: + case SpvOpSGreaterThan: binop_result = (lhs > rhs); break; - case spv::Op::OpSLessThanEqual: + case SpvOpSLessThanEqual: binop_result = (lhs <= rhs); break; - case spv::Op::OpSLessThan: + case SpvOpSLessThan: binop_result = (lhs < rhs); break; default: @@ -86,20 +85,20 @@ bool signed_int_binop_evaluates_to(T lhs, T rhs, spv::Op binop, // Analogous to 'float_binop_evaluates_to', but for unsigned int values. template -bool unsigned_int_binop_evaluates_to(T lhs, T rhs, spv::Op binop, +bool unsigned_int_binop_evaluates_to(T lhs, T rhs, SpvOp binop, bool required_value) { bool binop_result; switch (binop) { - case spv::Op::OpUGreaterThanEqual: + case SpvOpUGreaterThanEqual: binop_result = (lhs >= rhs); break; - case spv::Op::OpUGreaterThan: + case SpvOpUGreaterThan: binop_result = (lhs > rhs); break; - case spv::Op::OpULessThanEqual: + case SpvOpULessThanEqual: binop_result = (lhs <= rhs); break; - case spv::Op::OpULessThan: + case SpvOpULessThan: binop_result = (lhs < rhs); break; default: @@ -119,12 +118,12 @@ TransformationReplaceBooleanConstantWithConstantBinary:: TransformationReplaceBooleanConstantWithConstantBinary:: TransformationReplaceBooleanConstantWithConstantBinary( const protobufs::IdUseDescriptor& id_use_descriptor, uint32_t lhs_id, - uint32_t rhs_id, spv::Op comparison_opcode, + uint32_t rhs_id, SpvOp comparison_opcode, uint32_t fresh_id_for_binary_operation) { *message_.mutable_id_use_descriptor() = id_use_descriptor; message_.set_lhs_id(lhs_id); message_.set_rhs_id(rhs_id); - message_.set_opcode(uint32_t(comparison_opcode)); + message_.set_opcode(comparison_opcode); message_.set_fresh_id_for_binary_operation(fresh_id_for_binary_operation); } @@ -142,8 +141,8 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( if (!boolean_constant) { return false; } - if (!(boolean_constant->opcode() == spv::Op::OpConstantFalse || - boolean_constant->opcode() == spv::Op::OpConstantTrue)) { + if (!(boolean_constant->opcode() == SpvOpConstantFalse || + boolean_constant->opcode() == SpvOpConstantTrue)) { return false; } @@ -153,7 +152,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( if (!lhs_constant_inst) { return false; } - if (lhs_constant_inst->opcode() != spv::Op::OpConstant) { + if (lhs_constant_inst->opcode() != SpvOpConstant) { return false; } @@ -163,7 +162,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( if (!rhs_constant_inst) { return false; } - if (rhs_constant_inst->opcode() != spv::Op::OpConstant) { + if (rhs_constant_inst->opcode() != SpvOpConstant) { return false; } @@ -177,10 +176,9 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( ir_context->get_constant_mgr()->FindDeclaredConstant(message_.lhs_id()); auto rhs_constant = ir_context->get_constant_mgr()->FindDeclaredConstant(message_.rhs_id()); - bool expected_result = - (boolean_constant->opcode() == spv::Op::OpConstantTrue); + bool expected_result = (boolean_constant->opcode() == SpvOpConstantTrue); - const auto binary_opcode = static_cast(message_.opcode()); + const auto binary_opcode = static_cast(message_.opcode()); // We consider the floating point, signed and unsigned integer cases // separately. In each case the logic is very similar. @@ -249,7 +247,7 @@ bool TransformationReplaceBooleanConstantWithConstantBinary::IsApplicable( // a binary operator before an OpVariable, but in any case (b) the // constant we would be replacing is the initializer constant of the // OpVariable, and this cannot be the result of a binary operation. - if (instruction->opcode() == spv::Op::OpVariable) { + if (instruction->opcode() == SpvOpVariable) { return false; } @@ -270,7 +268,7 @@ TransformationReplaceBooleanConstantWithConstantBinary::ApplyWithResult( {SPV_OPERAND_TYPE_ID, {message_.lhs_id()}}, {SPV_OPERAND_TYPE_ID, {message_.rhs_id()}}}; auto binary_instruction = MakeUnique( - ir_context, static_cast(message_.opcode()), + ir_context, static_cast(message_.opcode()), ir_context->get_type_mgr()->GetId(&bool_type), message_.fresh_id_for_binary_operation(), operands); opt::Instruction* result = binary_instruction.get(); @@ -281,7 +279,7 @@ TransformationReplaceBooleanConstantWithConstantBinary::ApplyWithResult( // If |instruction_before_which_to_insert| is an OpPhi instruction, // then |binary_instruction| will be inserted into the parent block associated // with the OpPhi variable operand. - if (instruction_containing_constant_use->opcode() == spv::Op::OpPhi) { + if (instruction_containing_constant_use->opcode() == SpvOpPhi) { instruction_before_which_to_insert = ir_context->cfg() ->block(instruction_containing_constant_use->GetSingleWordInOperand( @@ -295,9 +293,8 @@ TransformationReplaceBooleanConstantWithConstantBinary::ApplyWithResult( { opt::Instruction* previous_node = instruction_before_which_to_insert->PreviousNode(); - if (previous_node && - (previous_node->opcode() == spv::Op::OpLoopMerge || - previous_node->opcode() == spv::Op::OpSelectionMerge)) { + if (previous_node && (previous_node->opcode() == SpvOpLoopMerge || + previous_node->opcode() == SpvOpSelectionMerge)) { instruction_before_which_to_insert = previous_node; } } diff --git a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h index 4d48bf2c..97c66bf9 100644 --- a/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h +++ b/source/fuzz/transformation_replace_boolean_constant_with_constant_binary.h @@ -32,7 +32,7 @@ class TransformationReplaceBooleanConstantWithConstantBinary TransformationReplaceBooleanConstantWithConstantBinary( const protobufs::IdUseDescriptor& id_use_descriptor, uint32_t lhs_id, - uint32_t rhs_id, spv::Op comparison_opcode, + uint32_t rhs_id, SpvOp comparison_opcode, uint32_t fresh_id_for_binary_operation); // - |message_.fresh_id_for_binary_operation| must not already be used by the diff --git a/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.cpp b/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.cpp index 4150bb13..9ea7cb6a 100644 --- a/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.cpp +++ b/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.cpp @@ -26,10 +26,10 @@ TransformationReplaceBranchFromDeadBlockWithExit:: TransformationReplaceBranchFromDeadBlockWithExit:: TransformationReplaceBranchFromDeadBlockWithExit(uint32_t block_id, - spv::Op opcode, + SpvOp opcode, uint32_t return_value_id) { message_.set_block_id(block_id); - message_.set_opcode(uint32_t(opcode)); + message_.set_opcode(opcode); message_.set_return_value_id(return_value_id); } @@ -45,11 +45,11 @@ bool TransformationReplaceBranchFromDeadBlockWithExit::IsApplicable( return false; } auto function_return_type_id = block->GetParent()->type_id(); - switch (spv::Op(message_.opcode())) { - case spv::Op::OpKill: + switch (message_.opcode()) { + case SpvOpKill: for (auto& entry_point : ir_context->module()->entry_points()) { - if (spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) != - spv::ExecutionModel::Fragment) { + if (entry_point.GetSingleWordInOperand(0) != + SpvExecutionModelFragment) { // OpKill is only allowed in a fragment shader. This is a // conservative check: if the module contains a non-fragment entry // point then adding an OpKill might lead to OpKill being used in a @@ -58,15 +58,15 @@ bool TransformationReplaceBranchFromDeadBlockWithExit::IsApplicable( } } break; - case spv::Op::OpReturn: + case SpvOpReturn: if (ir_context->get_def_use_mgr() ->GetDef(function_return_type_id) - ->opcode() != spv::Op::OpTypeVoid) { + ->opcode() != SpvOpTypeVoid) { // OpReturn is only allowed in a function with void return type. return false; } break; - case spv::Op::OpReturnValue: { + case SpvOpReturnValue: { // If the terminator is to be changed to OpReturnValue, with // |message_.return_value_id| being the value that will be returned, then // |message_.return_value_id| must have a compatible type and be available @@ -83,7 +83,7 @@ bool TransformationReplaceBranchFromDeadBlockWithExit::IsApplicable( break; } default: - assert(spv::Op(message_.opcode()) == spv::Op::OpUnreachable && + assert(message_.opcode() == SpvOpUnreachable && "Invalid early exit opcode."); break; } @@ -95,7 +95,7 @@ void TransformationReplaceBranchFromDeadBlockWithExit::Apply( // If the successor block has OpPhi instructions then arguments related to // |message_.block_id| need to be removed from these instruction. auto block = ir_context->get_instr_block(message_.block_id()); - assert(block->terminator()->opcode() == spv::Op::OpBranch && + assert(block->terminator()->opcode() == SpvOpBranch && "Precondition: the block must end with OpBranch."); auto successor = ir_context->get_instr_block( block->terminator()->GetSingleWordInOperand(0)); @@ -114,12 +114,12 @@ void TransformationReplaceBranchFromDeadBlockWithExit::Apply( // Rewrite the terminator of |message_.block_id|. opt::Instruction::OperandList new_terminator_in_operands; - if (spv::Op(message_.opcode()) == spv::Op::OpReturnValue) { + if (message_.opcode() == SpvOpReturnValue) { new_terminator_in_operands.push_back( {SPV_OPERAND_TYPE_ID, {message_.return_value_id()}}); } auto terminator = block->terminator(); - terminator->SetOpcode(static_cast(message_.opcode())); + terminator->SetOpcode(static_cast(message_.opcode())); terminator->SetInOperands(std::move(new_terminator_in_operands)); ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); } @@ -145,7 +145,7 @@ bool TransformationReplaceBranchFromDeadBlockWithExit::BlockIsSuitable( return false; } // The block's terminator must be OpBranch. - if (block.terminator()->opcode() != spv::Op::OpBranch) { + if (block.terminator()->opcode() != SpvOpBranch) { return false; } if (ir_context->GetStructuredCFGAnalysis()->IsInContinueConstruct( @@ -164,7 +164,7 @@ bool TransformationReplaceBranchFromDeadBlockWithExit::BlockIsSuitable( // Make sure that domination rules are satisfied when we remove the branch // from the |block| to its |successor|. return fuzzerutil::NewTerminatorPreservesDominationRules( - ir_context, block.id(), {ir_context, spv::Op::OpUnreachable}); + ir_context, block.id(), {ir_context, SpvOpUnreachable}); } } // namespace fuzz diff --git a/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h b/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h index 9a5d42e2..89667fcd 100644 --- a/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h +++ b/source/fuzz/transformation_replace_branch_from_dead_block_with_exit.h @@ -30,7 +30,7 @@ class TransformationReplaceBranchFromDeadBlockWithExit : public Transformation { protobufs::TransformationReplaceBranchFromDeadBlockWithExit message); TransformationReplaceBranchFromDeadBlockWithExit(uint32_t block_id, - spv::Op opcode, + SpvOp opcode, uint32_t return_value_id); // - |message_.block_id| must be the id of a dead block that is not part of diff --git a/source/fuzz/transformation_replace_constant_with_uniform.cpp b/source/fuzz/transformation_replace_constant_with_uniform.cpp index 7174e6a7..c6698c03 100644 --- a/source/fuzz/transformation_replace_constant_with_uniform.cpp +++ b/source/fuzz/transformation_replace_constant_with_uniform.cpp @@ -67,15 +67,15 @@ TransformationReplaceConstantWithUniform::MakeAccessChainInstruction( // The type id for the access chain is a uniform pointer with base type // matching the given constant id type. auto type_and_pointer_type = - ir_context->get_type_mgr()->GetTypeAndPointerType( - constant_type_id, spv::StorageClass::Uniform); + ir_context->get_type_mgr()->GetTypeAndPointerType(constant_type_id, + SpvStorageClassUniform); assert(type_and_pointer_type.first != nullptr); assert(type_and_pointer_type.second != nullptr); auto pointer_to_uniform_constant_type_id = ir_context->get_type_mgr()->GetId(type_and_pointer_type.second.get()); return MakeUnique( - ir_context, spv::Op::OpAccessChain, pointer_to_uniform_constant_type_id, + ir_context, SpvOpAccessChain, pointer_to_uniform_constant_type_id, message_.fresh_id_for_access_chain(), operands_for_access_chain); } @@ -84,9 +84,9 @@ TransformationReplaceConstantWithUniform::MakeLoadInstruction( spvtools::opt::IRContext* ir_context, uint32_t constant_type_id) const { opt::Instruction::OperandList operands_for_load = { {SPV_OPERAND_TYPE_ID, {message_.fresh_id_for_access_chain()}}}; - return MakeUnique( - ir_context, spv::Op::OpLoad, constant_type_id, - message_.fresh_id_for_load(), operands_for_load); + return MakeUnique(ir_context, SpvOpLoad, constant_type_id, + message_.fresh_id_for_load(), + operands_for_load); } opt::Instruction* @@ -99,7 +99,7 @@ TransformationReplaceConstantWithUniform::GetInsertBeforeInstruction( } // The use might be in an OpPhi instruction. - if (result->opcode() == spv::Op::OpPhi) { + if (result->opcode() == SpvOpPhi) { // OpPhi instructions must be the first instructions in a block. Thus, we // can't insert above the OpPhi instruction. Given the predecessor block // that corresponds to the id use, get the last instruction in that block @@ -108,19 +108,18 @@ TransformationReplaceConstantWithUniform::GetInsertBeforeInstruction( ir_context, result->GetSingleWordInOperand( message_.id_use_descriptor().in_operand_index() + 1), - spv::Op::OpLoad); + SpvOpLoad); } // The only operand that we could've replaced in the OpBranchConditional is // the condition id. But that operand has a boolean type and uniform variables // can't store booleans (see the spec on OpTypeBool). Thus, |result| can't be // an OpBranchConditional. - assert(result->opcode() != spv::Op::OpBranchConditional && + assert(result->opcode() != SpvOpBranchConditional && "OpBranchConditional has no operands to replace"); - assert( - fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, result) && - "We should be able to insert OpLoad and OpAccessChain at this point"); + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, result) && + "We should be able to insert OpLoad and OpAccessChain at this point"); return result; } @@ -192,15 +191,15 @@ bool TransformationReplaceConstantWithUniform::IsApplicable( // The use must not be a variable initializer; these are required to be // constants, so it would be illegal to replace one with a uniform access. - if (instruction_using_constant->opcode() == spv::Op::OpVariable) { + if (instruction_using_constant->opcode() == SpvOpVariable) { return false; } // The module needs to have a uniform pointer type suitable for indexing into // the uniform variable, i.e. matching the type of the constant we wish to // replace with a uniform. - opt::analysis::Pointer pointer_to_type_of_constant( - declared_constant->type(), spv::StorageClass::Uniform); + opt::analysis::Pointer pointer_to_type_of_constant(declared_constant->type(), + SpvStorageClassUniform); if (!ir_context->get_type_mgr()->GetId(&pointer_to_type_of_constant)) { return false; } diff --git a/source/fuzz/transformation_replace_copy_memory_with_load_store.cpp b/source/fuzz/transformation_replace_copy_memory_with_load_store.cpp index 8f141451..de9d1fd3 100644 --- a/source/fuzz/transformation_replace_copy_memory_with_load_store.cpp +++ b/source/fuzz/transformation_replace_copy_memory_with_load_store.cpp @@ -45,7 +45,7 @@ bool TransformationReplaceCopyMemoryWithLoadStore::IsApplicable( auto copy_memory_instruction = FindInstruction( message_.copy_memory_instruction_descriptor(), ir_context); if (!copy_memory_instruction || - copy_memory_instruction->opcode() != spv::Op::OpCopyMemory) { + copy_memory_instruction->opcode() != SpvOpCopyMemory) { return false; } return true; @@ -57,7 +57,7 @@ void TransformationReplaceCopyMemoryWithLoadStore::Apply( message_.copy_memory_instruction_descriptor(), ir_context); // |copy_memory_instruction| must be defined. assert(copy_memory_instruction && - copy_memory_instruction->opcode() == spv::Op::OpCopyMemory && + copy_memory_instruction->opcode() == SpvOpCopyMemory && "The required OpCopyMemory instruction must be defined."); // Integrity check: Both operands must be pointers. @@ -78,8 +78,8 @@ void TransformationReplaceCopyMemoryWithLoadStore::Apply( (void)target_type_opcode; (void)source_type_opcode; - assert(target_type_opcode == spv::Op::OpTypePointer && - source_type_opcode == spv::Op::OpTypePointer && + assert(target_type_opcode == SpvOpTypePointer && + source_type_opcode == SpvOpTypePointer && "Operands must be of type OpTypePointer"); // Integrity check: |source| and |target| must point to the same type. @@ -100,12 +100,12 @@ void TransformationReplaceCopyMemoryWithLoadStore::Apply( fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); FindInstruction(message_.copy_memory_instruction_descriptor(), ir_context) ->InsertBefore(MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {target->result_id()}}, {SPV_OPERAND_TYPE_ID, {message_.fresh_id()}}}))) ->InsertBefore(MakeUnique( - ir_context, spv::Op::OpLoad, target_pointee_type, message_.fresh_id(), + ir_context, SpvOpLoad, target_pointee_type, message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {source->result_id()}}}))); diff --git a/source/fuzz/transformation_replace_copy_object_with_store_load.cpp b/source/fuzz/transformation_replace_copy_object_with_store_load.cpp index f08a7345..e0643bf3 100644 --- a/source/fuzz/transformation_replace_copy_object_with_store_load.cpp +++ b/source/fuzz/transformation_replace_copy_object_with_store_load.cpp @@ -46,7 +46,7 @@ bool TransformationReplaceCopyObjectWithStoreLoad::IsApplicable( // This must be a defined OpCopyObject instruction. if (!copy_object_instruction || - copy_object_instruction->opcode() != spv::Op::OpCopyObject) { + copy_object_instruction->opcode() != SpvOpCopyObject) { return false; } @@ -54,14 +54,14 @@ bool TransformationReplaceCopyObjectWithStoreLoad::IsApplicable( // because we cannot define a pointer to pointer. if (ir_context->get_def_use_mgr() ->GetDef(copy_object_instruction->type_id()) - ->opcode() == spv::Op::OpTypePointer) { + ->opcode() == SpvOpTypePointer) { return false; } // A pointer type instruction pointing to the value type must be defined. auto pointer_type_id = fuzzerutil::MaybeGetPointerType( ir_context, copy_object_instruction->type_id(), - static_cast(message_.variable_storage_class())); + static_cast(message_.variable_storage_class())); if (!pointer_type_id) { return false; } @@ -74,10 +74,8 @@ bool TransformationReplaceCopyObjectWithStoreLoad::IsApplicable( return false; } // |message_.variable_storage_class| must be Private or Function. - return spv::StorageClass(message_.variable_storage_class()) == - spv::StorageClass::Private || - spv::StorageClass(message_.variable_storage_class()) == - spv::StorageClass::Function; + return message_.variable_storage_class() == SpvStorageClassPrivate || + message_.variable_storage_class() == SpvStorageClassFunction; } void TransformationReplaceCopyObjectWithStoreLoad::Apply( @@ -87,7 +85,7 @@ void TransformationReplaceCopyObjectWithStoreLoad::Apply( ir_context->get_def_use_mgr()->GetDef(message_.copy_object_result_id()); // |copy_object_instruction| must be defined. assert(copy_object_instruction && - copy_object_instruction->opcode() == spv::Op::OpCopyObject && + copy_object_instruction->opcode() == SpvOpCopyObject && "The required OpCopyObject instruction must be defined."); opt::BasicBlock* enclosing_block = @@ -98,15 +96,14 @@ void TransformationReplaceCopyObjectWithStoreLoad::Apply( // A pointer type instruction pointing to the value type must be defined. auto pointer_type_id = fuzzerutil::MaybeGetPointerType( ir_context, copy_object_instruction->type_id(), - static_cast(message_.variable_storage_class())); + static_cast(message_.variable_storage_class())); assert(pointer_type_id && "The required pointer type must be available."); // Adds a global or local variable (according to the storage class). - if (spv::StorageClass(message_.variable_storage_class()) == - spv::StorageClass::Private) { + if (message_.variable_storage_class() == SpvStorageClassPrivate) { opt::Instruction* new_global = fuzzerutil::AddGlobalVariable( ir_context, message_.fresh_variable_id(), pointer_type_id, - spv::StorageClass::Private, message_.variable_initializer_id()); + SpvStorageClassPrivate, message_.variable_initializer_id()); ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_global); } else { opt::Function* function = @@ -123,13 +120,13 @@ void TransformationReplaceCopyObjectWithStoreLoad::Apply( fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_variable_id()); opt::Instruction* load_instruction = copy_object_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpLoad, copy_object_instruction->type_id(), + ir_context, SpvOpLoad, copy_object_instruction->type_id(), message_.copy_object_result_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.fresh_variable_id()}}}))); opt::Instruction* store_instruction = load_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.fresh_variable_id()}}, {SPV_OPERAND_TYPE_ID, {src_operand}}}))); diff --git a/source/fuzz/transformation_replace_irrelevant_id.cpp b/source/fuzz/transformation_replace_irrelevant_id.cpp index 7f640639..a71f96a8 100644 --- a/source/fuzz/transformation_replace_irrelevant_id.cpp +++ b/source/fuzz/transformation_replace_irrelevant_id.cpp @@ -65,7 +65,7 @@ bool TransformationReplaceIrrelevantId::IsApplicable( } // The replacement id must not be the result of an OpFunction instruction. - if (replacement_id_def->opcode() == spv::Op::OpFunction) { + if (replacement_id_def->opcode() == SpvOpFunction) { return false; } @@ -130,7 +130,7 @@ bool TransformationReplaceIrrelevantId:: AttemptsToReplaceVariableInitializerWithNonConstant( const opt::Instruction& use_instruction, const opt::Instruction& replacement_for_use) { - return use_instruction.opcode() == spv::Op::OpVariable && + return use_instruction.opcode() == SpvOpVariable && !spvOpcodeIsConstant(replacement_for_use.opcode()); } diff --git a/source/fuzz/transformation_replace_linear_algebra_instruction.cpp b/source/fuzz/transformation_replace_linear_algebra_instruction.cpp index fb7b2948..2430ccab 100644 --- a/source/fuzz/transformation_replace_linear_algebra_instruction.cpp +++ b/source/fuzz/transformation_replace_linear_algebra_instruction.cpp @@ -68,28 +68,28 @@ void TransformationReplaceLinearAlgebraInstruction::Apply( FindInstruction(message_.instruction_descriptor(), ir_context); switch (linear_algebra_instruction->opcode()) { - case spv::Op::OpTranspose: + case SpvOpTranspose: ReplaceOpTranspose(ir_context, linear_algebra_instruction); break; - case spv::Op::OpVectorTimesScalar: + case SpvOpVectorTimesScalar: ReplaceOpVectorTimesScalar(ir_context, linear_algebra_instruction); break; - case spv::Op::OpMatrixTimesScalar: + case SpvOpMatrixTimesScalar: ReplaceOpMatrixTimesScalar(ir_context, linear_algebra_instruction); break; - case spv::Op::OpVectorTimesMatrix: + case SpvOpVectorTimesMatrix: ReplaceOpVectorTimesMatrix(ir_context, linear_algebra_instruction); break; - case spv::Op::OpMatrixTimesVector: + case SpvOpMatrixTimesVector: ReplaceOpMatrixTimesVector(ir_context, linear_algebra_instruction); break; - case spv::Op::OpMatrixTimesMatrix: + case SpvOpMatrixTimesMatrix: ReplaceOpMatrixTimesMatrix(ir_context, linear_algebra_instruction); break; - case spv::Op::OpOuterProduct: + case SpvOpOuterProduct: ReplaceOpOuterProduct(ir_context, linear_algebra_instruction); break; - case spv::Op::OpDot: + case SpvOpDot: ReplaceOpDot(ir_context, linear_algebra_instruction); break; default: @@ -112,7 +112,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3354): // Right now we only support certain operations. switch (instruction->opcode()) { - case spv::Op::OpTranspose: { + case SpvOpTranspose: { // For each matrix row, |2 * matrix_column_count| OpCompositeExtract and 1 // OpCompositeConstruct will be inserted. auto matrix_instruction = ir_context->get_def_use_mgr()->GetDef( @@ -130,7 +130,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( ->element_count(); return matrix_row_count * (2 * matrix_column_count + 1); } - case spv::Op::OpVectorTimesScalar: + case SpvOpVectorTimesScalar: // For each vector component, 1 OpCompositeExtract and 1 OpFMul will be // inserted. return 2 * @@ -140,7 +140,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( ->type_id()) ->AsVector() ->element_count(); - case spv::Op::OpMatrixTimesScalar: { + case SpvOpMatrixTimesScalar: { // For each matrix column, |1 + column.size| OpCompositeExtract, // |column.size| OpFMul and 1 OpCompositeConstruct instructions will be // inserted. @@ -154,7 +154,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( ->AsVector() ->element_count()); } - case spv::Op::OpVectorTimesMatrix: { + case SpvOpVectorTimesMatrix: { // For each vector component, 1 OpCompositeExtract instruction will be // inserted. For each matrix column, |1 + vector_component_count| // OpCompositeExtract, |vector_component_count| OpFMul and @@ -175,7 +175,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( ->element_count(); return vector_component_count * (3 * matrix_column_count + 1); } - case spv::Op::OpMatrixTimesVector: { + case SpvOpMatrixTimesVector: { // For each matrix column, |1 + matrix_row_count| OpCompositeExtract // will be inserted. For each matrix row, |matrix_column_count| OpFMul and // |matrix_column_count - 1| OpFAdd instructions will be inserted. For @@ -197,7 +197,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( return 3 * matrix_column_count * matrix_row_count + 2 * matrix_column_count - matrix_row_count; } - case spv::Op::OpMatrixTimesMatrix: { + case SpvOpMatrixTimesMatrix: { // For each matrix 2 column, 1 OpCompositeExtract, 1 OpCompositeConstruct, // |3 * matrix_1_row_count * matrix_1_column_count| OpCompositeExtract, // |matrix_1_row_count * matrix_1_column_count| OpFMul, @@ -228,7 +228,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( return matrix_2_column_count * (2 + matrix_1_row_count * (5 * matrix_1_column_count - 1)); } - case spv::Op::OpOuterProduct: { + case SpvOpOuterProduct: { // For each |vector_2| component, |vector_1_component_count + 1| // OpCompositeExtract, |vector_1_component_count| OpFMul and 1 // OpCompositeConstruct instructions will be inserted. @@ -248,7 +248,7 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount( ->element_count(); return 2 * vector_2_component_count * (vector_1_component_count + 1); } - case spv::Op::OpDot: + case SpvOpDot: // For each pair of vector components, 2 OpCompositeExtract and 1 OpFMul // will be inserted. The first two OpFMul instructions will result the // first OpFAdd instruction to be inserted. For each remaining OpFMul, 1 @@ -299,7 +299,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpTranspose( // Extracts the matrix column. uint32_t matrix_column_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_column_type), matrix_column_id, opt::Instruction::OperandList( @@ -309,7 +309,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpTranspose( // Extracts the matrix column component. column_component_ids[j] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_column_component_type), column_component_ids[j], opt::Instruction::OperandList( @@ -324,14 +324,14 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpTranspose( } result_column_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, ir_context->get_type_mgr()->GetId(resulting_matrix_column_type), result_column_ids[i], opt::Instruction::OperandList(in_operands))); } // The OpTranspose instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {result_column_ids[0]}); for (uint32_t i = 1; i < result_column_ids.size(); i++) { linear_algebra_instruction->AddOperand( @@ -363,8 +363,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesScalar( uint32_t vector_extract_id = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, vector_extract_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, scalar->type_id(), - vector_extract_id, + ir_context, SpvOpCompositeExtract, scalar->type_id(), vector_extract_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {vector->result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}}))); @@ -374,7 +373,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesScalar( float_multiplication_ids[i] = float_multiplication_id; fuzzerutil::UpdateModuleIdBound(ir_context, float_multiplication_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, scalar->type_id(), float_multiplication_id, + ir_context, SpvOpFMul, scalar->type_id(), float_multiplication_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {vector_extract_id}}, {SPV_OPERAND_TYPE_ID, {scalar->result_id()}}}))); @@ -382,7 +381,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesScalar( // The OpVectorTimesScalar instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {float_multiplication_ids[0]}); linear_algebra_instruction->SetInOperand(1, {float_multiplication_ids[1]}); for (uint32_t i = 2; i < float_multiplication_ids.size(); i++) { @@ -419,7 +418,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesScalar( uint32_t matrix_extract_id = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, matrix_extract_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_column_type), matrix_extract_id, opt::Instruction::OperandList( @@ -433,8 +432,8 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesScalar( uint32_t column_extract_id = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, column_extract_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, - scalar_instruction->type_id(), column_extract_id, + ir_context, SpvOpCompositeExtract, scalar_instruction->type_id(), + column_extract_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {matrix_extract_id}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {j}}}))); @@ -443,7 +442,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesScalar( float_multiplication_ids[j] = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, float_multiplication_ids[j]); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, scalar_instruction->type_id(), + ir_context, SpvOpFMul, scalar_instruction->type_id(), float_multiplication_ids[j], opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {column_extract_id}}, @@ -459,14 +458,14 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesScalar( composite_construct_ids[i] = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, composite_construct_ids[i]); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, ir_context->get_type_mgr()->GetId(matrix_column_type), composite_construct_ids[i], composite_construct_in_operands)); } // The OpMatrixTimesScalar instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {composite_construct_ids[0]}); linear_algebra_instruction->SetInOperand(1, {composite_construct_ids[1]}); for (uint32_t i = 2; i < composite_construct_ids.size(); i++) { @@ -496,7 +495,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( for (uint32_t i = 0; i < vector_component_count; i++) { vector_component_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_component_type), vector_component_ids[i], opt::Instruction::OperandList( @@ -521,7 +520,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( // Extracts matrix column. uint32_t matrix_extract_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_column_type), matrix_extract_id, opt::Instruction::OperandList( @@ -533,7 +532,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( // Extracts column component. uint32_t column_extract_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_component_type), column_extract_id, opt::Instruction::OperandList( @@ -543,7 +542,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( // Multiplies corresponding vector and column components. float_multiplication_ids[j] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, + ir_context, SpvOpFMul, ir_context->get_type_mgr()->GetId(vector_component_type), float_multiplication_ids[j], opt::Instruction::OperandList( @@ -556,7 +555,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( uint32_t float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[0]}}, @@ -565,7 +564,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id, opt::Instruction::OperandList( @@ -578,7 +577,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix( // The OpVectorTimesMatrix instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {result_component_ids[0]}); linear_algebra_instruction->SetInOperand(1, {result_component_ids[1]}); for (uint32_t i = 2; i < result_component_ids.size(); i++) { @@ -612,7 +611,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( for (uint32_t i = 0; i < matrix_column_count; i++) { matrix_column_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_column_type), matrix_column_ids[i], opt::Instruction::OperandList( @@ -633,7 +632,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( for (uint32_t i = 0; i < matrix_column_count; i++) { vector_component_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_component_type), vector_component_ids[i], opt::Instruction::OperandList( @@ -648,7 +647,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( // Extracts column component. uint32_t column_extract_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_component_type), column_extract_id, opt::Instruction::OperandList( @@ -658,7 +657,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( // Multiplies corresponding vector and column components. float_multiplication_ids[j] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, + ir_context, SpvOpFMul, ir_context->get_type_mgr()->GetId(vector_component_type), float_multiplication_ids[j], opt::Instruction::OperandList( @@ -671,7 +670,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( uint32_t float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[0]}}, @@ -680,7 +679,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id, opt::Instruction::OperandList( @@ -693,7 +692,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector( // The OpMatrixTimesVector instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {result_component_ids[0]}); linear_algebra_instruction->SetInOperand(1, {result_component_ids[1]}); for (uint32_t i = 2; i < result_component_ids.size(); i++) { @@ -744,7 +743,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( // Extracts matrix 2 column. uint32_t matrix_2_column_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_2_column_type), matrix_2_column_id, opt::Instruction::OperandList( @@ -758,7 +757,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( // Extracts matrix 1 column. uint32_t matrix_1_column_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_1_column_type), matrix_1_column_id, opt::Instruction::OperandList( @@ -769,7 +768,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( uint32_t matrix_1_column_component_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_1_column_component_type), matrix_1_column_component_id, opt::Instruction::OperandList( @@ -780,7 +779,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( uint32_t matrix_2_column_component_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(matrix_1_column_component_type), matrix_2_column_component_id, opt::Instruction::OperandList( @@ -790,7 +789,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( // Multiplies corresponding matrix 1 and matrix 2 column components. float_multiplication_ids[k] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, + ir_context, SpvOpFMul, ir_context->get_type_mgr()->GetId(matrix_1_column_component_type), float_multiplication_ids[k], opt::Instruction::OperandList( @@ -803,7 +802,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( uint32_t float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(matrix_1_column_component_type), float_add_id, opt::Instruction::OperandList( @@ -813,7 +812,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( float_add_id = message_.fresh_ids(fresh_id_index++); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, + ir_context, SpvOpFAdd, ir_context->get_type_mgr()->GetId(matrix_1_column_component_type), float_add_id, opt::Instruction::OperandList( @@ -831,14 +830,14 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesMatrix( } result_column_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, + ir_context, SpvOpCompositeConstruct, ir_context->get_type_mgr()->GetId(matrix_1_column_type), result_column_ids[i], opt::Instruction::OperandList(in_operands))); } // The OpMatrixTimesMatrix instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {result_column_ids[0]}); linear_algebra_instruction->SetInOperand(1, {result_column_ids[1]}); for (uint32_t i = 2; i < result_column_ids.size(); i++) { @@ -881,7 +880,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpOuterProduct( // Extracts |vector_2| component. uint32_t vector_2_component_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_1_component_type), vector_2_component_id, opt::Instruction::OperandList( @@ -893,7 +892,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpOuterProduct( // Extracts |vector_1| component. uint32_t vector_1_component_id = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, ir_context->get_type_mgr()->GetId(vector_1_component_type), vector_1_component_id, opt::Instruction::OperandList( @@ -903,7 +902,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpOuterProduct( // Multiplies |vector_1| and |vector_2| components. column_component_ids[j] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, + ir_context, SpvOpFMul, ir_context->get_type_mgr()->GetId(vector_1_component_type), column_component_ids[j], opt::Instruction::OperandList( @@ -918,13 +917,13 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpOuterProduct( } result_column_ids[i] = message_.fresh_ids(fresh_id_index++); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, - vector_1_instruction->type_id(), result_column_ids[i], in_operands)); + ir_context, SpvOpCompositeConstruct, vector_1_instruction->type_id(), + result_column_ids[i], in_operands)); } // The OpOuterProduct instruction is changed to an OpCompositeConstruct // instruction. - linear_algebra_instruction->SetOpcode(spv::Op::OpCompositeConstruct); + linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct); linear_algebra_instruction->SetInOperand(0, {result_column_ids[0]}); linear_algebra_instruction->SetInOperand(1, {result_column_ids[1]}); for (uint32_t i = 2; i < result_column_ids.size(); i++) { @@ -957,7 +956,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( uint32_t vector_1_extract_id = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, vector_1_extract_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, linear_algebra_instruction->type_id(), vector_1_extract_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {vector_1->result_id()}}, @@ -967,7 +966,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( uint32_t vector_2_extract_id = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, vector_2_extract_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, + ir_context, SpvOpCompositeExtract, linear_algebra_instruction->type_id(), vector_2_extract_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {vector_2->result_id()}}, @@ -977,7 +976,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( float_multiplication_ids[i] = message_.fresh_ids(fresh_id_index++); fuzzerutil::UpdateModuleIdBound(ir_context, float_multiplication_ids[i]); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFMul, linear_algebra_instruction->type_id(), + ir_context, SpvOpFMul, linear_algebra_instruction->type_id(), float_multiplication_ids[i], opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {vector_1_extract_id}}, @@ -987,7 +986,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( // If the vector has 2 components, then there will be 2 float multiplication // instructions. if (vectors_component_count == 2) { - linear_algebra_instruction->SetOpcode(spv::Op::OpFAdd); + linear_algebra_instruction->SetOpcode(SpvOpFAdd); linear_algebra_instruction->SetInOperand(0, {float_multiplication_ids[0]}); linear_algebra_instruction->SetInOperand(1, {float_multiplication_ids[1]}); } else { @@ -998,7 +997,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( float_add_ids.push_back(float_add_id); fuzzerutil::UpdateModuleIdBound(ir_context, float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, linear_algebra_instruction->type_id(), + ir_context, SpvOpFAdd, linear_algebra_instruction->type_id(), float_add_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[0]}}, @@ -1011,7 +1010,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( fuzzerutil::UpdateModuleIdBound(ir_context, float_add_id); float_add_ids.push_back(float_add_id); linear_algebra_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFAdd, linear_algebra_instruction->type_id(), + ir_context, SpvOpFAdd, linear_algebra_instruction->type_id(), float_add_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[i]}}, @@ -1020,7 +1019,7 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot( // The last OpFAdd instruction is got by changing some of the OpDot // instruction attributes. - linear_algebra_instruction->SetOpcode(spv::Op::OpFAdd); + linear_algebra_instruction->SetOpcode(SpvOpFAdd); linear_algebra_instruction->SetInOperand( 0, {float_multiplication_ids[float_multiplication_ids.size() - 1]}); linear_algebra_instruction->SetInOperand( diff --git a/source/fuzz/transformation_replace_load_store_with_copy_memory.cpp b/source/fuzz/transformation_replace_load_store_with_copy_memory.cpp index 36610f2f..e75337f6 100644 --- a/source/fuzz/transformation_replace_load_store_with_copy_memory.cpp +++ b/source/fuzz/transformation_replace_load_store_with_copy_memory.cpp @@ -48,14 +48,14 @@ bool TransformationReplaceLoadStoreWithCopyMemory::IsApplicable( // The OpLoad instruction must be defined. auto load_instruction = FindInstruction(message_.load_instruction_descriptor(), ir_context); - if (!load_instruction || load_instruction->opcode() != spv::Op::OpLoad) { + if (!load_instruction || load_instruction->opcode() != SpvOpLoad) { return false; } // The OpStore instruction must be defined. auto store_instruction = FindInstruction(message_.store_instruction_descriptor(), ir_context); - if (!store_instruction || store_instruction->opcode() != spv::Op::OpStore) { + if (!store_instruction || store_instruction->opcode() != SpvOpStore) { return false; } @@ -69,7 +69,7 @@ bool TransformationReplaceLoadStoreWithCopyMemory::IsApplicable( // Get storage class of the variable pointed by the source operand in OpLoad. opt::Instruction* source_id = ir_context->get_def_use_mgr()->GetDef( load_instruction->GetSingleWordOperand(2)); - spv::StorageClass storage_class = fuzzerutil::GetStorageClassFromPointerType( + SpvStorageClass storage_class = fuzzerutil::GetStorageClassFromPointerType( ir_context, source_id->type_id()); // Iterate over all instructions between |load_instruction| and @@ -99,11 +99,11 @@ void TransformationReplaceLoadStoreWithCopyMemory::Apply( // OpLoad and OpStore instructions must be defined. auto load_instruction = FindInstruction(message_.load_instruction_descriptor(), ir_context); - assert(load_instruction && load_instruction->opcode() == spv::Op::OpLoad && + assert(load_instruction && load_instruction->opcode() == SpvOpLoad && "The required OpLoad instruction must be defined."); auto store_instruction = FindInstruction(message_.store_instruction_descriptor(), ir_context); - assert(store_instruction && store_instruction->opcode() == spv::Op::OpStore && + assert(store_instruction && store_instruction->opcode() == SpvOpStore && "The required OpStore instruction must be defined."); // Intermediate values of the OpLoad and the OpStore must match. @@ -121,7 +121,7 @@ void TransformationReplaceLoadStoreWithCopyMemory::Apply( // Insert the OpCopyMemory instruction before the OpStore instruction. store_instruction->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCopyMemory, 0, 0, + ir_context, SpvOpCopyMemory, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {target_variable_id}}, {SPV_OPERAND_TYPE_ID, {source_variable_id}}}))); @@ -133,14 +133,14 @@ void TransformationReplaceLoadStoreWithCopyMemory::Apply( } bool TransformationReplaceLoadStoreWithCopyMemory::IsMemoryWritingOpCode( - spv::Op op_code) { + SpvOp op_code) { if (spvOpcodeIsAtomicOp(op_code)) { - return op_code != spv::Op::OpAtomicLoad; + return op_code != SpvOpAtomicLoad; } switch (op_code) { - case spv::Op::OpStore: - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpStore: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: return true; default: return false; @@ -148,10 +148,10 @@ bool TransformationReplaceLoadStoreWithCopyMemory::IsMemoryWritingOpCode( } bool TransformationReplaceLoadStoreWithCopyMemory::IsMemoryBarrierOpCode( - spv::Op op_code) { + SpvOp op_code) { switch (op_code) { - case spv::Op::OpMemoryBarrier: - case spv::Op::OpMemoryNamedBarrier: + case SpvOpMemoryBarrier: + case SpvOpMemoryNamedBarrier: return true; default: return false; @@ -159,13 +159,13 @@ bool TransformationReplaceLoadStoreWithCopyMemory::IsMemoryBarrierOpCode( } bool TransformationReplaceLoadStoreWithCopyMemory:: - IsStorageClassSafeAcrossMemoryBarriers(spv::StorageClass storage_class) { + IsStorageClassSafeAcrossMemoryBarriers(SpvStorageClass storage_class) { switch (storage_class) { - case spv::StorageClass::UniformConstant: - case spv::StorageClass::Input: - case spv::StorageClass::Uniform: - case spv::StorageClass::Private: - case spv::StorageClass::Function: + case SpvStorageClassUniformConstant: + case SpvStorageClassInput: + case SpvStorageClassUniform: + case SpvStorageClassPrivate: + case SpvStorageClassFunction: return true; default: return false; diff --git a/source/fuzz/transformation_replace_load_store_with_copy_memory.h b/source/fuzz/transformation_replace_load_store_with_copy_memory.h index 43c754e6..bb4d27ef 100644 --- a/source/fuzz/transformation_replace_load_store_with_copy_memory.h +++ b/source/fuzz/transformation_replace_load_store_with_copy_memory.h @@ -52,17 +52,17 @@ class TransformationReplaceLoadStoreWithCopyMemory : public Transformation { // Checks if the instruction that has an |op_code| might write to // the source operand of the OpLoad instruction. - static bool IsMemoryWritingOpCode(spv::Op op_code); + static bool IsMemoryWritingOpCode(SpvOp op_code); // Checks if the instruction that has an |op_code| is a memory barrier that // could interfere with the source operand of the OpLoad instruction - static bool IsMemoryBarrierOpCode(spv::Op op_code); + static bool IsMemoryBarrierOpCode(SpvOp op_code); // Checks if the |storage_class| of the source operand of the OpLoad // instruction implies that this variable cannot change (due to other threads) // across memory barriers. static bool IsStorageClassSafeAcrossMemoryBarriers( - spv::StorageClass storage_class); + SpvStorageClass storage_class); std::unordered_set GetFreshIds() const override; diff --git a/source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.cpp b/source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.cpp index eeda68df..84ca1aba 100644 --- a/source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.cpp +++ b/source/fuzz/transformation_replace_opphi_id_from_dead_predecessor.cpp @@ -38,7 +38,7 @@ bool TransformationReplaceOpPhiIdFromDeadPredecessor::IsApplicable( const TransformationContext& transformation_context) const { // |opphi_id| must be the id of an OpPhi instruction. auto opphi_def = ir_context->get_def_use_mgr()->GetDef(message_.opphi_id()); - if (!opphi_def || opphi_def->opcode() != spv::Op::OpPhi) { + if (!opphi_def || opphi_def->opcode() != SpvOpPhi) { return false; } diff --git a/source/fuzz/transformation_replace_opselect_with_conditional_branch.cpp b/source/fuzz/transformation_replace_opselect_with_conditional_branch.cpp index b2010a94..c0e6e449 100644 --- a/source/fuzz/transformation_replace_opselect_with_conditional_branch.cpp +++ b/source/fuzz/transformation_replace_opselect_with_conditional_branch.cpp @@ -50,7 +50,7 @@ bool TransformationReplaceOpSelectWithConditionalBranch::IsApplicable( ir_context->get_def_use_mgr()->GetDef(message_.select_id()); // The instruction must exist and it must be an OpSelect instruction. - if (!instruction || instruction->opcode() != spv::Op::OpSelect) { + if (!instruction || instruction->opcode() != SpvOpSelect) { return false; } @@ -90,7 +90,7 @@ bool TransformationReplaceOpSelectWithConditionalBranch::IsApplicable( // The predecessor must not be the header of a construct and it must end with // OpBranch. if (predecessor->GetMergeInst() != nullptr || - predecessor->terminator()->opcode() != spv::Op::OpBranch) { + predecessor->terminator()->opcode() != SpvOpBranch) { return false; } @@ -115,14 +115,13 @@ void TransformationReplaceOpSelectWithConditionalBranch::Apply( fuzzerutil::UpdateModuleIdBound(ir_context, id); // Create the new block. - auto new_block = MakeUnique( - MakeUnique(ir_context, spv::Op::OpLabel, 0, id, - opt::Instruction::OperandList{})); + auto new_block = MakeUnique(MakeUnique( + ir_context, SpvOpLabel, 0, id, opt::Instruction::OperandList{})); // Add an unconditional branch from the new block to the instruction // block. new_block->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {block->id()}}})); // Insert the new block right after the predecessor of the instruction @@ -137,11 +136,10 @@ void TransformationReplaceOpSelectWithConditionalBranch::Apply( // Add an OpSelectionMerge instruction to the predecessor block, where the // merge block is the instruction block. predecessor->AddInstruction(MakeUnique( - ir_context, spv::Op::OpSelectionMerge, 0, 0, - opt::Instruction::OperandList{ - {SPV_OPERAND_TYPE_ID, {block->id()}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}})); + ir_context, SpvOpSelectionMerge, 0, 0, + opt::Instruction::OperandList{{SPV_OPERAND_TYPE_ID, {block->id()}}, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, + {SpvSelectionControlMaskNone}}})); // |if_block| will be the true block, if it has been created, the instruction // block otherwise. @@ -160,7 +158,7 @@ void TransformationReplaceOpSelectWithConditionalBranch::Apply( // Add a conditional branching instruction to the predecessor, branching to // |if_block| if the condition is true and to |if_false| otherwise. predecessor->AddInstruction(MakeUnique( - ir_context, spv::Op::OpBranchConditional, 0, 0, + ir_context, SpvOpBranchConditional, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {instruction->GetSingleWordInOperand(0)}}, {SPV_OPERAND_TYPE_ID, {if_block}}, @@ -179,7 +177,7 @@ void TransformationReplaceOpSelectWithConditionalBranch::Apply( // Replace the OpSelect instruction in the merge block with an OpPhi. // This: OpSelect %type %cond %if %else // will become: OpPhi %type %if %if_pred %else %else_pred - instruction->SetOpcode(spv::Op::OpPhi); + instruction->SetOpcode(SpvOpPhi); std::vector operands; operands.emplace_back(instruction->GetInOperand(1)); diff --git a/source/fuzz/transformation_replace_parameter_with_global.cpp b/source/fuzz/transformation_replace_parameter_with_global.cpp index e80dfe90..caf67168 100644 --- a/source/fuzz/transformation_replace_parameter_with_global.cpp +++ b/source/fuzz/transformation_replace_parameter_with_global.cpp @@ -41,7 +41,7 @@ bool TransformationReplaceParameterWithGlobal::IsApplicable( // Check that |parameter_id| is valid. const auto* param_inst = ir_context->get_def_use_mgr()->GetDef(message_.parameter_id()); - if (!param_inst || param_inst->opcode() != spv::Op::OpFunctionParameter) { + if (!param_inst || param_inst->opcode() != SpvOpFunctionParameter) { return false; } @@ -69,7 +69,7 @@ bool TransformationReplaceParameterWithGlobal::IsApplicable( // Check that pointer type for the global variable exists in the module. if (!fuzzerutil::MaybeGetPointerType(ir_context, param_inst->type_id(), - spv::StorageClass::Private)) { + SpvStorageClassPrivate)) { return false; } @@ -91,8 +91,8 @@ void TransformationReplaceParameterWithGlobal::Apply( fuzzerutil::AddGlobalVariable( ir_context, message_.global_variable_fresh_id(), fuzzerutil::MaybeGetPointerType(ir_context, param_inst->type_id(), - spv::StorageClass::Private), - spv::StorageClass::Private, + SpvStorageClassPrivate), + SpvStorageClassPrivate, fuzzerutil::MaybeGetZeroConstant(ir_context, *transformation_context, param_inst->type_id(), false)); @@ -103,17 +103,16 @@ void TransformationReplaceParameterWithGlobal::Apply( // Insert an OpLoad instruction right after OpVariable instructions. auto it = function->begin()->begin(); while (it != function->begin()->end() && - !fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, it)) { + !fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, it)) { ++it; } - assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, it) && + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, it) && "Can't insert OpLoad or OpCopyMemory into the first basic block of " "the function"); it.InsertBefore(MakeUnique( - ir_context, spv::Op::OpLoad, param_inst->type_id(), - param_inst->result_id(), + ir_context, SpvOpLoad, param_inst->type_id(), param_inst->result_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.global_variable_fresh_id()}}})); @@ -133,14 +132,13 @@ void TransformationReplaceParameterWithGlobal::Apply( // Update all relevant OpFunctionCall instructions. for (auto* inst : fuzzerutil::GetCallers(ir_context, function->result_id())) { - assert( - fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpStore, inst) && - "Can't insert OpStore right before the function call"); + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore, inst) && + "Can't insert OpStore right before the function call"); // Insert an OpStore before the OpFunctionCall. +1 since the first // operand of OpFunctionCall is an id of the function. inst->InsertBefore(MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.global_variable_fresh_id()}}, {SPV_OPERAND_TYPE_ID, diff --git a/source/fuzz/transformation_replace_params_with_struct.cpp b/source/fuzz/transformation_replace_params_with_struct.cpp index c8af14ae..13eeccb4 100644 --- a/source/fuzz/transformation_replace_params_with_struct.cpp +++ b/source/fuzz/transformation_replace_params_with_struct.cpp @@ -142,7 +142,7 @@ void TransformationReplaceParamsWithStruct::Apply( // Add new parameter to the function. function->AddParameter(MakeUnique( - ir_context, spv::Op::OpFunctionParameter, struct_type_id, + ir_context, SpvOpFunctionParameter, struct_type_id, message_.fresh_parameter_id(), opt::Instruction::OperandList())); fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_parameter_id()); @@ -182,8 +182,8 @@ void TransformationReplaceParamsWithStruct::Apply( auto fresh_composite_id = caller_id_to_fresh_composite_id.at(inst->result_id()); inst->InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeConstruct, struct_type_id, - fresh_composite_id, std::move(composite_components))); + ir_context, SpvOpCompositeConstruct, struct_type_id, fresh_composite_id, + std::move(composite_components))); // Add a new operand to the OpFunctionCall instruction. inst->AddOperand({SPV_OPERAND_TYPE_ID, {fresh_composite_id}}); @@ -200,19 +200,19 @@ void TransformationReplaceParamsWithStruct::Apply( // Skip all OpVariable instructions. auto iter = function->begin()->begin(); while (iter != function->begin()->end() && - !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeExtract, iter)) { + !fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract, + iter)) { ++iter; } - assert(fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpCompositeExtract, iter) && + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract, + iter) && "Can't extract parameter's value from the structure"); // Insert OpCompositeExtract instructions to unpack parameters' values from // the struct type. iter.InsertBefore(MakeUnique( - ir_context, spv::Op::OpCompositeExtract, param_inst->type_id(), + ir_context, SpvOpCompositeExtract, param_inst->type_id(), param_inst->result_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.fresh_parameter_id()}}, diff --git a/source/fuzz/transformation_set_function_control.cpp b/source/fuzz/transformation_set_function_control.cpp index ef481719..02a8c9fe 100644 --- a/source/fuzz/transformation_set_function_control.cpp +++ b/source/fuzz/transformation_set_function_control.cpp @@ -40,9 +40,9 @@ bool TransformationSetFunctionControl::IsApplicable( // Check (via an assertion) that function control mask doesn't have any bad // bits set. - uint32_t acceptable_function_control_bits = uint32_t( - spv::FunctionControlMask::Inline | spv::FunctionControlMask::DontInline | - spv::FunctionControlMask::Pure | spv::FunctionControlMask::Const); + uint32_t acceptable_function_control_bits = + SpvFunctionControlInlineMask | SpvFunctionControlDontInlineMask | + SpvFunctionControlPureMask | SpvFunctionControlConstMask; // The following is to keep release-mode compilers happy as this variable is // only used in an assertion. (void)(acceptable_function_control_bits); @@ -51,19 +51,17 @@ bool TransformationSetFunctionControl::IsApplicable( // Check (via an assertion) that function control mask does not have both // Inline and DontInline bits set. - assert(!((message_.function_control() & - (uint32_t)spv::FunctionControlMask::Inline) && - (message_.function_control() & - (uint32_t)spv::FunctionControlMask::DontInline)) && + assert(!((message_.function_control() & SpvFunctionControlInlineMask) && + (message_.function_control() & SpvFunctionControlDontInlineMask)) && "It is not OK to set both the 'Inline' and 'DontInline' bits of a " "function control mask"); // Check that Const and Pure are only present if they were present on the // original function for (auto mask_bit : - {spv::FunctionControlMask::Pure, spv::FunctionControlMask::Const}) { - if ((message_.function_control() & uint32_t(mask_bit)) && - !(existing_function_control_mask & uint32_t(mask_bit))) { + {SpvFunctionControlPureMask, SpvFunctionControlConstMask}) { + if ((message_.function_control() & mask_bit) && + !(existing_function_control_mask & mask_bit)) { return false; } } diff --git a/source/fuzz/transformation_set_loop_control.cpp b/source/fuzz/transformation_set_loop_control.cpp index dc9ee7cf..14499606 100644 --- a/source/fuzz/transformation_set_loop_control.cpp +++ b/source/fuzz/transformation_set_loop_control.cpp @@ -38,20 +38,18 @@ bool TransformationSetLoopControl::IsApplicable( return false; } auto merge_inst = block->GetMergeInst(); - if (!merge_inst || merge_inst->opcode() != spv::Op::OpLoopMerge) { + if (!merge_inst || merge_inst->opcode() != SpvOpLoopMerge) { return false; } // We assert that the transformation does not try to set any meaningless bits // of the loop control mask. - uint32_t all_loop_control_mask_bits_set = uint32_t( - spv::LoopControlMask::Unroll | spv::LoopControlMask::DontUnroll | - spv::LoopControlMask::DependencyInfinite | - spv::LoopControlMask::DependencyLength | - spv::LoopControlMask::MinIterations | - spv::LoopControlMask::MaxIterations | - spv::LoopControlMask::IterationMultiple | - spv::LoopControlMask::PeelCount | spv::LoopControlMask::PartialCount); + uint32_t all_loop_control_mask_bits_set = + SpvLoopControlUnrollMask | SpvLoopControlDontUnrollMask | + SpvLoopControlDependencyInfiniteMask | + SpvLoopControlDependencyLengthMask | SpvLoopControlMinIterationsMask | + SpvLoopControlMaxIterationsMask | SpvLoopControlIterationMultipleMask | + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask; // The variable is only used in an assertion; the following keeps release-mode // compilers happy. @@ -67,11 +65,10 @@ bool TransformationSetLoopControl::IsApplicable( // Check that there is no attempt to set one of the loop controls that // requires guarantees to hold. - for (spv::LoopControlMask mask : {spv::LoopControlMask::DependencyInfinite, - spv::LoopControlMask::DependencyLength, - spv::LoopControlMask::MinIterations, - spv::LoopControlMask::MaxIterations, - spv::LoopControlMask::IterationMultiple}) { + for (SpvLoopControlMask mask : + {SpvLoopControlDependencyInfiniteMask, + SpvLoopControlDependencyLengthMask, SpvLoopControlMinIterationsMask, + SpvLoopControlMaxIterationsMask, SpvLoopControlIterationMultipleMask}) { // We have a problem if this loop control bit was not set in the original // loop control mask but is set by the transformation. if (LoopControlBitIsAddedByTransformation(mask, @@ -81,36 +78,33 @@ bool TransformationSetLoopControl::IsApplicable( } // Check that PeelCount and PartialCount are supported if used. - if ((message_.loop_control() & uint32_t(spv::LoopControlMask::PeelCount)) && + if ((message_.loop_control() & SpvLoopControlPeelCountMask) && !PeelCountIsSupported(ir_context)) { return false; } - if ((message_.loop_control() & - uint32_t(spv::LoopControlMask::PartialCount)) && + if ((message_.loop_control() & SpvLoopControlPartialCountMask) && !PartialCountIsSupported(ir_context)) { return false; } if (message_.peel_count() > 0 && - !(message_.loop_control() & uint32_t(spv::LoopControlMask::PeelCount))) { + !(message_.loop_control() & SpvLoopControlPeelCountMask)) { // Peel count provided, but peel count mask bit not set. return false; } if (message_.partial_count() > 0 && - !(message_.loop_control() & - uint32_t(spv::LoopControlMask::PartialCount))) { + !(message_.loop_control() & SpvLoopControlPartialCountMask)) { // Partial count provided, but partial count mask bit not set. return false; } // We must not set both 'don't unroll' and one of 'peel count' or 'partial // count'. - return !( - (message_.loop_control() & uint32_t(spv::LoopControlMask::DontUnroll)) && - (message_.loop_control() & uint32_t(spv::LoopControlMask::PeelCount | - spv::LoopControlMask::PartialCount))); + return !((message_.loop_control() & SpvLoopControlDontUnrollMask) && + (message_.loop_control() & + (SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask))); } void TransformationSetLoopControl::Apply( @@ -139,14 +133,13 @@ void TransformationSetLoopControl::Apply( uint32_t literal_index = 0; // Indexes into the literals from the original // instruction. - for (spv::LoopControlMask mask : {spv::LoopControlMask::DependencyLength, - spv::LoopControlMask::MinIterations, - spv::LoopControlMask::MaxIterations, - spv::LoopControlMask::IterationMultiple}) { + for (SpvLoopControlMask mask : + {SpvLoopControlDependencyLengthMask, SpvLoopControlMinIterationsMask, + SpvLoopControlMaxIterationsMask, SpvLoopControlIterationMultipleMask}) { // Check whether the bit was set in the original loop control mask. - if (existing_loop_control_mask & uint32_t(mask)) { + if (existing_loop_control_mask & mask) { // Check whether the bit is set in the new loop control mask. - if (message_.loop_control() & uint32_t(mask)) { + if (message_.loop_control() & mask) { // Add the associated literal to our sequence of replacement operands. new_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -161,13 +154,13 @@ void TransformationSetLoopControl::Apply( // If PeelCount is set in the new mask, |message_.peel_count| provides the // associated peel count. - if (message_.loop_control() & uint32_t(spv::LoopControlMask::PeelCount)) { + if (message_.loop_control() & SpvLoopControlPeelCountMask) { new_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.peel_count()}}); } // Similar, but for PartialCount. - if (message_.loop_control() & uint32_t(spv::LoopControlMask::PartialCount)) { + if (message_.loop_control() & SpvLoopControlPartialCountMask) { new_operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {message_.partial_count()}}); } @@ -184,11 +177,10 @@ protobufs::Transformation TransformationSetLoopControl::ToMessage() const { } bool TransformationSetLoopControl::LoopControlBitIsAddedByTransformation( - spv::LoopControlMask loop_control_single_bit_mask, + SpvLoopControlMask loop_control_single_bit_mask, uint32_t existing_loop_control_mask) const { - return !(uint32_t(loop_control_single_bit_mask) & - existing_loop_control_mask) && - (uint32_t(loop_control_single_bit_mask) & message_.loop_control()); + return !(loop_control_single_bit_mask & existing_loop_control_mask) && + (loop_control_single_bit_mask & message_.loop_control()); } bool TransformationSetLoopControl::PartialCountIsSupported( diff --git a/source/fuzz/transformation_set_loop_control.h b/source/fuzz/transformation_set_loop_control.h index d57447be..bc17c8a4 100644 --- a/source/fuzz/transformation_set_loop_control.h +++ b/source/fuzz/transformation_set_loop_control.h @@ -71,7 +71,7 @@ class TransformationSetLoopControl : public Transformation { // Returns true if and only if |loop_single_bit_mask| is *not* set in // |existing_loop_control| but *is* set in |message_.loop_control|. bool LoopControlBitIsAddedByTransformation( - spv::LoopControlMask loop_control_single_bit_mask, + SpvLoopControlMask loop_control_single_bit_mask, uint32_t existing_loop_control_mask) const; protobufs::TransformationSetLoopControl message_; diff --git a/source/fuzz/transformation_set_memory_operands_mask.cpp b/source/fuzz/transformation_set_memory_operands_mask.cpp index 16d591a6..5a986ad2 100644 --- a/source/fuzz/transformation_set_memory_operands_mask.cpp +++ b/source/fuzz/transformation_set_memory_operands_mask.cpp @@ -48,13 +48,10 @@ bool TransformationSetMemoryOperandsMask::IsApplicable( // which they were applied during fuzzing, hence why these are assertions // rather than applicability checks. assert(message_.memory_operands_mask_index() == 1); - assert( - spv::Op( - message_.memory_access_instruction().target_instruction_opcode()) == - spv::Op::OpCopyMemory || - spv::Op( - message_.memory_access_instruction().target_instruction_opcode()) == - spv::Op::OpCopyMemorySized); + assert(message_.memory_access_instruction().target_instruction_opcode() == + SpvOpCopyMemory || + message_.memory_access_instruction().target_instruction_opcode() == + SpvOpCopyMemorySized); assert(MultipleMemoryOperandMasksAreSupported(ir_context) && "Multiple memory operand masks are not supported for this SPIR-V " "version."); @@ -76,12 +73,12 @@ bool TransformationSetMemoryOperandsMask::IsApplicable( uint32_t original_mask = original_mask_in_operand_index < instruction->NumInOperands() ? instruction->GetSingleWordInOperand(original_mask_in_operand_index) - : static_cast(spv::MemoryAccessMask::MaskNone); + : static_cast(SpvMemoryAccessMaskNone); uint32_t new_mask = message_.memory_operands_mask(); // Volatile must not be removed - if ((original_mask & uint32_t(spv::MemoryAccessMask::Volatile)) && - !(new_mask & uint32_t(spv::MemoryAccessMask::Volatile))) { + if ((original_mask & SpvMemoryAccessVolatileMask) && + !(new_mask & SpvMemoryAccessVolatileMask)) { return false; } @@ -90,10 +87,10 @@ bool TransformationSetMemoryOperandsMask::IsApplicable( // their Volatile and Nontemporal flags to the same value (this works // because valid manipulation of Volatile is checked above, and the manner // in which Nontemporal is manipulated does not matter). - return (original_mask | uint32_t(spv::MemoryAccessMask::Volatile) | - uint32_t(spv::MemoryAccessMask::Nontemporal)) == - (new_mask | uint32_t(spv::MemoryAccessMask::Volatile) | - uint32_t(spv::MemoryAccessMask::Nontemporal)); + return (original_mask | SpvMemoryAccessVolatileMask | + SpvMemoryAccessNontemporalMask) == + (new_mask | SpvMemoryAccessVolatileMask | + SpvMemoryAccessNontemporalMask); } void TransformationSetMemoryOperandsMask::Apply( @@ -109,8 +106,8 @@ void TransformationSetMemoryOperandsMask::Apply( if (message_.memory_operands_mask_index() == 1 && GetInOperandIndexForMask(*instruction, 0) >= instruction->NumInOperands()) { - instruction->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, - {uint32_t(spv::MemoryAccessMask::MaskNone)}}); + instruction->AddOperand( + {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessMaskNone}}); } instruction->AddOperand( @@ -132,10 +129,10 @@ protobufs::Transformation TransformationSetMemoryOperandsMask::ToMessage() bool TransformationSetMemoryOperandsMask::IsMemoryAccess( const opt::Instruction& instruction) { switch (instruction.opcode()) { - case spv::Op::OpLoad: - case spv::Op::OpStore: - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpLoad: + case SpvOpStore: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: return true; default: return false; @@ -148,16 +145,16 @@ uint32_t TransformationSetMemoryOperandsMask::GetInOperandIndexForMask( // for the instruction. uint32_t first_mask_in_operand_index = 0; switch (instruction.opcode()) { - case spv::Op::OpLoad: + case SpvOpLoad: first_mask_in_operand_index = kOpLoadMemoryOperandsMaskIndex; break; - case spv::Op::OpStore: + case SpvOpStore: first_mask_in_operand_index = kOpStoreMemoryOperandsMaskIndex; break; - case spv::Op::OpCopyMemory: + case SpvOpCopyMemory: first_mask_in_operand_index = kOpCopyMemoryFirstMemoryOperandsMaskIndex; break; - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemorySized: first_mask_in_operand_index = kOpCopyMemorySizedFirstMemoryOperandsMaskIndex; break; @@ -195,12 +192,12 @@ uint32_t TransformationSetMemoryOperandsMask::GetInOperandIndexForMask( // Consider each bit that might have an associated extra input operand, and // count how many there are expected to be. uint32_t first_mask_extra_operand_count = 0; - for (auto mask_bit : {spv::MemoryAccessMask::Aligned, - spv::MemoryAccessMask::MakePointerAvailable, - spv::MemoryAccessMask::MakePointerAvailableKHR, - spv::MemoryAccessMask::MakePointerVisible, - spv::MemoryAccessMask::MakePointerVisibleKHR}) { - if (first_mask & uint32_t(mask_bit)) { + for (auto mask_bit : + {SpvMemoryAccessAlignedMask, SpvMemoryAccessMakePointerAvailableMask, + SpvMemoryAccessMakePointerAvailableKHRMask, + SpvMemoryAccessMakePointerVisibleMask, + SpvMemoryAccessMakePointerVisibleKHRMask}) { + if (first_mask & mask_bit) { first_mask_extra_operand_count++; } } diff --git a/source/fuzz/transformation_set_selection_control.cpp b/source/fuzz/transformation_set_selection_control.cpp index c6f68d9c..6dddbdf8 100644 --- a/source/fuzz/transformation_set_selection_control.cpp +++ b/source/fuzz/transformation_set_selection_control.cpp @@ -29,17 +29,14 @@ TransformationSetSelectionControl::TransformationSetSelectionControl( bool TransformationSetSelectionControl::IsApplicable( opt::IRContext* ir_context, const TransformationContext& /*unused*/) const { - assert((spv::SelectionControlMask(message_.selection_control()) == - spv::SelectionControlMask::MaskNone || - spv::SelectionControlMask(message_.selection_control()) == - spv::SelectionControlMask::Flatten || - spv::SelectionControlMask(message_.selection_control()) == - spv::SelectionControlMask::DontFlatten) && + assert((message_.selection_control() == SpvSelectionControlMaskNone || + message_.selection_control() == SpvSelectionControlFlattenMask || + message_.selection_control() == SpvSelectionControlDontFlattenMask) && "Selection control should never be set to something other than " "'None', 'Flatten' or 'DontFlatten'"); if (auto block = ir_context->get_instr_block(message_.block_id())) { if (auto merge_inst = block->GetMergeInst()) { - return merge_inst->opcode() == spv::Op::OpSelectionMerge; + return merge_inst->opcode() == SpvOpSelectionMerge; } } // Either the block did not exit, or did not end with OpSelectionMerge. diff --git a/source/fuzz/transformation_split_block.cpp b/source/fuzz/transformation_split_block.cpp index 959bedcd..e15dffa3 100644 --- a/source/fuzz/transformation_split_block.cpp +++ b/source/fuzz/transformation_split_block.cpp @@ -64,19 +64,19 @@ bool TransformationSplitBlock::IsApplicable( " block split point exists."); if (split_before->PreviousNode() && - split_before->PreviousNode()->opcode() == spv::Op::OpSelectionMerge) { + split_before->PreviousNode()->opcode() == SpvOpSelectionMerge) { // We cannot split directly after a selection merge: this would separate // the merge from its associated branch or switch operation. return false; } - if (split_before->opcode() == spv::Op::OpVariable) { + if (split_before->opcode() == SpvOpVariable) { // We cannot split directly after a variable; variables in a function // must be contiguous in the entry block. return false; } // We cannot split before an OpPhi unless the OpPhi has exactly one // associated incoming edge. - if (split_before->opcode() == spv::Op::OpPhi && + if (split_before->opcode() == SpvOpPhi && split_before->NumInOperands() != 2) { return false; } @@ -110,7 +110,7 @@ void TransformationSplitBlock::Apply( // The split does not automatically add a branch between the two parts of // the original block, so we add one. auto branch_instruction = MakeUnique( - ir_context, spv::Op::OpBranch, 0, 0, + ir_context, SpvOpBranch, 0, 0, std::initializer_list{opt::Operand( spv_operand_type_t::SPV_OPERAND_TYPE_ID, {message_.fresh_id()})}); auto branch_instruction_ptr = branch_instruction.get(); diff --git a/source/fuzz/transformation_store.cpp b/source/fuzz/transformation_store.cpp index 6ba1c551..c00cd345 100644 --- a/source/fuzz/transformation_store.cpp +++ b/source/fuzz/transformation_store.cpp @@ -48,7 +48,7 @@ bool TransformationStore::IsApplicable( // The pointer type must indeed be a pointer. auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id()); assert(pointer_type && "Type id must be defined."); - if (pointer_type->opcode() != spv::Op::OpTypePointer) { + if (pointer_type->opcode() != SpvOpTypePointer) { return false; } @@ -59,8 +59,8 @@ bool TransformationStore::IsApplicable( // We do not want to allow storing to null or undefined pointers. switch (pointer->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpUndef: + case SpvOpConstantNull: + case SpvOpUndef: return false; default: break; @@ -75,11 +75,11 @@ bool TransformationStore::IsApplicable( } // ... and it must be legitimate to insert a store before it. if (!message_.is_atomic() && !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpStore, insert_before)) { + SpvOpStore, insert_before)) { return false; } if (message_.is_atomic() && !fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpAtomicStore, insert_before)) { + SpvOpAtomicStore, insert_before)) { return false; } @@ -125,10 +125,10 @@ bool TransformationStore::IsApplicable( } // The memory scope and memory semantics instructions must have the // 'OpConstant' opcode. - if (memory_scope_instruction->opcode() != spv::Op::OpConstant) { + if (memory_scope_instruction->opcode() != SpvOpConstant) { return false; } - if (memory_semantics_instruction->opcode() != spv::Op::OpConstant) { + if (memory_semantics_instruction->opcode() != SpvOpConstant) { return false; } // The memory scope and memory semantics need to be available before @@ -145,12 +145,12 @@ bool TransformationStore::IsApplicable( // operand type with signedness does not matters. if (ir_context->get_def_use_mgr() ->GetDef(memory_scope_instruction->type_id()) - ->opcode() != spv::Op::OpTypeInt) { + ->opcode() != SpvOpTypeInt) { return false; } if (ir_context->get_def_use_mgr() ->GetDef(memory_semantics_instruction->type_id()) - ->opcode() != spv::Op::OpTypeInt) { + ->opcode() != SpvOpTypeInt) { return false; } @@ -172,20 +172,20 @@ bool TransformationStore::IsApplicable( return false; } - // The memory scope constant value must be that of spv::Scope::Invocation. + // The memory scope constant value must be that of SpvScopeInvocation. auto memory_scope_const_value = memory_scope_instruction->GetSingleWordInOperand(0); - if (spv::Scope(memory_scope_const_value) != spv::Scope::Invocation) { + if (memory_scope_const_value != SpvScopeInvocation) { return false; } // The memory semantics constant value must match the storage class of the // pointer being loaded from. - auto memory_semantics_const_value = static_cast( + auto memory_semantics_const_value = static_cast( memory_semantics_instruction->GetSingleWordInOperand(0)); if (memory_semantics_const_value != fuzzerutil::GetMemorySemanticsForStorageClass( - static_cast( + static_cast( pointer_type->GetSingleWordInOperand(0)))) { return false; } @@ -203,7 +203,7 @@ void TransformationStore::Apply(opt::IRContext* ir_context, auto insert_before = FindInstruction(message_.instruction_to_insert_before(), ir_context); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpAtomicStore, 0, 0, + ir_context, SpvOpAtomicStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_SCOPE_ID, {message_.memory_scope_id()}}, @@ -223,7 +223,7 @@ void TransformationStore::Apply(opt::IRContext* ir_context, auto insert_before = FindInstruction(message_.instruction_to_insert_before(), ir_context); auto new_instruction = MakeUnique( - ir_context, spv::Op::OpStore, 0, 0, + ir_context, SpvOpStore, 0, 0, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {message_.pointer_id()}}, {SPV_OPERAND_TYPE_ID, {message_.value_id()}}})); diff --git a/source/fuzz/transformation_store.h b/source/fuzz/transformation_store.h index 5b55ce6c..638713bb 100644 --- a/source/fuzz/transformation_store.h +++ b/source/fuzz/transformation_store.h @@ -38,7 +38,7 @@ class TransformationStore : public Transformation { // - |message_.is_atomic| must be true if want to work with OpAtomicStore. // - If |is_atomic| is true then |message_memory_scope_id| must be the id of // an OpConstant 32 bit integer instruction with the value - // spv::Scope::Invocation. + // SpvScopeInvocation. // - If |is_atomic| is true then |message_.memory_semantics_id| must be the id // of an OpConstant 32 bit integer instruction with the values // SpvMemorySemanticsWorkgroupMemoryMask or diff --git a/source/fuzz/transformation_swap_commutable_operands.cpp b/source/fuzz/transformation_swap_commutable_operands.cpp index 15121443..a02e95a0 100644 --- a/source/fuzz/transformation_swap_commutable_operands.cpp +++ b/source/fuzz/transformation_swap_commutable_operands.cpp @@ -35,9 +35,9 @@ bool TransformationSwapCommutableOperands::IsApplicable( FindInstruction(message_.instruction_descriptor(), ir_context); if (instruction == nullptr) return false; - spv::Op opcode = static_cast( + SpvOp opcode = static_cast( message_.instruction_descriptor().target_instruction_opcode()); - assert(spv::Op(instruction->opcode()) == opcode && + assert(instruction->opcode() == opcode && "The located instruction must have the same opcode as in the " "descriptor."); return spvOpcodeIsCommutativeBinaryOperator(opcode); diff --git a/source/fuzz/transformation_swap_conditional_branch_operands.cpp b/source/fuzz/transformation_swap_conditional_branch_operands.cpp index 520a6a8e..340836d1 100644 --- a/source/fuzz/transformation_swap_conditional_branch_operands.cpp +++ b/source/fuzz/transformation_swap_conditional_branch_operands.cpp @@ -38,7 +38,7 @@ bool TransformationSwapConditionalBranchOperands::IsApplicable( const auto* inst = FindInstruction(message_.instruction_descriptor(), ir_context); return fuzzerutil::IsFreshId(ir_context, message_.fresh_id()) && inst && - inst->opcode() == spv::Op::OpBranchConditional; + inst->opcode() == SpvOpBranchConditional; } void TransformationSwapConditionalBranchOperands::Apply( @@ -53,15 +53,13 @@ void TransformationSwapConditionalBranchOperands::Apply( // Compute the last instruction in the |block| that allows us to insert // OpLogicalNot above it. auto iter = fuzzerutil::GetIteratorForInstruction(block, branch_inst); - if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLogicalNot, - iter)) { + if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLogicalNot, iter)) { // There might be a merge instruction before OpBranchConditional. --iter; } - assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLogicalNot, - iter) && - "We should now be able to insert spv::Op::OpLogicalNot before |iter|"); + assert(fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLogicalNot, iter) && + "We should now be able to insert SpvOpLogicalNot before |iter|"); // Get the instruction whose result is used as a condition for // OpBranchConditional. @@ -72,7 +70,7 @@ void TransformationSwapConditionalBranchOperands::Apply( // We are swapping the labels in OpBranchConditional. This means that we must // invert the guard as well. We are using OpLogicalNot for that purpose here. auto new_instruction = MakeUnique( - ir_context, spv::Op::OpLogicalNot, condition_inst->type_id(), + ir_context, SpvOpLogicalNot, condition_inst->type_id(), message_.fresh_id(), opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {condition_inst->result_id()}}}); diff --git a/source/fuzz/transformation_swap_function_variables.cpp b/source/fuzz/transformation_swap_function_variables.cpp index 14ba7bb7..aec32fe1 100644 --- a/source/fuzz/transformation_swap_function_variables.cpp +++ b/source/fuzz/transformation_swap_function_variables.cpp @@ -43,8 +43,8 @@ bool TransformationSwapFunctionVariables::IsApplicable( return false; } // Both instructions must be variables. - if (instruction1->opcode() != spv::Op::OpVariable || - instruction2->opcode() != spv::Op::OpVariable) { + if (instruction1->opcode() != SpvOpVariable || + instruction2->opcode() != SpvOpVariable) { return false; } diff --git a/source/fuzz/transformation_toggle_access_chain_instruction.cpp b/source/fuzz/transformation_toggle_access_chain_instruction.cpp index ae6ab9ad..34523fe8 100644 --- a/source/fuzz/transformation_toggle_access_chain_instruction.cpp +++ b/source/fuzz/transformation_toggle_access_chain_instruction.cpp @@ -39,15 +39,14 @@ bool TransformationToggleAccessChainInstruction::IsApplicable( return false; } - spv::Op opcode = static_cast( + SpvOp opcode = static_cast( message_.instruction_descriptor().target_instruction_opcode()); assert(instruction->opcode() == opcode && "The located instruction must have the same opcode as in the " "descriptor."); - if (opcode == spv::Op::OpAccessChain || - opcode == spv::Op::OpInBoundsAccessChain) { + if (opcode == SpvOpAccessChain || opcode == SpvOpInBoundsAccessChain) { return true; } @@ -58,15 +57,15 @@ void TransformationToggleAccessChainInstruction::Apply( opt::IRContext* ir_context, TransformationContext* /*unused*/) const { auto instruction = FindInstruction(message_.instruction_descriptor(), ir_context); - spv::Op opcode = instruction->opcode(); + SpvOp opcode = instruction->opcode(); - if (opcode == spv::Op::OpAccessChain) { - instruction->SetOpcode(spv::Op::OpInBoundsAccessChain); + if (opcode == SpvOpAccessChain) { + instruction->SetOpcode(SpvOpInBoundsAccessChain); } else { - assert(opcode == spv::Op::OpInBoundsAccessChain && + assert(opcode == SpvOpInBoundsAccessChain && "The located instruction must be an OpInBoundsAccessChain " "instruction."); - instruction->SetOpcode(spv::Op::OpAccessChain); + instruction->SetOpcode(SpvOpAccessChain); } } diff --git a/source/fuzz/transformation_vector_shuffle.cpp b/source/fuzz/transformation_vector_shuffle.cpp index 8ba557c9..742a2c80 100644 --- a/source/fuzz/transformation_vector_shuffle.cpp +++ b/source/fuzz/transformation_vector_shuffle.cpp @@ -108,7 +108,7 @@ bool TransformationVectorShuffle::IsApplicable( // It must be legitimate to insert an OpVectorShuffle before the identified // instruction. return fuzzerutil::CanInsertOpcodeBeforeInstruction( - spv::Op::OpVectorShuffle, instruction_to_insert_before); + SpvOpVectorShuffle, instruction_to_insert_before); } void TransformationVectorShuffle::Apply( @@ -134,8 +134,8 @@ void TransformationVectorShuffle::Apply( FindInstruction(message_.instruction_to_insert_before(), ir_context); opt::Instruction* new_instruction = insert_before->InsertBefore(MakeUnique( - ir_context, spv::Op::OpVectorShuffle, result_type_id, - message_.fresh_id(), shuffle_operands)); + ir_context, SpvOpVectorShuffle, result_type_id, message_.fresh_id(), + shuffle_operands)); fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id()); // Inform the def-use manager about the new instruction and record its basic // block. diff --git a/source/fuzz/transformation_wrap_early_terminator_in_function.cpp b/source/fuzz/transformation_wrap_early_terminator_in_function.cpp index f59d78ad..468d809f 100644 --- a/source/fuzz/transformation_wrap_early_terminator_in_function.cpp +++ b/source/fuzz/transformation_wrap_early_terminator_in_function.cpp @@ -52,9 +52,9 @@ bool TransformationWrapEarlyTerminatorInFunction::IsApplicable( return false; } switch (early_terminator->opcode()) { - case spv::Op::OpKill: - case spv::Op::OpUnreachable: - case spv::Op::OpTerminateInvocation: + case SpvOpKill: + case SpvOpUnreachable: + case SpvOpTerminateInvocation: break; default: return false; @@ -119,7 +119,7 @@ void TransformationWrapEarlyTerminatorInFunction::Apply( MaybeGetWrapperFunction(ir_context, early_terminator->opcode()); iterator->InsertBefore(MakeUnique( - ir_context, spv::Op::OpFunctionCall, wrapper_function->type_id(), + ir_context, SpvOpFunctionCall, wrapper_function->type_id(), message_.fresh_id(), opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_ID, {wrapper_function->result_id()}}}))); @@ -130,9 +130,9 @@ void TransformationWrapEarlyTerminatorInFunction::Apply( ->AsVoid()) { new_in_operands.push_back( {SPV_OPERAND_TYPE_ID, {message_.returned_value_id()}}); - early_terminator->SetOpcode(spv::Op::OpReturnValue); + early_terminator->SetOpcode(SpvOpReturnValue); } else { - early_terminator->SetOpcode(spv::Op::OpReturn); + early_terminator->SetOpcode(SpvOpReturn); } early_terminator->SetInOperands(std::move(new_in_operands)); @@ -153,10 +153,10 @@ TransformationWrapEarlyTerminatorInFunction::ToMessage() const { opt::Function* TransformationWrapEarlyTerminatorInFunction::MaybeGetWrapperFunction( - opt::IRContext* ir_context, spv::Op early_terminator_opcode) { - assert((early_terminator_opcode == spv::Op::OpKill || - early_terminator_opcode == spv::Op::OpUnreachable || - early_terminator_opcode == spv::Op::OpTerminateInvocation) && + opt::IRContext* ir_context, SpvOp early_terminator_opcode) { + assert((early_terminator_opcode == SpvOpKill || + early_terminator_opcode == SpvOpUnreachable || + early_terminator_opcode == SpvOpTerminateInvocation) && "Invalid opcode."); auto void_type_id = fuzzerutil::MaybeGetVoidType(ir_context); if (!void_type_id) { diff --git a/source/fuzz/transformation_wrap_early_terminator_in_function.h b/source/fuzz/transformation_wrap_early_terminator_in_function.h index d824783b..d6e55517 100644 --- a/source/fuzz/transformation_wrap_early_terminator_in_function.h +++ b/source/fuzz/transformation_wrap_early_terminator_in_function.h @@ -60,8 +60,8 @@ class TransformationWrapEarlyTerminatorInFunction : public Transformation { protobufs::Transformation ToMessage() const override; - static opt::Function* MaybeGetWrapperFunction( - opt::IRContext* ir_context, spv::Op early_terminator_opcode); + static opt::Function* MaybeGetWrapperFunction(opt::IRContext* ir_context, + SpvOp early_terminator_opcode); private: protobufs::TransformationWrapEarlyTerminatorInFunction message_; diff --git a/source/fuzz/transformation_wrap_region_in_selection.cpp b/source/fuzz/transformation_wrap_region_in_selection.cpp index a63d1ac5..01c98cca 100644 --- a/source/fuzz/transformation_wrap_region_in_selection.cpp +++ b/source/fuzz/transformation_wrap_region_in_selection.cpp @@ -53,14 +53,14 @@ void TransformationWrapRegionInSelection::Apply( TransformationContext* transformation_context) const { auto* new_header_block = ir_context->cfg()->block(message_.region_entry_block_id()); - assert(new_header_block->terminator()->opcode() == spv::Op::OpBranch && + assert(new_header_block->terminator()->opcode() == SpvOpBranch && "This condition should have been checked in the IsApplicable"); const auto successor_id = new_header_block->terminator()->GetSingleWordInOperand(0); // Change |entry_block|'s terminator to |OpBranchConditional|. - new_header_block->terminator()->SetOpcode(spv::Op::OpBranchConditional); + new_header_block->terminator()->SetOpcode(SpvOpBranchConditional); new_header_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {fuzzerutil::MaybeGetBoolConstant(ir_context, *transformation_context, @@ -70,11 +70,11 @@ void TransformationWrapRegionInSelection::Apply( // Insert OpSelectionMerge before the terminator. new_header_block->terminator()->InsertBefore(MakeUnique( - ir_context, spv::Op::OpSelectionMerge, 0, 0, + ir_context, SpvOpSelectionMerge, 0, 0, opt::Instruction::OperandList{ {SPV_OPERAND_TYPE_ID, {message_.region_exit_block_id()}}, {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}})); + {SpvSelectionControlMaskNone}}})); // We've change the module so we must invalidate analyses. ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); @@ -130,7 +130,7 @@ bool TransformationWrapRegionInSelection::IsApplicableToBlockRange( } // |header_block_candidate| must have an OpBranch terminator. - if (header_block_candidate->terminator()->opcode() != spv::Op::OpBranch) { + if (header_block_candidate->terminator()->opcode() != SpvOpBranch) { return false; } diff --git a/source/fuzz/transformation_wrap_vector_synonym.cpp b/source/fuzz/transformation_wrap_vector_synonym.cpp index 3b1543dd..490bcd78 100644 --- a/source/fuzz/transformation_wrap_vector_synonym.cpp +++ b/source/fuzz/transformation_wrap_vector_synonym.cpp @@ -83,7 +83,7 @@ bool TransformationWrapVectorSynonym::IsApplicable( } auto vec1_type = ir_context->get_def_use_mgr()->GetDef(vec1_type_id); - if (vec1_type->opcode() != spv::Op::OpTypeVector) { + if (vec1_type->opcode() != SpvOpTypeVector) { return false; } @@ -178,18 +178,18 @@ bool TransformationWrapVectorSynonym::IsInstructionSupported( auto type_instruction = ir_context->get_def_use_mgr()->GetDef(instruction.type_id()); - if ((type_instruction->opcode() != spv::Op::OpTypeInt && - type_instruction->opcode() != spv::Op::OpTypeFloat)) { + if ((type_instruction->opcode() != SpvOpTypeInt && + type_instruction->opcode() != SpvOpTypeFloat)) { return false; } switch (instruction.opcode()) { - case spv::Op::OpIAdd: - case spv::Op::OpISub: - case spv::Op::OpIMul: - case spv::Op::OpFAdd: - case spv::Op::OpFSub: - case spv::Op::OpFMul: + case SpvOpIAdd: + case SpvOpISub: + case SpvOpIMul: + case SpvOpFAdd: + case SpvOpFSub: + case SpvOpFMul: return true; default: return false; diff --git a/source/fuzz/uniform_buffer_element_descriptor.cpp b/source/fuzz/uniform_buffer_element_descriptor.cpp index 55e84de8..90fd85e9 100644 --- a/source/fuzz/uniform_buffer_element_descriptor.cpp +++ b/source/fuzz/uniform_buffer_element_descriptor.cpp @@ -49,11 +49,10 @@ opt::Instruction* FindUniformVariable( for (auto& inst : context->types_values()) { // Consider all global variables with uniform storage class. - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { continue; } - if (spv::StorageClass(inst.GetSingleWordInOperand(0)) != - spv::StorageClass::Uniform) { + if (inst.GetSingleWordInOperand(0) != SpvStorageClassUniform) { continue; } @@ -61,7 +60,7 @@ opt::Instruction* FindUniformVariable( // matching that in |uniform_buffer_element|. bool descriptor_set_matches = false; context->get_decoration_mgr()->ForEachDecoration( - inst.result_id(), uint32_t(spv::Decoration::DescriptorSet), + inst.result_id(), SpvDecorationDescriptorSet, [&descriptor_set_matches, &uniform_buffer_element_descriptor]( const opt::Instruction& decoration_inst) { const uint32_t kDescriptorSetOperandIndex = 2; @@ -80,7 +79,7 @@ opt::Instruction* FindUniformVariable( // in |uniform_buffer_element|. bool binding_matches = false; context->get_decoration_mgr()->ForEachDecoration( - inst.result_id(), uint32_t(spv::Decoration::Binding), + inst.result_id(), SpvDecorationBinding, [&binding_matches, &uniform_buffer_element_descriptor]( const opt::Instruction& decoration_inst) { const uint32_t kBindingOperandIndex = 2; diff --git a/source/instruction.h b/source/instruction.h index 2acbb572..9e7dccd0 100644 --- a/source/instruction.h +++ b/source/instruction.h @@ -26,7 +26,7 @@ struct spv_instruction_t { // Normally, both opcode and extInstType contain valid data. // However, when the assembler parses ! as the first word in // an instruction and opcode and extInstType are invalid. - spv::Op opcode; + SpvOp opcode; spv_ext_inst_type_t extInstType; // The Id of the result type, if this instruction has one. Zero otherwise. diff --git a/source/latest_version_spirv_header.h b/source/latest_version_spirv_header.h index f6ab5c84..e4f28e43 100644 --- a/source/latest_version_spirv_header.h +++ b/source/latest_version_spirv_header.h @@ -15,6 +15,6 @@ #ifndef SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ #define SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ -#include "spirv/unified1/spirv.hpp11" +#include "spirv/unified1/spirv.h" #endif // SOURCE_LATEST_VERSION_SPIRV_HEADER_H_ diff --git a/source/libspirv.cpp b/source/libspirv.cpp index 83e8629b..be76caaa 100644 --- a/source/libspirv.cpp +++ b/source/libspirv.cpp @@ -108,40 +108,6 @@ bool SpirvTools::Disassemble(const uint32_t* binary, const size_t binary_size, return status == SPV_SUCCESS; } -struct CxxParserContext { - const HeaderParser& header_parser; - const InstructionParser& instruction_parser; -}; - -bool SpirvTools::Parse(const std::vector& binary, - const HeaderParser& header_parser, - const InstructionParser& instruction_parser, - spv_diagnostic* diagnostic) { - CxxParserContext parser_context = {header_parser, instruction_parser}; - - spv_parsed_header_fn_t header_fn_wrapper = - [](void* user_data, spv_endianness_t endianness, uint32_t magic, - uint32_t version, uint32_t generator, uint32_t id_bound, - uint32_t reserved) { - CxxParserContext* ctx = reinterpret_cast(user_data); - spv_parsed_header_t header = {magic, version, generator, id_bound, - reserved}; - - return ctx->header_parser(endianness, header); - }; - - spv_parsed_instruction_fn_t instruction_fn_wrapper = - [](void* user_data, const spv_parsed_instruction_t* instruction) { - CxxParserContext* ctx = reinterpret_cast(user_data); - return ctx->instruction_parser(*instruction); - }; - - spv_result_t status = spvBinaryParse( - impl_->context, &parser_context, binary.data(), binary.size(), - header_fn_wrapper, instruction_fn_wrapper, diagnostic); - return status == SPV_SUCCESS; -} - bool SpirvTools::Validate(const std::vector& binary) const { return Validate(binary.data(), binary.size()); } diff --git a/source/link/BUILD.gn b/source/link/BUILD.gn index 09ea68f6..cba0cb7d 100644 --- a/source/link/BUILD.gn +++ b/source/link/BUILD.gn @@ -26,57 +26,8 @@ config("deqp_spirvtool_link_config") { ] } -config("spv_headers_public_config") { - include_dirs = [ "include" ] -} - -config("spvtools_include_gen_dirs") { - include_dirs = [ "$target_gen_dir" ] -} - -config("spvtools_internal_config") { - include_dirs = [ - ".", - "//third_party/spirv-headers/include", - ] - - configs = [ - ":spv_headers_public_config", - ":spvtools_include_gen_dirs", - ] - - cflags = [] - if (is_clang) { - cflags += [ - "-Wno-implicit-fallthrough", - "-Wno-newline-eof", - "-Wno-unreachable-code-break", - "-Wno-unreachable-code-return", - ] - } else if (!is_win) { - # Work around a false-positive on a Skia GCC 10 builder. - cflags += [ "-Wno-format-truncation" ] - } else { - # Make MSVC report the correct value for __cplusplus - cflags += [ "/Zc:__cplusplus" ] - } - - if (!is_win) { - cflags += [ "-std=c++17" ] - } else { - cflags += [ "/std:c++17" ] - } -} - ohos_source_set("deqp_spirvtool_link_source") { - sources = [ - "//third_party/spirv-tools/include/spirv-tools/instrument.hpp", - "//third_party/spirv-tools/include/spirv-tools/libspirv.h", - "//third_party/spirv-tools/include/spirv-tools/libspirv.hpp", - "//third_party/spirv-tools/include/spirv-tools/linker.hpp", - "//third_party/spirv-tools/include/spirv-tools/optimizer.hpp", - "//third_party/spirv-tools/source/link/linker.cpp", - ] + sources = [ "//third_party/spirv-tools/source/link/linker.cpp" ] include_dirs = deqp_common_include_dirs include_dirs += [ @@ -87,14 +38,7 @@ ohos_source_set("deqp_spirvtool_link_source") { "//third_party/spirv-tools/include", ] - if (build_with_chromium) { - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - } - configs = [ ":deqp_spirvtool_link_config" ] - configs += [ ":spv_headers_public_config" ] - configs += [ ":spvtools_internal_config" ] } ohos_static_library("libdeqp_spirvtools-link") { @@ -102,7 +46,6 @@ ohos_static_library("libdeqp_spirvtools-link") { ":deqp_spirvtool_link_source", "//third_party/spirv-tools:libdeqp_spirvtools", "//third_party/spirv-tools/source/opt:libdeqp_spirvtools-opt", - "//third_party/spirv-tools/source/val:libdeqp_spirvtools-val", ] part_name = "graphic_2d" subsystem_name = "graphic" diff --git a/source/link/CMakeLists.txt b/source/link/CMakeLists.txt index a35b9a58..a452a107 100644 --- a/source/link/CMakeLists.txt +++ b/source/link/CMakeLists.txt @@ -31,7 +31,10 @@ set_property(TARGET SPIRV-Tools-link PROPERTY FOLDER "SPIRV-Tools libraries") spvtools_check_symbol_exports(SPIRV-Tools-link) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-link EXPORT SPIRV-Tools-linkTargets) + install(TARGETS SPIRV-Tools-link EXPORT SPIRV-Tools-linkTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-linkTargets FILE SPIRV-Tools-linkTargets.cmake) spvtools_config_package_dir(SPIRV-Tools-link PACKAGE_DIR) diff --git a/source/link/linker.cpp b/source/link/linker.cpp index 58930e45..3b388cc6 100644 --- a/source/link/linker.cpp +++ b/source/link/linker.cpp @@ -57,12 +57,12 @@ using opt::analysis::TypeManager; // Stores various information about an imported or exported symbol. struct LinkageSymbolInfo { - spv::Id id; // ID of the symbol - spv::Id type_id; // ID of the type of the symbol + SpvId id; // ID of the symbol + SpvId type_id; // ID of the type of the symbol std::string name; // unique name defining the symbol and used for matching // imports and exports together - std::vector parameter_ids; // ID of the parameters of the symbol, if - // it is a function + std::vector parameter_ids; // ID of the parameters of the symbol, if + // it is a function }; struct LinkageEntry { LinkageSymbolInfo imported_symbol; @@ -91,8 +91,7 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer, // should be non-null. |max_id_bound| should be strictly greater than 0. spv_result_t GenerateHeader(const MessageConsumer& consumer, const std::vector& modules, - uint32_t max_id_bound, opt::ModuleHeader* header, - const LinkerOptions& options); + uint32_t max_id_bound, opt::ModuleHeader* header); // Merge all the modules from |in_modules| into a single module owned by // |linked_context|. @@ -203,8 +202,7 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer, spv_result_t GenerateHeader(const MessageConsumer& consumer, const std::vector& modules, - uint32_t max_id_bound, opt::ModuleHeader* header, - const LinkerOptions& options) { + uint32_t max_id_bound, opt::ModuleHeader* header) { spv_position_t position = {}; if (modules.empty()) @@ -214,12 +212,10 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer, return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA) << "|max_id_bound| of GenerateHeader should not be null."; - uint32_t linked_version = modules.front()->version(); + const uint32_t linked_version = modules.front()->version(); for (std::size_t i = 1; i < modules.size(); ++i) { const uint32_t module_version = modules[i]->version(); - if (options.GetUseHighestVersion()) { - linked_version = std::max(linked_version, module_version); - } else if (module_version != linked_version) { + if (module_version != linked_version) return DiagnosticStream({0, 0, 1}, consumer, "", SPV_ERROR_INTERNAL) << "Conflicting SPIR-V versions: " << SPV_SPIRV_VERSION_MAJOR_PART(linked_version) << "." @@ -228,10 +224,9 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer, << SPV_SPIRV_VERSION_MAJOR_PART(module_version) << "." << SPV_SPIRV_VERSION_MINOR_PART(module_version) << " (input module " << (i + 1) << ")."; - } } - header->magic_number = spv::MagicNumber; + header->magic_number = SpvMagicNumber; header->version = linked_version; header->generator = SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_LINKER, 0); header->bound = max_id_bound; @@ -372,7 +367,7 @@ spv_result_t MergeModules(const MessageConsumer& consumer, std::vector processed_words = spvtools::utils::MakeVector(processed_string); linked_module->AddDebug3Inst(std::unique_ptr( - new Instruction(linked_context, spv::Op::OpModuleProcessed, 0u, 0u, + new Instruction(linked_context, SpvOpModuleProcessed, 0u, 0u, {{SPV_OPERAND_TYPE_LITERAL_STRING, processed_words}}))); } @@ -382,7 +377,7 @@ spv_result_t MergeModules(const MessageConsumer& consumer, std::unique_ptr(inst.Clone(linked_context))); // TODO(pierremoreau): Since the modules have not been validate, should we - // expect spv::StorageClass::Function variables outside + // expect SpvStorageClassFunction variables outside // functions? for (const auto& module : input_modules) { for (const auto& inst : module->types_values()) { @@ -419,18 +414,16 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, // Figure out the imports and exports for (const auto& decoration : linked_context.annotations()) { - if (decoration.opcode() != spv::Op::OpDecorate || - spv::Decoration(decoration.GetSingleWordInOperand(1u)) != - spv::Decoration::LinkageAttributes) + if (decoration.opcode() != SpvOpDecorate || + decoration.GetSingleWordInOperand(1u) != SpvDecorationLinkageAttributes) continue; - const spv::Id id = decoration.GetSingleWordInOperand(0u); + const SpvId id = decoration.GetSingleWordInOperand(0u); // Ignore if the targeted symbol is a built-in bool is_built_in = false; for (const auto& id_decoration : decoration_manager.GetDecorationsFor(id, false)) { - if (spv::Decoration(id_decoration->GetSingleWordInOperand(1u)) == - spv::Decoration::BuiltIn) { + if (id_decoration->GetSingleWordInOperand(1u) == SpvDecorationBuiltIn) { is_built_in = true; break; } @@ -454,9 +447,9 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY) << "ID " << id << " is never defined:\n"; - if (def_inst->opcode() == spv::Op::OpVariable) { + if (def_inst->opcode() == SpvOpVariable) { symbol_info.type_id = def_inst->type_id(); - } else if (def_inst->opcode() == spv::Op::OpFunction) { + } else if (def_inst->opcode() == SpvOpFunction) { symbol_info.type_id = def_inst->GetSingleWordInOperand(1u); // range-based for loop calls begin()/end(), but never cbegin()/cend(), @@ -474,9 +467,9 @@ spv_result_t GetImportExportPairs(const MessageConsumer& consumer, << " LinkageAttributes; " << id << " is neither of them.\n"; } - if (spv::LinkageType(type) == spv::LinkageType::Import) + if (type == SpvLinkageTypeImport) imports.push_back(symbol_info); - else if (spv::LinkageType(type) == spv::LinkageType::Export) + else if (type == SpvLinkageTypeExport) exports[symbol_info.name].push_back(symbol_info); } @@ -592,7 +585,7 @@ spv_result_t RemoveLinkageSpecificInstructions( // TODO(pierremoreau): This will not work if the decoration is applied // through a group, but the linker does not support that // either. - std::unordered_set imports; + std::unordered_set imports; if (options.GetAllowPartialLinkage()) { imports.reserve(linkings_to_do.size()); for (const auto& linking_entry : linkings_to_do) @@ -608,11 +601,9 @@ spv_result_t RemoveLinkageSpecificInstructions( // * if we do not allow partial linkage, remove all import annotations; // * otherwise, remove the annotation only if there was a corresponding // export. - if (inst->opcode() == spv::Op::OpDecorate && - spv::Decoration(inst->GetSingleWordOperand(1u)) == - spv::Decoration::LinkageAttributes && - spv::LinkageType(inst->GetSingleWordOperand(3u)) == - spv::LinkageType::Import && + if (inst->opcode() == SpvOpDecorate && + inst->GetSingleWordOperand(1u) == SpvDecorationLinkageAttributes && + inst->GetSingleWordOperand(3u) == SpvLinkageTypeImport && (!options.GetAllowPartialLinkage() || imports.find(inst->GetSingleWordOperand(0u)) != imports.end())) { linked_context->KillInst(&*inst); @@ -625,11 +616,9 @@ spv_result_t RemoveLinkageSpecificInstructions( for (auto inst = next; inst != linked_context->annotation_end(); inst = next) { ++next; - if (inst->opcode() == spv::Op::OpDecorate && - spv::Decoration(inst->GetSingleWordOperand(1u)) == - spv::Decoration::LinkageAttributes && - spv::LinkageType(inst->GetSingleWordOperand(3u)) == - spv::LinkageType::Export) { + if (inst->opcode() == SpvOpDecorate && + inst->GetSingleWordOperand(1u) == SpvDecorationLinkageAttributes && + inst->GetSingleWordOperand(3u) == SpvLinkageTypeExport) { linked_context->KillInst(&*inst); } } @@ -639,11 +628,10 @@ spv_result_t RemoveLinkageSpecificInstructions( // not allowed if (!options.GetCreateLibrary() && !options.GetAllowPartialLinkage()) { for (auto& inst : linked_context->capabilities()) - if (spv::Capability(inst.GetSingleWordInOperand(0u)) == - spv::Capability::Linkage) { + if (inst.GetSingleWordInOperand(0u) == SpvCapabilityLinkage) { linked_context->KillInst(&inst); // The RemoveDuplicatesPass did remove duplicated capabilities, so we - // now there aren’t more spv::Capability::Linkage further down. + // now there aren’t more SpvCapabilityLinkage further down. break; } } @@ -683,7 +671,7 @@ spv_result_t VerifyLimits(const MessageConsumer& consumer, size_t num_global_values = 0u; for (const auto& inst : linked_context.module()->types_values()) { - num_global_values += inst.opcode() == spv::Op::OpVariable; + num_global_values += inst.opcode() == SpvOpVariable; } if (num_global_values >= SPV_LIMIT_GLOBAL_VARIABLES_MAX) DiagnosticStream(position, consumer, "", SPV_WARNING) @@ -758,7 +746,7 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries, // Phase 2: Generate the header opt::ModuleHeader header; - res = GenerateHeader(consumer, modules, max_id_bound, &header, options); + res = GenerateHeader(consumer, modules, max_id_bound, &header); if (res != SPV_SUCCESS) return res; IRContext linked_context(c_context->target_env, consumer); linked_context.module()->SetHeader(header); diff --git a/source/lint/CMakeLists.txt b/source/lint/CMakeLists.txt index 4704beb1..1feae3f9 100644 --- a/source/lint/CMakeLists.txt +++ b/source/lint/CMakeLists.txt @@ -46,7 +46,10 @@ set_property(TARGET SPIRV-Tools-lint PROPERTY FOLDER "SPIRV-Tools libraries") spvtools_check_symbol_exports(SPIRV-Tools-lint) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-lint EXPORT SPIRV-Tools-lintTargets) + install(TARGETS SPIRV-Tools-lint EXPORT SPIRV-Tools-lintTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-lintTargets FILE SPIRV-Tools-lintTargets.cmake) spvtools_config_package_dir(SPIRV-Tools-lint PACKAGE_DIR) diff --git a/source/lint/divergence_analysis.cpp b/source/lint/divergence_analysis.cpp index fe32e1ac..b5a72b45 100644 --- a/source/lint/divergence_analysis.cpp +++ b/source/lint/divergence_analysis.cpp @@ -19,6 +19,7 @@ #include "source/opt/dataflow.h" #include "source/opt/function.h" #include "source/opt/instruction.h" +#include "spirv/unified1/spirv.h" namespace spvtools { namespace lint { @@ -31,7 +32,7 @@ void DivergenceAnalysis::EnqueueSuccessors(opt::Instruction* inst) { uint32_t block_id; if (inst->IsBlockTerminator()) { block_id = context().get_instr_block(inst)->id(); - } else if (inst->opcode() == spv::Op::OpLabel) { + } else if (inst->opcode() == SpvOpLabel) { block_id = inst->result_id(); opt::BasicBlock* bb = context().cfg()->block(block_id); // Only enqueue phi instructions, as other uses don't affect divergence. @@ -53,7 +54,7 @@ void DivergenceAnalysis::EnqueueSuccessors(opt::Instruction* inst) { opt::DataFlowAnalysis::VisitResult DivergenceAnalysis::Visit( opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpLabel) { + if (inst->opcode() == SpvOpLabel) { return VisitBlock(inst->result_id()); } else { return VisitInstruction(inst); @@ -127,12 +128,12 @@ DivergenceAnalysis::ComputeInstructionDivergence(opt::Instruction* inst) { // Device/QueueFamily could satisfy fully uniform. uint32_t id = inst->result_id(); // Handle divergence roots. - if (inst->opcode() == spv::Op::OpFunctionParameter) { + if (inst->opcode() == SpvOpFunctionParameter) { divergence_source_[id] = 0; return divergence_[id] = DivergenceLevel::kDivergent; } else if (inst->IsLoad()) { spvtools::opt::Instruction* var = inst->GetBaseAddress(); - if (var->opcode() != spv::Op::OpVariable) { + if (var->opcode() != SpvOpVariable) { // Assume divergent. divergence_source_[id] = 0; return DivergenceLevel::kDivergent; @@ -165,30 +166,29 @@ DivergenceAnalysis::ComputeVariableDivergence(opt::Instruction* var) { uint32_t def_id = var->result_id(); DivergenceLevel ret; switch (type->storage_class()) { - case spv::StorageClass::Function: - case spv::StorageClass::Generic: - case spv::StorageClass::AtomicCounter: - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - case spv::StorageClass::Output: - case spv::StorageClass::Workgroup: - case spv::StorageClass::Image: // Image atomics probably aren't uniform. - case spv::StorageClass::Private: + case SpvStorageClassFunction: + case SpvStorageClassGeneric: + case SpvStorageClassAtomicCounter: + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassOutput: + case SpvStorageClassWorkgroup: + case SpvStorageClassImage: // Image atomics probably aren't uniform. + case SpvStorageClassPrivate: ret = DivergenceLevel::kDivergent; break; - case spv::StorageClass::Input: + case SpvStorageClassInput: ret = DivergenceLevel::kDivergent; // If this variable has a Flat decoration, it is partially uniform. // TODO(kuhar): Track access chain indices and also consider Flat members // of a structure. context().get_decoration_mgr()->WhileEachDecoration( - def_id, static_cast(spv::Decoration::Flat), - [&ret](const opt::Instruction&) { + def_id, SpvDecorationFlat, [&ret](const opt::Instruction&) { ret = DivergenceLevel::kPartiallyUniform; return false; }); break; - case spv::StorageClass::UniformConstant: + case SpvStorageClassUniformConstant: // May be a storage image which is also written to; mark those as // divergent. if (!var->IsVulkanStorageImage() || var->IsReadOnlyPointer()) { @@ -197,10 +197,9 @@ DivergenceAnalysis::ComputeVariableDivergence(opt::Instruction* var) { ret = DivergenceLevel::kDivergent; } break; - case spv::StorageClass::Uniform: - case spv::StorageClass::PushConstant: - case spv::StorageClass::CrossWorkgroup: // Not for shaders; default - // uniform. + case SpvStorageClassUniform: + case SpvStorageClassPushConstant: + case SpvStorageClassCrossWorkgroup: // Not for shaders; default uniform. default: ret = DivergenceLevel::kUniform; break; @@ -217,7 +216,7 @@ void DivergenceAnalysis::Setup(opt::Function* function) { function->entry().get(), [this](const opt::BasicBlock* bb) { uint32_t id = bb->id(); if (bb->terminator() == nullptr || - bb->terminator()->opcode() != spv::Op::OpBranch) { + bb->terminator()->opcode() != SpvOpBranch) { follow_unconditional_branches_[id] = id; } else { uint32_t target_id = bb->terminator()->GetSingleWordInOperand(0); diff --git a/source/lint/lint_divergent_derivatives.cpp b/source/lint/lint_divergent_derivatives.cpp index 82d5ac63..512847b0 100644 --- a/source/lint/lint_divergent_derivatives.cpp +++ b/source/lint/lint_divergent_derivatives.cpp @@ -27,6 +27,7 @@ #include "source/opt/instruction.h" #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.h" +#include "spirv/unified1/spirv.h" namespace spvtools { namespace lint { @@ -42,7 +43,7 @@ std::string GetFriendlyName(opt::IRContext* context, uint32_t id) { ss << id; } else { opt::Instruction* inst_name = names.begin()->second; - if (inst_name->opcode() == spv::Op::OpName) { + if (inst_name->opcode() == SpvOpName) { ss << names.begin()->second->GetInOperand(0).AsString(); ss << "[" << id << "]"; } else { @@ -53,26 +54,26 @@ std::string GetFriendlyName(opt::IRContext* context, uint32_t id) { } bool InstructionHasDerivative(const opt::Instruction& inst) { - static const spv::Op derivative_opcodes[] = { + static const SpvOp derivative_opcodes[] = { // Implicit derivatives. - spv::Op::OpImageSampleImplicitLod, - spv::Op::OpImageSampleDrefImplicitLod, - spv::Op::OpImageSampleProjImplicitLod, - spv::Op::OpImageSampleProjDrefImplicitLod, - spv::Op::OpImageSparseSampleImplicitLod, - spv::Op::OpImageSparseSampleDrefImplicitLod, - spv::Op::OpImageSparseSampleProjImplicitLod, - spv::Op::OpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSampleImplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, // Explicit derivatives. - spv::Op::OpDPdx, - spv::Op::OpDPdy, - spv::Op::OpFwidth, - spv::Op::OpDPdxFine, - spv::Op::OpDPdyFine, - spv::Op::OpFwidthFine, - spv::Op::OpDPdxCoarse, - spv::Op::OpDPdyCoarse, - spv::Op::OpFwidthCoarse, + SpvOpDPdx, + SpvOpDPdy, + SpvOpFwidth, + SpvOpDPdxFine, + SpvOpDPdyFine, + SpvOpFwidthFine, + SpvOpDPdxCoarse, + SpvOpDPdyCoarse, + SpvOpFwidthCoarse, }; return std::find(std::begin(derivative_opcodes), std::end(derivative_opcodes), inst.opcode()) != std::end(derivative_opcodes); @@ -96,14 +97,13 @@ void PrintDivergenceFlow(opt::IRContext* context, DivergenceAnalysis div, opt::analysis::DefUseManager* def_use = context->get_def_use_mgr(); opt::CFG* cfg = context->cfg(); while (id != 0) { - bool is_block = def_use->GetDef(id)->opcode() == spv::Op::OpLabel; + bool is_block = def_use->GetDef(id)->opcode() == SpvOpLabel; if (is_block) { Warn(context, nullptr) << "block " << GetFriendlyName(context, id) << " is divergent"; uint32_t source = div.GetDivergenceSource(id); // Skip intermediate blocks. - while (source != 0 && - def_use->GetDef(source)->opcode() == spv::Op::OpLabel) { + while (source != 0 && def_use->GetDef(source)->opcode() == SpvOpLabel) { id = source; source = div.GetDivergenceSource(id); } @@ -122,7 +122,7 @@ void PrintDivergenceFlow(opt::IRContext* context, DivergenceAnalysis div, opt::Instruction* source_def = source == 0 ? nullptr : def_use->GetDef(source); // First print data -> data dependencies. - while (source != 0 && source_def->opcode() != spv::Op::OpLabel) { + while (source != 0 && source_def->opcode() != SpvOpLabel) { Warn(context, def_use->GetDef(id)) << "because " << GetFriendlyName(context, id) << " uses value " << GetFriendlyName(context, source) diff --git a/source/lint/linter.cpp b/source/lint/linter.cpp index 74806767..e4ed04ea 100644 --- a/source/lint/linter.cpp +++ b/source/lint/linter.cpp @@ -19,6 +19,7 @@ #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.h" #include "spirv-tools/libspirv.hpp" +#include "spirv/unified1/spirv.h" namespace spvtools { diff --git a/source/name_mapper.cpp b/source/name_mapper.cpp index b2d0f445..3b31d33a 100644 --- a/source/name_mapper.cpp +++ b/source/name_mapper.cpp @@ -100,18 +100,18 @@ void FriendlyNameMapper::SaveName(uint32_t id, void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id, uint32_t built_in) { #define GLCASE(name) \ - case spv::BuiltIn::name: \ + case SpvBuiltIn##name: \ SaveName(target_id, "gl_" #name); \ return; #define GLCASE2(name, suggested) \ - case spv::BuiltIn::name: \ + case SpvBuiltIn##name: \ SaveName(target_id, "gl_" #suggested); \ return; #define CASE(name) \ - case spv::BuiltIn::name: \ + case SpvBuiltIn##name: \ SaveName(target_id, #name); \ return; - switch (spv::BuiltIn(built_in)) { + switch (built_in) { GLCASE(Position) GLCASE(PointSize) GLCASE(ClipDistance) @@ -170,28 +170,28 @@ void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id, spv_result_t FriendlyNameMapper::ParseInstruction( const spv_parsed_instruction_t& inst) { const auto result_id = inst.result_id; - switch (spv::Op(inst.opcode)) { - case spv::Op::OpName: + switch (inst.opcode) { + case SpvOpName: SaveName(inst.words[1], spvDecodeLiteralStringOperand(inst, 1)); break; - case spv::Op::OpDecorate: + case SpvOpDecorate: // Decorations come after OpName. So OpName will take precedence over // decorations. // // In theory, we should also handle OpGroupDecorate. But that's unlikely // to occur. - if (spv::Decoration(inst.words[2]) == spv::Decoration::BuiltIn) { + if (inst.words[2] == SpvDecorationBuiltIn) { assert(inst.num_words > 3); SaveBuiltInName(inst.words[1], inst.words[3]); } break; - case spv::Op::OpTypeVoid: + case SpvOpTypeVoid: SaveName(result_id, "void"); break; - case spv::Op::OpTypeBool: + case SpvOpTypeBool: SaveName(result_id, "bool"); break; - case spv::Op::OpTypeInt: { + case SpvOpTypeInt: { std::string signedness; std::string root; const auto bit_width = inst.words[2]; @@ -216,7 +216,7 @@ spv_result_t FriendlyNameMapper::ParseInstruction( if (0 == inst.words[3]) signedness = "u"; SaveName(result_id, signedness + root); } break; - case spv::Op::OpTypeFloat: { + case SpvOpTypeFloat: { const auto bit_width = inst.words[2]; switch (bit_width) { case 16: @@ -233,68 +233,68 @@ spv_result_t FriendlyNameMapper::ParseInstruction( break; } } break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: SaveName(result_id, std::string("v") + to_string(inst.words[3]) + NameForId(inst.words[2])); break; - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: SaveName(result_id, std::string("mat") + to_string(inst.words[3]) + NameForId(inst.words[2])); break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: SaveName(result_id, std::string("_arr_") + NameForId(inst.words[2]) + "_" + NameForId(inst.words[3])); break; - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: SaveName(result_id, std::string("_runtimearr_") + NameForId(inst.words[2])); break; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: SaveName(result_id, std::string("_ptr_") + NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, inst.words[2]) + "_" + NameForId(inst.words[3])); break; - case spv::Op::OpTypePipe: + case SpvOpTypePipe: SaveName(result_id, std::string("Pipe") + NameForEnumOperand(SPV_OPERAND_TYPE_ACCESS_QUALIFIER, inst.words[2])); break; - case spv::Op::OpTypeEvent: + case SpvOpTypeEvent: SaveName(result_id, "Event"); break; - case spv::Op::OpTypeDeviceEvent: + case SpvOpTypeDeviceEvent: SaveName(result_id, "DeviceEvent"); break; - case spv::Op::OpTypeReserveId: + case SpvOpTypeReserveId: SaveName(result_id, "ReserveId"); break; - case spv::Op::OpTypeQueue: + case SpvOpTypeQueue: SaveName(result_id, "Queue"); break; - case spv::Op::OpTypeOpaque: + case SpvOpTypeOpaque: SaveName(result_id, std::string("Opaque_") + Sanitize(spvDecodeLiteralStringOperand(inst, 1))); break; - case spv::Op::OpTypePipeStorage: + case SpvOpTypePipeStorage: SaveName(result_id, "PipeStorage"); break; - case spv::Op::OpTypeNamedBarrier: + case SpvOpTypeNamedBarrier: SaveName(result_id, "NamedBarrier"); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // Structs are mapped rather simplisitically. Just indicate that they // are a struct and then give the raw Id number. SaveName(result_id, std::string("_struct_") + to_string(result_id)); break; - case spv::Op::OpConstantTrue: + case SpvOpConstantTrue: SaveName(result_id, "true"); break; - case spv::Op::OpConstantFalse: + case SpvOpConstantFalse: SaveName(result_id, "false"); break; - case spv::Op::OpConstant: { + case SpvOpConstant: { std::ostringstream value; EmitNumericLiteral(&value, inst, inst.operands[2]); auto value_str = value.str(); diff --git a/source/opcode.cpp b/source/opcode.cpp index ffbb2e8b..3f927290 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -64,7 +64,7 @@ const char* spvGeneratorStr(uint32_t generator) { return "Unknown"; } -uint32_t spvOpcodeMake(uint16_t wordCount, spv::Op opcode) { +uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) { return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16); } @@ -125,7 +125,7 @@ spv_result_t spvOpcodeTableNameLookup(spv_target_env env, spv_result_t spvOpcodeTableValueLookup(spv_target_env env, const spv_opcode_table table, - const spv::Op opcode, + const SpvOp opcode, spv_opcode_desc* pEntry) { if (!table) return SPV_ERROR_INVALID_TABLE; if (!pEntry) return SPV_ERROR_INVALID_POINTER; @@ -166,7 +166,7 @@ spv_result_t spvOpcodeTableValueLookup(spv_target_env env, return SPV_ERROR_INVALID_LOOKUP; } -void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, +void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, const uint16_t wordCount, const spv_endianness_t endian, spv_instruction_t* pInst) { pInst->opcode = opcode; @@ -177,7 +177,7 @@ void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, uint16_t thisWordCount; uint16_t thisOpcode; spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode); - assert(opcode == static_cast(thisOpcode) && + assert(opcode == static_cast(thisOpcode) && wordCount == thisWordCount && "Endianness failed!"); } } @@ -186,7 +186,7 @@ void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, const char* spvOpcodeString(const uint32_t opcode) { const auto beg = kOpcodeTableEntries; const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries); - spv_opcode_desc_t needle = {"", static_cast(opcode), + spv_opcode_desc_t needle = {"", static_cast(opcode), 0, nullptr, 0, {}, false, false, @@ -196,7 +196,7 @@ const char* spvOpcodeString(const uint32_t opcode) { return lhs.opcode < rhs.opcode; }; auto it = std::lower_bound(beg, end, needle, comp); - if (it != end && it->opcode == spv::Op(opcode)) { + if (it != end && it->opcode == opcode) { return it->name; } @@ -204,148 +204,140 @@ const char* spvOpcodeString(const uint32_t opcode) { return "unknown"; } -const char* spvOpcodeString(const spv::Op opcode) { - return spvOpcodeString(static_cast(opcode)); -} - -int32_t spvOpcodeIsScalarType(const spv::Op opcode) { +int32_t spvOpcodeIsScalarType(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeBool: return true; default: return false; } } -int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) { +int32_t spvOpcodeIsSpecConstant(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpSpecConstant: - case spv::Op::OpSpecConstantComposite: - case spv::Op::OpSpecConstantOp: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: + case SpvOpSpecConstantComposite: + case SpvOpSpecConstantOp: return true; default: return false; } } -int32_t spvOpcodeIsConstant(const spv::Op opcode) { +int32_t spvOpcodeIsConstant(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: - case spv::Op::OpConstant: - case spv::Op::OpConstantComposite: - case spv::Op::OpConstantSampler: - case spv::Op::OpConstantNull: - case spv::Op::OpConstantFunctionPointerINTEL: - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpSpecConstant: - case spv::Op::OpSpecConstantComposite: - case spv::Op::OpSpecConstantOp: + case SpvOpConstantTrue: + case SpvOpConstantFalse: + case SpvOpConstant: + case SpvOpConstantComposite: + case SpvOpConstantSampler: + case SpvOpConstantNull: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: + case SpvOpSpecConstantComposite: + case SpvOpSpecConstantOp: return true; default: return false; } } -bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) { - return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode); +bool spvOpcodeIsConstantOrUndef(const SpvOp opcode) { + return opcode == SpvOpUndef || spvOpcodeIsConstant(opcode); } -bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode) { +bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpSpecConstant: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: + case SpvOpSpecConstant: return true; default: return false; } } -int32_t spvOpcodeIsComposite(const spv::Op opcode) { +int32_t spvOpcodeIsComposite(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeStruct: - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeStruct: + case SpvOpTypeCooperativeMatrixNV: return true; default: return false; } } -bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) { +bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpVariable: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpFunctionParameter: - case spv::Op::OpImageTexelPointer: - case spv::Op::OpCopyObject: - case spv::Op::OpSelect: - case spv::Op::OpPhi: - case spv::Op::OpFunctionCall: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpLoad: - case spv::Op::OpConstantNull: + case SpvOpVariable: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpFunctionParameter: + case SpvOpImageTexelPointer: + case SpvOpCopyObject: + case SpvOpSelect: + case SpvOpPhi: + case SpvOpFunctionCall: + case SpvOpPtrAccessChain: + case SpvOpLoad: + case SpvOpConstantNull: return true; default: return false; } } -int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) { +int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpVariable: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpFunctionParameter: - case spv::Op::OpImageTexelPointer: - case spv::Op::OpCopyObject: + case SpvOpVariable: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpFunctionParameter: + case SpvOpImageTexelPointer: + case SpvOpCopyObject: return true; default: return false; } } -int32_t spvOpcodeGeneratesType(spv::Op op) { +int32_t spvOpcodeGeneratesType(SpvOp op) { switch (op) { - case spv::Op::OpTypeVoid: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeStruct: - case spv::Op::OpTypeOpaque: - case spv::Op::OpTypePointer: - case spv::Op::OpTypeFunction: - case spv::Op::OpTypeEvent: - case spv::Op::OpTypeDeviceEvent: - case spv::Op::OpTypeReserveId: - case spv::Op::OpTypeQueue: - case spv::Op::OpTypePipe: - case spv::Op::OpTypePipeStorage: - case spv::Op::OpTypeNamedBarrier: - case spv::Op::OpTypeAccelerationStructureNV: - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: - // case spv::Op::OpTypeAccelerationStructureKHR: covered by - // spv::Op::OpTypeAccelerationStructureNV - case spv::Op::OpTypeRayQueryKHR: - case spv::Op::OpTypeHitObjectNV: + case SpvOpTypeVoid: + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeImage: + case SpvOpTypeSampler: + case SpvOpTypeSampledImage: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeStruct: + case SpvOpTypeOpaque: + case SpvOpTypePointer: + case SpvOpTypeFunction: + case SpvOpTypeEvent: + case SpvOpTypeDeviceEvent: + case SpvOpTypeReserveId: + case SpvOpTypeQueue: + case SpvOpTypePipe: + case SpvOpTypePipeStorage: + case SpvOpTypeNamedBarrier: + case SpvOpTypeAccelerationStructureNV: + case SpvOpTypeCooperativeMatrixNV: + // case SpvOpTypeAccelerationStructureKHR: covered by + // SpvOpTypeAccelerationStructureNV + case SpvOpTypeRayQueryKHR: return true; default: // In particular, OpTypeForwardPointer does not generate a type, @@ -356,15 +348,15 @@ int32_t spvOpcodeGeneratesType(spv::Op op) { return 0; } -bool spvOpcodeIsDecoration(const spv::Op opcode) { +bool spvOpcodeIsDecoration(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpMemberDecorate: - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorateStringGOOGLE: + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpMemberDecorate: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: return true; default: break; @@ -372,403 +364,402 @@ bool spvOpcodeIsDecoration(const spv::Op opcode) { return false; } -bool spvOpcodeIsLoad(const spv::Op opcode) { +bool spvOpcodeIsLoad(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpLoad: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageFetch: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageSparseRead: + case SpvOpLoad: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageFetch: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageRead: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpImageSparseRead: return true; default: return false; } } -bool spvOpcodeIsBranch(spv::Op opcode) { +bool spvOpcodeIsBranch(SpvOp opcode) { switch (opcode) { - case spv::Op::OpBranch: - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: + case SpvOpBranch: + case SpvOpBranchConditional: + case SpvOpSwitch: return true; default: return false; } } -bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) { +bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicFAddEXT: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicFMinEXT: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicFMaxEXT: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: + case SpvOpAtomicLoad: + case SpvOpAtomicExchange: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicFAddEXT: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicFMinEXT: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicFMaxEXT: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: return true; default: return false; } } -bool spvOpcodeIsAtomicOp(const spv::Op opcode) { - return (spvOpcodeIsAtomicWithLoad(opcode) || - opcode == spv::Op::OpAtomicStore || - opcode == spv::Op::OpAtomicFlagClear); +bool spvOpcodeIsAtomicOp(const SpvOp opcode) { + return (spvOpcodeIsAtomicWithLoad(opcode) || opcode == SpvOpAtomicStore || + opcode == SpvOpAtomicFlagClear); } -bool spvOpcodeIsReturn(spv::Op opcode) { +bool spvOpcodeIsReturn(SpvOp opcode) { switch (opcode) { - case spv::Op::OpReturn: - case spv::Op::OpReturnValue: + case SpvOpReturn: + case SpvOpReturnValue: return true; default: return false; } } -bool spvOpcodeIsAbort(spv::Op opcode) { +bool spvOpcodeIsAbort(SpvOp opcode) { switch (opcode) { - case spv::Op::OpKill: - case spv::Op::OpUnreachable: - case spv::Op::OpTerminateInvocation: - case spv::Op::OpTerminateRayKHR: - case spv::Op::OpIgnoreIntersectionKHR: - case spv::Op::OpEmitMeshTasksEXT: + case SpvOpKill: + case SpvOpUnreachable: + case SpvOpTerminateInvocation: + case SpvOpTerminateRayKHR: + case SpvOpIgnoreIntersectionKHR: + case SpvOpEmitMeshTasksEXT: return true; default: return false; } } -bool spvOpcodeIsReturnOrAbort(spv::Op opcode) { +bool spvOpcodeIsReturnOrAbort(SpvOp opcode) { return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode); } -bool spvOpcodeIsBlockTerminator(spv::Op opcode) { +bool spvOpcodeIsBlockTerminator(SpvOp opcode) { return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode); } -bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) { +bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) { switch (opcode) { - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeOpaque: - case spv::Op::OpTypeEvent: - case spv::Op::OpTypeDeviceEvent: - case spv::Op::OpTypeReserveId: - case spv::Op::OpTypeQueue: - case spv::Op::OpTypePipe: - case spv::Op::OpTypeForwardPointer: - case spv::Op::OpTypePipeStorage: - case spv::Op::OpTypeNamedBarrier: + case SpvOpTypeImage: + case SpvOpTypeSampler: + case SpvOpTypeSampledImage: + case SpvOpTypeOpaque: + case SpvOpTypeEvent: + case SpvOpTypeDeviceEvent: + case SpvOpTypeReserveId: + case SpvOpTypeQueue: + case SpvOpTypePipe: + case SpvOpTypeForwardPointer: + case SpvOpTypePipeStorage: + case SpvOpTypeNamedBarrier: return true; default: return false; } } -bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) { +bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode) { switch (opcode) { - case spv::Op::OpGroupNonUniformElect: - case spv::Op::OpGroupNonUniformAll: - case spv::Op::OpGroupNonUniformAny: - case spv::Op::OpGroupNonUniformAllEqual: - case spv::Op::OpGroupNonUniformBroadcast: - case spv::Op::OpGroupNonUniformBroadcastFirst: - case spv::Op::OpGroupNonUniformBallot: - case spv::Op::OpGroupNonUniformInverseBallot: - case spv::Op::OpGroupNonUniformBallotBitExtract: - case spv::Op::OpGroupNonUniformBallotBitCount: - case spv::Op::OpGroupNonUniformBallotFindLSB: - case spv::Op::OpGroupNonUniformBallotFindMSB: - case spv::Op::OpGroupNonUniformShuffle: - case spv::Op::OpGroupNonUniformShuffleXor: - case spv::Op::OpGroupNonUniformShuffleUp: - case spv::Op::OpGroupNonUniformShuffleDown: - case spv::Op::OpGroupNonUniformIAdd: - case spv::Op::OpGroupNonUniformFAdd: - case spv::Op::OpGroupNonUniformIMul: - case spv::Op::OpGroupNonUniformFMul: - case spv::Op::OpGroupNonUniformSMin: - case spv::Op::OpGroupNonUniformUMin: - case spv::Op::OpGroupNonUniformFMin: - case spv::Op::OpGroupNonUniformSMax: - case spv::Op::OpGroupNonUniformUMax: - case spv::Op::OpGroupNonUniformFMax: - case spv::Op::OpGroupNonUniformBitwiseAnd: - case spv::Op::OpGroupNonUniformBitwiseOr: - case spv::Op::OpGroupNonUniformBitwiseXor: - case spv::Op::OpGroupNonUniformLogicalAnd: - case spv::Op::OpGroupNonUniformLogicalOr: - case spv::Op::OpGroupNonUniformLogicalXor: - case spv::Op::OpGroupNonUniformQuadBroadcast: - case spv::Op::OpGroupNonUniformQuadSwap: - case spv::Op::OpGroupNonUniformRotateKHR: + case SpvOpGroupNonUniformElect: + case SpvOpGroupNonUniformAll: + case SpvOpGroupNonUniformAny: + case SpvOpGroupNonUniformAllEqual: + case SpvOpGroupNonUniformBroadcast: + case SpvOpGroupNonUniformBroadcastFirst: + case SpvOpGroupNonUniformBallot: + case SpvOpGroupNonUniformInverseBallot: + case SpvOpGroupNonUniformBallotBitExtract: + case SpvOpGroupNonUniformBallotBitCount: + case SpvOpGroupNonUniformBallotFindLSB: + case SpvOpGroupNonUniformBallotFindMSB: + case SpvOpGroupNonUniformShuffle: + case SpvOpGroupNonUniformShuffleXor: + case SpvOpGroupNonUniformShuffleUp: + case SpvOpGroupNonUniformShuffleDown: + case SpvOpGroupNonUniformIAdd: + case SpvOpGroupNonUniformFAdd: + case SpvOpGroupNonUniformIMul: + case SpvOpGroupNonUniformFMul: + case SpvOpGroupNonUniformSMin: + case SpvOpGroupNonUniformUMin: + case SpvOpGroupNonUniformFMin: + case SpvOpGroupNonUniformSMax: + case SpvOpGroupNonUniformUMax: + case SpvOpGroupNonUniformFMax: + case SpvOpGroupNonUniformBitwiseAnd: + case SpvOpGroupNonUniformBitwiseOr: + case SpvOpGroupNonUniformBitwiseXor: + case SpvOpGroupNonUniformLogicalAnd: + case SpvOpGroupNonUniformLogicalOr: + case SpvOpGroupNonUniformLogicalXor: + case SpvOpGroupNonUniformQuadBroadcast: + case SpvOpGroupNonUniformQuadSwap: + case SpvOpGroupNonUniformRotateKHR: return true; default: return false; } } -bool spvOpcodeIsScalarizable(spv::Op opcode) { +bool spvOpcodeIsScalarizable(SpvOp opcode) { switch (opcode) { - case spv::Op::OpPhi: - case spv::Op::OpCopyObject: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: + case SpvOpPhi: + case SpvOpCopyObject: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpVectorInsertDynamic: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: return true; default: return false; } } -bool spvOpcodeIsDebug(spv::Op opcode) { +bool spvOpcodeIsDebug(SpvOp opcode) { switch (opcode) { - case spv::Op::OpName: - case spv::Op::OpMemberName: - case spv::Op::OpSource: - case spv::Op::OpSourceContinued: - case spv::Op::OpSourceExtension: - case spv::Op::OpString: - case spv::Op::OpLine: - case spv::Op::OpNoLine: - case spv::Op::OpModuleProcessed: + case SpvOpName: + case SpvOpMemberName: + case SpvOpSource: + case SpvOpSourceContinued: + case SpvOpSourceExtension: + case SpvOpString: + case SpvOpLine: + case SpvOpNoLine: + case SpvOpModuleProcessed: return true; default: return false; } } -bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) { +bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode) { switch (opcode) { - case spv::Op::OpPtrEqual: - case spv::Op::OpPtrNotEqual: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: + case SpvOpPtrEqual: + case SpvOpPtrNotEqual: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpOrdered: + case SpvOpUnordered: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: return true; default: return false; } } -bool spvOpcodeIsLinearAlgebra(spv::Op opcode) { +bool spvOpcodeIsLinearAlgebra(SpvOp opcode) { switch (opcode) { - case spv::Op::OpTranspose: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: + case SpvOpTranspose: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: return true; default: return false; } } -bool spvOpcodeIsImageSample(const spv::Op opcode) { +bool spvOpcodeIsImageSample(const SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: return true; default: return false; } } -std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) { +std::vector spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode) { switch (opcode) { - case spv::Op::OpMemoryBarrier: + case SpvOpMemoryBarrier: return {1}; - case spv::Op::OpAtomicStore: - case spv::Op::OpControlBarrier: - case spv::Op::OpAtomicFlagClear: - case spv::Op::OpMemoryNamedBarrier: + case SpvOpAtomicStore: + case SpvOpControlBarrier: + case SpvOpAtomicFlagClear: + case SpvOpMemoryNamedBarrier: return {2}; - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicFAddEXT: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: + case SpvOpAtomicLoad: + case SpvOpAtomicExchange: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicFAddEXT: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: return {4}; - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: return {4, 5}; default: return {}; } } -bool spvOpcodeIsAccessChain(spv::Op opcode) { +bool spvOpcodeIsAccessChain(SpvOp opcode) { switch (opcode) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: return true; default: return false; } } -bool spvOpcodeIsBit(spv::Op opcode) { +bool spvOpcodeIsBit(SpvOp opcode) { switch (opcode) { - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitReverse: + case SpvOpBitCount: return true; default: return false; diff --git a/source/opcode.h b/source/opcode.h index 217aeb2b..77a0bed2 100644 --- a/source/opcode.h +++ b/source/opcode.h @@ -29,7 +29,7 @@ const char* spvGeneratorStr(uint32_t generator); // Combines word_count and opcode enumerant in single word. -uint32_t spvOpcodeMake(uint16_t word_count, spv::Op opcode); +uint32_t spvOpcodeMake(uint16_t word_count, SpvOp opcode); // Splits word into into two constituent parts: word_count and opcode. void spvOpcodeSplit(const uint32_t word, uint16_t* word_count, @@ -45,118 +45,115 @@ spv_result_t spvOpcodeTableNameLookup(spv_target_env, // SPV_SUCCESS and writes a handle of the table entry into *entry. spv_result_t spvOpcodeTableValueLookup(spv_target_env, const spv_opcode_table table, - const spv::Op opcode, + const SpvOp opcode, spv_opcode_desc* entry); // Copies an instruction's word and fixes the endianness to host native. The // source instruction's stream/opcode/endianness is in the words/opcode/endian // parameter. The word_count parameter specifies the number of words to copy. // Writes copied instruction into *inst. -void spvInstructionCopy(const uint32_t* words, const spv::Op opcode, +void spvInstructionCopy(const uint32_t* words, const SpvOp opcode, const uint16_t word_count, const spv_endianness_t endian, spv_instruction_t* inst); // Determine if the given opcode is a scalar type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeIsScalarType(const spv::Op opcode); +int32_t spvOpcodeIsScalarType(const SpvOp opcode); // Determines if the given opcode is a specialization constant. Returns zero if // false, non-zero otherwise. -int32_t spvOpcodeIsSpecConstant(const spv::Op opcode); +int32_t spvOpcodeIsSpecConstant(const SpvOp opcode); // Determines if the given opcode is a constant. Returns zero if false, non-zero // otherwise. -int32_t spvOpcodeIsConstant(const spv::Op opcode); +int32_t spvOpcodeIsConstant(const SpvOp opcode); // Returns true if the given opcode is a constant or undef. -bool spvOpcodeIsConstantOrUndef(const spv::Op opcode); +bool spvOpcodeIsConstantOrUndef(const SpvOp opcode); // Returns true if the given opcode is a scalar specialization constant. -bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode); +bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode); // Determines if the given opcode is a composite type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeIsComposite(const spv::Op opcode); +int32_t spvOpcodeIsComposite(const SpvOp opcode); // Determines if the given opcode results in a pointer when using the logical // addressing model. Returns zero if false, non-zero otherwise. -int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode); +int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode); // Returns whether the given opcode could result in a pointer or a variable // pointer when using the logical addressing model. -bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode); +bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode); // Determines if the given opcode generates a type. Returns zero if false, // non-zero otherwise. -int32_t spvOpcodeGeneratesType(spv::Op opcode); +int32_t spvOpcodeGeneratesType(SpvOp opcode); // Returns true if the opcode adds a decoration to an id. -bool spvOpcodeIsDecoration(const spv::Op opcode); +bool spvOpcodeIsDecoration(const SpvOp opcode); // Returns true if the opcode is a load from memory into a result id. This // function only considers core instructions. -bool spvOpcodeIsLoad(const spv::Op opcode); +bool spvOpcodeIsLoad(const SpvOp opcode); // Returns true if the opcode is an atomic operation that uses the original // value. -bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode); +bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode); // Returns true if the opcode is an atomic operation. -bool spvOpcodeIsAtomicOp(const spv::Op opcode); +bool spvOpcodeIsAtomicOp(const SpvOp opcode); // Returns true if the given opcode is a branch instruction. -bool spvOpcodeIsBranch(spv::Op opcode); +bool spvOpcodeIsBranch(SpvOp opcode); // Returns true if the given opcode is a return instruction. -bool spvOpcodeIsReturn(spv::Op opcode); +bool spvOpcodeIsReturn(SpvOp opcode); // Returns true if the given opcode aborts execution. To abort means that after // executing that instruction, no other instructions will be executed regardless // of the context in which the instruction appears. Note that `OpUnreachable` // is considered an abort even if its behaviour is undefined. -bool spvOpcodeIsAbort(spv::Op opcode); +bool spvOpcodeIsAbort(SpvOp opcode); // Returns true if the given opcode is a return instruction or it aborts // execution. -bool spvOpcodeIsReturnOrAbort(spv::Op opcode); +bool spvOpcodeIsReturnOrAbort(SpvOp opcode); // Returns true if the given opcode is a basic block terminator. -bool spvOpcodeIsBlockTerminator(spv::Op opcode); +bool spvOpcodeIsBlockTerminator(SpvOp opcode); // Returns true if the given opcode always defines an opaque type. -bool spvOpcodeIsBaseOpaqueType(spv::Op opcode); +bool spvOpcodeIsBaseOpaqueType(SpvOp opcode); // Returns true if the given opcode is a non-uniform group operation. -bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode); +bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode); // Returns true if the opcode with vector inputs could be divided into a series // of independent scalar operations that would give the same result. -bool spvOpcodeIsScalarizable(spv::Op opcode); +bool spvOpcodeIsScalarizable(SpvOp opcode); // Returns true if the given opcode is a debug instruction. -bool spvOpcodeIsDebug(spv::Op opcode); +bool spvOpcodeIsDebug(SpvOp opcode); // Returns true for opcodes that are binary operators, // where the order of the operands is irrelevant. -bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode); +bool spvOpcodeIsCommutativeBinaryOperator(SpvOp opcode); // Returns true for opcodes that represent linear algebra instructions. -bool spvOpcodeIsLinearAlgebra(spv::Op opcode); +bool spvOpcodeIsLinearAlgebra(SpvOp opcode); // Returns true for opcodes that represent image sample instructions. -bool spvOpcodeIsImageSample(spv::Op opcode); +bool spvOpcodeIsImageSample(SpvOp opcode); // Returns a vector containing the indices of the memory semantics // operands for |opcode|. -std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode); +std::vector spvOpcodeMemorySemanticsOperandIndices(SpvOp opcode); // Returns true for opcodes that represent access chain instructions. -bool spvOpcodeIsAccessChain(spv::Op opcode); +bool spvOpcodeIsAccessChain(SpvOp opcode); // Returns true for opcodes that represent bit instructions. -bool spvOpcodeIsBit(spv::Op opcode); - -// Gets the name of an instruction, without the "Op" prefix. -const char* spvOpcodeString(const spv::Op opcode); +bool spvOpcodeIsBit(SpvOp opcode); #endif // SOURCE_OPCODE_H_ diff --git a/source/operand.cpp b/source/operand.cpp index 6577f8f7..0c255a35 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -26,6 +26,7 @@ #include "source/macro.h" #include "source/opcode.h" #include "source/spirv_constant.h" +#include "source/spirv_target_env.h" // For now, assume unified1 contains up to SPIR-V 1.3 and no later // SPIR-V version. @@ -47,7 +48,7 @@ spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable, return SPV_SUCCESS; } -spv_result_t spvOperandTableNameLookup(spv_target_env, +spv_result_t spvOperandTableNameLookup(spv_target_env env, const spv_operand_table table, const spv_operand_type_t type, const char* name, @@ -56,18 +57,31 @@ spv_result_t spvOperandTableNameLookup(spv_target_env, if (!table) return SPV_ERROR_INVALID_TABLE; if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER; + const auto version = spvVersionForTargetEnv(env); for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) { const auto& group = table->types[typeIndex]; if (type != group.type) continue; for (uint64_t index = 0; index < group.count; ++index) { const auto& entry = group.entries[index]; // We consider the current operand as available as long as - // it is in the grammar. It might not be *valid* to use, - // but that should be checked by the validator, not by parsing. + // 1. The target environment satisfies the minimal requirement of the + // operand; or + // 2. There is at least one extension enabling this operand; or + // 3. There is at least one capability enabling this operand. + // + // Note that the second rule assumes the extension enabling this operand + // is indeed requested in the SPIR-V code; checking that should be + // validator's work. if (nameLength == strlen(entry.name) && !strncmp(entry.name, name, nameLength)) { - *pEntry = &entry; - return SPV_SUCCESS; + if ((version >= entry.minVersion && version <= entry.lastVersion) || + entry.numExtensions > 0u || entry.numCapabilities > 0u) { + *pEntry = &entry; + return SPV_SUCCESS; + } else { + // if there is no extension/capability then the version is wrong + return SPV_ERROR_WRONG_VERSION; + } } } } @@ -75,7 +89,7 @@ spv_result_t spvOperandTableNameLookup(spv_target_env, return SPV_ERROR_INVALID_LOOKUP; } -spv_result_t spvOperandTableValueLookup(spv_target_env, +spv_result_t spvOperandTableValueLookup(spv_target_env env, const spv_operand_table table, const spv_operand_type_t type, const uint32_t value, @@ -96,15 +110,33 @@ spv_result_t spvOperandTableValueLookup(spv_target_env, const auto beg = group.entries; const auto end = group.entries + group.count; + // We need to loop here because there can exist multiple symbols for the + // same operand value, and they can be introduced in different target + // environments, which means they can have different minimal version + // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V + // version as long as the SPV_KHR_shader_ballot extension is there; but + // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric + // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension + // requirements. // Assumes the underlying table is already sorted ascendingly according to // opcode value. - auto it = std::lower_bound(beg, end, needle, comp); - if (it != end && it->value == value) { - // The current operand is considered available as long as - // it is in the grammar. It might not be *valid* to use, - // but that should be checked by the validator, not by parsing. - *pEntry = it; - return SPV_SUCCESS; + const auto version = spvVersionForTargetEnv(env); + for (auto it = std::lower_bound(beg, end, needle, comp); + it != end && it->value == value; ++it) { + // We consider the current operand as available as long as + // 1. The target environment satisfies the minimal requirement of the + // operand; or + // 2. There is at least one extension enabling this operand; or + // 3. There is at least one capability enabling this operand. + // + // Note that the second rule assumes the extension enabling this operand + // is indeed requested in the SPIR-V code; checking that should be + // validator's work. + if ((version >= it->minVersion && version <= it->lastVersion) || + it->numExtensions > 0u || it->numCapabilities > 0u) { + *pEntry = it; + return SPV_SUCCESS; + } } } @@ -123,7 +155,6 @@ const char* spvOperandTypeStr(spv_operand_type_t type) { case SPV_OPERAND_TYPE_LITERAL_INTEGER: case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER: case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER: - case SPV_OPERAND_TYPE_LITERAL_FLOAT: return "literal number"; case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER: return "possibly multi-word literal integer"; @@ -205,21 +236,6 @@ const char* spvOperandTypeStr(spv_operand_type_t type) { case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: return "packed vector format"; - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: - return "cooperative matrix operands"; - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT: - return "cooperative matrix layout"; - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE: - return "cooperative matrix use"; - case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER: - return "initialization mode qualifier"; - case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: - return "host access qualifier"; - case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL: - return "load cache control"; - case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: - return "store cache control"; case SPV_OPERAND_TYPE_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: return "image"; @@ -309,7 +325,6 @@ bool spvOperandIsConcrete(spv_operand_type_t type) { } switch (type) { case SPV_OPERAND_TYPE_LITERAL_INTEGER: - case SPV_OPERAND_TYPE_LITERAL_FLOAT: case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: @@ -354,12 +369,6 @@ bool spvOperandIsConcrete(spv_operand_type_t type) { case SPV_OPERAND_TYPE_QUANTIZATION_MODES: case SPV_OPERAND_TYPE_OVERFLOW_MODES: case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT: - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE: - case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER: - case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: - case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL: - case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: return true; default: break; @@ -378,7 +387,6 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) { case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: return true; default: break; @@ -397,7 +405,6 @@ bool spvOperandIsOptional(spv_operand_type_t type) { case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER: case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: case SPV_OPERAND_TYPE_OPTIONAL_CIV: return true; default: @@ -505,7 +512,7 @@ bool spvIsInIdType(spv_operand_type_t type) { } std::function spvOperandCanBeForwardDeclaredFunction( - spv::Op opcode) { + SpvOp opcode) { std::function out; if (spvOpcodeGeneratesType(opcode)) { // All types can use forward pointers. @@ -513,57 +520,57 @@ std::function spvOperandCanBeForwardDeclaredFunction( return out; } switch (opcode) { - case spv::Op::OpExecutionMode: - case spv::Op::OpExecutionModeId: - case spv::Op::OpEntryPoint: - case spv::Op::OpName: - case spv::Op::OpMemberName: - case spv::Op::OpSelectionMerge: - case spv::Op::OpDecorate: - case spv::Op::OpMemberDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorateStringGOOGLE: - case spv::Op::OpBranch: - case spv::Op::OpLoopMerge: + case SpvOpExecutionMode: + case SpvOpExecutionModeId: + case SpvOpEntryPoint: + case SpvOpName: + case SpvOpMemberName: + case SpvOpSelectionMerge: + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: + case SpvOpBranch: + case SpvOpLoopMerge: out = [](unsigned) { return true; }; break; - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: + case SpvOpBranchConditional: + case SpvOpSwitch: out = [](unsigned index) { return index != 0; }; break; - case spv::Op::OpFunctionCall: + case SpvOpFunctionCall: // The Function parameter. out = [](unsigned index) { return index == 2; }; break; - case spv::Op::OpPhi: + case SpvOpPhi: out = [](unsigned index) { return index > 1; }; break; - case spv::Op::OpEnqueueKernel: + case SpvOpEnqueueKernel: // The Invoke parameter. out = [](unsigned index) { return index == 8; }; break; - case spv::Op::OpGetKernelNDrangeSubGroupCount: - case spv::Op::OpGetKernelNDrangeMaxSubGroupSize: + case SpvOpGetKernelNDrangeSubGroupCount: + case SpvOpGetKernelNDrangeMaxSubGroupSize: // The Invoke parameter. out = [](unsigned index) { return index == 3; }; break; - case spv::Op::OpGetKernelWorkGroupSize: - case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple: + case SpvOpGetKernelWorkGroupSize: + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: // The Invoke parameter. out = [](unsigned index) { return index == 2; }; break; - case spv::Op::OpTypeForwardPointer: + case SpvOpTypeForwardPointer: out = [](unsigned index) { return index == 0; }; break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: out = [](unsigned index) { return index == 1; }; break; default: diff --git a/source/operand.h b/source/operand.h index a3010d93..7c73c6f5 100644 --- a/source/operand.h +++ b/source/operand.h @@ -139,7 +139,7 @@ bool spvIsInIdType(spv_operand_type_t type); // of the operand can be forward declared. This function will // used in the SSA validation stage of the pipeline std::function spvOperandCanBeForwardDeclaredFunction( - spv::Op opcode); + SpvOp opcode); // Takes the instruction key of a debug info extension instruction // and returns a function object that will return true if the index diff --git a/source/opt/BUILD.gn b/source/opt/BUILD.gn index 1b3d906b..2afbfa38 100644 --- a/source/opt/BUILD.gn +++ b/source/opt/BUILD.gn @@ -25,295 +25,118 @@ config("deqp_spirvtool_opt_config") { ] } -config("spv_headers_public_config") { - include_dirs = [ "include" ] -} - -config("spvtools_include_gen_dirs") { - include_dirs = [ "$target_gen_dir" ] -} - -config("spvtools_internal_config") { - include_dirs = [ - ".", - "//third_party/spirv-headers/include", - ] - - configs = [ - ":spv_headers_public_config", - ":spvtools_include_gen_dirs", - ] - - cflags = [] - if (is_clang) { - cflags += [ - "-Wno-implicit-fallthrough", - "-Wno-newline-eof", - "-Wno-unreachable-code-break", - "-Wno-unreachable-code-return", - ] - } else if (!is_win) { - # Work around a false-positive on a Skia GCC 10 builder. - cflags += [ "-Wno-format-truncation" ] - } else { - # Make MSVC report the correct value for __cplusplus - cflags += [ "/Zc:__cplusplus" ] - } - - if (!is_win) { - cflags += [ "-std=c++17" ] - } else { - cflags += [ "/std:c++17" ] - } -} - ohos_source_set("deqp_spirvtool_opt_source") { sources = [ - "//third_party/spirv-tools/include/spirv-tools/instrument.hpp", - "//third_party/spirv-tools/include/spirv-tools/libspirv.h", - "//third_party/spirv-tools/include/spirv-tools/libspirv.hpp", - "//third_party/spirv-tools/include/spirv-tools/linker.hpp", - "//third_party/spirv-tools/include/spirv-tools/optimizer.hpp", "//third_party/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp", - "//third_party/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h", "//third_party/spirv-tools/source/opt/amd_ext_to_khr.cpp", - "//third_party/spirv-tools/source/opt/amd_ext_to_khr.h", - "//third_party/spirv-tools/source/opt/analyze_live_input_pass.cpp", - "//third_party/spirv-tools/source/opt/analyze_live_input_pass.h", "//third_party/spirv-tools/source/opt/basic_block.cpp", - "//third_party/spirv-tools/source/opt/basic_block.h", "//third_party/spirv-tools/source/opt/block_merge_pass.cpp", - "//third_party/spirv-tools/source/opt/block_merge_pass.h", "//third_party/spirv-tools/source/opt/block_merge_util.cpp", - "//third_party/spirv-tools/source/opt/block_merge_util.h", "//third_party/spirv-tools/source/opt/build_module.cpp", - "//third_party/spirv-tools/source/opt/build_module.h", "//third_party/spirv-tools/source/opt/ccp_pass.cpp", - "//third_party/spirv-tools/source/opt/ccp_pass.h", "//third_party/spirv-tools/source/opt/cfg.cpp", - "//third_party/spirv-tools/source/opt/cfg.h", "//third_party/spirv-tools/source/opt/cfg_cleanup_pass.cpp", - "//third_party/spirv-tools/source/opt/cfg_cleanup_pass.h", "//third_party/spirv-tools/source/opt/code_sink.cpp", - "//third_party/spirv-tools/source/opt/code_sink.h", "//third_party/spirv-tools/source/opt/combine_access_chains.cpp", - "//third_party/spirv-tools/source/opt/combine_access_chains.h", "//third_party/spirv-tools/source/opt/compact_ids_pass.cpp", - "//third_party/spirv-tools/source/opt/compact_ids_pass.h", "//third_party/spirv-tools/source/opt/composite.cpp", - "//third_party/spirv-tools/source/opt/composite.h", "//third_party/spirv-tools/source/opt/const_folding_rules.cpp", - "//third_party/spirv-tools/source/opt/const_folding_rules.h", "//third_party/spirv-tools/source/opt/constants.cpp", - "//third_party/spirv-tools/source/opt/constants.h", "//third_party/spirv-tools/source/opt/control_dependence.cpp", - "//third_party/spirv-tools/source/opt/control_dependence.h", "//third_party/spirv-tools/source/opt/convert_to_half_pass.cpp", - "//third_party/spirv-tools/source/opt/convert_to_half_pass.h", "//third_party/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp", - "//third_party/spirv-tools/source/opt/convert_to_sampled_image_pass.h", "//third_party/spirv-tools/source/opt/copy_prop_arrays.cpp", - "//third_party/spirv-tools/source/opt/copy_prop_arrays.h", "//third_party/spirv-tools/source/opt/dataflow.cpp", - "//third_party/spirv-tools/source/opt/dataflow.h", "//third_party/spirv-tools/source/opt/dead_branch_elim_pass.cpp", - "//third_party/spirv-tools/source/opt/dead_branch_elim_pass.h", "//third_party/spirv-tools/source/opt/dead_insert_elim_pass.cpp", - "//third_party/spirv-tools/source/opt/dead_insert_elim_pass.h", "//third_party/spirv-tools/source/opt/dead_variable_elimination.cpp", - "//third_party/spirv-tools/source/opt/dead_variable_elimination.h", "//third_party/spirv-tools/source/opt/debug_info_manager.cpp", - "//third_party/spirv-tools/source/opt/debug_info_manager.h", "//third_party/spirv-tools/source/opt/decoration_manager.cpp", - "//third_party/spirv-tools/source/opt/decoration_manager.h", "//third_party/spirv-tools/source/opt/def_use_manager.cpp", - "//third_party/spirv-tools/source/opt/def_use_manager.h", "//third_party/spirv-tools/source/opt/desc_sroa.cpp", - "//third_party/spirv-tools/source/opt/desc_sroa.h", "//third_party/spirv-tools/source/opt/desc_sroa_util.cpp", - "//third_party/spirv-tools/source/opt/desc_sroa_util.h", "//third_party/spirv-tools/source/opt/dominator_analysis.cpp", - "//third_party/spirv-tools/source/opt/dominator_analysis.h", "//third_party/spirv-tools/source/opt/dominator_tree.cpp", - "//third_party/spirv-tools/source/opt/dominator_tree.h", "//third_party/spirv-tools/source/opt/eliminate_dead_constant_pass.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_constant_pass.h", "//third_party/spirv-tools/source/opt/eliminate_dead_functions_pass.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_functions_pass.h", "//third_party/spirv-tools/source/opt/eliminate_dead_functions_util.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_functions_util.h", - "//third_party/spirv-tools/source/opt/eliminate_dead_io_components_pass.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_io_components_pass.h", + "//third_party/spirv-tools/source/opt/eliminate_dead_input_components_pass.cpp", "//third_party/spirv-tools/source/opt/eliminate_dead_members_pass.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_members_pass.h", - "//third_party/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp", - "//third_party/spirv-tools/source/opt/eliminate_dead_output_stores_pass.h", - "//third_party/spirv-tools/source/opt/empty_pass.h", "//third_party/spirv-tools/source/opt/feature_manager.cpp", - "//third_party/spirv-tools/source/opt/feature_manager.h", "//third_party/spirv-tools/source/opt/fix_func_call_arguments.cpp", - "//third_party/spirv-tools/source/opt/fix_func_call_arguments.h", "//third_party/spirv-tools/source/opt/fix_storage_class.cpp", - "//third_party/spirv-tools/source/opt/fix_storage_class.h", "//third_party/spirv-tools/source/opt/flatten_decoration_pass.cpp", - "//third_party/spirv-tools/source/opt/flatten_decoration_pass.h", "//third_party/spirv-tools/source/opt/fold.cpp", - "//third_party/spirv-tools/source/opt/fold.h", "//third_party/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp", - "//third_party/spirv-tools/source/opt/fold_spec_constant_op_and_composite_pass.h", "//third_party/spirv-tools/source/opt/folding_rules.cpp", - "//third_party/spirv-tools/source/opt/folding_rules.h", "//third_party/spirv-tools/source/opt/freeze_spec_constant_value_pass.cpp", - "//third_party/spirv-tools/source/opt/freeze_spec_constant_value_pass.h", "//third_party/spirv-tools/source/opt/function.cpp", - "//third_party/spirv-tools/source/opt/function.h", "//third_party/spirv-tools/source/opt/graphics_robust_access_pass.cpp", - "//third_party/spirv-tools/source/opt/graphics_robust_access_pass.h", "//third_party/spirv-tools/source/opt/if_conversion.cpp", - "//third_party/spirv-tools/source/opt/if_conversion.h", "//third_party/spirv-tools/source/opt/inline_exhaustive_pass.cpp", - "//third_party/spirv-tools/source/opt/inline_exhaustive_pass.h", "//third_party/spirv-tools/source/opt/inline_opaque_pass.cpp", - "//third_party/spirv-tools/source/opt/inline_opaque_pass.h", "//third_party/spirv-tools/source/opt/inline_pass.cpp", - "//third_party/spirv-tools/source/opt/inline_pass.h", "//third_party/spirv-tools/source/opt/inst_bindless_check_pass.cpp", - "//third_party/spirv-tools/source/opt/inst_bindless_check_pass.h", "//third_party/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp", - "//third_party/spirv-tools/source/opt/inst_buff_addr_check_pass.h", "//third_party/spirv-tools/source/opt/inst_debug_printf_pass.cpp", - "//third_party/spirv-tools/source/opt/inst_debug_printf_pass.h", "//third_party/spirv-tools/source/opt/instruction.cpp", - "//third_party/spirv-tools/source/opt/instruction.h", "//third_party/spirv-tools/source/opt/instruction_list.cpp", - "//third_party/spirv-tools/source/opt/instruction_list.h", "//third_party/spirv-tools/source/opt/instrument_pass.cpp", - "//third_party/spirv-tools/source/opt/instrument_pass.h", "//third_party/spirv-tools/source/opt/interface_var_sroa.cpp", - "//third_party/spirv-tools/source/opt/interface_var_sroa.h", "//third_party/spirv-tools/source/opt/interp_fixup_pass.cpp", - "//third_party/spirv-tools/source/opt/interp_fixup_pass.h", - "//third_party/spirv-tools/source/opt/invocation_interlock_placement_pass.cpp", - "//third_party/spirv-tools/source/opt/invocation_interlock_placement_pass.h", - "//third_party/spirv-tools/source/opt/ir_builder.h", "//third_party/spirv-tools/source/opt/ir_context.cpp", - "//third_party/spirv-tools/source/opt/ir_context.h", "//third_party/spirv-tools/source/opt/ir_loader.cpp", - "//third_party/spirv-tools/source/opt/ir_loader.h", - "//third_party/spirv-tools/source/opt/iterator.h", "//third_party/spirv-tools/source/opt/licm_pass.cpp", - "//third_party/spirv-tools/source/opt/licm_pass.h", - "//third_party/spirv-tools/source/opt/liveness.cpp", - "//third_party/spirv-tools/source/opt/liveness.h", "//third_party/spirv-tools/source/opt/local_access_chain_convert_pass.cpp", - "//third_party/spirv-tools/source/opt/local_access_chain_convert_pass.h", "//third_party/spirv-tools/source/opt/local_redundancy_elimination.cpp", - "//third_party/spirv-tools/source/opt/local_redundancy_elimination.h", "//third_party/spirv-tools/source/opt/local_single_block_elim_pass.cpp", - "//third_party/spirv-tools/source/opt/local_single_block_elim_pass.h", "//third_party/spirv-tools/source/opt/local_single_store_elim_pass.cpp", - "//third_party/spirv-tools/source/opt/local_single_store_elim_pass.h", - "//third_party/spirv-tools/source/opt/log.h", "//third_party/spirv-tools/source/opt/loop_dependence.cpp", - "//third_party/spirv-tools/source/opt/loop_dependence.h", "//third_party/spirv-tools/source/opt/loop_dependence_helpers.cpp", "//third_party/spirv-tools/source/opt/loop_descriptor.cpp", - "//third_party/spirv-tools/source/opt/loop_descriptor.h", "//third_party/spirv-tools/source/opt/loop_fission.cpp", - "//third_party/spirv-tools/source/opt/loop_fission.h", "//third_party/spirv-tools/source/opt/loop_fusion.cpp", - "//third_party/spirv-tools/source/opt/loop_fusion.h", "//third_party/spirv-tools/source/opt/loop_fusion_pass.cpp", - "//third_party/spirv-tools/source/opt/loop_fusion_pass.h", "//third_party/spirv-tools/source/opt/loop_peeling.cpp", - "//third_party/spirv-tools/source/opt/loop_peeling.h", "//third_party/spirv-tools/source/opt/loop_unroller.cpp", - "//third_party/spirv-tools/source/opt/loop_unroller.h", "//third_party/spirv-tools/source/opt/loop_unswitch_pass.cpp", - "//third_party/spirv-tools/source/opt/loop_unswitch_pass.h", "//third_party/spirv-tools/source/opt/loop_utils.cpp", - "//third_party/spirv-tools/source/opt/loop_utils.h", "//third_party/spirv-tools/source/opt/mem_pass.cpp", - "//third_party/spirv-tools/source/opt/mem_pass.h", "//third_party/spirv-tools/source/opt/merge_return_pass.cpp", - "//third_party/spirv-tools/source/opt/merge_return_pass.h", "//third_party/spirv-tools/source/opt/module.cpp", - "//third_party/spirv-tools/source/opt/module.h", - "//third_party/spirv-tools/source/opt/null_pass.h", "//third_party/spirv-tools/source/opt/optimizer.cpp", "//third_party/spirv-tools/source/opt/pass.cpp", - "//third_party/spirv-tools/source/opt/pass.h", "//third_party/spirv-tools/source/opt/pass_manager.cpp", - "//third_party/spirv-tools/source/opt/pass_manager.h", - "//third_party/spirv-tools/source/opt/passes.h", "//third_party/spirv-tools/source/opt/private_to_local_pass.cpp", - "//third_party/spirv-tools/source/opt/private_to_local_pass.h", "//third_party/spirv-tools/source/opt/propagator.cpp", - "//third_party/spirv-tools/source/opt/propagator.h", "//third_party/spirv-tools/source/opt/reduce_load_size.cpp", - "//third_party/spirv-tools/source/opt/reduce_load_size.h", "//third_party/spirv-tools/source/opt/redundancy_elimination.cpp", - "//third_party/spirv-tools/source/opt/redundancy_elimination.h", - "//third_party/spirv-tools/source/opt/reflect.h", "//third_party/spirv-tools/source/opt/register_pressure.cpp", - "//third_party/spirv-tools/source/opt/register_pressure.h", "//third_party/spirv-tools/source/opt/relax_float_ops_pass.cpp", - "//third_party/spirv-tools/source/opt/relax_float_ops_pass.h", "//third_party/spirv-tools/source/opt/remove_dontinline_pass.cpp", - "//third_party/spirv-tools/source/opt/remove_dontinline_pass.h", "//third_party/spirv-tools/source/opt/remove_duplicates_pass.cpp", - "//third_party/spirv-tools/source/opt/remove_duplicates_pass.h", "//third_party/spirv-tools/source/opt/remove_unused_interface_variables_pass.cpp", - "//third_party/spirv-tools/source/opt/remove_unused_interface_variables_pass.h", "//third_party/spirv-tools/source/opt/replace_desc_array_access_using_var_index.cpp", - "//third_party/spirv-tools/source/opt/replace_desc_array_access_using_var_index.h", "//third_party/spirv-tools/source/opt/replace_invalid_opc.cpp", - "//third_party/spirv-tools/source/opt/replace_invalid_opc.h", "//third_party/spirv-tools/source/opt/scalar_analysis.cpp", - "//third_party/spirv-tools/source/opt/scalar_analysis.h", - "//third_party/spirv-tools/source/opt/scalar_analysis_nodes.h", "//third_party/spirv-tools/source/opt/scalar_analysis_simplification.cpp", "//third_party/spirv-tools/source/opt/scalar_replacement_pass.cpp", - "//third_party/spirv-tools/source/opt/scalar_replacement_pass.h", "//third_party/spirv-tools/source/opt/set_spec_constant_default_value_pass.cpp", - "//third_party/spirv-tools/source/opt/set_spec_constant_default_value_pass.h", "//third_party/spirv-tools/source/opt/simplification_pass.cpp", - "//third_party/spirv-tools/source/opt/simplification_pass.h", "//third_party/spirv-tools/source/opt/spread_volatile_semantics.cpp", - "//third_party/spirv-tools/source/opt/spread_volatile_semantics.h", "//third_party/spirv-tools/source/opt/ssa_rewrite_pass.cpp", - "//third_party/spirv-tools/source/opt/ssa_rewrite_pass.h", "//third_party/spirv-tools/source/opt/strength_reduction_pass.cpp", - "//third_party/spirv-tools/source/opt/strength_reduction_pass.h", "//third_party/spirv-tools/source/opt/strip_debug_info_pass.cpp", - "//third_party/spirv-tools/source/opt/strip_debug_info_pass.h", "//third_party/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp", - "//third_party/spirv-tools/source/opt/strip_nonsemantic_info_pass.h", "//third_party/spirv-tools/source/opt/struct_cfg_analysis.cpp", - "//third_party/spirv-tools/source/opt/struct_cfg_analysis.h", - "//third_party/spirv-tools/source/opt/switch_descriptorset_pass.cpp", - "//third_party/spirv-tools/source/opt/switch_descriptorset_pass.h", - "//third_party/spirv-tools/source/opt/tree_iterator.h", - "//third_party/spirv-tools/source/opt/trim_capabilities_pass.cpp", - "//third_party/spirv-tools/source/opt/trim_capabilities_pass.h", "//third_party/spirv-tools/source/opt/type_manager.cpp", - "//third_party/spirv-tools/source/opt/type_manager.h", "//third_party/spirv-tools/source/opt/types.cpp", - "//third_party/spirv-tools/source/opt/types.h", "//third_party/spirv-tools/source/opt/unify_const_pass.cpp", - "//third_party/spirv-tools/source/opt/unify_const_pass.h", "//third_party/spirv-tools/source/opt/upgrade_memory_model.cpp", - "//third_party/spirv-tools/source/opt/upgrade_memory_model.h", "//third_party/spirv-tools/source/opt/value_number_table.cpp", - "//third_party/spirv-tools/source/opt/value_number_table.h", "//third_party/spirv-tools/source/opt/vector_dce.cpp", - "//third_party/spirv-tools/source/opt/vector_dce.h", "//third_party/spirv-tools/source/opt/workaround1209.cpp", - "//third_party/spirv-tools/source/opt/workaround1209.h", "//third_party/spirv-tools/source/opt/wrap_opkill.cpp", - "//third_party/spirv-tools/source/opt/wrap_opkill.h", - "//third_party/spirv-tools/source/util/timer.cpp", - "//third_party/spirv-tools/source/util/timer.h", ] include_dirs = deqp_common_include_dirs @@ -323,17 +146,9 @@ ohos_source_set("deqp_spirvtool_opt_source") { "//third_party/spirv-headers/include", "//third_party/spirv-headers/include/spirv/unified1", "//third_party/spirv-tools/include", - "//third_party/spirv-tools/source/util", ] - if (build_with_chromium) { - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - } - configs = [ ":deqp_spirvtool_opt_config" ] - configs += [ ":spv_headers_public_config" ] - configs += [ ":spvtools_internal_config" ] } ohos_static_library("libdeqp_spirvtools-opt") { diff --git a/source/opt/CMakeLists.txt b/source/opt/CMakeLists.txt index 6ebbfbf0..75fe4c0f 100644 --- a/source/opt/CMakeLists.txt +++ b/source/opt/CMakeLists.txt @@ -15,7 +15,6 @@ set(SPIRV_TOOLS_OPT_SOURCES fix_func_call_arguments.h aggressive_dead_code_elim_pass.h amd_ext_to_khr.h - analyze_live_input_pass.h basic_block.h block_merge_pass.h block_merge_util.h @@ -47,9 +46,8 @@ set(SPIRV_TOOLS_OPT_SOURCES eliminate_dead_constant_pass.h eliminate_dead_functions_pass.h eliminate_dead_functions_util.h - eliminate_dead_io_components_pass.h + eliminate_dead_input_components_pass.h eliminate_dead_members_pass.h - eliminate_dead_output_stores_pass.h empty_pass.h feature_manager.h fix_storage_class.h @@ -71,13 +69,11 @@ set(SPIRV_TOOLS_OPT_SOURCES instruction_list.h instrument_pass.h interface_var_sroa.h - invocation_interlock_placement_pass.h interp_fixup_pass.h ir_builder.h ir_context.h ir_loader.h licm_pass.h - liveness.h local_access_chain_convert_pass.h local_redundancy_elimination.h local_single_block_elim_pass.h @@ -122,9 +118,7 @@ set(SPIRV_TOOLS_OPT_SOURCES strip_debug_info_pass.h strip_nonsemantic_info_pass.h struct_cfg_analysis.h - switch_descriptorset_pass.h tree_iterator.h - trim_capabilities_pass.h type_manager.h types.h unify_const_pass.h @@ -137,7 +131,6 @@ set(SPIRV_TOOLS_OPT_SOURCES fix_func_call_arguments.cpp aggressive_dead_code_elim_pass.cpp amd_ext_to_khr.cpp - analyze_live_input_pass.cpp basic_block.cpp block_merge_pass.cpp block_merge_util.cpp @@ -169,9 +162,8 @@ set(SPIRV_TOOLS_OPT_SOURCES eliminate_dead_constant_pass.cpp eliminate_dead_functions_pass.cpp eliminate_dead_functions_util.cpp - eliminate_dead_io_components_pass.cpp + eliminate_dead_input_components_pass.cpp eliminate_dead_members_pass.cpp - eliminate_dead_output_stores_pass.cpp feature_manager.cpp fix_storage_class.cpp flatten_decoration_pass.cpp @@ -192,12 +184,10 @@ set(SPIRV_TOOLS_OPT_SOURCES instruction_list.cpp instrument_pass.cpp interface_var_sroa.cpp - invocation_interlock_placement_pass.cpp interp_fixup_pass.cpp ir_context.cpp ir_loader.cpp licm_pass.cpp - liveness.cpp local_access_chain_convert_pass.cpp local_redundancy_elimination.cpp local_single_block_elim_pass.cpp @@ -240,8 +230,6 @@ set(SPIRV_TOOLS_OPT_SOURCES strip_debug_info_pass.cpp strip_nonsemantic_info_pass.cpp struct_cfg_analysis.cpp - switch_descriptorset_pass.cpp - trim_capabilities_pass.cpp type_manager.cpp types.cpp unify_const_pass.cpp @@ -277,7 +265,10 @@ set_property(TARGET SPIRV-Tools-opt PROPERTY FOLDER "SPIRV-Tools libraries") spvtools_check_symbol_exports(SPIRV-Tools-opt) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-opt EXPORT SPIRV-Tools-optTargets) + install(TARGETS SPIRV-Tools-opt EXPORT SPIRV-Tools-optTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake) spvtools_config_package_dir(SPIRV-Tools-opt PACKAGE_DIR) diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index b372571f..7fa5c8a9 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -21,58 +21,61 @@ #include #include "source/cfa.h" +#include "source/latest_version_glsl_std_450_header.h" #include "source/opt/eliminate_dead_functions_util.h" #include "source/opt/ir_builder.h" +#include "source/opt/iterator.h" #include "source/opt/reflect.h" #include "source/spirv_constant.h" #include "source/util/string_utils.h" namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kTypePointerStorageClassInIdx = 0; -constexpr uint32_t kEntryPointFunctionIdInIdx = 1; -constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; -constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; -constexpr uint32_t kCopyMemoryTargetAddrInIdx = 0; -constexpr uint32_t kCopyMemorySourceAddrInIdx = 1; -constexpr uint32_t kLoadSourceAddrInIdx = 0; -constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; -constexpr uint32_t kGlobalVariableVariableIndex = 12; +const uint32_t kTypePointerStorageClassInIdx = 0; +const uint32_t kEntryPointFunctionIdInIdx = 1; +const uint32_t kSelectionMergeMergeBlockIdInIdx = 0; +const uint32_t kLoopMergeContinueBlockIdInIdx = 1; +const uint32_t kCopyMemoryTargetAddrInIdx = 0; +const uint32_t kCopyMemorySourceAddrInIdx = 1; +const uint32_t kLoadSourceAddrInIdx = 0; +const uint32_t kDebugDeclareOperandVariableIndex = 5; +const uint32_t kGlobalVariableVariableIndex = 12; // Sorting functor to present annotation instructions in an easy-to-process // order. The functor orders by opcode first and falls back on unique id // ordering if both instructions have the same opcode. // // Desired priority: -// spv::Op::OpGroupDecorate -// spv::Op::OpGroupMemberDecorate -// spv::Op::OpDecorate -// spv::Op::OpMemberDecorate -// spv::Op::OpDecorateId -// spv::Op::OpDecorateStringGOOGLE -// spv::Op::OpDecorationGroup +// SpvOpGroupDecorate +// SpvOpGroupMemberDecorate +// SpvOpDecorate +// SpvOpMemberDecorate +// SpvOpDecorateId +// SpvOpDecorateStringGOOGLE +// SpvOpDecorationGroup struct DecorationLess { bool operator()(const Instruction* lhs, const Instruction* rhs) const { assert(lhs && rhs); - spv::Op lhsOp = lhs->opcode(); - spv::Op rhsOp = rhs->opcode(); + SpvOp lhsOp = lhs->opcode(); + SpvOp rhsOp = rhs->opcode(); if (lhsOp != rhsOp) { #define PRIORITY_CASE(opcode) \ if (lhsOp == opcode && rhsOp != opcode) return true; \ if (rhsOp == opcode && lhsOp != opcode) return false; // OpGroupDecorate and OpGroupMember decorate are highest priority to // eliminate dead targets early and simplify subsequent checks. - PRIORITY_CASE(spv::Op::OpGroupDecorate) - PRIORITY_CASE(spv::Op::OpGroupMemberDecorate) - PRIORITY_CASE(spv::Op::OpDecorate) - PRIORITY_CASE(spv::Op::OpMemberDecorate) - PRIORITY_CASE(spv::Op::OpDecorateId) - PRIORITY_CASE(spv::Op::OpDecorateStringGOOGLE) + PRIORITY_CASE(SpvOpGroupDecorate) + PRIORITY_CASE(SpvOpGroupMemberDecorate) + PRIORITY_CASE(SpvOpDecorate) + PRIORITY_CASE(SpvOpMemberDecorate) + PRIORITY_CASE(SpvOpDecorateId) + PRIORITY_CASE(SpvOpDecorateStringGOOGLE) // OpDecorationGroup is lowest priority to ensure use/def chains remain // usable for instructions that target this group. - PRIORITY_CASE(spv::Op::OpDecorationGroup) + PRIORITY_CASE(SpvOpDecorationGroup) #undef PRIORITY_CASE } @@ -83,26 +86,25 @@ struct DecorationLess { } // namespace -bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, - spv::StorageClass storageClass) { +bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, uint32_t storageClass) { if (varId == 0) return false; const Instruction* varInst = get_def_use_mgr()->GetDef(varId); - const spv::Op op = varInst->opcode(); - if (op != spv::Op::OpVariable) return false; + const SpvOp op = varInst->opcode(); + if (op != SpvOpVariable) return false; const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (varTypeInst->opcode() != spv::Op::OpTypePointer) return false; - return spv::StorageClass(varTypeInst->GetSingleWordInOperand( - kTypePointerStorageClassInIdx)) == storageClass; + if (varTypeInst->opcode() != SpvOpTypePointer) return false; + return varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) == + storageClass; } bool AggressiveDCEPass::IsLocalVar(uint32_t varId, Function* func) { - if (IsVarOfStorage(varId, spv::StorageClass::Function)) { + if (IsVarOfStorage(varId, SpvStorageClassFunction)) { return true; } - if (!IsVarOfStorage(varId, spv::StorageClass::Private) && - !IsVarOfStorage(varId, spv::StorageClass::Workgroup)) { + if (!IsVarOfStorage(varId, SpvStorageClassPrivate) && + !IsVarOfStorage(varId, SpvStorageClassWorkgroup)) { return false; } @@ -120,21 +122,21 @@ void AggressiveDCEPass::AddStores(Function* func, uint32_t ptrId) { if (blk && blk->GetParent() != func) return; switch (user->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpCopyObject: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpCopyObject: this->AddStores(func, user->result_id()); break; - case spv::Op::OpLoad: + case SpvOpLoad: break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: if (user->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx) == ptrId) { AddToWorklist(user); } break; // If default, assume it stores e.g. frexp, modf, function call - case spv::Op::OpStore: + case SpvOpStore: default: AddToWorklist(user); break; @@ -152,12 +154,11 @@ bool AggressiveDCEPass::AllExtensionsSupported() const { // Only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise // around unknown extended instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == spv::Op::OpExtInstImport && + assert(inst.opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && - (extension_name != "NonSemantic.Shader.DebugInfo.100") && - (extension_name != "NonSemantic.DebugPrintf")) { + extension_name != "NonSemantic.Shader.DebugInfo.100") { return false; } } @@ -171,11 +172,11 @@ bool AggressiveDCEPass::IsTargetDead(Instruction* inst) { // This must be a decoration group. We go through annotations in a specific // order. So if this is not used by any group or group member decorates, it // is dead. - assert(tInst->opcode() == spv::Op::OpDecorationGroup); + assert(tInst->opcode() == SpvOpDecorationGroup); bool dead = true; get_def_use_mgr()->ForEachUser(tInst, [&dead](Instruction* user) { - if (user->opcode() == spv::Op::OpGroupDecorate || - user->opcode() == spv::Op::OpGroupMemberDecorate) + if (user->opcode() == SpvOpGroupDecorate || + user->opcode() == SpvOpGroupMemberDecorate) dead = false; }); return dead; @@ -196,7 +197,7 @@ void AggressiveDCEPass::ProcessLoad(Function* func, uint32_t varId) { void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) { std::unique_ptr newBranch( - new Instruction(context(), spv::Op::OpBranch, 0, 0, + new Instruction(context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); context()->AnalyzeDefUse(&*newBranch); context()->set_instr_block(&*newBranch, bp); @@ -205,8 +206,8 @@ void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) { void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( Instruction* mergeInst) { - assert(mergeInst->opcode() == spv::Op::OpSelectionMerge || - mergeInst->opcode() == spv::Op::OpLoopMerge); + assert(mergeInst->opcode() == SpvOpSelectionMerge || + mergeInst->opcode() == SpvOpLoopMerge); BasicBlock* header = context()->get_instr_block(mergeInst); const uint32_t mergeId = mergeInst->GetSingleWordInOperand(0); @@ -222,7 +223,7 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( } }); - if (mergeInst->opcode() != spv::Op::OpLoopMerge) { + if (mergeInst->opcode() != SpvOpLoopMerge) { return; } @@ -230,27 +231,26 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( const uint32_t contId = mergeInst->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); get_def_use_mgr()->ForEachUser(contId, [&contId, this](Instruction* user) { - spv::Op op = user->opcode(); - if (op == spv::Op::OpBranchConditional || op == spv::Op::OpSwitch) { + SpvOp op = user->opcode(); + if (op == SpvOpBranchConditional || op == SpvOpSwitch) { // A conditional branch or switch can only be a continue if it does not // have a merge instruction or its merge block is not the continue block. Instruction* hdrMerge = GetMergeInstruction(user); - if (hdrMerge != nullptr && - hdrMerge->opcode() == spv::Op::OpSelectionMerge) { + if (hdrMerge != nullptr && hdrMerge->opcode() == SpvOpSelectionMerge) { uint32_t hdrMergeId = hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); if (hdrMergeId == contId) return; // Need to mark merge instruction too AddToWorklist(hdrMerge); } - } else if (op == spv::Op::OpBranch) { + } else if (op == SpvOpBranch) { // An unconditional branch can only be a continue if it is not // branching to its own merge block. BasicBlock* blk = context()->get_instr_block(user); Instruction* hdrBranch = GetHeaderBranch(blk); if (hdrBranch == nullptr) return; Instruction* hdrMerge = GetMergeInstruction(hdrBranch); - if (hdrMerge->opcode() == spv::Op::OpLoopMerge) return; + if (hdrMerge->opcode() == SpvOpLoopMerge) return; uint32_t hdrMergeId = hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); if (contId == hdrMergeId) return; @@ -277,11 +277,11 @@ bool AggressiveDCEPass::KillDeadInstructions( uint32_t merge_block_id = 0; (*bi)->ForEachInst([this, &modified, &merge_block_id](Instruction* inst) { if (IsLive(inst)) return; - if (inst->opcode() == spv::Op::OpLabel) return; + if (inst->opcode() == SpvOpLabel) return; // If dead instruction is selection merge, remember merge block // for new branch at end of block - if (inst->opcode() == spv::Op::OpSelectionMerge || - inst->opcode() == spv::Op::OpLoopMerge) + if (inst->opcode() == SpvOpSelectionMerge || + inst->opcode() == SpvOpLoopMerge) merge_block_id = inst->GetSingleWordInOperand(0); to_kill_.push_back(inst); modified = true; @@ -295,19 +295,19 @@ bool AggressiveDCEPass::KillDeadInstructions( } auto merge_terminator = (*bi)->terminator(); - if (merge_terminator->opcode() == spv::Op::OpUnreachable) { + if (merge_terminator->opcode() == SpvOpUnreachable) { // The merge was unreachable. This is undefined behaviour so just // return (or return an undef). Then mark the new return as live. auto func_ret_type_inst = get_def_use_mgr()->GetDef(func->type_id()); - if (func_ret_type_inst->opcode() == spv::Op::OpTypeVoid) { - merge_terminator->SetOpcode(spv::Op::OpReturn); + if (func_ret_type_inst->opcode() == SpvOpTypeVoid) { + merge_terminator->SetOpcode(SpvOpReturn); } else { // Find an undef for the return value and make sure it gets kept by // the pass. auto undef_id = Type2Undef(func->type_id()); auto undef = get_def_use_mgr()->GetDef(undef_id); live_insts_.Set(undef->unique_id()); - merge_terminator->SetOpcode(spv::Op::OpReturnValue); + merge_terminator->SetOpcode(SpvOpReturnValue); merge_terminator->SetInOperands({{SPV_OPERAND_TYPE_ID, {undef_id}}}); get_def_use_mgr()->AnalyzeInstUse(merge_terminator); } @@ -369,11 +369,11 @@ void AggressiveDCEPass::AddDecorationsToWorkList(const Instruction* inst) { // We only care about OpDecorateId instructions because the are the only // decorations that will reference an id that will have to be kept live // because of that use. - if (dec->opcode() != spv::Op::OpDecorateId) { + if (dec->opcode() != SpvOpDecorateId) { continue; } - if (spv::Decoration(dec->GetSingleWordInOperand(1)) == - spv::Decoration::HlslCounterBufferGOOGLE) { + if (dec->GetSingleWordInOperand(1) == + SpvDecorationHlslCounterBufferGOOGLE) { // These decorations should not force the use id to be live. It will be // removed if either the target or the in operand are dead. continue; @@ -391,7 +391,7 @@ void AggressiveDCEPass::MarkLoadedVariablesAsLive(Function* func, } std::vector AggressiveDCEPass::GetLoadedVariables(Instruction* inst) { - if (inst->opcode() == spv::Op::OpFunctionCall) { + if (inst->opcode() == SpvOpFunctionCall) { return GetLoadedVariablesFromFunctionCall(inst); } uint32_t var_id = GetLoadedVariableFromNonFunctionCalls(inst); @@ -409,11 +409,11 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( } switch (inst->opcode()) { - case spv::Op::OpLoad: - case spv::Op::OpImageTexelPointer: + case SpvOpLoad: + case SpvOpImageTexelPointer: return GetVariableId(inst->GetSingleWordInOperand(kLoadSourceAddrInIdx)); - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: return GetVariableId( inst->GetSingleWordInOperand(kCopyMemorySourceAddrInIdx)); default: @@ -436,11 +436,8 @@ uint32_t AggressiveDCEPass::GetLoadedVariableFromNonFunctionCalls( std::vector AggressiveDCEPass::GetLoadedVariablesFromFunctionCall( const Instruction* inst) { - assert(inst->opcode() == spv::Op::OpFunctionCall); + assert(inst->opcode() == SpvOpFunctionCall); std::vector live_variables; - // NOTE: we should only be checking function call parameters here, not the - // function itself, however, `IsPtr` will trivially return false for - // OpFunction inst->ForEachInId([this, &live_variables](const uint32_t* operand_id) { if (!IsPtr(*operand_id)) return; uint32_t var_id = GetVariableId(*operand_id); @@ -484,7 +481,7 @@ void AggressiveDCEPass::MarkBlockAsLive(Instruction* inst) { // the loop, so the loop construct must be live. We exclude the label because // it does not matter how many times it is executed. This could be extended // to more instructions, but we will need it for now. - if (inst->opcode() != spv::Op::OpLabel) + if (inst->opcode() != SpvOpLabel) MarkLoopConstructAsLiveIfLoopHeader(basic_block); Instruction* next_branch_inst = GetBranchForNextHeader(basic_block); @@ -494,8 +491,8 @@ void AggressiveDCEPass::MarkBlockAsLive(Instruction* inst) { AddToWorklist(mergeInst); } - if (inst->opcode() == spv::Op::OpLoopMerge || - inst->opcode() == spv::Op::OpSelectionMerge) { + if (inst->opcode() == SpvOpLoopMerge || + inst->opcode() == SpvOpSelectionMerge) { AddBreaksAndContinuesToWorklist(inst); } } @@ -532,27 +529,27 @@ void AggressiveDCEPass::InitializeWorkList( // cleaned up. for (auto& bi : structured_order) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - spv::Op op = ii->opcode(); + SpvOp op = ii->opcode(); if (ii->IsBranch()) { continue; } switch (op) { - case spv::Op::OpStore: { + case SpvOpStore: { uint32_t var_id = 0; (void)GetPtr(&*ii, &var_id); if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); } break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: { + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: { uint32_t var_id = 0; uint32_t target_addr_id = ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx); (void)GetPtr(target_addr_id, &var_id); if (!IsLocalVar(var_id, func)) AddToWorklist(&*ii); } break; - case spv::Op::OpLoopMerge: - case spv::Op::OpSelectionMerge: - case spv::Op::OpUnreachable: + case SpvOpLoopMerge: + case SpvOpSelectionMerge: + case SpvOpUnreachable: break; default: { // Function calls, atomics, function params, function returns, etc. @@ -581,10 +578,8 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { auto* var = get_def_use_mgr()->GetDef(entry.GetSingleWordInOperand(i)); auto storage_class = var->GetSingleWordInOperand(0u); // Vulkan support outputs without an associated input, but not inputs - // without an associated output. Don't remove outputs unless explicitly - // allowed. - if (!remove_outputs_ && - spv::StorageClass(storage_class) == spv::StorageClass::Output) { + // without an associated output. + if (storage_class == SpvStorageClassOutput) { AddToWorklist(var); } } @@ -593,29 +588,24 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { } } for (auto& anno : get_module()->annotations()) { - if (anno.opcode() == spv::Op::OpDecorate) { + if (anno.opcode() == SpvOpDecorate) { // Keep workgroup size. - if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::BuiltIn && - spv::BuiltIn(anno.GetSingleWordInOperand(2u)) == - spv::BuiltIn::WorkgroupSize) { + if (anno.GetSingleWordInOperand(1u) == SpvDecorationBuiltIn && + anno.GetSingleWordInOperand(2u) == SpvBuiltInWorkgroupSize) { AddToWorklist(&anno); } if (context()->preserve_bindings()) { // Keep all bindings. - if ((spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::DescriptorSet) || - (spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::Binding)) { + if ((anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet) || + (anno.GetSingleWordInOperand(1u) == SpvDecorationBinding)) { AddToWorklist(&anno); } } if (context()->preserve_spec_constants()) { // Keep all specialization constant instructions - if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::SpecId) { + if (anno.GetSingleWordInOperand(1u) == SpvDecorationSpecId) { AddToWorklist(&anno); } } @@ -634,7 +624,7 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { debug_global_seen = true; dbg.ForEachInId([this](const uint32_t* iid) { Instruction* in_inst = get_def_use_mgr()->GetDef(*iid); - if (in_inst->opcode() == spv::Op::OpVariable) return; + if (in_inst->opcode() == SpvOpVariable) return; AddToWorklist(in_inst); }); } @@ -657,19 +647,19 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() { Pass::Status AggressiveDCEPass::ProcessImpl() { // Current functionality assumes shader capability // TODO(greg-lunarg): Handle additional capabilities - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) return Status::SuccessWithoutChange; // Current functionality assumes relaxed logical addressing (see // instruction.h) // TODO(greg-lunarg): Handle non-logical addressing - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) return Status::SuccessWithoutChange; // The variable pointer extension is no longer needed to use the capability, // so we have to look for the capability. if (context()->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)) + SpvCapabilityVariablePointersStorageBuffer)) return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, @@ -753,7 +743,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { bool modified = false; Instruction* instruction = &*get_module()->debug2_begin(); while (instruction) { - if (instruction->opcode() != spv::Op::OpName) { + if (instruction->opcode() != SpvOpName) { instruction = instruction->NextNode(); continue; } @@ -774,22 +764,22 @@ bool AggressiveDCEPass::ProcessGlobalValues() { std::sort(annotations.begin(), annotations.end(), DecorationLess()); for (auto annotation : annotations) { switch (annotation->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpMemberDecorate: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorateStringGOOGLE: + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } break; - case spv::Op::OpDecorateId: + case SpvOpDecorateId: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } else { - if (spv::Decoration(annotation->GetSingleWordInOperand(1)) == - spv::Decoration::HlslCounterBufferGOOGLE) { + if (annotation->GetSingleWordInOperand(1) == + SpvDecorationHlslCounterBufferGOOGLE) { // HlslCounterBuffer will reference an id other than the target. // If that id is dead, then the decoration can be removed as well. uint32_t counter_buffer_id = annotation->GetSingleWordInOperand(2); @@ -802,7 +792,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } } break; - case spv::Op::OpGroupDecorate: { + case SpvOpGroupDecorate: { // Go through the targets of this group decorate. Remove each dead // target. If all targets are dead, remove this decoration. bool dead = true; @@ -828,7 +818,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } break; } - case spv::Op::OpGroupMemberDecorate: { + case SpvOpGroupMemberDecorate: { // Go through the targets of this group member decorate. Remove each // dead target (and member index). If all targets are dead, remove this // decoration. @@ -856,7 +846,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { } break; } - case spv::Op::OpDecorationGroup: + case SpvOpDecorationGroup: // By the time we hit decoration groups we've checked everything that // can target them. So if they have no uses they must be dead. if (get_def_use_mgr()->NumUsers(annotation) == 0) { @@ -897,7 +887,7 @@ bool AggressiveDCEPass::ProcessGlobalValues() { // this live as it does not have a result id. This is a little too // conservative since it is not known if the structure type that needed // it is still live. TODO(greg-lunarg): Only save if needed. - if (val.opcode() == spv::Op::OpTypeForwardPointer) { + if (val.opcode() == SpvOpTypeForwardPointer) { uint32_t ptr_ty_id = val.GetSingleWordInOperand(0); Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); if (IsLive(ptr_ty_inst)) continue; @@ -941,8 +931,6 @@ Pass::Status AggressiveDCEPass::Process() { void AggressiveDCEPass::InitExtensions() { extensions_allowlist_.clear(); - - // clang-format off extensions_allowlist_.insert({ "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_trinary_minmax", @@ -990,7 +978,6 @@ void AggressiveDCEPass::InitExtensions() { "SPV_KHR_ray_query", "SPV_EXT_fragment_invocation_density", "SPV_EXT_physical_storage_buffer", - "SPV_KHR_physical_storage_buffer", "SPV_KHR_terminate_invocation", "SPV_KHR_shader_clock", "SPV_KHR_vulkan_memory_model", @@ -1000,12 +987,7 @@ void AggressiveDCEPass::InitExtensions() { "SPV_KHR_non_semantic_info", "SPV_KHR_uniform_group_instructions", "SPV_KHR_fragment_shader_barycentric", - "SPV_NV_bindless_texture", - "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock", - "SPV_NV_compute_shader_derivatives" }); - // clang-format on } Instruction* AggressiveDCEPass::GetHeaderBranch(BasicBlock* blk) { @@ -1101,9 +1083,8 @@ bool AggressiveDCEPass::IsEntryPoint(Function* func) { } bool AggressiveDCEPass::HasCall(Function* func) { - return !func->WhileEachInst([](Instruction* inst) { - return inst->opcode() != spv::Op::OpFunctionCall; - }); + return !func->WhileEachInst( + [](Instruction* inst) { return inst->opcode() != SpvOpFunctionCall; }); } void AggressiveDCEPass::MarkFirstBlockAsLive(Function* func) { diff --git a/source/opt/aggressive_dead_code_elim_pass.h b/source/opt/aggressive_dead_code_elim_pass.h index fbe08ad0..c1291dc4 100644 --- a/source/opt/aggressive_dead_code_elim_pass.h +++ b/source/opt/aggressive_dead_code_elim_pass.h @@ -44,10 +44,8 @@ class AggressiveDCEPass : public MemPass { using GetBlocksFunction = std::function*(const BasicBlock*)>; - AggressiveDCEPass(bool preserve_interface = false, - bool remove_outputs = false) - : preserve_interface_(preserve_interface), - remove_outputs_(remove_outputs) {} + AggressiveDCEPass(bool preserve_interface = false) + : preserve_interface_(preserve_interface) {} const char* name() const override { return "eliminate-dead-code-aggressive"; } Status Process() override; @@ -65,14 +63,9 @@ class AggressiveDCEPass : public MemPass { // is not allowed. bool preserve_interface_; - // Output variables can be removed from the interface if this is true. - // This is safe if the caller knows that the corresponding input variable - // in the following shader has been removed. It is false by default. - bool remove_outputs_; - // Return true if |varId| is a variable of |storageClass|. |varId| must either // be 0 or the result of an instruction. - bool IsVarOfStorage(uint32_t varId, spv::StorageClass storageClass); + bool IsVarOfStorage(uint32_t varId, uint32_t storageClass); // Return true if the instance of the variable |varId| can only be access in // |func|. For example, a function scope variable, or a private variable diff --git a/source/opt/amd_ext_to_khr.cpp b/source/opt/amd_ext_to_khr.cpp index a314567f..dd9bafda 100644 --- a/source/opt/amd_ext_to_khr.cpp +++ b/source/opt/amd_ext_to_khr.cpp @@ -24,6 +24,7 @@ namespace spvtools { namespace opt { + namespace { enum AmdShaderBallotExtOpcodes { @@ -135,19 +136,19 @@ bool ReplaceTrinaryMid(IRContext* ctx, Instruction* inst, // Returns a folding rule that will replace the opcode with |opcode| and add // the capabilities required. The folding rule assumes it is folding an // OpGroup*NonUniformAMD instruction from the SPV_AMD_shader_ballot extension. -template +template bool ReplaceGroupNonuniformOperationOpCode( IRContext* ctx, Instruction* inst, const std::vector&) { switch (new_opcode) { - case spv::Op::OpGroupNonUniformIAdd: - case spv::Op::OpGroupNonUniformFAdd: - case spv::Op::OpGroupNonUniformUMin: - case spv::Op::OpGroupNonUniformSMin: - case spv::Op::OpGroupNonUniformFMin: - case spv::Op::OpGroupNonUniformUMax: - case spv::Op::OpGroupNonUniformSMax: - case spv::Op::OpGroupNonUniformFMax: + case SpvOpGroupNonUniformIAdd: + case SpvOpGroupNonUniformFAdd: + case SpvOpGroupNonUniformUMin: + case SpvOpGroupNonUniformSMin: + case SpvOpGroupNonUniformFMin: + case SpvOpGroupNonUniformUMax: + case SpvOpGroupNonUniformSMax: + case SpvOpGroupNonUniformFMax: break; default: assert( @@ -156,21 +157,21 @@ bool ReplaceGroupNonuniformOperationOpCode( } switch (inst->opcode()) { - case spv::Op::OpGroupIAddNonUniformAMD: - case spv::Op::OpGroupFAddNonUniformAMD: - case spv::Op::OpGroupUMinNonUniformAMD: - case spv::Op::OpGroupSMinNonUniformAMD: - case spv::Op::OpGroupFMinNonUniformAMD: - case spv::Op::OpGroupUMaxNonUniformAMD: - case spv::Op::OpGroupSMaxNonUniformAMD: - case spv::Op::OpGroupFMaxNonUniformAMD: + case SpvOpGroupIAddNonUniformAMD: + case SpvOpGroupFAddNonUniformAMD: + case SpvOpGroupUMinNonUniformAMD: + case SpvOpGroupSMinNonUniformAMD: + case SpvOpGroupFMinNonUniformAMD: + case SpvOpGroupUMaxNonUniformAMD: + case SpvOpGroupSMaxNonUniformAMD: + case SpvOpGroupFMaxNonUniformAMD: break; default: assert(false && "Should be replacing a group non uniform arithmetic operation."); } - ctx->AddCapability(spv::Capability::GroupNonUniformArithmetic); + ctx->AddCapability(SpvCapabilityGroupNonUniformArithmetic); inst->SetOpcode(new_opcode); return true; } @@ -214,8 +215,8 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); ctx->AddExtension("SPV_KHR_shader_ballot"); - ctx->AddCapability(spv::Capability::GroupNonUniformBallot); - ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); + ctx->AddCapability(SpvCapabilityGroupNonUniformBallot); + ctx->AddCapability(SpvCapabilityGroupNonUniformShuffle); InstructionBuilder ir_builder( ctx, inst, @@ -225,8 +226,8 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, uint32_t offset_id = inst->GetSingleWordInOperand(3); // Get the subgroup invocation id. - uint32_t var_id = ctx->GetBuiltinInputVarId( - uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + uint32_t var_id = + ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); Instruction* var_ptr_type = @@ -238,38 +239,35 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, uint32_t quad_mask = ir_builder.GetUintConstantId(3); // This gives the offset in the group of 4 of this invocation. - Instruction* quad_idx = ir_builder.AddBinaryOp( - uint_type_id, spv::Op::OpBitwiseAnd, id->result_id(), quad_mask); + Instruction* quad_idx = ir_builder.AddBinaryOp(uint_type_id, SpvOpBitwiseAnd, + id->result_id(), quad_mask); // Get the invocation id of the first invocation in the group of 4. - Instruction* quad_ldr = - ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseXor, - id->result_id(), quad_idx->result_id()); + Instruction* quad_ldr = ir_builder.AddBinaryOp( + uint_type_id, SpvOpBitwiseXor, id->result_id(), quad_idx->result_id()); // Get the offset of the target invocation from the offset vector. Instruction* my_offset = - ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpVectorExtractDynamic, - offset_id, quad_idx->result_id()); + ir_builder.AddBinaryOp(uint_type_id, SpvOpVectorExtractDynamic, offset_id, + quad_idx->result_id()); // Determine the index of the invocation to read from. - Instruction* target_inv = - ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpIAdd, - quad_ldr->result_id(), my_offset->result_id()); + Instruction* target_inv = ir_builder.AddBinaryOp( + uint_type_id, SpvOpIAdd, quad_ldr->result_id(), my_offset->result_id()); // Do the group operations uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); - uint32_t subgroup_scope = - ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + uint32_t subgroup_scope = ir_builder.GetUintConstantId(SpvScopeSubgroup); const auto* ballot_value_const = const_mgr->GetConstant( type_mgr->GetUIntVectorType(4), {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); Instruction* ballot_value = const_mgr->GetDefiningInstruction(ballot_value_const); Instruction* is_active = ir_builder.AddNaryOp( - type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, + type_mgr->GetBoolTypeId(), SpvOpGroupNonUniformBallotBitExtract, {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); Instruction* shuffle = - ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, + ir_builder.AddNaryOp(inst->type_id(), SpvOpGroupNonUniformShuffle, {subgroup_scope, data_id, target_inv->result_id()}); // Create the null constant to use in the select. @@ -278,7 +276,7 @@ bool ReplaceSwizzleInvocations(IRContext* ctx, Instruction* inst, Instruction* null_inst = const_mgr->GetDefiningInstruction(null); // Build the select. - inst->SetOpcode(spv::Op::OpSelect); + inst->SetOpcode(SpvOpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); @@ -329,8 +327,8 @@ bool ReplaceSwizzleInvocationsMasked( analysis::DefUseManager* def_use_mgr = ctx->get_def_use_mgr(); analysis::ConstantManager* const_mgr = ctx->get_constant_mgr(); - ctx->AddCapability(spv::Capability::GroupNonUniformBallot); - ctx->AddCapability(spv::Capability::GroupNonUniformShuffle); + ctx->AddCapability(SpvCapabilityGroupNonUniformBallot); + ctx->AddCapability(SpvCapabilityGroupNonUniformShuffle); InstructionBuilder ir_builder( ctx, inst, @@ -340,7 +338,7 @@ bool ReplaceSwizzleInvocationsMasked( uint32_t data_id = inst->GetSingleWordInOperand(2); Instruction* mask_inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(3)); - assert(mask_inst->opcode() == spv::Op::OpConstantComposite && + assert(mask_inst->opcode() == SpvOpConstantComposite && "The mask is suppose to be a vector constant."); assert(mask_inst->NumInOperands() == 3 && "The mask is suppose to have 3 components."); @@ -350,8 +348,8 @@ bool ReplaceSwizzleInvocationsMasked( uint32_t uint_z = mask_inst->GetSingleWordInOperand(2); // Get the subgroup invocation id. - uint32_t var_id = ctx->GetBuiltinInputVarId( - uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); + uint32_t var_id = + ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); ctx->AddExtension("SPV_KHR_shader_ballot"); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); @@ -363,30 +361,28 @@ bool ReplaceSwizzleInvocationsMasked( // Do the bitwise operations. uint32_t mask_extended = ir_builder.GetUintConstantId(0xFFFFFFE0); - Instruction* and_mask = ir_builder.AddBinaryOp( - uint_type_id, spv::Op::OpBitwiseOr, uint_x, mask_extended); - Instruction* and_result = - ir_builder.AddBinaryOp(uint_type_id, spv::Op::OpBitwiseAnd, - id->result_id(), and_mask->result_id()); + Instruction* and_mask = ir_builder.AddBinaryOp(uint_type_id, SpvOpBitwiseOr, + uint_x, mask_extended); + Instruction* and_result = ir_builder.AddBinaryOp( + uint_type_id, SpvOpBitwiseAnd, id->result_id(), and_mask->result_id()); Instruction* or_result = ir_builder.AddBinaryOp( - uint_type_id, spv::Op::OpBitwiseOr, and_result->result_id(), uint_y); + uint_type_id, SpvOpBitwiseOr, and_result->result_id(), uint_y); Instruction* target_inv = ir_builder.AddBinaryOp( - uint_type_id, spv::Op::OpBitwiseXor, or_result->result_id(), uint_z); + uint_type_id, SpvOpBitwiseXor, or_result->result_id(), uint_z); // Do the group operations uint32_t uint_max_id = ir_builder.GetUintConstantId(0xFFFFFFFF); - uint32_t subgroup_scope = - ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + uint32_t subgroup_scope = ir_builder.GetUintConstantId(SpvScopeSubgroup); const auto* ballot_value_const = const_mgr->GetConstant( type_mgr->GetUIntVectorType(4), {uint_max_id, uint_max_id, uint_max_id, uint_max_id}); Instruction* ballot_value = const_mgr->GetDefiningInstruction(ballot_value_const); Instruction* is_active = ir_builder.AddNaryOp( - type_mgr->GetBoolTypeId(), spv::Op::OpGroupNonUniformBallotBitExtract, + type_mgr->GetBoolTypeId(), SpvOpGroupNonUniformBallotBitExtract, {subgroup_scope, ballot_value->result_id(), target_inv->result_id()}); Instruction* shuffle = - ir_builder.AddNaryOp(inst->type_id(), spv::Op::OpGroupNonUniformShuffle, + ir_builder.AddNaryOp(inst->type_id(), SpvOpGroupNonUniformShuffle, {subgroup_scope, data_id, target_inv->result_id()}); // Create the null constant to use in the select. @@ -395,7 +391,7 @@ bool ReplaceSwizzleInvocationsMasked( Instruction* null_inst = const_mgr->GetDefiningInstruction(null); // Build the select. - inst->SetOpcode(spv::Op::OpSelect); + inst->SetOpcode(SpvOpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_active->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {shuffle->result_id()}}); @@ -424,9 +420,9 @@ bool ReplaceSwizzleInvocationsMasked( // Also adding the capabilities and builtins that are needed. bool ReplaceWriteInvocation(IRContext* ctx, Instruction* inst, const std::vector&) { - uint32_t var_id = ctx->GetBuiltinInputVarId( - uint32_t(spv::BuiltIn::SubgroupLocalInvocationId)); - ctx->AddCapability(spv::Capability::SubgroupBallotKHR); + uint32_t var_id = + ctx->GetBuiltinInputVarId(SpvBuiltInSubgroupLocalInvocationId); + ctx->AddCapability(SpvCapabilitySubgroupBallotKHR); ctx->AddExtension("SPV_KHR_shader_ballot"); assert(var_id != 0 && "Could not get SubgroupLocalInvocationId variable."); Instruction* var_inst = ctx->get_def_use_mgr()->GetDef(var_id); @@ -441,11 +437,11 @@ bool ReplaceWriteInvocation(IRContext* ctx, Instruction* inst, analysis::Bool bool_type; uint32_t bool_type_id = ctx->get_type_mgr()->GetTypeInstruction(&bool_type); Instruction* cmp = - ir_builder.AddBinaryOp(bool_type_id, spv::Op::OpIEqual, t->result_id(), + ir_builder.AddBinaryOp(bool_type_id, SpvOpIEqual, t->result_id(), inst->GetSingleWordInOperand(4)); // Build a select. - inst->SetOpcode(spv::Op::OpSelect); + inst->SetOpcode(SpvOpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {cmp->result_id()}}); new_operands.push_back(inst->GetInOperand(3)); @@ -483,15 +479,14 @@ bool ReplaceMbcnt(IRContext* context, Instruction* inst, analysis::TypeManager* type_mgr = context->get_type_mgr(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - uint32_t var_id = - context->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::SubgroupLtMask)); + uint32_t var_id = context->GetBuiltinInputVarId(SpvBuiltInSubgroupLtMask); assert(var_id != 0 && "Could not get SubgroupLtMask variable."); - context->AddCapability(spv::Capability::GroupNonUniformBallot); + context->AddCapability(SpvCapabilityGroupNonUniformBallot); Instruction* var_inst = def_use_mgr->GetDef(var_id); Instruction* var_ptr_type = def_use_mgr->GetDef(var_inst->type_id()); Instruction* var_type = def_use_mgr->GetDef(var_ptr_type->GetSingleWordInOperand(1)); - assert(var_type->opcode() == spv::Op::OpTypeVector && + assert(var_type->opcode() == SpvOpTypeVector && "Variable is suppose to be a vector of 4 ints"); // Get the type for the shuffle. @@ -514,12 +509,11 @@ bool ReplaceMbcnt(IRContext* context, Instruction* inst, Instruction* shuffle = ir_builder.AddVectorShuffle( shuffle_type_id, load->result_id(), load->result_id(), {0, 1}); Instruction* bitcast = ir_builder.AddUnaryOp( - mask_inst->type_id(), spv::Op::OpBitcast, shuffle->result_id()); - Instruction* t = - ir_builder.AddBinaryOp(mask_inst->type_id(), spv::Op::OpBitwiseAnd, - bitcast->result_id(), mask_id); + mask_inst->type_id(), SpvOpBitcast, shuffle->result_id()); + Instruction* t = ir_builder.AddBinaryOp(mask_inst->type_id(), SpvOpBitwiseAnd, + bitcast->result_id(), mask_id); - inst->SetOpcode(spv::Op::OpBitCount); + inst->SetOpcode(SpvOpBitCount); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {t->result_id()}}}); context->UpdateDefUse(inst); return true; @@ -605,11 +599,11 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, // Negate the input values. Instruction* nx = - ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, x->result_id()); + ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, x->result_id()); Instruction* ny = - ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, y->result_id()); + ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, y->result_id()); Instruction* nz = - ir_builder.AddUnaryOp(float_type_id, spv::Op::OpFNegate, z->result_id()); + ir_builder.AddUnaryOp(float_type_id, SpvOpFNegate, z->result_id()); // Get the abolsute values of the inputs. Instruction* ax = ir_builder.AddNaryExtendedInstruction( @@ -620,12 +614,12 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); // Find which values are negative. Used in later computations. - Instruction* is_z_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); - Instruction* is_y_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); - Instruction* is_x_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); + Instruction* is_z_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + x->result_id(), f0_const_id); // Compute cubema Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( @@ -634,21 +628,19 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, Instruction* amax = ir_builder.AddNaryExtendedInstruction( float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, {az->result_id(), amax_x_y->result_id()}); - Instruction* cubema = ir_builder.AddBinaryOp(float_type_id, spv::Op::OpFMul, + Instruction* cubema = ir_builder.AddBinaryOp(float_type_id, SpvOpFMul, f2_const_id, amax->result_id()); // Do the comparisons needed for computing cubesc and cubetc. Instruction* is_z_max = - ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ir_builder.AddBinaryOp(bool_id, SpvOpFOrdGreaterThanEqual, az->result_id(), amax_x_y->result_id()); - Instruction* not_is_z_max = ir_builder.AddUnaryOp( - bool_id, spv::Op::OpLogicalNot, is_z_max->result_id()); - Instruction* y_gr_x = - ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, - ay->result_id(), ax->result_id()); - Instruction* is_y_max = - ir_builder.AddBinaryOp(bool_id, spv::Op::OpLogicalAnd, - not_is_z_max->result_id(), y_gr_x->result_id()); + Instruction* not_is_z_max = + ir_builder.AddUnaryOp(bool_id, SpvOpLogicalNot, is_z_max->result_id()); + Instruction* y_gr_x = ir_builder.AddBinaryOp( + bool_id, SpvOpFOrdGreaterThanEqual, ay->result_id(), ax->result_id()); + Instruction* is_y_max = ir_builder.AddBinaryOp( + bool_id, SpvOpLogicalAnd, not_is_z_max->result_id(), y_gr_x->result_id()); // Select the correct value for cubesc. Instruction* cubesc_case_1 = ir_builder.AddSelect( @@ -675,10 +667,10 @@ bool ReplaceCubeFaceCoord(IRContext* ctx, Instruction* inst, Instruction* denom = ir_builder.AddCompositeConstruct( v2_float_type_id, {cubema->result_id(), cubema->result_id()}); Instruction* div = ir_builder.AddBinaryOp( - v2_float_type_id, spv::Op::OpFDiv, cube->result_id(), denom->result_id()); + v2_float_type_id, SpvOpFDiv, cube->result_id(), denom->result_id()); // Get the final result by adding 0.5 to |div|. - inst->SetOpcode(spv::Op::OpFAdd); + inst->SetOpcode(SpvOpFAdd); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {div->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {vec_const_id}}); @@ -760,23 +752,22 @@ bool ReplaceCubeFaceIndex(IRContext* ctx, Instruction* inst, float_type_id, glsl405_ext_inst_id, GLSLstd450FAbs, {z->result_id()}); // Find which values are negative. Used in later computations. - Instruction* is_z_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, z->result_id(), f0_const_id); - Instruction* is_y_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, y->result_id(), f0_const_id); - Instruction* is_x_neg = ir_builder.AddBinaryOp( - bool_id, spv::Op::OpFOrdLessThan, x->result_id(), f0_const_id); + Instruction* is_z_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + z->result_id(), f0_const_id); + Instruction* is_y_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + y->result_id(), f0_const_id); + Instruction* is_x_neg = ir_builder.AddBinaryOp(bool_id, SpvOpFOrdLessThan, + x->result_id(), f0_const_id); // Find the max value. Instruction* amax_x_y = ir_builder.AddNaryExtendedInstruction( float_type_id, glsl405_ext_inst_id, GLSLstd450FMax, {ax->result_id(), ay->result_id()}); Instruction* is_z_max = - ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, + ir_builder.AddBinaryOp(bool_id, SpvOpFOrdGreaterThanEqual, az->result_id(), amax_x_y->result_id()); - Instruction* y_gr_x = - ir_builder.AddBinaryOp(bool_id, spv::Op::OpFOrdGreaterThanEqual, - ay->result_id(), ax->result_id()); + Instruction* y_gr_x = ir_builder.AddBinaryOp( + bool_id, SpvOpFOrdGreaterThanEqual, ay->result_id(), ax->result_id()); // Get the value for each case. Instruction* case_z = ir_builder.AddSelect( @@ -792,7 +783,7 @@ bool ReplaceCubeFaceIndex(IRContext* ctx, Instruction* inst, case_y->result_id(), case_x->result_id()); // Get the final result by adding 0.5 to |div|. - inst->SetOpcode(spv::Op::OpSelect); + inst->SetOpcode(SpvOpSelect); Instruction::OperandList new_operands; new_operands.push_back({SPV_OPERAND_TYPE_ID, {is_z_max->result_id()}}); new_operands.push_back({SPV_OPERAND_TYPE_ID, {case_z->result_id()}}); @@ -822,12 +813,11 @@ bool ReplaceTimeAMD(IRContext* ctx, Instruction* inst, ctx, inst, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); ctx->AddExtension("SPV_KHR_shader_clock"); - ctx->AddCapability(spv::Capability::ShaderClockKHR); + ctx->AddCapability(SpvCapabilityShaderClockKHR); - inst->SetOpcode(spv::Op::OpReadClockKHR); + inst->SetOpcode(SpvOpReadClockKHR); Instruction::OperandList args; - uint32_t subgroup_scope_id = - ir_builder.GetUintConstantId(uint32_t(spv::Scope::Subgroup)); + uint32_t subgroup_scope_id = ir_builder.GetUintConstantId(SpvScopeSubgroup); args.push_back({SPV_OPERAND_TYPE_ID, {subgroup_scope_id}}); inst->SetInOperands(std::move(args)); ctx->UpdateDefUse(inst); @@ -841,22 +831,22 @@ class AmdExtFoldingRules : public FoldingRules { protected: virtual void AddFoldingRules() override { - rules_[spv::Op::OpGroupIAddNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupFAddNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupUMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupSMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupFMinNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupUMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupSMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); - rules_[spv::Op::OpGroupFMaxNonUniformAMD].push_back( - ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupIAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupFAddNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupUMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupSMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupFMinNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupUMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupSMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); + rules_[SpvOpGroupFMaxNonUniformAMD].push_back( + ReplaceGroupNonuniformOperationOpCode); uint32_t extension_id = context()->module()->GetExtInstImportId("SPV_AMD_shader_ballot"); @@ -944,7 +934,7 @@ Pass::Status AmdExtensionToKhrPass::Process() { std::vector to_be_killed; for (Instruction& inst : context()->module()->extensions()) { - if (inst.opcode() == spv::Op::OpExtension) { + if (inst.opcode() == SpvOpExtension) { if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { to_be_killed.push_back(&inst); } @@ -952,7 +942,7 @@ Pass::Status AmdExtensionToKhrPass::Process() { } for (Instruction& inst : context()->ext_inst_imports()) { - if (inst.opcode() == spv::Op::OpExtInstImport) { + if (inst.opcode() == SpvOpExtInstImport) { if (ext_to_remove.count(inst.GetInOperand(0).AsString()) != 0) { to_be_killed.push_back(&inst); } diff --git a/source/opt/analyze_live_input_pass.cpp b/source/opt/analyze_live_input_pass.cpp deleted file mode 100755 index 529e6846..00000000 --- a/source/opt/analyze_live_input_pass.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "source/opt/analyze_live_input_pass.h" - -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -Pass::Status AnalyzeLiveInputPass::Process() { - // Current functionality assumes shader capability - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) - return Status::SuccessWithoutChange; - Pass::Status status = DoLiveInputAnalysis(); - return status; -} - -Pass::Status AnalyzeLiveInputPass::DoLiveInputAnalysis() { - // Current functionality only supports frag, tesc, tese or geom shaders. - // Report failure for any other stage. - auto stage = context()->GetStage(); - if (stage != spv::ExecutionModel::Fragment && - stage != spv::ExecutionModel::TessellationControl && - stage != spv::ExecutionModel::TessellationEvaluation && - stage != spv::ExecutionModel::Geometry) - return Status::Failure; - context()->get_liveness_mgr()->GetLiveness(live_locs_, live_builtins_); - return Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/basic_block.cpp b/source/opt/basic_block.cpp index a9fc8e2f..e82a744a 100644 --- a/source/opt/basic_block.cpp +++ b/source/opt/basic_block.cpp @@ -16,16 +16,20 @@ #include +#include "source/opt/function.h" #include "source/opt/ir_context.h" +#include "source/opt/module.h" #include "source/opt/reflect.h" #include "source/util/make_unique.h" namespace spvtools { namespace opt { namespace { -constexpr uint32_t kLoopMergeContinueBlockIdInIdx = 1; -constexpr uint32_t kLoopMergeMergeBlockIdInIdx = 0; -constexpr uint32_t kSelectionMergeMergeBlockIdInIdx = 0; + +const uint32_t kLoopMergeContinueBlockIdInIdx = 1; +const uint32_t kLoopMergeMergeBlockIdInIdx = 0; +const uint32_t kSelectionMergeMergeBlockIdInIdx = 0; + } // namespace BasicBlock* BasicBlock::Clone(IRContext* context) const { @@ -54,7 +58,7 @@ const Instruction* BasicBlock::GetMergeInst() const { if (iter != cbegin()) { --iter; const auto opcode = iter->opcode(); - if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { + if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { result = &*iter; } } @@ -69,7 +73,7 @@ Instruction* BasicBlock::GetMergeInst() { if (iter != begin()) { --iter; const auto opcode = iter->opcode(); - if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) { + if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { result = &*iter; } } @@ -78,7 +82,7 @@ Instruction* BasicBlock::GetMergeInst() { const Instruction* BasicBlock::GetLoopMergeInst() const { if (auto* merge = GetMergeInst()) { - if (merge->opcode() == spv::Op::OpLoopMerge) { + if (merge->opcode() == SpvOpLoopMerge) { return merge; } } @@ -87,7 +91,7 @@ const Instruction* BasicBlock::GetLoopMergeInst() const { Instruction* BasicBlock::GetLoopMergeInst() { if (auto* merge = GetMergeInst()) { - if (merge->opcode() == spv::Op::OpLoopMerge) { + if (merge->opcode() == SpvOpLoopMerge) { return merge; } } @@ -96,7 +100,7 @@ Instruction* BasicBlock::GetLoopMergeInst() { void BasicBlock::KillAllInsts(bool killLabel) { ForEachInst([killLabel](Instruction* ip) { - if (killLabel || ip->opcode() != spv::Op::OpLabel) { + if (killLabel || ip->opcode() != SpvOpLabel) { ip->context()->KillInst(ip); } }); @@ -114,10 +118,10 @@ bool BasicBlock::WhileEachSuccessorLabel( const std::function& f) const { const auto br = &insts_.back(); switch (br->opcode()) { - case spv::Op::OpBranch: + case SpvOpBranch: return f(br->GetOperand(0).words[0]); - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: { + case SpvOpBranchConditional: + case SpvOpSwitch: { bool is_first = true; return br->WhileEachInId([&is_first, &f](const uint32_t* idp) { if (!is_first) return f(*idp); @@ -134,13 +138,13 @@ void BasicBlock::ForEachSuccessorLabel( const std::function& f) { auto br = &insts_.back(); switch (br->opcode()) { - case spv::Op::OpBranch: { + case SpvOpBranch: { uint32_t tmp_id = br->GetOperand(0).words[0]; f(&tmp_id); if (tmp_id != br->GetOperand(0).words[0]) br->SetOperand(0, {tmp_id}); } break; - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: { + case SpvOpBranchConditional: + case SpvOpSwitch: { bool is_first = true; br->ForEachInId([&is_first, &f](uint32_t* idp) { if (!is_first) f(idp); @@ -167,8 +171,7 @@ void BasicBlock::ForMergeAndContinueLabel( --ii; if (ii == insts_.begin()) return; --ii; - if (ii->opcode() == spv::Op::OpSelectionMerge || - ii->opcode() == spv::Op::OpLoopMerge) { + if (ii->opcode() == SpvOpSelectionMerge || ii->opcode() == SpvOpLoopMerge) { ii->ForEachInId([&f](const uint32_t* idp) { f(*idp); }); } } @@ -179,9 +182,9 @@ uint32_t BasicBlock::MergeBlockIdIfAny() const { uint32_t mbid = 0; if (merge_ii != cbegin()) { --merge_ii; - if (merge_ii->opcode() == spv::Op::OpLoopMerge) { + if (merge_ii->opcode() == SpvOpLoopMerge) { mbid = merge_ii->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx); - } else if (merge_ii->opcode() == spv::Op::OpSelectionMerge) { + } else if (merge_ii->opcode() == SpvOpSelectionMerge) { mbid = merge_ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); } } @@ -201,7 +204,7 @@ uint32_t BasicBlock::ContinueBlockIdIfAny() const { uint32_t cbid = 0; if (merge_ii != cbegin()) { --merge_ii; - if (merge_ii->opcode() == spv::Op::OpLoopMerge) { + if (merge_ii->opcode() == SpvOpLoopMerge) { cbid = merge_ii->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx); } } @@ -238,9 +241,9 @@ BasicBlock* BasicBlock::SplitBasicBlock(IRContext* context, uint32_t label_id, iterator iter) { assert(!insts_.empty()); - std::unique_ptr new_block_temp = MakeUnique( - MakeUnique(context, spv::Op::OpLabel, 0, label_id, - std::initializer_list{})); + std::unique_ptr new_block_temp = + MakeUnique(MakeUnique( + context, SpvOpLabel, 0, label_id, std::initializer_list{})); BasicBlock* new_block = new_block_temp.get(); function_->InsertBasicBlockAfter(std::move(new_block_temp), this); diff --git a/source/opt/basic_block.h b/source/opt/basic_block.h index 24d5fceb..dd3b2e28 100644 --- a/source/opt/basic_block.h +++ b/source/opt/basic_block.h @@ -319,7 +319,7 @@ inline bool BasicBlock::WhileEachPhiInst( Instruction* inst = &insts_.front(); while (inst != nullptr) { Instruction* next_instruction = inst->NextNode(); - if (inst->opcode() != spv::Op::OpPhi) break; + if (inst->opcode() != SpvOpPhi) break; if (!inst->WhileEachInst(f, run_on_debug_line_insts)) return false; inst = next_instruction; } diff --git a/source/opt/block_merge_pass.cpp b/source/opt/block_merge_pass.cpp index d6c33e52..ef7f31fe 100644 --- a/source/opt/block_merge_pass.cpp +++ b/source/opt/block_merge_pass.cpp @@ -16,8 +16,11 @@ #include "source/opt/block_merge_pass.h" +#include + #include "source/opt/block_merge_util.h" #include "source/opt/ir_context.h" +#include "source/opt/iterator.h" namespace spvtools { namespace opt { diff --git a/source/opt/block_merge_util.cpp b/source/opt/block_merge_util.cpp index fe23e36f..8ae8020a 100644 --- a/source/opt/block_merge_util.cpp +++ b/source/opt/block_merge_util.cpp @@ -20,6 +20,7 @@ namespace spvtools { namespace opt { namespace blockmergeutil { + namespace { // Returns true if |block| contains a merge instruction. @@ -33,15 +34,14 @@ bool IsHeader(IRContext* context, uint32_t id) { // Returns true if |id| is the merge target of a merge instruction. bool IsMerge(IRContext* context, uint32_t id) { - return !context->get_def_use_mgr()->WhileEachUse( - id, [](Instruction* user, uint32_t index) { - spv::Op op = user->opcode(); - if ((op == spv::Op::OpLoopMerge || op == spv::Op::OpSelectionMerge) && - index == 0u) { - return false; - } - return true; - }); + return !context->get_def_use_mgr()->WhileEachUse(id, [](Instruction* user, + uint32_t index) { + SpvOp op = user->opcode(); + if ((op == SpvOpLoopMerge || op == SpvOpSelectionMerge) && index == 0u) { + return false; + } + return true; + }); } // Returns true if |block| is the merge target of a merge instruction. @@ -53,8 +53,8 @@ bool IsMerge(IRContext* context, BasicBlock* block) { bool IsContinue(IRContext* context, uint32_t id) { return !context->get_def_use_mgr()->WhileEachUse( id, [](Instruction* user, uint32_t index) { - spv::Op op = user->opcode(); - if (op == spv::Op::OpLoopMerge && index == 1u) { + SpvOp op = user->opcode(); + if (op == SpvOpLoopMerge && index == 1u) { return false; } return true; @@ -82,7 +82,7 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) { auto ii = block->end(); --ii; Instruction* br = &*ii; - if (br->opcode() != spv::Op::OpBranch) { + if (br->opcode() != SpvOpBranch) { return false; } @@ -119,33 +119,12 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) { // The merge must be a loop merge because a selection merge cannot be // followed by an unconditional branch. BasicBlock* succ_block = context->get_instr_block(lab_id); - spv::Op succ_term_op = succ_block->terminator()->opcode(); - assert(merge_inst->opcode() == spv::Op::OpLoopMerge); - if (succ_term_op != spv::Op::OpBranch && - succ_term_op != spv::Op::OpBranchConditional) { + SpvOp succ_term_op = succ_block->terminator()->opcode(); + assert(merge_inst->opcode() == SpvOpLoopMerge); + if (succ_term_op != SpvOpBranch && succ_term_op != SpvOpBranchConditional) { return false; } } - - if (succ_is_merge || IsContinue(context, lab_id)) { - auto* struct_cfg = context->GetStructuredCFGAnalysis(); - auto switch_block_id = struct_cfg->ContainingSwitch(block->id()); - if (switch_block_id) { - auto switch_merge_id = struct_cfg->SwitchMergeBlock(switch_block_id); - const auto* switch_inst = - &*block->GetParent()->FindBlock(switch_block_id)->tail(); - for (uint32_t i = 1; i < switch_inst->NumInOperands(); i += 2) { - auto target_id = switch_inst->GetSingleWordInOperand(i); - if (target_id == block->id() && target_id != switch_merge_id) { - // Case constructs must be structurally dominated by the OpSwitch. - // Since the successor is the merge/continue for another construct, - // merging the blocks would break that requirement. - return false; - } - } - } - } - return true; } @@ -171,11 +150,6 @@ void MergeWithSuccessor(IRContext* context, Function* func, // sbi must follow bi in func's ordering. assert(sbi != func->end()); - if (sbi->tail()->opcode() == spv::Op::OpSwitch && - sbi->MergeBlockIdIfAny() != 0) { - context->InvalidateAnalyses(IRContext::Analysis::kAnalysisStructuredCFG); - } - // Update the inst-to-block mapping for the instructions in sbi. for (auto& inst : *sbi) { context->set_instr_block(&inst, &*bi); diff --git a/source/opt/ccp_pass.cpp b/source/opt/ccp_pass.cpp index 46bfc907..5f855027 100644 --- a/source/opt/ccp_pass.cpp +++ b/source/opt/ccp_pass.cpp @@ -24,15 +24,19 @@ #include "source/opt/fold.h" #include "source/opt/function.h" +#include "source/opt/module.h" #include "source/opt/propagator.h" namespace spvtools { namespace opt { + namespace { + // This SSA id is never defined nor referenced in the IR. It is a special ID // which represents varying values. When an ID is found to have a varying // value, its entry in the |values_| table maps to kVaryingSSAId. -constexpr uint32_t kVaryingSSAId = std::numeric_limits::max(); +const uint32_t kVaryingSSAId = std::numeric_limits::max(); + } // namespace bool CCPPass::IsVaryingValue(uint32_t id) const { return id == kVaryingSSAId; } @@ -132,7 +136,7 @@ SSAPropagator::PropStatus CCPPass::VisitAssignment(Instruction* instr) { // If this is a copy operation, and the RHS is a known constant, assign its // value to the LHS. - if (instr->opcode() == spv::Op::OpCopyObject) { + if (instr->opcode() == SpvOpCopyObject) { uint32_t rhs_id = instr->GetSingleWordInOperand(0); auto it = values_.find(rhs_id); if (it != values_.end()) { @@ -207,10 +211,10 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, *dest_bb = nullptr; uint32_t dest_label = 0; - if (instr->opcode() == spv::Op::OpBranch) { + if (instr->opcode() == SpvOpBranch) { // An unconditional jump always goes to its unique destination. dest_label = instr->GetSingleWordInOperand(0); - } else if (instr->opcode() == spv::Op::OpBranchConditional) { + } else if (instr->opcode() == SpvOpBranchConditional) { // For a conditional branch, determine whether the predicate selector has a // known value in |values_|. If it does, set the destination block // according to the selector's boolean value. @@ -239,7 +243,7 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, // For an OpSwitch, extract the value taken by the switch selector and check // which of the target literals it matches. The branch associated with that // literal is the taken branch. - assert(instr->opcode() == spv::Op::OpSwitch); + assert(instr->opcode() == SpvOpSwitch); if (instr->GetOperand(0).words.size() != 1) { // If the selector is wider than 32-bits, return varying. TODO(dnovillo): // Add support for wider constants. @@ -286,7 +290,7 @@ SSAPropagator::PropStatus CCPPass::VisitBranch(Instruction* instr, SSAPropagator::PropStatus CCPPass::VisitInstruction(Instruction* instr, BasicBlock** dest_bb) { *dest_bb = nullptr; - if (instr->opcode() == spv::Op::OpPhi) { + if (instr->opcode() == SpvOpPhi) { return VisitPhi(instr); } else if (instr->IsBranch()) { return VisitBranch(instr, dest_bb); diff --git a/source/opt/cfg.cpp b/source/opt/cfg.cpp index 4c4bb256..a0248d54 100644 --- a/source/opt/cfg.cpp +++ b/source/opt/cfg.cpp @@ -29,16 +29,16 @@ namespace { using cbb_ptr = const opt::BasicBlock*; // Universal Limit of ResultID + 1 -constexpr int kMaxResultId = 0x400000; +const int kMaxResultId = 0x400000; } // namespace CFG::CFG(Module* module) : module_(module), pseudo_entry_block_(std::unique_ptr( - new Instruction(module->context(), spv::Op::OpLabel, 0, 0, {}))), + new Instruction(module->context(), SpvOpLabel, 0, 0, {}))), pseudo_exit_block_(std::unique_ptr(new Instruction( - module->context(), spv::Op::OpLabel, 0, kMaxResultId, {}))) { + module->context(), SpvOpLabel, 0, kMaxResultId, {}))) { for (auto& fn : *module) { for (auto& blk : fn) { RegisterBlock(&blk); @@ -81,7 +81,7 @@ void CFG::ComputeStructuredOrder(Function* func, BasicBlock* root, BasicBlock* end, std::list* order) { assert(module_->context()->get_feature_mgr()->HasCapability( - spv::Capability::Shader) && + SpvCapabilityShader) && "This only works on structured control flow"); // Compute structured successors and do DFS. @@ -228,7 +228,7 @@ BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) { // Create the new header bb basic bb. // Leave the phi instructions behind. auto iter = bb->begin(); - while (iter->opcode() == spv::Op::OpPhi) { + while (iter->opcode() == SpvOpPhi) { ++iter; } @@ -304,7 +304,7 @@ BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) { context, bb, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); bb->AddInstruction( - MakeUnique(context, spv::Op::OpBranch, 0, 0, + MakeUnique(context, SpvOpBranch, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {new_header->id()}}})); context->AnalyzeUses(bb->terminator()); diff --git a/source/opt/cfg_cleanup_pass.cpp b/source/opt/cfg_cleanup_pass.cpp index 26fed89f..6d48637a 100644 --- a/source/opt/cfg_cleanup_pass.cpp +++ b/source/opt/cfg_cleanup_pass.cpp @@ -16,9 +16,13 @@ // constructs (e.g., unreachable basic blocks, empty control flow structures, // etc) +#include +#include + #include "source/opt/cfg_cleanup_pass.h" #include "source/opt/function.h" +#include "source/opt/module.h" namespace spvtools { namespace opt { diff --git a/source/opt/code_sink.cpp b/source/opt/code_sink.cpp index 90231791..cd777974 100644 --- a/source/opt/code_sink.cpp +++ b/source/opt/code_sink.cpp @@ -14,9 +14,11 @@ #include "code_sink.h" +#include #include #include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" #include "source/opt/ir_context.h" #include "source/util/bit_vector.h" @@ -48,8 +50,7 @@ bool CodeSinkingPass::SinkInstructionsInBB(BasicBlock* bb) { } bool CodeSinkingPass::SinkInstruction(Instruction* inst) { - if (inst->opcode() != spv::Op::OpLoad && - inst->opcode() != spv::Op::OpAccessChain) { + if (inst->opcode() != SpvOpLoad && inst->opcode() != SpvOpAccessChain) { return false; } @@ -59,7 +60,7 @@ bool CodeSinkingPass::SinkInstruction(Instruction* inst) { if (BasicBlock* target_bb = FindNewBasicBlockFor(inst)) { Instruction* pos = &*target_bb->begin(); - while (pos->opcode() == spv::Op::OpPhi) { + while (pos->opcode() == SpvOpPhi) { pos = pos->NextNode(); } @@ -78,7 +79,7 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { std::unordered_set bbs_with_uses; get_def_use_mgr()->ForEachUse( inst, [&bbs_with_uses, this](Instruction* use, uint32_t idx) { - if (use->opcode() != spv::Op::OpPhi) { + if (use->opcode() != SpvOpPhi) { BasicBlock* use_bb = context()->get_instr_block(use); if (use_bb) { bbs_with_uses.insert(use_bb->id()); @@ -98,7 +99,7 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { // of succ_bb, then |inst| can be moved to succ_bb. If succ_bb, has move // then one predecessor, then moving |inst| into succ_bb could cause it to // be executed more often, so the search has to stop. - if (bb->terminator()->opcode() == spv::Op::OpBranch) { + if (bb->terminator()->opcode() == SpvOpBranch) { uint32_t succ_bb_id = bb->terminator()->GetSingleWordInOperand(0); if (cfg()->preds(succ_bb_id).size() == 1) { bb = context()->get_instr_block(succ_bb_id); @@ -112,8 +113,7 @@ BasicBlock* CodeSinkingPass::FindNewBasicBlockFor(Instruction* inst) { // instruction or an OpLoopMerge, then it is a break or continue. We could // figure it out, but not worth doing it now. Instruction* merge_inst = bb->GetMergeInst(); - if (merge_inst == nullptr || - merge_inst->opcode() != spv::Op::OpSelectionMerge) { + if (merge_inst == nullptr || merge_inst->opcode() != SpvOpSelectionMerge) { break; } @@ -173,7 +173,7 @@ bool CodeSinkingPass::ReferencesMutableMemory(Instruction* inst) { } Instruction* base_ptr = inst->GetBaseAddress(); - if (base_ptr->opcode() != spv::Op::OpVariable) { + if (base_ptr->opcode() != SpvOpVariable) { return true; } @@ -185,8 +185,7 @@ bool CodeSinkingPass::ReferencesMutableMemory(Instruction* inst) { return true; } - if (spv::StorageClass(base_ptr->GetSingleWordInOperand(0)) != - spv::StorageClass::Uniform) { + if (base_ptr->GetSingleWordInOperand(0) != SpvStorageClassUniform) { return true; } @@ -201,41 +200,41 @@ bool CodeSinkingPass::HasUniformMemorySync() { bool has_sync = false; get_module()->ForEachInst([this, &has_sync](Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpMemoryBarrier: { + case SpvOpMemoryBarrier: { uint32_t mem_semantics_id = inst->GetSingleWordInOperand(1); if (IsSyncOnUniform(mem_semantics_id)) { has_sync = true; } break; } - case spv::Op::OpControlBarrier: - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicFAddEXT: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicFMinEXT: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicFMaxEXT: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: - case spv::Op::OpAtomicFlagClear: { + case SpvOpControlBarrier: + case SpvOpAtomicLoad: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicFAddEXT: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicFMinEXT: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicFMaxEXT: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: + case SpvOpAtomicFlagClear: { uint32_t mem_semantics_id = inst->GetSingleWordInOperand(2); if (IsSyncOnUniform(mem_semantics_id)) { has_sync = true; } break; } - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: if (IsSyncOnUniform(inst->GetSingleWordInOperand(2)) || IsSyncOnUniform(inst->GetSingleWordInOperand(3))) { has_sync = true; @@ -260,30 +259,28 @@ bool CodeSinkingPass::IsSyncOnUniform(uint32_t mem_semantics_id) const { // If it does not affect uniform memory, then it is does not apply to uniform // memory. - if ((mem_semantics_int & uint32_t(spv::MemorySemanticsMask::UniformMemory)) == - 0) { + if ((mem_semantics_int & SpvMemorySemanticsUniformMemoryMask) == 0) { return false; } // Check if there is an acquire or release. If so not, this it does not add // any memory constraints. - return (mem_semantics_int & - uint32_t(spv::MemorySemanticsMask::Acquire | - spv::MemorySemanticsMask::AcquireRelease | - spv::MemorySemanticsMask::Release)) != 0; + return (mem_semantics_int & (SpvMemorySemanticsAcquireMask | + SpvMemorySemanticsAcquireReleaseMask | + SpvMemorySemanticsReleaseMask)) != 0; } bool CodeSinkingPass::HasPossibleStore(Instruction* var_inst) { - assert(var_inst->opcode() == spv::Op::OpVariable || - var_inst->opcode() == spv::Op::OpAccessChain || - var_inst->opcode() == spv::Op::OpPtrAccessChain); + assert(var_inst->opcode() == SpvOpVariable || + var_inst->opcode() == SpvOpAccessChain || + var_inst->opcode() == SpvOpPtrAccessChain); return get_def_use_mgr()->WhileEachUser(var_inst, [this](Instruction* use) { switch (use->opcode()) { - case spv::Op::OpStore: + case SpvOpStore: return true; - case spv::Op::OpAccessChain: - case spv::Op::OpPtrAccessChain: + case SpvOpAccessChain: + case SpvOpPtrAccessChain: return HasPossibleStore(use); default: return false; diff --git a/source/opt/combine_access_chains.cpp b/source/opt/combine_access_chains.cpp index 99ec7962..142897a2 100644 --- a/source/opt/combine_access_chains.cpp +++ b/source/opt/combine_access_chains.cpp @@ -44,10 +44,10 @@ bool CombineAccessChains::ProcessFunction(Function& function) { function.entry().get(), [&modified, this](BasicBlock* block) { block->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: modified |= CombineAccessChain(inst); break; default: @@ -76,10 +76,10 @@ uint32_t CombineAccessChains::GetConstantValue( uint32_t CombineAccessChains::GetArrayStride(const Instruction* inst) { uint32_t array_stride = 0; context()->get_decoration_mgr()->WhileEachDecoration( - inst->type_id(), uint32_t(spv::Decoration::ArrayStride), + inst->type_id(), SpvDecorationArrayStride, [&array_stride](const Instruction& decoration) { - assert(decoration.opcode() != spv::Op::OpDecorateId); - if (decoration.opcode() == spv::Op::OpDecorate) { + assert(decoration.opcode() != SpvOpDecorateId); + if (decoration.opcode() == SpvOpDecorate) { array_stride = decoration.GetSingleWordInOperand(1); } else { array_stride = decoration.GetSingleWordInOperand(2); @@ -200,18 +200,18 @@ bool CombineAccessChains::CreateNewInputOperands( } bool CombineAccessChains::CombineAccessChain(Instruction* inst) { - assert((inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpAccessChain || - inst->opcode() == spv::Op::OpInBoundsAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) && + assert((inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpAccessChain || + inst->opcode() == SpvOpInBoundsAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain) && "Wrong opcode. Expected an access chain."); Instruction* ptr_input = context()->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0)); - if (ptr_input->opcode() != spv::Op::OpAccessChain && - ptr_input->opcode() != spv::Op::OpInBoundsAccessChain && - ptr_input->opcode() != spv::Op::OpPtrAccessChain && - ptr_input->opcode() != spv::Op::OpInBoundsPtrAccessChain) { + if (ptr_input->opcode() != SpvOpAccessChain && + ptr_input->opcode() != SpvOpInBoundsAccessChain && + ptr_input->opcode() != SpvOpPtrAccessChain && + ptr_input->opcode() != SpvOpInBoundsPtrAccessChain) { return false; } @@ -246,7 +246,7 @@ bool CombineAccessChains::CombineAccessChain(Instruction* inst) { } else if (inst->NumInOperands() == 1) { // |inst| is a no-op, change it to a copy. Instruction simplification will // clean it up. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); } else { std::vector new_operands; if (!CreateNewInputOperands(ptr_input, inst, &new_operands)) return false; @@ -259,25 +259,23 @@ bool CombineAccessChains::CombineAccessChain(Instruction* inst) { return true; } -spv::Op CombineAccessChains::UpdateOpcode(spv::Op base_opcode, - spv::Op input_opcode) { - auto IsInBounds = [](spv::Op opcode) { - return opcode == spv::Op::OpInBoundsPtrAccessChain || - opcode == spv::Op::OpInBoundsAccessChain; +SpvOp CombineAccessChains::UpdateOpcode(SpvOp base_opcode, SpvOp input_opcode) { + auto IsInBounds = [](SpvOp opcode) { + return opcode == SpvOpInBoundsPtrAccessChain || + opcode == SpvOpInBoundsAccessChain; }; - if (input_opcode == spv::Op::OpInBoundsPtrAccessChain) { - if (!IsInBounds(base_opcode)) return spv::Op::OpPtrAccessChain; - } else if (input_opcode == spv::Op::OpInBoundsAccessChain) { - if (!IsInBounds(base_opcode)) return spv::Op::OpAccessChain; + if (input_opcode == SpvOpInBoundsPtrAccessChain) { + if (!IsInBounds(base_opcode)) return SpvOpPtrAccessChain; + } else if (input_opcode == SpvOpInBoundsAccessChain) { + if (!IsInBounds(base_opcode)) return SpvOpAccessChain; } return input_opcode; } -bool CombineAccessChains::IsPtrAccessChain(spv::Op opcode) { - return opcode == spv::Op::OpPtrAccessChain || - opcode == spv::Op::OpInBoundsPtrAccessChain; +bool CombineAccessChains::IsPtrAccessChain(SpvOp opcode) { + return opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain; } bool CombineAccessChains::Has64BitIndices(Instruction* inst) { diff --git a/source/opt/combine_access_chains.h b/source/opt/combine_access_chains.h index 32ee50d3..531209ec 100644 --- a/source/opt/combine_access_chains.h +++ b/source/opt/combine_access_chains.h @@ -68,10 +68,10 @@ class CombineAccessChains : public Pass { std::vector* new_operands); // Returns the opcode to use for the combined access chain. - spv::Op UpdateOpcode(spv::Op base_opcode, spv::Op input_opcode); + SpvOp UpdateOpcode(SpvOp base_opcode, SpvOp input_opcode); // Returns true if |opcode| is a pointer access chain. - bool IsPtrAccessChain(spv::Op opcode); + bool IsPtrAccessChain(SpvOp opcode); // Returns true if |inst| (an access chain) has 64-bit indices. bool Has64BitIndices(Instruction* inst); diff --git a/source/opt/const_folding_rules.cpp b/source/opt/const_folding_rules.cpp index e676974c..0ad755c9 100644 --- a/source/opt/const_folding_rules.cpp +++ b/source/opt/const_folding_rules.cpp @@ -19,7 +19,8 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kExtractCompositeIdInIdx = 0; + +const uint32_t kExtractCompositeIdInIdx = 0; // Returns a constants with the value NaN of the given type. Only works for // 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs. @@ -88,22 +89,6 @@ const analysis::Constant* NegateFPConst(const analysis::Type* result_type, return nullptr; } -// Returns a constants with the value |-val| of the given type. -const analysis::Constant* NegateIntConst(const analysis::Type* result_type, - const analysis::Constant* val, - analysis::ConstantManager* const_mgr) { - const analysis::Integer* int_type = result_type->AsInteger(); - assert(int_type != nullptr); - - if (val->AsNullConstant()) { - return val; - } - - uint64_t new_value = static_cast(-val->GetSignExtendedValue()); - return const_mgr->GetIntConst(new_value, int_type->width(), - int_type->IsSigned()); -} - // Folds an OpcompositeExtract where input is a composite constant. ConstantFoldingRule FoldExtractWithConstants() { return [](IRContext* context, Instruction* inst, @@ -135,102 +120,11 @@ ConstantFoldingRule FoldExtractWithConstants() { }; } -// Folds an OpcompositeInsert where input is a composite constant. -ConstantFoldingRule FoldInsertWithConstants() { - return [](IRContext* context, Instruction* inst, - const std::vector& constants) - -> const analysis::Constant* { - analysis::ConstantManager* const_mgr = context->get_constant_mgr(); - const analysis::Constant* object = constants[0]; - const analysis::Constant* composite = constants[1]; - if (object == nullptr || composite == nullptr) { - return nullptr; - } - - // If there is more than 1 index, then each additional constant used by the - // index will need to be recreated to use the inserted object. - std::vector chain; - std::vector components; - const analysis::Type* type = nullptr; - const uint32_t final_index = (inst->NumInOperands() - 1); - - // Work down hierarchy of all indexes - for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { - type = composite->type(); - - if (composite->AsNullConstant()) { - // Make new composite so it can be inserted in the index with the - // non-null value - if (const auto new_composite = - const_mgr->GetNullCompositeConstant(type)) { - // Keep track of any indexes along the way to last index - if (i != final_index) { - chain.push_back(new_composite); - } - components = new_composite->AsCompositeConstant()->GetComponents(); - } else { - // Unsupported input type (such as structs) - return nullptr; - } - } else { - // Keep track of any indexes along the way to last index - if (i != final_index) { - chain.push_back(composite); - } - components = composite->AsCompositeConstant()->GetComponents(); - } - const uint32_t index = inst->GetSingleWordInOperand(i); - composite = components[index]; - } - - // Final index in hierarchy is inserted with new object. - const uint32_t final_operand = inst->GetSingleWordInOperand(final_index); - std::vector ids; - for (size_t i = 0; i < components.size(); i++) { - const analysis::Constant* constant = - (i == final_operand) ? object : components[i]; - Instruction* member_inst = const_mgr->GetDefiningInstruction(constant); - ids.push_back(member_inst->result_id()); - } - const analysis::Constant* new_constant = const_mgr->GetConstant(type, ids); - - // Work backwards up the chain and replace each index with new constant. - for (size_t i = chain.size(); i > 0; i--) { - // Need to insert any previous instruction into the module first. - // Can't just insert in types_values_begin() because it will move above - // where the types are declared. - // Can't compare with location of inst because not all new added - // instructions are added to types_values_ - auto iter = context->types_values_end(); - Module::inst_iterator* pos = &iter; - const_mgr->BuildInstructionAndAddToModule(new_constant, pos); - - composite = chain[i - 1]; - components = composite->AsCompositeConstant()->GetComponents(); - type = composite->type(); - ids.clear(); - for (size_t k = 0; k < components.size(); k++) { - const uint32_t index = - inst->GetSingleWordInOperand(1 + static_cast(i)); - const analysis::Constant* constant = - (k == index) ? new_constant : components[k]; - const uint32_t constant_id = - const_mgr->FindDeclaredConstant(constant, 0); - ids.push_back(constant_id); - } - new_constant = const_mgr->GetConstant(type, ids); - } - - // If multiple constants were created, only need to return the top index. - return new_constant; - }; -} - ConstantFoldingRule FoldVectorShuffleWithConstants() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == spv::Op::OpVectorShuffle); + assert(inst->opcode() == SpvOpVectorShuffle); const analysis::Constant* c1 = constants[0]; const analysis::Constant* c2 = constants[1]; if (c1 == nullptr || c2 == nullptr) { @@ -286,7 +180,7 @@ ConstantFoldingRule FoldVectorTimesScalar() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == spv::Op::OpVectorTimesScalar); + assert(inst->opcode() == SpvOpVectorTimesScalar); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -357,74 +251,11 @@ ConstantFoldingRule FoldVectorTimesScalar() { }; } -// Returns to the constant that results from tranposing |matrix|. The result -// will have type |result_type|, and |matrix| must exist in |context|. The -// result constant will also exist in |context|. -const analysis::Constant* TransposeMatrix(const analysis::Constant* matrix, - analysis::Matrix* result_type, - IRContext* context) { - analysis::ConstantManager* const_mgr = context->get_constant_mgr(); - if (matrix->AsNullConstant() != nullptr) { - return const_mgr->GetNullCompositeConstant(result_type); - } - - const auto& columns = matrix->AsMatrixConstant()->GetComponents(); - uint32_t number_of_rows = columns[0]->type()->AsVector()->element_count(); - - // Collect the ids of the elements in their new positions. - std::vector> result_elements(number_of_rows); - for (const analysis::Constant* column : columns) { - if (column->AsNullConstant()) { - column = const_mgr->GetNullCompositeConstant(column->type()); - } - const auto& column_components = column->AsVectorConstant()->GetComponents(); - - for (uint32_t row = 0; row < number_of_rows; ++row) { - result_elements[row].push_back( - const_mgr->GetDefiningInstruction(column_components[row]) - ->result_id()); - } - } - - // Create the constant for each row in the result, and collect the ids. - std::vector result_columns(number_of_rows); - for (uint32_t col = 0; col < number_of_rows; ++col) { - auto* element = const_mgr->GetConstant(result_type->element_type(), - result_elements[col]); - result_columns[col] = - const_mgr->GetDefiningInstruction(element)->result_id(); - } - - // Create the matrix constant from the row ids, and return it. - return const_mgr->GetConstant(result_type, result_columns); -} - -const analysis::Constant* FoldTranspose( - IRContext* context, Instruction* inst, - const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpTranspose); - - analysis::TypeManager* type_mgr = context->get_type_mgr(); - if (!inst->IsFloatingPointFoldingAllowed()) { - if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) { - return nullptr; - } - } - - const analysis::Constant* matrix = constants[0]; - if (matrix == nullptr) { - return nullptr; - } - - auto* result_type = type_mgr->GetType(inst->type_id()); - return TransposeMatrix(matrix, result_type->AsMatrix(), context); -} - ConstantFoldingRule FoldVectorTimesMatrix() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == spv::Op::OpVectorTimesMatrix); + assert(inst->opcode() == SpvOpVectorTimesMatrix); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -455,7 +286,13 @@ ConstantFoldingRule FoldVectorTimesMatrix() { assert(c1->type()->AsVector()->element_type() == element_type && c2->type()->AsMatrix()->element_type() == vector_type); + // Get a float vector that is the result of vector-times-matrix. + std::vector c1_components = + c1->GetVectorComponents(const_mgr); + std::vector c2_components = + c2->AsMatrixConstant()->GetComponents(); uint32_t resultVectorSize = result_type->AsVector()->element_count(); + std::vector ids; if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) { @@ -468,23 +305,15 @@ ConstantFoldingRule FoldVectorTimesMatrix() { return const_mgr->GetConstant(vector_type, ids); } - // Get a float vector that is the result of vector-times-matrix. - std::vector c1_components = - c1->GetVectorComponents(const_mgr); - std::vector c2_components = - c2->AsMatrixConstant()->GetComponents(); - if (float_type->width() == 32) { for (uint32_t i = 0; i < resultVectorSize; ++i) { float result_scalar = 0.0f; - if (!c2_components[i]->AsNullConstant()) { - const analysis::VectorConstant* c2_vec = - c2_components[i]->AsVectorConstant(); - for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { - float c1_scalar = c1_components[j]->GetFloat(); - float c2_scalar = c2_vec->GetComponents()[j]->GetFloat(); - result_scalar += c1_scalar * c2_scalar; - } + const analysis::VectorConstant* c2_vec = + c2_components[i]->AsVectorConstant(); + for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { + float c1_scalar = c1_components[j]->GetFloat(); + float c2_scalar = c2_vec->GetComponents()[j]->GetFloat(); + result_scalar += c1_scalar * c2_scalar; } utils::FloatProxy result(result_scalar); std::vector words = result.GetWords(); @@ -496,14 +325,12 @@ ConstantFoldingRule FoldVectorTimesMatrix() { } else if (float_type->width() == 64) { for (uint32_t i = 0; i < c2_components.size(); ++i) { double result_scalar = 0.0; - if (!c2_components[i]->AsNullConstant()) { - const analysis::VectorConstant* c2_vec = - c2_components[i]->AsVectorConstant(); - for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { - double c1_scalar = c1_components[j]->GetDouble(); - double c2_scalar = c2_vec->GetComponents()[j]->GetDouble(); - result_scalar += c1_scalar * c2_scalar; - } + const analysis::VectorConstant* c2_vec = + c2_components[i]->AsVectorConstant(); + for (uint32_t j = 0; j < c2_vec->GetComponents().size(); ++j) { + double c1_scalar = c1_components[j]->GetDouble(); + double c2_scalar = c2_vec->GetComponents()[j]->GetDouble(); + result_scalar += c1_scalar * c2_scalar; } utils::FloatProxy result(result_scalar); std::vector words = result.GetWords(); @@ -521,7 +348,7 @@ ConstantFoldingRule FoldMatrixTimesVector() { return [](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - assert(inst->opcode() == spv::Op::OpMatrixTimesVector); + assert(inst->opcode() == SpvOpMatrixTimesVector); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -551,7 +378,13 @@ ConstantFoldingRule FoldMatrixTimesVector() { assert(c1->type()->AsMatrix()->element_type() == vector_type); assert(c2->type()->AsVector()->element_type() == element_type); + // Get a float vector that is the result of matrix-times-vector. + std::vector c1_components = + c1->AsMatrixConstant()->GetComponents(); + std::vector c2_components = + c2->GetVectorComponents(const_mgr); uint32_t resultVectorSize = result_type->AsVector()->element_count(); + std::vector ids; if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) { @@ -564,24 +397,16 @@ ConstantFoldingRule FoldMatrixTimesVector() { return const_mgr->GetConstant(vector_type, ids); } - // Get a float vector that is the result of matrix-times-vector. - std::vector c1_components = - c1->AsMatrixConstant()->GetComponents(); - std::vector c2_components = - c2->GetVectorComponents(const_mgr); - if (float_type->width() == 32) { for (uint32_t i = 0; i < resultVectorSize; ++i) { float result_scalar = 0.0f; for (uint32_t j = 0; j < c1_components.size(); ++j) { - if (!c1_components[j]->AsNullConstant()) { - float c1_scalar = c1_components[j] - ->AsVectorConstant() - ->GetComponents()[i] - ->GetFloat(); - float c2_scalar = c2_components[j]->GetFloat(); - result_scalar += c1_scalar * c2_scalar; - } + float c1_scalar = c1_components[j] + ->AsVectorConstant() + ->GetComponents()[i] + ->GetFloat(); + float c2_scalar = c2_components[j]->GetFloat(); + result_scalar += c1_scalar * c2_scalar; } utils::FloatProxy result(result_scalar); std::vector words = result.GetWords(); @@ -594,14 +419,12 @@ ConstantFoldingRule FoldMatrixTimesVector() { for (uint32_t i = 0; i < resultVectorSize; ++i) { double result_scalar = 0.0; for (uint32_t j = 0; j < c1_components.size(); ++j) { - if (!c1_components[j]->AsNullConstant()) { - double c1_scalar = c1_components[j] - ->AsVectorConstant() - ->GetComponents()[i] - ->GetDouble(); - double c2_scalar = c2_components[j]->GetDouble(); - result_scalar += c1_scalar * c2_scalar; - } + double c1_scalar = c1_components[j] + ->AsVectorConstant() + ->GetComponents()[i] + ->GetDouble(); + double c2_scalar = c2_components[j]->GetDouble(); + result_scalar += c1_scalar * c2_scalar; } utils::FloatProxy result(result_scalar); std::vector words = result.GetWords(); @@ -635,9 +458,9 @@ ConstantFoldingRule FoldCompositeWithConstants() { } uint32_t component_type_id = 0; - if (type_inst->opcode() == spv::Op::OpTypeStruct) { + if (type_inst->opcode() == SpvOpTypeStruct) { component_type_id = type_inst->GetSingleWordInOperand(i); - } else if (type_inst->opcode() == spv::Op::OpTypeArray) { + } else if (type_inst->opcode() == SpvOpTypeArray) { component_type_id = type_inst->GetSingleWordInOperand(0); } @@ -666,24 +489,27 @@ using BinaryScalarFoldingRule = std::function; -// Returns a |ConstantFoldingRule| that folds unary scalar ops -// using |scalar_rule| and unary vectors ops by applying +// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops +// using |scalar_rule| and unary float point vectors ops by applying // |scalar_rule| to the elements of the vector. The |ConstantFoldingRule| // that is returned assumes that |constants| contains 1 entry. If they are // not |nullptr|, then their type is either |Float| or |Integer| or a |Vector| // whose element type is |Float| or |Integer|. -ConstantFoldingRule FoldUnaryOp(UnaryScalarFoldingRule scalar_rule) { +ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) { return [scalar_rule](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { - analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); const analysis::Type* result_type = type_mgr->GetType(inst->type_id()); const analysis::Vector* vector_type = result_type->AsVector(); + if (!inst->IsFloatingPointFoldingAllowed()) { + return nullptr; + } + const analysis::Constant* arg = - (inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0]; + (inst->opcode() == SpvOpExtInst) ? constants[1] : constants[0]; if (arg == nullptr) { return nullptr; @@ -716,25 +542,6 @@ ConstantFoldingRule FoldUnaryOp(UnaryScalarFoldingRule scalar_rule) { }; } -// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops -// using |scalar_rule| and unary float point vectors ops by applying -// |scalar_rule| to the elements of the vector. The |ConstantFoldingRule| -// that is returned assumes that |constants| contains 1 entry. If they are -// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector| -// whose element type is |Float| or |Integer|. -ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) { - auto folding_rule = FoldUnaryOp(scalar_rule); - return [folding_rule](IRContext* context, Instruction* inst, - const std::vector& constants) - -> const analysis::Constant* { - if (!inst->IsFloatingPointFoldingAllowed()) { - return nullptr; - } - - return folding_rule(context, inst, constants); - }; -} - // Returns the result of folding the constants in |constants| according the // |scalar_rule|. If |result_type| is a vector, then |scalar_rule| is applied // per component. @@ -792,7 +599,7 @@ ConstantFoldingRule FoldFPBinaryOp(BinaryScalarFoldingRule scalar_rule) { if (!inst->IsFloatingPointFoldingAllowed()) { return nullptr; } - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { return FoldFPBinaryOp(scalar_rule, inst->type_id(), {constants[1], constants[2]}, context); } @@ -967,11 +774,6 @@ const analysis::Constant* FoldScalarFPDivide( return FoldFPScalarDivideByZero(result_type, numerator, const_mgr); } - uint32_t width = denominator->type()->AsFloat()->width(); - if (width != 32 && width != 64) { - return nullptr; - } - const analysis::FloatConstant* denominator_float = denominator->AsFloatConstant(); if (denominator_float && denominator->GetValueAsDouble() == -0.0) { @@ -1142,10 +944,20 @@ ConstantFoldingRule FoldOpDotWithConstants() { }; } -ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(NegateFPConst); } -ConstantFoldingRule FoldSNegate() { return FoldUnaryOp(NegateIntConst); } +// This function defines a |UnaryScalarFoldingRule| that subtracts the constant +// from zero. +UnaryScalarFoldingRule FoldFNegateOp() { + return [](const analysis::Type* result_type, const analysis::Constant* a, + analysis::ConstantManager* const_mgr) -> const analysis::Constant* { + assert(result_type != nullptr && a != nullptr); + assert(result_type == a->type()); + return NegateFPConst(result_type, a, const_mgr); + }; +} -ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { +ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(FoldFNegateOp()); } + +ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) { return [cmp_opcode](IRContext* context, Instruction* inst, const std::vector& constants) -> const analysis::Constant* { @@ -1173,7 +985,7 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { return nullptr; } - if (operand_inst->opcode() != spv::Op::OpExtInst) { + if (operand_inst->opcode() != SpvOpExtInst) { return nullptr; } @@ -1197,25 +1009,25 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { bool result = false; switch (cmp_opcode) { - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: if (constants[0]) { if (min_const) { if (constants[0]->GetValueAsDouble() < min_const->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == spv::Op::OpFOrdLessThan || - cmp_opcode == spv::Op::OpFUnordLessThan); + result = (cmp_opcode == SpvOpFOrdLessThan || + cmp_opcode == SpvOpFUnordLessThan); } } if (max_const) { if (constants[0]->GetValueAsDouble() >= max_const->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == spv::Op::OpFOrdLessThan || - cmp_opcode == spv::Op::OpFUnordLessThan); + result = !(cmp_opcode == SpvOpFOrdLessThan || + cmp_opcode == SpvOpFUnordLessThan); } } } @@ -1225,8 +1037,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { if (max_const->GetValueAsDouble() < constants[1]->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == spv::Op::OpFOrdLessThan || - cmp_opcode == spv::Op::OpFUnordLessThan); + result = (cmp_opcode == SpvOpFOrdLessThan || + cmp_opcode == SpvOpFUnordLessThan); } } @@ -1234,31 +1046,31 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { if (min_const->GetValueAsDouble() >= constants[1]->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == spv::Op::OpFOrdLessThan || - cmp_opcode == spv::Op::OpFUnordLessThan); + result = !(cmp_opcode == SpvOpFOrdLessThan || + cmp_opcode == SpvOpFUnordLessThan); } } } break; - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: if (constants[0]) { if (min_const) { if (constants[0]->GetValueAsDouble() <= min_const->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || - cmp_opcode == spv::Op::OpFUnordLessThanEqual); + result = (cmp_opcode == SpvOpFOrdLessThanEqual || + cmp_opcode == SpvOpFUnordLessThanEqual); } } if (max_const) { if (constants[0]->GetValueAsDouble() > max_const->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || - cmp_opcode == spv::Op::OpFUnordLessThanEqual); + result = !(cmp_opcode == SpvOpFOrdLessThanEqual || + cmp_opcode == SpvOpFUnordLessThanEqual); } } } @@ -1268,8 +1080,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { if (max_const->GetValueAsDouble() <= constants[1]->GetValueAsDouble()) { found_result = true; - result = (cmp_opcode == spv::Op::OpFOrdLessThanEqual || - cmp_opcode == spv::Op::OpFUnordLessThanEqual); + result = (cmp_opcode == SpvOpFOrdLessThanEqual || + cmp_opcode == SpvOpFUnordLessThanEqual); } } @@ -1277,8 +1089,8 @@ ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) { if (min_const->GetValueAsDouble() > constants[1]->GetValueAsDouble()) { found_result = true; - result = !(cmp_opcode == spv::Op::OpFOrdLessThanEqual || - cmp_opcode == spv::Op::OpFUnordLessThanEqual); + result = !(cmp_opcode == SpvOpFOrdLessThanEqual || + cmp_opcode == SpvOpFUnordLessThanEqual); } } } @@ -1305,7 +1117,7 @@ ConstantFoldingRule FoldFMix() { const std::vector& constants) -> const analysis::Constant* { analysis::ConstantManager* const_mgr = context->get_constant_mgr(); - assert(inst->opcode() == spv::Op::OpExtInst && + assert(inst->opcode() == SpvOpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1455,7 +1267,7 @@ const analysis::Constant* FoldMax(const analysis::Type* result_type, const analysis::Constant* FoldClamp1( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpExtInst && + assert(inst->opcode() == SpvOpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1481,7 +1293,7 @@ const analysis::Constant* FoldClamp1( const analysis::Constant* FoldClamp2( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpExtInst && + assert(inst->opcode() == SpvOpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1509,7 +1321,7 @@ const analysis::Constant* FoldClamp2( const analysis::Constant* FoldClamp3( IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpExtInst && + assert(inst->opcode() == SpvOpExtInst && "Expecting an extended instruction."); assert(inst->GetSingleWordInOperand(0) == context->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && @@ -1595,72 +1407,68 @@ void ConstantFoldingRules::AddFoldingRules() { // applies to the instruction, the rest of the rules will not be attempted. // Take that into consideration. - rules_[spv::Op::OpCompositeConstruct].push_back(FoldCompositeWithConstants()); + rules_[SpvOpCompositeConstruct].push_back(FoldCompositeWithConstants()); - rules_[spv::Op::OpCompositeExtract].push_back(FoldExtractWithConstants()); - rules_[spv::Op::OpCompositeInsert].push_back(FoldInsertWithConstants()); + rules_[SpvOpCompositeExtract].push_back(FoldExtractWithConstants()); - rules_[spv::Op::OpConvertFToS].push_back(FoldFToI()); - rules_[spv::Op::OpConvertFToU].push_back(FoldFToI()); - rules_[spv::Op::OpConvertSToF].push_back(FoldIToF()); - rules_[spv::Op::OpConvertUToF].push_back(FoldIToF()); + rules_[SpvOpConvertFToS].push_back(FoldFToI()); + rules_[SpvOpConvertFToU].push_back(FoldFToI()); + rules_[SpvOpConvertSToF].push_back(FoldIToF()); + rules_[SpvOpConvertUToF].push_back(FoldIToF()); - rules_[spv::Op::OpDot].push_back(FoldOpDotWithConstants()); - rules_[spv::Op::OpFAdd].push_back(FoldFAdd()); - rules_[spv::Op::OpFDiv].push_back(FoldFDiv()); - rules_[spv::Op::OpFMul].push_back(FoldFMul()); - rules_[spv::Op::OpFSub].push_back(FoldFSub()); + rules_[SpvOpDot].push_back(FoldOpDotWithConstants()); + rules_[SpvOpFAdd].push_back(FoldFAdd()); + rules_[SpvOpFDiv].push_back(FoldFDiv()); + rules_[SpvOpFMul].push_back(FoldFMul()); + rules_[SpvOpFSub].push_back(FoldFSub()); - rules_[spv::Op::OpFOrdEqual].push_back(FoldFOrdEqual()); + rules_[SpvOpFOrdEqual].push_back(FoldFOrdEqual()); - rules_[spv::Op::OpFUnordEqual].push_back(FoldFUnordEqual()); + rules_[SpvOpFUnordEqual].push_back(FoldFUnordEqual()); - rules_[spv::Op::OpFOrdNotEqual].push_back(FoldFOrdNotEqual()); + rules_[SpvOpFOrdNotEqual].push_back(FoldFOrdNotEqual()); - rules_[spv::Op::OpFUnordNotEqual].push_back(FoldFUnordNotEqual()); + rules_[SpvOpFUnordNotEqual].push_back(FoldFUnordNotEqual()); - rules_[spv::Op::OpFOrdLessThan].push_back(FoldFOrdLessThan()); - rules_[spv::Op::OpFOrdLessThan].push_back( - FoldFClampFeedingCompare(spv::Op::OpFOrdLessThan)); + rules_[SpvOpFOrdLessThan].push_back(FoldFOrdLessThan()); + rules_[SpvOpFOrdLessThan].push_back( + FoldFClampFeedingCompare(SpvOpFOrdLessThan)); - rules_[spv::Op::OpFUnordLessThan].push_back(FoldFUnordLessThan()); - rules_[spv::Op::OpFUnordLessThan].push_back( - FoldFClampFeedingCompare(spv::Op::OpFUnordLessThan)); + rules_[SpvOpFUnordLessThan].push_back(FoldFUnordLessThan()); + rules_[SpvOpFUnordLessThan].push_back( + FoldFClampFeedingCompare(SpvOpFUnordLessThan)); - rules_[spv::Op::OpFOrdGreaterThan].push_back(FoldFOrdGreaterThan()); - rules_[spv::Op::OpFOrdGreaterThan].push_back( - FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThan)); + rules_[SpvOpFOrdGreaterThan].push_back(FoldFOrdGreaterThan()); + rules_[SpvOpFOrdGreaterThan].push_back( + FoldFClampFeedingCompare(SpvOpFOrdGreaterThan)); - rules_[spv::Op::OpFUnordGreaterThan].push_back(FoldFUnordGreaterThan()); - rules_[spv::Op::OpFUnordGreaterThan].push_back( - FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThan)); + rules_[SpvOpFUnordGreaterThan].push_back(FoldFUnordGreaterThan()); + rules_[SpvOpFUnordGreaterThan].push_back( + FoldFClampFeedingCompare(SpvOpFUnordGreaterThan)); - rules_[spv::Op::OpFOrdLessThanEqual].push_back(FoldFOrdLessThanEqual()); - rules_[spv::Op::OpFOrdLessThanEqual].push_back( - FoldFClampFeedingCompare(spv::Op::OpFOrdLessThanEqual)); + rules_[SpvOpFOrdLessThanEqual].push_back(FoldFOrdLessThanEqual()); + rules_[SpvOpFOrdLessThanEqual].push_back( + FoldFClampFeedingCompare(SpvOpFOrdLessThanEqual)); - rules_[spv::Op::OpFUnordLessThanEqual].push_back(FoldFUnordLessThanEqual()); - rules_[spv::Op::OpFUnordLessThanEqual].push_back( - FoldFClampFeedingCompare(spv::Op::OpFUnordLessThanEqual)); + rules_[SpvOpFUnordLessThanEqual].push_back(FoldFUnordLessThanEqual()); + rules_[SpvOpFUnordLessThanEqual].push_back( + FoldFClampFeedingCompare(SpvOpFUnordLessThanEqual)); - rules_[spv::Op::OpFOrdGreaterThanEqual].push_back(FoldFOrdGreaterThanEqual()); - rules_[spv::Op::OpFOrdGreaterThanEqual].push_back( - FoldFClampFeedingCompare(spv::Op::OpFOrdGreaterThanEqual)); + rules_[SpvOpFOrdGreaterThanEqual].push_back(FoldFOrdGreaterThanEqual()); + rules_[SpvOpFOrdGreaterThanEqual].push_back( + FoldFClampFeedingCompare(SpvOpFOrdGreaterThanEqual)); - rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( - FoldFUnordGreaterThanEqual()); - rules_[spv::Op::OpFUnordGreaterThanEqual].push_back( - FoldFClampFeedingCompare(spv::Op::OpFUnordGreaterThanEqual)); + rules_[SpvOpFUnordGreaterThanEqual].push_back(FoldFUnordGreaterThanEqual()); + rules_[SpvOpFUnordGreaterThanEqual].push_back( + FoldFClampFeedingCompare(SpvOpFUnordGreaterThanEqual)); - rules_[spv::Op::OpVectorShuffle].push_back(FoldVectorShuffleWithConstants()); - rules_[spv::Op::OpVectorTimesScalar].push_back(FoldVectorTimesScalar()); - rules_[spv::Op::OpVectorTimesMatrix].push_back(FoldVectorTimesMatrix()); - rules_[spv::Op::OpMatrixTimesVector].push_back(FoldMatrixTimesVector()); - rules_[spv::Op::OpTranspose].push_back(FoldTranspose); + rules_[SpvOpVectorShuffle].push_back(FoldVectorShuffleWithConstants()); + rules_[SpvOpVectorTimesScalar].push_back(FoldVectorTimesScalar()); + rules_[SpvOpVectorTimesMatrix].push_back(FoldVectorTimesMatrix()); + rules_[SpvOpMatrixTimesVector].push_back(FoldMatrixTimesVector()); - rules_[spv::Op::OpFNegate].push_back(FoldFNegate()); - rules_[spv::Op::OpSNegate].push_back(FoldSNegate()); - rules_[spv::Op::OpQuantizeToF16].push_back(FoldQuantizeToF16()); + rules_[SpvOpFNegate].push_back(FoldFNegate()); + rules_[SpvOpQuantizeToF16].push_back(FoldQuantizeToF16()); // Add rules for GLSLstd450 FeatureManager* feature_manager = context_->get_feature_mgr(); diff --git a/source/opt/const_folding_rules.h b/source/opt/const_folding_rules.h index fa345321..41ee2aa2 100644 --- a/source/opt/const_folding_rules.h +++ b/source/opt/const_folding_rules.h @@ -88,7 +88,7 @@ class ConstantFoldingRules { // Returns true if there is at least 1 folding rule for |inst|. const std::vector& GetRulesForInstruction( const Instruction* inst) const { - if (inst->opcode() != spv::Op::OpExtInst) { + if (inst->opcode() != SpvOpExtInst) { auto it = rules_.find(inst->opcode()); if (it != rules_.end()) { return it->second.value; @@ -108,15 +108,9 @@ class ConstantFoldingRules { virtual void AddFoldingRules(); protected: - struct hasher { - size_t operator()(const spv::Op& op) const noexcept { - return std::hash()(uint32_t(op)); - } - }; - // |rules[opcode]| is the set of rules that can be applied to instructions // with |opcode| as the opcode. - std::unordered_map rules_; + std::unordered_map rules_; // The folding rules for extended instructions. std::map ext_rules_; diff --git a/source/opt/constants.cpp b/source/opt/constants.cpp index a487a45b..bcff08c1 100644 --- a/source/opt/constants.cpp +++ b/source/opt/constants.cpp @@ -14,6 +14,7 @@ #include "source/opt/constants.h" +#include #include #include "source/opt/ir_context.h" @@ -305,16 +306,16 @@ const Constant* ConstantManager::GetConstantFromInst(const Instruction* inst) { switch (inst->opcode()) { // OpConstant{True|False} have the value embedded in the opcode. So they // are not handled by the for-loop above. Here we add the value explicitly. - case spv::Op::OpConstantTrue: + case SpvOp::SpvOpConstantTrue: literal_words_or_ids.push_back(true); break; - case spv::Op::OpConstantFalse: + case SpvOp::SpvOpConstantFalse: literal_words_or_ids.push_back(false); break; - case spv::Op::OpConstantNull: - case spv::Op::OpConstant: - case spv::Op::OpConstantComposite: - case spv::Op::OpSpecConstantComposite: + case SpvOp::SpvOpConstantNull: + case SpvOp::SpvOpConstant: + case SpvOp::SpvOpConstantComposite: + case SpvOp::SpvOpSpecConstantComposite: break; default: return nullptr; @@ -328,22 +329,22 @@ std::unique_ptr ConstantManager::CreateInstruction( uint32_t type = (type_id == 0) ? context()->get_type_mgr()->GetId(c->type()) : type_id; if (c->AsNullConstant()) { - return MakeUnique(context(), spv::Op::OpConstantNull, type, id, - std::initializer_list{}); + return MakeUnique(context(), SpvOp::SpvOpConstantNull, type, + id, std::initializer_list{}); } else if (const BoolConstant* bc = c->AsBoolConstant()) { return MakeUnique( context(), - bc->value() ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse, type, - id, std::initializer_list{}); + bc->value() ? SpvOp::SpvOpConstantTrue : SpvOp::SpvOpConstantFalse, + type, id, std::initializer_list{}); } else if (const IntConstant* ic = c->AsIntConstant()) { return MakeUnique( - context(), spv::Op::OpConstant, type, id, + context(), SpvOp::SpvOpConstant, type, id, std::initializer_list{ Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, ic->words())}); } else if (const FloatConstant* fc = c->AsFloatConstant()) { return MakeUnique( - context(), spv::Op::OpConstant, type, id, + context(), SpvOp::SpvOpConstant, type, id, std::initializer_list{ Operand(spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, fc->words())}); @@ -361,9 +362,9 @@ std::unique_ptr ConstantManager::CreateCompositeInstruction( uint32_t component_index = 0; for (const Constant* component_const : cc->GetComponents()) { uint32_t component_type_id = 0; - if (type_inst && type_inst->opcode() == spv::Op::OpTypeStruct) { + if (type_inst && type_inst->opcode() == SpvOpTypeStruct) { component_type_id = type_inst->GetSingleWordInOperand(component_index); - } else if (type_inst && type_inst->opcode() == spv::Op::OpTypeArray) { + } else if (type_inst && type_inst->opcode() == SpvOpTypeArray) { component_type_id = type_inst->GetSingleWordInOperand(0); } uint32_t id = FindDeclaredConstant(component_const, component_type_id); @@ -380,7 +381,7 @@ std::unique_ptr ConstantManager::CreateCompositeInstruction( } uint32_t type = (type_id == 0) ? context()->get_type_mgr()->GetId(cc->type()) : type_id; - return MakeUnique(context(), spv::Op::OpConstantComposite, type, + return MakeUnique(context(), SpvOp::SpvOpConstantComposite, type, result_id, std::move(operands)); } @@ -390,43 +391,6 @@ const Constant* ConstantManager::GetConstant( return cst ? RegisterConstant(std::move(cst)) : nullptr; } -const Constant* ConstantManager::GetNullCompositeConstant(const Type* type) { - std::vector literal_words_or_id; - - if (type->AsVector()) { - const Type* element_type = type->AsVector()->element_type(); - const uint32_t null_id = GetNullConstId(element_type); - const uint32_t element_count = type->AsVector()->element_count(); - for (uint32_t i = 0; i < element_count; i++) { - literal_words_or_id.push_back(null_id); - } - } else if (type->AsMatrix()) { - const Type* element_type = type->AsMatrix()->element_type(); - const uint32_t null_id = GetNullConstId(element_type); - const uint32_t element_count = type->AsMatrix()->element_count(); - for (uint32_t i = 0; i < element_count; i++) { - literal_words_or_id.push_back(null_id); - } - } else if (type->AsStruct()) { - // TODO (sfricke-lunarg) add proper struct support - return nullptr; - } else if (type->AsArray()) { - const Type* element_type = type->AsArray()->element_type(); - const uint32_t null_id = GetNullConstId(element_type); - assert(type->AsArray()->length_info().words[0] == - analysis::Array::LengthInfo::kConstant && - "unexpected array length"); - const uint32_t element_count = type->AsArray()->length_info().words[0]; - for (uint32_t i = 0; i < element_count; i++) { - literal_words_or_id.push_back(null_id); - } - } else { - return nullptr; - } - - return GetConstant(type, literal_words_or_id); -} - const Constant* ConstantManager::GetNumericVectorConstantWithWords( const Vector* type, const std::vector& literal_words) { const auto* element_type = type->element_type(); @@ -435,8 +399,6 @@ const Constant* ConstantManager::GetNumericVectorConstantWithWords( words_per_element = float_type->width() / 32; else if (const auto* int_type = element_type->AsInteger()) words_per_element = int_type->width() / 32; - else if (element_type->AsBool() != nullptr) - words_per_element = 1; if (words_per_element != 1 && words_per_element != 2) return nullptr; @@ -483,48 +445,18 @@ const Constant* ConstantManager::GetDoubleConst(double val) { return c; } -uint32_t ConstantManager::GetSIntConstId(int32_t val) { +uint32_t ConstantManager::GetSIntConst(int32_t val) { Type* sint_type = context()->get_type_mgr()->GetSIntType(); const Constant* c = GetConstant(sint_type, {static_cast(val)}); return GetDefiningInstruction(c)->result_id(); } -const Constant* ConstantManager::GetIntConst(uint64_t val, int32_t bitWidth, - bool isSigned) { - Type* int_type = context()->get_type_mgr()->GetIntType(bitWidth, isSigned); - - if (isSigned) { - // Sign extend the value. - int32_t num_of_bit_to_ignore = 64 - bitWidth; - val = static_cast(val << num_of_bit_to_ignore) >> - num_of_bit_to_ignore; - } else { - // Clear the upper bit that are not used. - uint64_t mask = ((1ull << bitWidth) - 1); - val &= mask; - } - - if (bitWidth <= 32) { - return GetConstant(int_type, {static_cast(val)}); - } - - // If the value is more than 32-bit, we need to split the operands into two - // 32-bit integers. - return GetConstant( - int_type, {static_cast(val >> 32), static_cast(val)}); -} - -uint32_t ConstantManager::GetUIntConstId(uint32_t val) { +uint32_t ConstantManager::GetUIntConst(uint32_t val) { Type* uint_type = context()->get_type_mgr()->GetUIntType(); const Constant* c = GetConstant(uint_type, {val}); return GetDefiningInstruction(c)->result_id(); } -uint32_t ConstantManager::GetNullConstId(const Type* type) { - const Constant* c = GetConstant(type, {}); - return GetDefiningInstruction(c)->result_id(); -} - std::vector Constant::GetVectorComponents( analysis::ConstantManager* const_mgr) const { std::vector components; diff --git a/source/opt/constants.h b/source/opt/constants.h index ae8dc625..588ca3e7 100644 --- a/source/opt/constants.h +++ b/source/opt/constants.h @@ -520,14 +520,6 @@ class ConstantManager { literal_words_or_ids.end())); } - // Takes a type and creates a OpConstantComposite - // This allows a - // OpConstantNull %composite_type - // to become a - // OpConstantComposite %composite_type %null %null ... etc - // Assumes type is a Composite already, otherwise returns null - const Constant* GetNullCompositeConstant(const Type* type); - // Gets or creates a unique Constant instance of Vector type |type| with // numeric elements and a vector of constant defining words |literal_words|. // If a Constant instance existed already in the constant pool, it returns a @@ -657,19 +649,10 @@ class ConstantManager { const Constant* GetDoubleConst(double val); // Returns the id of a 32-bit signed integer constant with value |val|. - uint32_t GetSIntConstId(int32_t val); - - // Returns an integer constant with `bitWidth` and value |val|. If `isSigned` - // is true, the constant will be a signed integer. Otherwise it will be - // unsigned. Only the `bitWidth` lower order bits of |val| will be used. The - // rest will be ignored. - const Constant* GetIntConst(uint64_t val, int32_t bitWidth, bool isSigned); + uint32_t GetSIntConst(int32_t val); // Returns the id of a 32-bit unsigned integer constant with value |val|. - uint32_t GetUIntConstId(uint32_t val); - - // Returns the id of a OpConstantNull with type of |type|. - uint32_t GetNullConstId(const Type* type); + uint32_t GetUIntConst(uint32_t val); private: // Creates a Constant instance with the given type and a vector of constant diff --git a/source/opt/control_dependence.cpp b/source/opt/control_dependence.cpp index 3d481396..f4879e0f 100644 --- a/source/opt/control_dependence.cpp +++ b/source/opt/control_dependence.cpp @@ -16,12 +16,15 @@ #include #include +#include +#include #include "source/opt/basic_block.h" #include "source/opt/cfg.h" #include "source/opt/dominator_analysis.h" #include "source/opt/function.h" #include "source/opt/instruction.h" +#include "spirv/unified1/spirv.h" // Computes the control dependence graph (CDG) using the algorithm in Cytron // 1991, "Efficiently Computing Static Single Assignment Form and the Control @@ -46,8 +49,8 @@ uint32_t ControlDependence::GetConditionID(const CFG& cfg) const { } const BasicBlock* source_bb = cfg.block(source_bb_id()); const Instruction* branch = source_bb->terminator(); - assert((branch->opcode() == spv::Op::OpBranchConditional || - branch->opcode() == spv::Op::OpSwitch) && + assert((branch->opcode() == SpvOpBranchConditional || + branch->opcode() == SpvOpSwitch) && "invalid control dependence; last instruction must be conditional " "branch or switch"); return branch->GetSingleWordInOperand(0); diff --git a/source/opt/convert_to_half_pass.cpp b/source/opt/convert_to_half_pass.cpp index cb0065d2..4086e31a 100644 --- a/source/opt/convert_to_half_pass.cpp +++ b/source/opt/convert_to_half_pass.cpp @@ -18,16 +18,19 @@ #include "source/opt/ir_builder.h" +namespace { + +// Indices of operands in SPIR-V instructions +static const int kImageSampleDrefIdInIdx = 2; + +} // anonymous namespace + namespace spvtools { namespace opt { -namespace { -// Indices of operands in SPIR-V instructions -constexpr int kImageSampleDrefIdInIdx = 2; -} // namespace bool ConvertToHalfPass::IsArithmetic(Instruction* inst) { return target_ops_core_.count(inst->opcode()) != 0 || - (inst->opcode() == spv::Op::OpExtInst && + (inst->opcode() == SpvOpExtInst && inst->GetSingleWordInOperand(0) == context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); @@ -39,21 +42,12 @@ bool ConvertToHalfPass::IsFloat(Instruction* inst, uint32_t width) { return Pass::IsFloat(ty_id, width); } -bool ConvertToHalfPass::IsStruct(Instruction* inst) { - uint32_t ty_id = inst->type_id(); - if (ty_id == 0) return false; - Instruction* ty_inst = Pass::GetBaseType(ty_id); - return (ty_inst->opcode() == spv::Op::OpTypeStruct); -} - bool ConvertToHalfPass::IsDecoratedRelaxed(Instruction* inst) { uint32_t r_id = inst->result_id(); for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) - if (r_inst->opcode() == spv::Op::OpDecorate && - spv::Decoration(r_inst->GetSingleWordInOperand(1)) == - spv::Decoration::RelaxedPrecision) { + if (r_inst->opcode() == SpvOpDecorate && + r_inst->GetSingleWordInOperand(1) == SpvDecorationRelaxedPrecision) return true; - } return false; } @@ -63,10 +57,6 @@ bool ConvertToHalfPass::IsRelaxed(uint32_t id) { void ConvertToHalfPass::AddRelaxed(uint32_t id) { relaxed_ids_set_.insert(id); } -bool ConvertToHalfPass::CanRelaxOpOperands(Instruction* inst) { - return image_ops_.count(inst->opcode()) == 0; -} - analysis::Type* ConvertToHalfPass::FloatScalarType(uint32_t width) { analysis::Float float_ty(width); return context()->get_type_mgr()->GetRegisteredType(&float_ty); @@ -92,12 +82,12 @@ analysis::Type* ConvertToHalfPass::FloatMatrixType(uint32_t v_cnt, uint32_t ConvertToHalfPass::EquivFloatTypeId(uint32_t ty_id, uint32_t width) { analysis::Type* reg_equiv_ty; Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); - if (ty_inst->opcode() == spv::Op::OpTypeMatrix) + if (ty_inst->opcode() == SpvOpTypeMatrix) reg_equiv_ty = FloatMatrixType(ty_inst->GetSingleWordInOperand(1), ty_inst->GetSingleWordInOperand(0), width); - else if (ty_inst->opcode() == spv::Op::OpTypeVector) + else if (ty_inst->opcode() == SpvOpTypeVector) reg_equiv_ty = FloatVectorType(ty_inst->GetSingleWordInOperand(1), width); - else // spv::Op::OpTypeFloat + else // SpvOpTypeFloat reg_equiv_ty = FloatScalarType(width); return context()->get_type_mgr()->GetTypeInstruction(reg_equiv_ty); } @@ -112,18 +102,18 @@ void ConvertToHalfPass::GenConvert(uint32_t* val_idp, uint32_t width, InstructionBuilder builder( context(), inst, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - if (val_inst->opcode() == spv::Op::OpUndef) - cvt_inst = builder.AddNullaryOp(nty_id, spv::Op::OpUndef); + if (val_inst->opcode() == SpvOpUndef) + cvt_inst = builder.AddNullaryOp(nty_id, SpvOpUndef); else - cvt_inst = builder.AddUnaryOp(nty_id, spv::Op::OpFConvert, *val_idp); + cvt_inst = builder.AddUnaryOp(nty_id, SpvOpFConvert, *val_idp); *val_idp = cvt_inst->result_id(); } bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { - if (inst->opcode() != spv::Op::OpFConvert) return false; + if (inst->opcode() != SpvOpFConvert) return false; uint32_t mty_id = inst->type_id(); Instruction* mty_inst = get_def_use_mgr()->GetDef(mty_id); - if (mty_inst->opcode() != spv::Op::OpTypeMatrix) return false; + if (mty_inst->opcode() != SpvOpTypeMatrix) return false; uint32_t vty_id = mty_inst->GetSingleWordInOperand(0); uint32_t v_cnt = mty_inst->GetSingleWordInOperand(1); Instruction* vty_inst = get_def_use_mgr()->GetDef(vty_id); @@ -140,18 +130,18 @@ bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { std::vector opnds = {}; for (uint32_t vidx = 0; vidx < v_cnt; ++vidx) { Instruction* ext_inst = builder.AddIdLiteralOp( - orig_vty_id, spv::Op::OpCompositeExtract, orig_mat_id, vidx); + orig_vty_id, SpvOpCompositeExtract, orig_mat_id, vidx); Instruction* cvt_inst = - builder.AddUnaryOp(vty_id, spv::Op::OpFConvert, ext_inst->result_id()); + builder.AddUnaryOp(vty_id, SpvOpFConvert, ext_inst->result_id()); opnds.push_back({SPV_OPERAND_TYPE_ID, {cvt_inst->result_id()}}); } uint32_t mat_id = TakeNextId(); std::unique_ptr mat_inst(new Instruction( - context(), spv::Op::OpCompositeConstruct, mty_id, mat_id, opnds)); + context(), SpvOpCompositeConstruct, mty_id, mat_id, opnds)); (void)builder.AddInstruction(std::move(mat_inst)); context()->ReplaceAllUsesWith(inst->result_id(), mat_id); // Turn original instruction into copy so it is valid. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetResultType(EquivFloatTypeId(mty_id, orig_width)); get_def_use_mgr()->AnalyzeInstUse(inst); return true; @@ -160,11 +150,10 @@ bool ConvertToHalfPass::MatConvertCleanup(Instruction* inst) { bool ConvertToHalfPass::RemoveRelaxedDecoration(uint32_t id) { return context()->get_decoration_mgr()->RemoveDecorationsFrom( id, [](const Instruction& dec) { - if (dec.opcode() == spv::Op::OpDecorate && - spv::Decoration(dec.GetSingleWordInOperand(1u)) == - spv::Decoration::RelaxedPrecision) { + if (dec.opcode() == SpvOpDecorate && + dec.GetSingleWordInOperand(1u) == SpvDecorationRelaxedPrecision) return true; - } else + else return false; }); } @@ -207,8 +196,8 @@ bool ConvertToHalfPass::ProcessPhi(Instruction* inst, uint32_t from_width, auto insert_before = bp->tail(); if (insert_before != bp->begin()) { --insert_before; - if (insert_before->opcode() != spv::Op::OpSelectionMerge && - insert_before->opcode() != spv::Op::OpLoopMerge) + if (insert_before->opcode() != SpvOpSelectionMerge && + insert_before->opcode() != SpvOpLoopMerge) ++insert_before; } GenConvert(prev_idp, to_width, &*insert_before); @@ -240,8 +229,7 @@ bool ConvertToHalfPass::ProcessConvert(Instruction* inst) { // changed to half. uint32_t val_id = inst->GetSingleWordInOperand(0); Instruction* val_inst = get_def_use_mgr()->GetDef(val_id); - if (inst->type_id() == val_inst->type_id()) - inst->SetOpcode(spv::Op::OpCopyObject); + if (inst->type_id() == val_inst->type_id()) inst->SetOpcode(SpvOpCopyObject); return true; // modified } @@ -263,7 +251,7 @@ bool ConvertToHalfPass::ProcessImageRef(Instruction* inst) { bool ConvertToHalfPass::ProcessDefault(Instruction* inst) { // If non-relaxed instruction has changed operands, need to convert // them back to float32 - if (inst->opcode() == spv::Op::OpPhi) return ProcessPhi(inst, 16u, 32u); + if (inst->opcode() == SpvOpPhi) return ProcessPhi(inst, 16u, 32u); bool modified = false; inst->ForEachInId([&inst, &modified, this](uint32_t* idp) { if (converted_ids_.count(*idp) == 0) return; @@ -281,9 +269,9 @@ bool ConvertToHalfPass::GenHalfInst(Instruction* inst) { bool inst_relaxed = IsRelaxed(inst->result_id()); if (IsArithmetic(inst) && inst_relaxed) modified = GenHalfArith(inst); - else if (inst->opcode() == spv::Op::OpPhi && inst_relaxed) + else if (inst->opcode() == SpvOpPhi && inst_relaxed) modified = ProcessPhi(inst, 32u, 16u); - else if (inst->opcode() == spv::Op::OpFConvert) + else if (inst->opcode() == SpvOpFConvert) modified = ProcessConvert(inst); else if (image_ops_.count(inst->opcode()) != 0) modified = ProcessImageRef(inst); @@ -305,7 +293,6 @@ bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) { bool relax = true; inst->ForEachInId([&relax, this](uint32_t* idp) { Instruction* op_inst = get_def_use_mgr()->GetDef(*idp); - if (IsStruct(op_inst)) relax = false; if (!IsFloat(op_inst, 32)) return; if (!IsRelaxed(*idp)) relax = false; }); @@ -317,8 +304,7 @@ bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) { relax = true; get_def_use_mgr()->ForEachUser(inst, [&relax, this](Instruction* uinst) { if (uinst->result_id() == 0 || !IsFloat(uinst, 32) || - (!IsDecoratedRelaxed(uinst) && !IsRelaxed(uinst->result_id())) || - !CanRelaxOpOperands(uinst)) { + (!IsDecoratedRelaxed(uinst) && !IsRelaxed(uinst->result_id()))) { relax = false; return; } @@ -364,7 +350,7 @@ Pass::Status ConvertToHalfPass::ProcessImpl() { }; bool modified = context()->ProcessReachableCallTree(pfn); // If modified, make sure module has Float16 capability - if (modified) context()->AddCapability(spv::Capability::Float16); + if (modified) context()->AddCapability(SpvCapabilityFloat16); // Remove all RelaxedPrecision decorations from instructions and globals for (auto c_id : relaxed_ids_set_) { modified |= RemoveRelaxedDecoration(c_id); @@ -385,44 +371,44 @@ Pass::Status ConvertToHalfPass::Process() { void ConvertToHalfPass::Initialize() { target_ops_core_ = { - spv::Op::OpVectorExtractDynamic, - spv::Op::OpVectorInsertDynamic, - spv::Op::OpVectorShuffle, - spv::Op::OpCompositeConstruct, - spv::Op::OpCompositeInsert, - spv::Op::OpCompositeExtract, - spv::Op::OpCopyObject, - spv::Op::OpTranspose, - spv::Op::OpConvertSToF, - spv::Op::OpConvertUToF, - // spv::Op::OpFConvert, - // spv::Op::OpQuantizeToF16, - spv::Op::OpFNegate, - spv::Op::OpFAdd, - spv::Op::OpFSub, - spv::Op::OpFMul, - spv::Op::OpFDiv, - spv::Op::OpFMod, - spv::Op::OpVectorTimesScalar, - spv::Op::OpMatrixTimesScalar, - spv::Op::OpVectorTimesMatrix, - spv::Op::OpMatrixTimesVector, - spv::Op::OpMatrixTimesMatrix, - spv::Op::OpOuterProduct, - spv::Op::OpDot, - spv::Op::OpSelect, - spv::Op::OpFOrdEqual, - spv::Op::OpFUnordEqual, - spv::Op::OpFOrdNotEqual, - spv::Op::OpFUnordNotEqual, - spv::Op::OpFOrdLessThan, - spv::Op::OpFUnordLessThan, - spv::Op::OpFOrdGreaterThan, - spv::Op::OpFUnordGreaterThan, - spv::Op::OpFOrdLessThanEqual, - spv::Op::OpFUnordLessThanEqual, - spv::Op::OpFOrdGreaterThanEqual, - spv::Op::OpFUnordGreaterThanEqual, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeConstruct, + SpvOpCompositeInsert, + SpvOpCompositeExtract, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpConvertSToF, + SpvOpConvertUToF, + // SpvOpFConvert, + // SpvOpQuantizeToF16, + SpvOpFNegate, + SpvOpFAdd, + SpvOpFSub, + SpvOpFMul, + SpvOpFDiv, + SpvOpFMod, + SpvOpVectorTimesScalar, + SpvOpMatrixTimesScalar, + SpvOpVectorTimesMatrix, + SpvOpMatrixTimesVector, + SpvOpMatrixTimesMatrix, + SpvOpOuterProduct, + SpvOpDot, + SpvOpSelect, + SpvOpFOrdEqual, + SpvOpFUnordEqual, + SpvOpFOrdNotEqual, + SpvOpFUnordNotEqual, + SpvOpFOrdLessThan, + SpvOpFUnordLessThan, + SpvOpFOrdGreaterThan, + SpvOpFUnordGreaterThan, + SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpFUnordGreaterThanEqual, }; target_ops_450_ = { GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, @@ -441,53 +427,53 @@ void ConvertToHalfPass::Initialize() { GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; - image_ops_ = {spv::Op::OpImageSampleImplicitLod, - spv::Op::OpImageSampleExplicitLod, - spv::Op::OpImageSampleDrefImplicitLod, - spv::Op::OpImageSampleDrefExplicitLod, - spv::Op::OpImageSampleProjImplicitLod, - spv::Op::OpImageSampleProjExplicitLod, - spv::Op::OpImageSampleProjDrefImplicitLod, - spv::Op::OpImageSampleProjDrefExplicitLod, - spv::Op::OpImageFetch, - spv::Op::OpImageGather, - spv::Op::OpImageDrefGather, - spv::Op::OpImageRead, - spv::Op::OpImageSparseSampleImplicitLod, - spv::Op::OpImageSparseSampleExplicitLod, - spv::Op::OpImageSparseSampleDrefImplicitLod, - spv::Op::OpImageSparseSampleDrefExplicitLod, - spv::Op::OpImageSparseSampleProjImplicitLod, - spv::Op::OpImageSparseSampleProjExplicitLod, - spv::Op::OpImageSparseSampleProjDrefImplicitLod, - spv::Op::OpImageSparseSampleProjDrefExplicitLod, - spv::Op::OpImageSparseFetch, - spv::Op::OpImageSparseGather, - spv::Op::OpImageSparseDrefGather, - spv::Op::OpImageSparseTexelsResident, - spv::Op::OpImageSparseRead}; + image_ops_ = {SpvOpImageSampleImplicitLod, + SpvOpImageSampleExplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageFetch, + SpvOpImageGather, + SpvOpImageDrefGather, + SpvOpImageRead, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleExplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseFetch, + SpvOpImageSparseGather, + SpvOpImageSparseDrefGather, + SpvOpImageSparseTexelsResident, + SpvOpImageSparseRead}; dref_image_ops_ = { - spv::Op::OpImageSampleDrefImplicitLod, - spv::Op::OpImageSampleDrefExplicitLod, - spv::Op::OpImageSampleProjDrefImplicitLod, - spv::Op::OpImageSampleProjDrefExplicitLod, - spv::Op::OpImageDrefGather, - spv::Op::OpImageSparseSampleDrefImplicitLod, - spv::Op::OpImageSparseSampleDrefExplicitLod, - spv::Op::OpImageSparseSampleProjDrefImplicitLod, - spv::Op::OpImageSparseSampleProjDrefExplicitLod, - spv::Op::OpImageSparseDrefGather, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageDrefGather, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseDrefGather, }; closure_ops_ = { - spv::Op::OpVectorExtractDynamic, - spv::Op::OpVectorInsertDynamic, - spv::Op::OpVectorShuffle, - spv::Op::OpCompositeConstruct, - spv::Op::OpCompositeInsert, - spv::Op::OpCompositeExtract, - spv::Op::OpCopyObject, - spv::Op::OpTranspose, - spv::Op::OpPhi, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeConstruct, + SpvOpCompositeInsert, + SpvOpCompositeExtract, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpPhi, }; relaxed_ids_set_.clear(); converted_ids_.clear(); diff --git a/source/opt/convert_to_half_pass.h b/source/opt/convert_to_half_pass.h index 8e10c4fb..c6e84d1b 100644 --- a/source/opt/convert_to_half_pass.h +++ b/source/opt/convert_to_half_pass.h @@ -45,7 +45,6 @@ class ConvertToHalfPass : public Pass { // Return true if |inst| returns scalar, vector or matrix type with base // float and |width| bool IsFloat(Instruction* inst, uint32_t width); - bool IsStruct(Instruction* inst); // Return true if |inst| is decorated with RelaxedPrecision bool IsDecoratedRelaxed(Instruction* inst); @@ -56,9 +55,6 @@ class ConvertToHalfPass : public Pass { // Add |id| to the relaxed id set void AddRelaxed(uint32_t id); - // Return true if the instruction's operands can be relaxed - bool CanRelaxOpOperands(Instruction* inst); - // Return type id for float with |width| analysis::Type* FloatScalarType(uint32_t width); @@ -124,26 +120,20 @@ class ConvertToHalfPass : public Pass { // Initialize state for converting to half void Initialize(); - struct hasher { - size_t operator()(const spv::Op& op) const noexcept { - return std::hash()(uint32_t(op)); - } - }; - // Set of core operations to be processed - std::unordered_set target_ops_core_; + std::unordered_set target_ops_core_; // Set of 450 extension operations to be processed std::unordered_set target_ops_450_; - // Set of all sample operations, including dref and non-dref operations - std::unordered_set image_ops_; + // Set of sample operations + std::unordered_set image_ops_; - // Set of only dref sample operations - std::unordered_set dref_image_ops_; + // Set of dref sample operations + std::unordered_set dref_image_ops_; - // Set of operations that can be marked as relaxed - std::unordered_set closure_ops_; + // Set of dref sample operations + std::unordered_set closure_ops_; // Set of ids of all relaxed instructions std::unordered_set relaxed_ids_set_; diff --git a/source/opt/convert_to_sampled_image_pass.cpp b/source/opt/convert_to_sampled_image_pass.cpp index c82db41c..e84d3578 100644 --- a/source/opt/convert_to_sampled_image_pass.cpp +++ b/source/opt/convert_to_sampled_image_pass.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "source/opt/ir_builder.h" #include "source/util/make_unique.h" @@ -69,7 +70,7 @@ uint32_t GetImageTypeOfSampledImage(analysis::TypeManager* type_mgr, Instruction* GetNonCopyObjectDef(analysis::DefUseManager* def_use_mgr, uint32_t inst_id) { Instruction* inst = def_use_mgr->GetDef(inst_id); - while (inst->opcode() == spv::Op::OpCopyObject) { + while (inst->opcode() == SpvOpCopyObject) { inst_id = inst->GetSingleWordInOperand(0u); inst = def_use_mgr->GetDef(inst_id); } @@ -86,9 +87,8 @@ bool ConvertToSampledImagePass::GetDescriptorSetBinding( bool found_binding_to_convert = false; for (auto decorate : decoration_manager->GetDecorationsFor(inst.result_id(), false)) { - spv::Decoration decoration = - spv::Decoration(decorate->GetSingleWordInOperand(1u)); - if (decoration == spv::Decoration::DescriptorSet) { + uint32_t decoration = decorate->GetSingleWordInOperand(1u); + if (decoration == SpvDecorationDescriptorSet) { if (found_descriptor_set_to_convert) { assert(false && "A resource has two OpDecorate for the descriptor set"); return false; @@ -96,7 +96,7 @@ bool ConvertToSampledImagePass::GetDescriptorSetBinding( descriptor_set_binding->descriptor_set = decorate->GetSingleWordInOperand(2u); found_descriptor_set_to_convert = true; - } else if (decoration == spv::Decoration::Binding) { + } else if (decoration == SpvDecorationBinding) { if (found_binding_to_convert) { assert(false && "A resource has two OpDecorate for the binding"); return false; @@ -116,7 +116,7 @@ bool ConvertToSampledImagePass::ShouldResourceBeConverted( const analysis::Type* ConvertToSampledImagePass::GetVariableType( const Instruction& variable) const { - if (variable.opcode() != spv::Op::OpVariable) return nullptr; + if (variable.opcode() != SpvOpVariable) return nullptr; auto* type = context()->get_type_mgr()->GetType(variable.type_id()); auto* pointer_type = type->AsPointer(); if (!pointer_type) return nullptr; @@ -124,12 +124,12 @@ const analysis::Type* ConvertToSampledImagePass::GetVariableType( return pointer_type->pointee_type(); } -spv::StorageClass ConvertToSampledImagePass::GetStorageClass( +SpvStorageClass ConvertToSampledImagePass::GetStorageClass( const Instruction& variable) const { - assert(variable.opcode() == spv::Op::OpVariable); + assert(variable.opcode() == SpvOpVariable); auto* type = context()->get_type_mgr()->GetType(variable.type_id()); auto* pointer_type = type->AsPointer(); - if (!pointer_type) return spv::StorageClass::Max; + if (!pointer_type) return SpvStorageClassMax; return pointer_type->storage_class(); } @@ -205,12 +205,12 @@ Pass::Status ConvertToSampledImagePass::Process() { void ConvertToSampledImagePass::FindUses(const Instruction* inst, std::vector* uses, - spv::Op user_opcode) const { + uint32_t user_opcode) const { auto* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(inst, [uses, user_opcode, this](Instruction* user) { if (user->opcode() == user_opcode) { uses->push_back(user); - } else if (user->opcode() == spv::Op::OpCopyObject) { + } else if (user->opcode() == SpvOpCopyObject) { FindUses(user, uses, user_opcode); } }); @@ -221,21 +221,21 @@ void ConvertToSampledImagePass::FindUsesOfImage( auto* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(image, [uses, this](Instruction* user) { switch (user->opcode()) { - case spv::Op::OpImageFetch: - case spv::Op::OpImageRead: - case spv::Op::OpImageWrite: - case spv::Op::OpImageQueryFormat: - case spv::Op::OpImageQueryOrder: - case spv::Op::OpImageQuerySizeLod: - case spv::Op::OpImageQuerySize: - case spv::Op::OpImageQueryLevels: - case spv::Op::OpImageQuerySamples: - case spv::Op::OpImageSparseFetch: + case SpvOpImageFetch: + case SpvOpImageRead: + case SpvOpImageWrite: + case SpvOpImageQueryFormat: + case SpvOpImageQueryOrder: + case SpvOpImageQuerySizeLod: + case SpvOpImageQuerySize: + case SpvOpImageQueryLevels: + case SpvOpImageQuerySamples: + case SpvOpImageSparseFetch: uses->push_back(user); default: break; } - if (user->opcode() == spv::Op::OpCopyObject) { + if (user->opcode() == SpvOpCopyObject) { FindUsesOfImage(user, uses); } }); @@ -248,7 +248,7 @@ Instruction* ConvertToSampledImagePass::CreateImageExtraction( IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); return builder.AddUnaryOp( GetImageTypeOfSampledImage(context()->get_type_mgr(), sampled_image), - spv::Op::OpImage, sampled_image->result_id()); + SpvOpImage, sampled_image->result_id()); } uint32_t ConvertToSampledImagePass::GetSampledImageTypeForImage( @@ -284,7 +284,7 @@ bool ConvertToSampledImagePass:: auto* def_use_mgr = context()->get_def_use_mgr(); uint32_t sampler_id = sampled_image_inst->GetSingleWordInOperand(1u); auto* sampler_load = def_use_mgr->GetDef(sampler_id); - if (sampler_load->opcode() != spv::Op::OpLoad) return false; + if (sampler_load->opcode() != SpvOpLoad) return false; auto* sampler = def_use_mgr->GetDef(sampler_load->GetSingleWordInOperand(0u)); DescriptorSetAndBinding sampler_descriptor_set_binding; return GetDescriptorSetBinding(*sampler, &sampler_descriptor_set_binding) && @@ -295,7 +295,7 @@ void ConvertToSampledImagePass::UpdateSampledImageUses( Instruction* image_load, Instruction* image_extraction, const DescriptorSetAndBinding& image_descriptor_set_binding) { std::vector sampled_image_users; - FindUses(image_load, &sampled_image_users, spv::Op::OpSampledImage); + FindUses(image_load, &sampled_image_users, SpvOpSampledImage); auto* def_use_mgr = context()->get_def_use_mgr(); for (auto* sampled_image_inst : sampled_image_users) { @@ -328,7 +328,7 @@ bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage( context()->get_type_mgr()->GetType(sampled_image_type_id); if (sampled_image_type == nullptr) return false; auto storage_class = GetStorageClass(*image_variable); - if (storage_class == spv::StorageClass::Max) return false; + if (storage_class == SpvStorageClassMax) return false; analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class); // Make sure |image_variable| is behind its type i.e., avoid the forward @@ -343,7 +343,7 @@ Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage( Instruction* image_variable, const DescriptorSetAndBinding& descriptor_set_binding) { std::vector image_variable_loads; - FindUses(image_variable, &image_variable_loads, spv::Op::OpLoad); + FindUses(image_variable, &image_variable_loads, SpvOpLoad); if (image_variable_loads.empty()) return Status::SuccessWithoutChange; const uint32_t sampled_image_type_id = @@ -364,14 +364,14 @@ Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage( bool ConvertToSampledImagePass::DoesSampledImageReferenceImage( Instruction* sampled_image_inst, Instruction* image_variable) { - if (sampled_image_inst->opcode() != spv::Op::OpSampledImage) return false; + if (sampled_image_inst->opcode() != SpvOpSampledImage) return false; auto* def_use_mgr = context()->get_def_use_mgr(); auto* image_load = GetNonCopyObjectDef( def_use_mgr, sampled_image_inst->GetSingleWordInOperand(0u)); - if (image_load->opcode() != spv::Op::OpLoad) return false; + if (image_load->opcode() != SpvOpLoad) return false; auto* image = GetNonCopyObjectDef(def_use_mgr, image_load->GetSingleWordInOperand(0u)); - return image->opcode() == spv::Op::OpVariable && + return image->opcode() == SpvOpVariable && image->result_id() == image_variable->result_id(); } @@ -381,10 +381,10 @@ Pass::Status ConvertToSampledImagePass::CheckUsesOfSamplerVariable( if (image_to_be_combined_with == nullptr) return Status::Failure; std::vector sampler_variable_loads; - FindUses(sampler_variable, &sampler_variable_loads, spv::Op::OpLoad); + FindUses(sampler_variable, &sampler_variable_loads, SpvOpLoad); for (auto* load : sampler_variable_loads) { std::vector sampled_image_users; - FindUses(load, &sampled_image_users, spv::Op::OpSampledImage); + FindUses(load, &sampled_image_users, SpvOpSampledImage); for (auto* sampled_image_inst : sampled_image_users) { if (!DoesSampledImageReferenceImage(sampled_image_inst, image_to_be_combined_with)) { diff --git a/source/opt/convert_to_sampled_image_pass.h b/source/opt/convert_to_sampled_image_pass.h index a8b1501e..d3938af7 100644 --- a/source/opt/convert_to_sampled_image_pass.h +++ b/source/opt/convert_to_sampled_image_pass.h @@ -120,13 +120,13 @@ class ConvertToSampledImagePass : public Pass { const analysis::Type* GetVariableType(const Instruction& variable) const; // Returns the storage class of |variable|. - spv::StorageClass GetStorageClass(const Instruction& variable) const; + SpvStorageClass GetStorageClass(const Instruction& variable) const; // Finds |inst|'s users whose opcode is |user_opcode| or users of OpCopyObject // instructions of |inst| whose opcode is |user_opcode| and puts them in // |uses|. void FindUses(const Instruction* inst, std::vector* uses, - spv::Op user_opcode) const; + uint32_t user_opcode) const; // Finds OpImage* instructions using |image| or OpCopyObject instructions that // copy |image| and puts them in |uses|. diff --git a/source/opt/copy_prop_arrays.cpp b/source/opt/copy_prop_arrays.cpp index 66a268fb..0b235629 100644 --- a/source/opt/copy_prop_arrays.cpp +++ b/source/opt/copy_prop_arrays.cpp @@ -22,12 +22,12 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kLoadPointerInOperand = 0; -constexpr uint32_t kStorePointerInOperand = 0; -constexpr uint32_t kStoreObjectInOperand = 1; -constexpr uint32_t kCompositeExtractObjectInOperand = 0; -constexpr uint32_t kTypePointerStorageClassInIdx = 0; -constexpr uint32_t kTypePointerPointeeInIdx = 1; +const uint32_t kLoadPointerInOperand = 0; +const uint32_t kStorePointerInOperand = 0; +const uint32_t kStoreObjectInOperand = 1; +const uint32_t kCompositeExtractObjectInOperand = 0; +const uint32_t kTypePointerStorageClassInIdx = 0; +const uint32_t kTypePointerPointeeInIdx = 1; bool IsDebugDeclareOrValue(Instruction* di) { auto dbg_opcode = di->GetCommonDebugOpcode(); @@ -46,8 +46,8 @@ Pass::Status CopyPropagateArrays::Process() { BasicBlock* entry_bb = &*function.begin(); - for (auto var_inst = entry_bb->begin(); - var_inst->opcode() == spv::Op::OpVariable; ++var_inst) { + for (auto var_inst = entry_bb->begin(); var_inst->opcode() == SpvOpVariable; + ++var_inst) { if (!IsPointerToArrayType(var_inst->type_id())) { continue; } @@ -76,7 +76,7 @@ Pass::Status CopyPropagateArrays::Process() { std::unique_ptr CopyPropagateArrays::FindSourceObjectIfPossible(Instruction* var_inst, Instruction* store_inst) { - assert(var_inst->opcode() == spv::Op::OpVariable && "Expecting a variable."); + assert(var_inst->opcode() == SpvOpVariable && "Expecting a variable."); // Check that the variable is a composite object where |store_inst| // dominates all of its loads. @@ -114,7 +114,7 @@ Instruction* CopyPropagateArrays::FindStoreInstruction( Instruction* store_inst = nullptr; get_def_use_mgr()->WhileEachUser( var_inst, [&store_inst, var_inst](Instruction* use) { - if (use->opcode() == spv::Op::OpStore && + if (use->opcode() == SpvOpStore && use->GetSingleWordInOperand(kStorePointerInOperand) == var_inst->result_id()) { if (store_inst == nullptr) { @@ -132,7 +132,7 @@ Instruction* CopyPropagateArrays::FindStoreInstruction( void CopyPropagateArrays::PropagateObject(Instruction* var_inst, MemoryObject* source, Instruction* insertion_point) { - assert(var_inst->opcode() == spv::Op::OpVariable && + assert(var_inst->opcode() == SpvOpVariable && "This function propagates variables."); Instruction* new_access_chain = BuildNewAccessChain(insertion_point, source); @@ -166,17 +166,17 @@ Instruction* CopyPropagateArrays::BuildNewAccessChain( bool CopyPropagateArrays::HasNoStores(Instruction* ptr_inst) { return get_def_use_mgr()->WhileEachUser(ptr_inst, [this](Instruction* use) { - if (use->opcode() == spv::Op::OpLoad) { + if (use->opcode() == SpvOpLoad) { return true; - } else if (use->opcode() == spv::Op::OpAccessChain) { + } else if (use->opcode() == SpvOpAccessChain) { return HasNoStores(use); - } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { + } else if (use->IsDecoration() || use->opcode() == SpvOpName) { return true; - } else if (use->opcode() == spv::Op::OpStore) { + } else if (use->opcode() == SpvOpStore) { return false; - } else if (use->opcode() == spv::Op::OpImageTexelPointer) { + } else if (use->opcode() == SpvOpImageTexelPointer) { return true; - } else if (use->opcode() == spv::Op::OpEntryPoint) { + } else if (use->opcode() == SpvOpEntryPoint) { return true; } // Some other instruction. Be conservative. @@ -193,19 +193,19 @@ bool CopyPropagateArrays::HasValidReferencesOnly(Instruction* ptr_inst, return get_def_use_mgr()->WhileEachUser( ptr_inst, [this, store_inst, dominator_analysis, ptr_inst](Instruction* use) { - if (use->opcode() == spv::Op::OpLoad || - use->opcode() == spv::Op::OpImageTexelPointer) { + if (use->opcode() == SpvOpLoad || + use->opcode() == SpvOpImageTexelPointer) { // TODO: If there are many load in the same BB as |store_inst| the // time to do the multiple traverses can add up. Consider collecting // those loads and doing a single traversal. return dominator_analysis->Dominates(store_inst, use); - } else if (use->opcode() == spv::Op::OpAccessChain) { + } else if (use->opcode() == SpvOpAccessChain) { return HasValidReferencesOnly(use, store_inst); - } else if (use->IsDecoration() || use->opcode() == spv::Op::OpName) { + } else if (use->IsDecoration() || use->opcode() == SpvOpName) { return true; - } else if (use->opcode() == spv::Op::OpStore) { + } else if (use->opcode() == SpvOpStore) { // If we are storing to part of the object it is not an candidate. - return ptr_inst->opcode() == spv::Op::OpVariable && + return ptr_inst->opcode() == SpvOpVariable && store_inst->GetSingleWordInOperand(kStorePointerInOperand) == ptr_inst->result_id(); } else if (IsDebugDeclareOrValue(use)) { @@ -221,15 +221,15 @@ CopyPropagateArrays::GetSourceObjectIfAny(uint32_t result) { Instruction* result_inst = context()->get_def_use_mgr()->GetDef(result); switch (result_inst->opcode()) { - case spv::Op::OpLoad: + case SpvOpLoad: return BuildMemoryObjectFromLoad(result_inst); - case spv::Op::OpCompositeExtract: + case SpvOpCompositeExtract: return BuildMemoryObjectFromExtract(result_inst); - case spv::Op::OpCompositeConstruct: + case SpvOpCompositeConstruct: return BuildMemoryObjectFromCompositeConstruct(result_inst); - case spv::Op::OpCopyObject: + case SpvOpCopyObject: return GetSourceObjectIfAny(result_inst->GetSingleWordInOperand(0)); - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: return BuildMemoryObjectFromInsert(result_inst); default: return nullptr; @@ -251,7 +251,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { // // It is built in reverse order because the different |OpAccessChain| // instructions are visited in reverse order from which they are applied. - while (current_inst->opcode() == spv::Op::OpAccessChain) { + while (current_inst->opcode() == SpvOpAccessChain) { for (uint32_t i = current_inst->NumInOperands() - 1; i >= 1; --i) { uint32_t element_index_id = current_inst->GetSingleWordInOperand(i); components_in_reverse.push_back(element_index_id); @@ -263,7 +263,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { // instruction followed by a series of |OpAccessChain| instructions, then // return |nullptr| because we cannot identify the owner or access chain // exactly. - if (current_inst->opcode() != spv::Op::OpVariable) { + if (current_inst->opcode() != SpvOpVariable) { return nullptr; } @@ -276,7 +276,7 @@ CopyPropagateArrays::BuildMemoryObjectFromLoad(Instruction* load_inst) { std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromExtract(Instruction* extract_inst) { - assert(extract_inst->opcode() == spv::Op::OpCompositeExtract && + assert(extract_inst->opcode() == SpvOpCompositeExtract && "Expecting an OpCompositeExtract instruction."); std::unique_ptr result = GetSourceObjectIfAny( extract_inst->GetSingleWordInOperand(kCompositeExtractObjectInOperand)); @@ -297,7 +297,7 @@ CopyPropagateArrays::BuildMemoryObjectFromExtract(Instruction* extract_inst) { std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( Instruction* conststruct_inst) { - assert(conststruct_inst->opcode() == spv::Op::OpCompositeConstruct && + assert(conststruct_inst->opcode() == SpvOpCompositeConstruct && "Expecting an OpCompositeConstruct instruction."); // If every operand in the instruction are part of the same memory object, and @@ -352,7 +352,7 @@ CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct( std::unique_ptr CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { - assert(insert_inst->opcode() == spv::Op::OpCompositeInsert && + assert(insert_inst->opcode() == SpvOpCompositeInsert && "Expecting an OpCompositeInsert instruction."); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); @@ -407,7 +407,7 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) { Instruction* current_insert = def_use_mgr->GetDef(insert_inst->GetSingleWordInOperand(1)); for (uint32_t i = number_of_elements - 1; i > 0; --i) { - if (current_insert->opcode() != spv::Op::OpCompositeInsert) { + if (current_insert->opcode() != SpvOpCompositeInsert) { return nullptr; } @@ -500,7 +500,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, if (IsDebugDeclareOrValue(use)) return true; switch (use->opcode()) { - case spv::Op::OpLoad: { + case SpvOpLoad: { analysis::Pointer* pointer_type = type->AsPointer(); uint32_t new_type_id = type_mgr->GetId(pointer_type->pointee_type()); @@ -509,7 +509,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case spv::Op::OpAccessChain: { + case SpvOpAccessChain: { analysis::Pointer* pointer_type = type->AsPointer(); const analysis::Type* pointee_type = pointer_type->pointee_type(); @@ -547,7 +547,7 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case spv::Op::OpCompositeExtract: { + case SpvOpCompositeExtract: { std::vector access_chain; for (uint32_t i = 1; i < use->NumInOperands(); ++i) { access_chain.push_back(use->GetSingleWordInOperand(i)); @@ -565,13 +565,13 @@ bool CopyPropagateArrays::CanUpdateUses(Instruction* original_ptr_inst, } return true; } - case spv::Op::OpStore: + case SpvOpStore: // If needed, we can create an element-by-element copy to change the // type of the value being stored. This way we can always handled // stores. return true; - case spv::Op::OpImageTexelPointer: - case spv::Op::OpName: + case SpvOpImageTexelPointer: + case SpvOpName: return true; default: return use->IsDecoration(); @@ -598,8 +598,8 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, if (use->IsCommonDebugInstr()) { switch (use->GetCommonDebugOpcode()) { case CommonDebugInfoDebugDeclare: { - if (new_ptr_inst->opcode() == spv::Op::OpVariable || - new_ptr_inst->opcode() == spv::Op::OpFunctionParameter) { + if (new_ptr_inst->opcode() == SpvOpVariable || + new_ptr_inst->opcode() == SpvOpFunctionParameter) { context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); context()->AnalyzeUses(use); @@ -640,7 +640,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, } switch (use->opcode()) { - case spv::Op::OpLoad: { + case SpvOpLoad: { // Replace the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -658,7 +658,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case spv::Op::OpAccessChain: { + case SpvOpAccessChain: { // Update the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -685,7 +685,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, pointer_type_inst->GetSingleWordInOperand(kTypePointerPointeeInIdx), access_chain); - spv::StorageClass storage_class = static_cast( + SpvStorageClass storage_class = static_cast( pointer_type_inst->GetSingleWordInOperand( kTypePointerStorageClassInIdx)); @@ -700,7 +700,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case spv::Op::OpCompositeExtract: { + case SpvOpCompositeExtract: { // Update the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -721,7 +721,7 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } } break; - case spv::Op::OpStore: + case SpvOpStore: // If the use is the pointer, then it is the single store to that // variable. We do not want to replace it. Instead, it will become // dead after all of the loads are removed, and ADCE will get rid of it. @@ -744,11 +744,11 @@ void CopyPropagateArrays::UpdateUses(Instruction* original_ptr_inst, context()->AnalyzeUses(use); } break; - case spv::Op::OpDecorate: + case SpvOpDecorate: // We treat an OpImageTexelPointer as a load. The result type should // always have the Image storage class, and should not need to be // updated. - case spv::Op::OpImageTexelPointer: + case SpvOpImageTexelPointer: // Replace the actual use. context()->ForgetUses(use); use->SetOperand(index, {new_ptr_inst->result_id()}); @@ -766,13 +766,13 @@ uint32_t CopyPropagateArrays::GetMemberTypeId( for (uint32_t element_index : access_chain) { Instruction* type_inst = get_def_use_mgr()->GetDef(id); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeMatrix: + case SpvOpTypeVector: id = type_inst->GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: id = type_inst->GetSingleWordInOperand(element_index); break; default: diff --git a/source/opt/copy_prop_arrays.h b/source/opt/copy_prop_arrays.h index 7486f808..9e7641f6 100644 --- a/source/opt/copy_prop_arrays.h +++ b/source/opt/copy_prop_arrays.h @@ -134,13 +134,13 @@ class CopyPropagateArrays : public MemPass { var_pointer_inst->GetSingleWordInOperand(1), GetAccessIds()); uint32_t member_pointer_type_id = type_mgr->FindPointerToType( - member_type_id, static_cast( + member_type_id, static_cast( var_pointer_inst->GetSingleWordInOperand(0))); return member_pointer_type_id; } // Returns the storage class of the memory object. - spv::StorageClass GetStorageClass() const { + SpvStorageClass GetStorageClass() const { analysis::TypeManager* type_mgr = GetVariable()->context()->get_type_mgr(); const analysis::Pointer* pointer_type = diff --git a/source/opt/dataflow.cpp b/source/opt/dataflow.cpp index 63737f19..c91fad08 100644 --- a/source/opt/dataflow.cpp +++ b/source/opt/dataflow.cpp @@ -14,6 +14,7 @@ #include "source/opt/dataflow.h" +#include #include namespace spvtools { @@ -77,7 +78,7 @@ void ForwardDataFlowAnalysis::EnqueueUsers(Instruction* inst) { } void ForwardDataFlowAnalysis::EnqueueBlockSuccessors(Instruction* inst) { - if (inst->opcode() != spv::Op::OpLabel) return; + if (inst->opcode() != SpvOpLabel) return; context() .cfg() ->block(inst->result_id()) diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp index 1526b9e0..d99b7f78 100644 --- a/source/opt/dead_branch_elim_pass.cpp +++ b/source/opt/dead_branch_elim_pass.cpp @@ -23,30 +23,34 @@ #include "source/cfa.h" #include "source/opt/ir_context.h" +#include "source/opt/iterator.h" #include "source/opt/struct_cfg_analysis.h" #include "source/util/make_unique.h" namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kBranchCondTrueLabIdInIdx = 1; -constexpr uint32_t kBranchCondFalseLabIdInIdx = 2; -} // namespace + +const uint32_t kBranchCondTrueLabIdInIdx = 1; +const uint32_t kBranchCondFalseLabIdInIdx = 2; + +} // anonymous namespace bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) { bool condIsConst; Instruction* cInst = get_def_use_mgr()->GetDef(condId); switch (cInst->opcode()) { - case spv::Op::OpConstantNull: - case spv::Op::OpConstantFalse: { + case SpvOpConstantNull: + case SpvOpConstantFalse: { *condVal = false; condIsConst = true; } break; - case spv::Op::OpConstantTrue: { + case SpvOpConstantTrue: { *condVal = true; condIsConst = true; } break; - case spv::Op::OpLogicalNot: { + case SpvOpLogicalNot: { bool negVal; condIsConst = GetConstCondition(cInst->GetSingleWordInOperand(0), &negVal); @@ -61,13 +65,13 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { Instruction* sInst = get_def_use_mgr()->GetDef(selId); uint32_t typeId = sInst->type_id(); Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); - if (!typeInst || (typeInst->opcode() != spv::Op::OpTypeInt)) return false; + if (!typeInst || (typeInst->opcode() != SpvOpTypeInt)) return false; // TODO(greg-lunarg): Support non-32 bit ints if (typeInst->GetSingleWordInOperand(0) != 32) return false; - if (sInst->opcode() == spv::Op::OpConstant) { + if (sInst->opcode() == SpvOpConstant) { *selVal = sInst->GetSingleWordInOperand(0); return true; - } else if (sInst->opcode() == spv::Op::OpConstantNull) { + } else if (sInst->opcode() == SpvOpConstantNull) { *selVal = 0; return true; } @@ -77,7 +81,7 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { void DeadBranchElimPass::AddBranch(uint32_t labelId, BasicBlock* bp) { assert(get_def_use_mgr()->GetDef(labelId) != nullptr); std::unique_ptr newBranch( - new Instruction(context(), spv::Op::OpBranch, 0, 0, + new Instruction(context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); context()->AnalyzeDefUse(&*newBranch); context()->set_instr_block(&*newBranch, bp); @@ -111,13 +115,13 @@ bool DeadBranchElimPass::MarkLiveBlocks( Instruction* terminator = block->terminator(); uint32_t live_lab_id = 0; // Check if the terminator has a single valid successor. - if (terminator->opcode() == spv::Op::OpBranchConditional) { + if (terminator->opcode() == SpvOpBranchConditional) { bool condVal; if (GetConstCondition(terminator->GetSingleWordInOperand(0u), &condVal)) { live_lab_id = terminator->GetSingleWordInOperand( condVal ? kBranchCondTrueLabIdInIdx : kBranchCondFalseLabIdInIdx); } - } else if (terminator->opcode() == spv::Op::OpSwitch) { + } else if (terminator->opcode() == SpvOpSwitch) { uint32_t sel_val; if (GetConstInteger(terminator->GetSingleWordInOperand(0u), &sel_val)) { // Search switch operands for selector value, set live_lab_id to @@ -190,8 +194,8 @@ bool DeadBranchElimPass::SimplifyBranch(BasicBlock* block, uint32_t live_lab_id) { Instruction* merge_inst = block->GetMergeInst(); Instruction* terminator = block->terminator(); - if (merge_inst && merge_inst->opcode() == spv::Op::OpSelectionMerge) { - if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch && + if (merge_inst && merge_inst->opcode() == SpvOpSelectionMerge) { + if (merge_inst->NextNode()->opcode() == SpvOpSwitch && SwitchHasNestedBreak(block->id())) { if (terminator->NumInOperands() == 2) { // We cannot remove the branch, and it already has a single case, so no @@ -262,7 +266,7 @@ bool DeadBranchElimPass::FixPhiNodesInLiveBlocks( for (auto& block : *func) { if (live_blocks.count(&block)) { for (auto iter = block.begin(); iter != block.end();) { - if (iter->opcode() != spv::Op::OpPhi) { + if (iter->opcode() != SpvOpPhi) { break; } @@ -288,7 +292,7 @@ bool DeadBranchElimPass::FixPhiNodesInLiveBlocks( cont_iter->second == &block && inst->NumInOperands() > 4) { if (get_def_use_mgr() ->GetDef(inst->GetSingleWordInOperand(i - 1)) - ->opcode() == spv::Op::OpUndef) { + ->opcode() == SpvOpUndef) { // Already undef incoming value, no change necessary. operands.push_back(inst->GetInOperand(i - 1)); operands.push_back(inst->GetInOperand(i)); @@ -374,14 +378,14 @@ bool DeadBranchElimPass::EraseDeadBlocks( if (unreachable_continues.count(&*ebi)) { uint32_t cont_id = unreachable_continues.find(&*ebi)->second->id(); if (ebi->begin() != ebi->tail() || - ebi->terminator()->opcode() != spv::Op::OpBranch || + ebi->terminator()->opcode() != SpvOpBranch || ebi->terminator()->GetSingleWordInOperand(0u) != cont_id) { // Make unreachable, but leave the label. KillAllInsts(&*ebi, false); // Add unconditional branch to header. assert(unreachable_continues.count(&*ebi)); ebi->AddInstruction(MakeUnique( - context(), spv::Op::OpBranch, 0, 0, + context(), SpvOpBranch, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {cont_id}}})); get_def_use_mgr()->AnalyzeInstUse(&*ebi->tail()); context()->set_instr_block(&*ebi->tail(), &*ebi); @@ -390,12 +394,12 @@ bool DeadBranchElimPass::EraseDeadBlocks( ++ebi; } else if (unreachable_merges.count(&*ebi)) { if (ebi->begin() != ebi->tail() || - ebi->terminator()->opcode() != spv::Op::OpUnreachable) { + ebi->terminator()->opcode() != SpvOpUnreachable) { // Make unreachable, but leave the label. KillAllInsts(&*ebi, false); // Add unreachable terminator. ebi->AddInstruction( - MakeUnique(context(), spv::Op::OpUnreachable, 0, 0, + MakeUnique(context(), SpvOpUnreachable, 0, 0, std::initializer_list{})); context()->AnalyzeUses(ebi->terminator()); context()->set_instr_block(ebi->terminator(), &*ebi); @@ -461,7 +465,7 @@ void DeadBranchElimPass::FixBlockOrder() { }; // Structured order is more intuitive so use it where possible. - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { context()->ProcessReachableCallTree(reorder_structured); } else { context()->ProcessReachableCallTree(reorder_dominators); @@ -473,8 +477,7 @@ Pass::Status DeadBranchElimPass::Process() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == spv::Op::OpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Process all entry point functions ProcessFunction pfn = [this](Function* fp) { return EliminateDeadBranches(fp); @@ -498,7 +501,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( Instruction* branch = start_block->terminator(); uint32_t next_block_id = 0; switch (branch->opcode()) { - case spv::Op::OpBranchConditional: + case SpvOpBranchConditional: next_block_id = start_block->MergeBlockIdIfAny(); if (next_block_id == 0) { // If a possible target is the |loop_merge_id| or |loop_continue_id|, @@ -527,7 +530,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( } } break; - case spv::Op::OpSwitch: + case SpvOpSwitch: next_block_id = start_block->MergeBlockIdIfAny(); if (next_block_id == 0) { // A switch with no merge instructions can have at most 5 targets: @@ -575,7 +578,7 @@ Instruction* DeadBranchElimPass::FindFirstExitFromSelectionMerge( // The fall through is case 3. } break; - case spv::Op::OpBranch: + case SpvOpBranch: // Need to check if this is the header of a loop nested in the // selection construct. next_block_id = start_block->MergeBlockIdIfAny(); diff --git a/source/opt/dead_insert_elim_pass.cpp b/source/opt/dead_insert_elim_pass.cpp index f985e4c2..d877f0f9 100644 --- a/source/opt/dead_insert_elim_pass.cpp +++ b/source/opt/dead_insert_elim_pass.cpp @@ -23,29 +23,32 @@ namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kTypeVectorCountInIdx = 1; -constexpr uint32_t kTypeMatrixCountInIdx = 1; -constexpr uint32_t kTypeArrayLengthIdInIdx = 1; -constexpr uint32_t kTypeIntWidthInIdx = 0; -constexpr uint32_t kConstantValueInIdx = 0; -constexpr uint32_t kInsertObjectIdInIdx = 0; -constexpr uint32_t kInsertCompositeIdInIdx = 1; -} // namespace + +const uint32_t kTypeVectorCountInIdx = 1; +const uint32_t kTypeMatrixCountInIdx = 1; +const uint32_t kTypeArrayLengthIdInIdx = 1; +const uint32_t kTypeIntWidthInIdx = 0; +const uint32_t kConstantValueInIdx = 0; +const uint32_t kInsertObjectIdInIdx = 0; +const uint32_t kInsertCompositeIdInIdx = 1; + +} // anonymous namespace uint32_t DeadInsertElimPass::NumComponents(Instruction* typeInst) { switch (typeInst->opcode()) { - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { return typeInst->GetSingleWordInOperand(kTypeVectorCountInIdx); } break; - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { return typeInst->GetSingleWordInOperand(kTypeMatrixCountInIdx); } break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { uint32_t lenId = typeInst->GetSingleWordInOperand(kTypeArrayLengthIdInIdx); Instruction* lenInst = get_def_use_mgr()->GetDef(lenId); - if (lenInst->opcode() != spv::Op::OpConstant) return 0; + if (lenInst->opcode() != SpvOpConstant) return 0; uint32_t lenTypeId = lenInst->type_id(); Instruction* lenTypeInst = get_def_use_mgr()->GetDef(lenTypeId); // TODO(greg-lunarg): Support non-32-bit array length @@ -53,7 +56,7 @@ uint32_t DeadInsertElimPass::NumComponents(Instruction* typeInst) { return 0; return lenInst->GetSingleWordInOperand(kConstantValueInIdx); } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { return typeInst->NumInOperands(); } break; default: { return 0; } break; @@ -65,10 +68,10 @@ void DeadInsertElimPass::MarkInsertChain( uint32_t extOffset, std::unordered_set* visited_phis) { // Not currently optimizing array inserts. Instruction* typeInst = get_def_use_mgr()->GetDef(insertChain->type_id()); - if (typeInst->opcode() == spv::Op::OpTypeArray) return; + if (typeInst->opcode() == SpvOpTypeArray) return; // Insert chains are only composed of inserts and phis - if (insertChain->opcode() != spv::Op::OpCompositeInsert && - insertChain->opcode() != spv::Op::OpPhi) + if (insertChain->opcode() != SpvOpCompositeInsert && + insertChain->opcode() != SpvOpPhi) return; // If extract indices are empty, mark all subcomponents if type // is constant length. @@ -86,7 +89,7 @@ void DeadInsertElimPass::MarkInsertChain( } } Instruction* insInst = insertChain; - while (insInst->opcode() == spv::Op::OpCompositeInsert) { + while (insInst->opcode() == SpvOpCompositeInsert) { // If no extract indices, mark insert and inserted object (which might // also be an insert chain) and continue up the chain though the input // composite. @@ -136,7 +139,7 @@ void DeadInsertElimPass::MarkInsertChain( insInst = get_def_use_mgr()->GetDef(compId); } // If insert chain ended with phi, do recursive call on each operand - if (insInst->opcode() != spv::Op::OpPhi) return; + if (insInst->opcode() != SpvOpPhi) return; // Mark phi visited to prevent potential infinite loop. If phi is already // visited, return to avoid infinite loop. if (visited_phis->count(insInst->result_id()) != 0) return; @@ -176,17 +179,17 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { // Only process Inserts and composite Phis - spv::Op op = ii->opcode(); + SpvOp op = ii->opcode(); Instruction* typeInst = get_def_use_mgr()->GetDef(ii->type_id()); - if (op != spv::Op::OpCompositeInsert && - (op != spv::Op::OpPhi || !spvOpcodeIsComposite(typeInst->opcode()))) + if (op != SpvOpCompositeInsert && + (op != SpvOpPhi || !spvOpcodeIsComposite(typeInst->opcode()))) continue; // The marking algorithm can be expensive for large arrays and the // efficacy of eliminating dead inserts into arrays is questionable. // Skip optimizing array inserts for now. Just mark them live. // TODO(greg-lunarg): Eliminate dead array inserts - if (op == spv::Op::OpCompositeInsert) { - if (typeInst->opcode() == spv::Op::OpTypeArray) { + if (op == SpvOpCompositeInsert) { + if (typeInst->opcode() == SpvOpTypeArray) { liveInserts_.insert(ii->result_id()); continue; } @@ -195,11 +198,11 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { get_def_use_mgr()->ForEachUser(id, [&ii, this](Instruction* user) { if (user->IsCommonDebugInstr()) return; switch (user->opcode()) { - case spv::Op::OpCompositeInsert: - case spv::Op::OpPhi: + case SpvOpCompositeInsert: + case SpvOpPhi: // Use by insert or phi does not initiate marking break; - case spv::Op::OpCompositeExtract: { + case SpvOpCompositeExtract: { // Capture extract indices std::vector extIndices; uint32_t icnt = 0; @@ -213,8 +216,7 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { } break; default: { // Mark inserts in chain for all components - std::unordered_set visited_phis; - MarkInsertChain(&*ii, nullptr, 0, &visited_phis); + MarkInsertChain(&*ii, nullptr, 0, nullptr); } break; } }); @@ -224,7 +226,7 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) { std::vector dead_instructions; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - if (ii->opcode() != spv::Op::OpCompositeInsert) continue; + if (ii->opcode() != SpvOpCompositeInsert) continue; const uint32_t id = ii->result_id(); if (liveInserts_.find(id) != liveInserts_.end()) continue; const uint32_t replId = diff --git a/source/opt/dead_variable_elimination.cpp b/source/opt/dead_variable_elimination.cpp index e39132c2..28371068 100644 --- a/source/opt/dead_variable_elimination.cpp +++ b/source/opt/dead_variable_elimination.cpp @@ -33,7 +33,7 @@ Pass::Status DeadVariableElimination::Process() { // Get the reference count for all of the global OpVariable instructions. for (auto& inst : context()->types_values()) { - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOp::SpvOpVariable) { continue; } @@ -43,11 +43,11 @@ Pass::Status DeadVariableElimination::Process() { // Check the linkage. If it is exported, it could be reference somewhere // else, so we must keep the variable around. get_decoration_mgr()->ForEachDecoration( - result_id, uint32_t(spv::Decoration::LinkageAttributes), + result_id, SpvDecorationLinkageAttributes, [&count](const Instruction& linkage_instruction) { uint32_t last_operand = linkage_instruction.NumOperands() - 1; - if (spv::LinkageType(linkage_instruction.GetSingleWordOperand( - last_operand)) == spv::LinkageType::Export) { + if (linkage_instruction.GetSingleWordOperand(last_operand) == + SpvLinkageTypeExport) { count = kMustKeep; } }); @@ -57,8 +57,7 @@ Pass::Status DeadVariableElimination::Process() { // at the uses and count the number of real references. count = 0; get_def_use_mgr()->ForEachUser(result_id, [&count](Instruction* user) { - if (!IsAnnotationInst(user->opcode()) && - user->opcode() != spv::Op::OpName) { + if (!IsAnnotationInst(user->opcode()) && user->opcode() != SpvOpName) { ++count; } }); @@ -82,7 +81,7 @@ Pass::Status DeadVariableElimination::Process() { void DeadVariableElimination::DeleteVariable(uint32_t result_id) { Instruction* inst = get_def_use_mgr()->GetDef(result_id); - assert(inst->opcode() == spv::Op::OpVariable && + assert(inst->opcode() == SpvOpVariable && "Should not be trying to delete anything other than an OpVariable."); // Look for an initializer that references another variable. We need to know @@ -94,7 +93,7 @@ void DeadVariableElimination::DeleteVariable(uint32_t result_id) { // TODO: Handle OpSpecConstantOP which might be defined in terms of other // variables. Will probably require a unified dead code pass that does all // instruction types. (Issue 906) - if (initializer->opcode() == spv::Op::OpVariable) { + if (initializer->opcode() == SpvOpVariable) { uint32_t initializer_id = initializer->result_id(); size_t& count = reference_count_[initializer_id]; if (count != kMustKeep) { diff --git a/source/opt/debug_info_manager.cpp b/source/opt/debug_info_manager.cpp index 1e614c6f..3585186f 100644 --- a/source/opt/debug_info_manager.cpp +++ b/source/opt/debug_info_manager.cpp @@ -22,31 +22,32 @@ // Constants for OpenCL.DebugInfo.100 & NonSemantic.Shader.DebugInfo.100 // extension instructions. +static const uint32_t kOpLineOperandLineIndex = 1; +static const uint32_t kLineOperandIndexDebugFunction = 7; +static const uint32_t kLineOperandIndexDebugLexicalBlock = 5; +static const uint32_t kLineOperandIndexDebugLine = 5; +static const uint32_t kDebugFunctionOperandFunctionIndex = 13; +static const uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; +static const uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; +static const uint32_t kDebugFunctionOperandParentIndex = 9; +static const uint32_t kDebugTypeCompositeOperandParentIndex = 9; +static const uint32_t kDebugLexicalBlockOperandParentIndex = 7; +static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6; +static const uint32_t kDebugExpressOperandOperationIndex = 4; +static const uint32_t kDebugDeclareOperandLocalVariableIndex = 4; +static const uint32_t kDebugDeclareOperandVariableIndex = 5; +static const uint32_t kDebugValueOperandExpressionIndex = 6; +static const uint32_t kDebugOperationOperandOperationIndex = 4; +static const uint32_t kOpVariableOperandStorageClassIndex = 2; +static const uint32_t kDebugLocalVariableOperandParentIndex = 9; +static const uint32_t kExtInstInstructionInIdx = 1; +static const uint32_t kDebugGlobalVariableOperandFlagsIndex = 12; +static const uint32_t kDebugLocalVariableOperandFlagsIndex = 10; + namespace spvtools { namespace opt { namespace analysis { namespace { -constexpr uint32_t kOpLineOperandLineIndex = 1; -constexpr uint32_t kLineOperandIndexDebugFunction = 7; -constexpr uint32_t kLineOperandIndexDebugLexicalBlock = 5; -constexpr uint32_t kLineOperandIndexDebugLine = 5; -constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; -constexpr uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4; -constexpr uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5; -constexpr uint32_t kDebugFunctionOperandParentIndex = 9; -constexpr uint32_t kDebugTypeCompositeOperandParentIndex = 9; -constexpr uint32_t kDebugLexicalBlockOperandParentIndex = 7; -constexpr uint32_t kDebugInlinedAtOperandInlinedIndex = 6; -constexpr uint32_t kDebugExpressOperandOperationIndex = 4; -constexpr uint32_t kDebugDeclareOperandLocalVariableIndex = 4; -constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; -constexpr uint32_t kDebugValueOperandExpressionIndex = 6; -constexpr uint32_t kDebugOperationOperandOperationIndex = 4; -constexpr uint32_t kOpVariableOperandStorageClassIndex = 2; -constexpr uint32_t kDebugLocalVariableOperandParentIndex = 9; -constexpr uint32_t kExtInstInstructionInIdx = 1; -constexpr uint32_t kDebugGlobalVariableOperandFlagsIndex = 12; -constexpr uint32_t kDebugLocalVariableOperandFlagsIndex = 10; void SetInlinedOperand(Instruction* dbg_inlined_at, uint32_t inlined_operand) { assert(dbg_inlined_at); @@ -155,8 +156,7 @@ void DebugInfoManager::RegisterDbgDeclare(uint32_t var_id, uint32_t AddNewConstInGlobals(IRContext* context, uint32_t const_value) { uint32_t id = context->TakeNextId(); std::unique_ptr new_const(new Instruction( - context, spv::Op::OpConstant, context->get_type_mgr()->GetUIntTypeId(), - id, + context, SpvOpConstant, context->get_type_mgr()->GetUIntTypeId(), id, { {spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, {const_value}}, @@ -212,7 +212,7 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, break; } } else { - if (line->opcode() == spv::Op::OpLine) { + if (line->opcode() == SpvOpLine) { line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex); } else if (line->GetShader100DebugOpcode() == NonSemanticShaderDebugInfo100DebugLine) { @@ -230,19 +230,18 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line, // constants that may be generated here is likely not significant // and will likely be cleaned up in later passes. if (line_number_type == spv_operand_type_t::SPV_OPERAND_TYPE_ID && - line->opcode() == spv::Op::OpLine) { + line->opcode() == SpvOpLine) { if (!context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse) || !context()->AreAnalysesValid(IRContext::Analysis::kAnalysisConstants)) line_number = AddNewConstInGlobals(context(), line_number); else - line_number = - context()->get_constant_mgr()->GetUIntConstId(line_number); + line_number = context()->get_constant_mgr()->GetUIntConst(line_number); } } uint32_t result_id = context()->TakeNextId(); std::unique_ptr inlined_at(new Instruction( - context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {setId}}, @@ -335,8 +334,8 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() { if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { deref_operation = std::unique_ptr(new Instruction( - context(), spv::Op::OpExtInst, - context()->get_type_mgr()->GetVoidTypeId(), result_id, + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + result_id, { {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, @@ -345,11 +344,11 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() { {static_cast(OpenCLDebugInfo100Deref)}}, })); } else { - uint32_t deref_id = context()->get_constant_mgr()->GetUIntConstId( + uint32_t deref_id = context()->get_constant_mgr()->GetUIntConst( NonSemanticShaderDebugInfo100Deref); deref_operation = std::unique_ptr( - new Instruction(context(), spv::Op::OpExtInst, + new Instruction(context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -391,7 +390,7 @@ Instruction* DebugInfoManager::GetDebugInfoNone() { uint32_t result_id = context()->TakeNextId(); std::unique_ptr dbg_info_none_inst(new Instruction( - context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -415,7 +414,7 @@ Instruction* DebugInfoManager::GetEmptyDebugExpression() { uint32_t result_id = context()->TakeNextId(); std::unique_ptr empty_debug_expr(new Instruction( - context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), result_id, { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -528,7 +527,7 @@ bool DebugInfoManager::IsDeclareVisibleToInstr(Instruction* dbg_declare, assert(scope != nullptr); std::vector scope_ids; - if (scope->opcode() == spv::Op::OpPhi) { + if (scope->opcode() == SpvOpPhi) { scope_ids.push_back(scope->GetDebugScope().GetLexicalScope()); for (uint32_t i = 0; i < scope->NumInOperands(); i += 2) { auto* value = context()->get_def_use_mgr()->GetDef( @@ -572,8 +571,8 @@ bool DebugInfoManager::AddDebugValueForVariable(Instruction* scope_and_line, // Avoid inserting the new DebugValue between OpPhi or OpVariable // instructions. Instruction* insert_before = insert_pos->NextNode(); - while (insert_before->opcode() == spv::Op::OpPhi || - insert_before->opcode() == spv::Op::OpVariable) { + while (insert_before->opcode() == SpvOpPhi || + insert_before->opcode() == SpvOpVariable) { insert_before = insert_before->NextNode(); } modified |= AddDebugValueForDecl(dbg_decl_or_val, value_id, insert_before, @@ -654,10 +653,9 @@ uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare( } auto* var = context()->get_def_use_mgr()->GetDef(var_id); - if (var->opcode() == spv::Op::OpVariable && - spv::StorageClass( - var->GetSingleWordOperand(kOpVariableOperandStorageClassIndex)) == - spv::StorageClass::Function) { + if (var->opcode() == SpvOpVariable && + SpvStorageClass(var->GetSingleWordOperand( + kOpVariableOperandStorageClassIndex)) == SpvStorageClassFunction) { return var_id; } return 0; @@ -764,8 +762,8 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( CommonDebugInfoDebugGlobalVariable) { return; } - assert(local_var->opcode() == spv::Op::OpVariable || - local_var->opcode() == spv::Op::OpFunctionParameter); + assert(local_var->opcode() == SpvOpVariable || + local_var->opcode() == SpvOpFunctionParameter); // Convert |dbg_global_var| to DebugLocalVariable dbg_global_var->SetInOperand(kExtInstInstructionInIdx, @@ -782,7 +780,7 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( // Create a DebugDeclare std::unique_ptr new_dbg_decl(new Instruction( - context(), spv::Op::OpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), context()->TakeNextId(), { {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, @@ -796,7 +794,7 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable( })); // Must insert after all OpVariables in block Instruction* insert_before = local_var; - while (insert_before->opcode() == spv::Op::OpVariable) + while (insert_before->opcode() == SpvOpVariable) insert_before = insert_before->NextNode(); auto* added_dbg_decl = insert_before->InsertBefore(std::move(new_dbg_decl)); if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) diff --git a/source/opt/decoration_manager.cpp b/source/opt/decoration_manager.cpp index 3e95dbc3..2146c359 100644 --- a/source/opt/decoration_manager.cpp +++ b/source/opt/decoration_manager.cpp @@ -22,9 +22,6 @@ #include "source/opt/ir_context.h" -namespace spvtools { -namespace opt { -namespace analysis { namespace { using InstructionVector = std::vector; using DecorationSet = std::set; @@ -52,6 +49,10 @@ bool IsSubset(const DecorationSet& a, const DecorationSet& b) { } } // namespace +namespace spvtools { +namespace opt { +namespace analysis { + bool DecorationManager::RemoveDecorationsFrom( uint32_t id, std::function pred) { bool was_modified = false; @@ -75,8 +76,8 @@ bool DecorationManager::RemoveDecorationsFrom( // applying the group. std::unordered_set indirect_decorations_to_remove; for (Instruction* inst : decorations_info.indirect_decorations) { - assert(inst->opcode() == spv::Op::OpGroupDecorate || - inst->opcode() == spv::Op::OpGroupMemberDecorate); + assert(inst->opcode() == SpvOpGroupDecorate || + inst->opcode() == SpvOpGroupMemberDecorate); std::vector group_decorations_to_keep; const uint32_t group_id = inst->GetSingleWordInOperand(0u); @@ -98,8 +99,7 @@ bool DecorationManager::RemoveDecorationsFrom( } // Otherwise, remove |id| from the targets of |group_id| - const uint32_t stride = - inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + const uint32_t stride = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; for (uint32_t i = 1u; i < inst->NumInOperands();) { if (inst->GetSingleWordInOperand(i) != id) { i += stride; @@ -212,16 +212,16 @@ bool DecorationManager::HaveTheSameDecorations(uint32_t id1, } switch (inst->opcode()) { - case spv::Op::OpDecorate: + case SpvOpDecorate: decorate_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: member_decorate_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpDecorateId: + case SpvOpDecorateId: decorate_id_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpDecorateStringGOOGLE: + case SpvOpDecorateStringGOOGLE: decorate_string_set->emplace(std::move(decoration_payload)); break; default: @@ -278,16 +278,16 @@ bool DecorationManager::HaveSubsetOfDecorations(uint32_t id1, } switch (inst->opcode()) { - case spv::Op::OpDecorate: + case SpvOpDecorate: decorate_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: member_decorate_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpDecorateId: + case SpvOpDecorateId: decorate_id_set->emplace(std::move(decoration_payload)); break; - case spv::Op::OpDecorateStringGOOGLE: + case SpvOpDecorateStringGOOGLE: decorate_string_set->emplace(std::move(decoration_payload)); break; default: @@ -328,10 +328,10 @@ bool DecorationManager::AreDecorationsTheSame(const Instruction* inst1, const Instruction* inst2, bool ignore_target) const { switch (inst1->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpMemberDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: break; default: return false; @@ -358,18 +358,17 @@ void DecorationManager::AnalyzeDecorations() { void DecorationManager::AddDecoration(Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorate: { + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorate: { const auto target_id = inst->GetSingleWordInOperand(0u); id_to_decoration_insts_[target_id].direct_decorations.push_back(inst); break; } - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: { - const uint32_t start = - inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: { + const uint32_t start = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; const uint32_t stride = start; for (uint32_t i = start; i < inst->NumInOperands(); i += stride) { const auto target_id = inst->GetSingleWordInOperand(i); @@ -385,7 +384,7 @@ void DecorationManager::AddDecoration(Instruction* inst) { } } -void DecorationManager::AddDecoration(spv::Op opcode, +void DecorationManager::AddDecoration(SpvOp opcode, std::vector opnds) { IRContext* ctx = module_->context(); std::unique_ptr newDecoOp( @@ -395,7 +394,7 @@ void DecorationManager::AddDecoration(spv::Op opcode, void DecorationManager::AddDecoration(uint32_t inst_id, uint32_t decoration) { AddDecoration( - spv::Op::OpDecorate, + SpvOpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}}); } @@ -403,7 +402,7 @@ void DecorationManager::AddDecoration(uint32_t inst_id, uint32_t decoration) { void DecorationManager::AddDecorationVal(uint32_t inst_id, uint32_t decoration, uint32_t decoration_value) { AddDecoration( - spv::Op::OpDecorate, + SpvOpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -414,7 +413,7 @@ void DecorationManager::AddMemberDecoration(uint32_t inst_id, uint32_t member, uint32_t decoration, uint32_t decoration_value) { AddDecoration( - spv::Op::OpMemberDecorate, + SpvOpMemberDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inst_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {member}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration}}, @@ -437,10 +436,9 @@ std::vector DecorationManager::InternalGetDecorationsFor( [include_linkage, &decorations](const std::vector& direct_decorations) { for (Instruction* inst : direct_decorations) { - const bool is_linkage = - inst->opcode() == spv::Op::OpDecorate && - spv::Decoration(inst->GetSingleWordInOperand(1u)) == - spv::Decoration::LinkageAttributes; + const bool is_linkage = inst->opcode() == SpvOpDecorate && + inst->GetSingleWordInOperand(1u) == + SpvDecorationLinkageAttributes; if (include_linkage || !is_linkage) decorations.push_back(inst); } }; @@ -461,17 +459,17 @@ std::vector DecorationManager::InternalGetDecorationsFor( bool DecorationManager::WhileEachDecoration( uint32_t id, uint32_t decoration, - std::function f) const { + std::function f) { for (const Instruction* inst : GetDecorationsFor(id, true)) { switch (inst->opcode()) { - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: if (inst->GetSingleWordInOperand(2) == decoration) { if (!f(*inst)) return false; } break; - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: if (inst->GetSingleWordInOperand(1) == decoration) { if (!f(*inst)) return false; } @@ -485,19 +483,14 @@ bool DecorationManager::WhileEachDecoration( void DecorationManager::ForEachDecoration( uint32_t id, uint32_t decoration, - std::function f) const { + std::function f) { WhileEachDecoration(id, decoration, [&f](const Instruction& inst) { f(inst); return true; }); } -bool DecorationManager::HasDecoration(uint32_t id, - spv::Decoration decoration) const { - return HasDecoration(id, static_cast(decoration)); -} - -bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) const { +bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) { bool has_decoration = false; ForEachDecoration(id, decoration, [&has_decoration](const Instruction&) { has_decoration = true; @@ -530,14 +523,14 @@ void DecorationManager::CloneDecorations(uint32_t from, uint32_t to) { decoration_list->second.indirect_decorations; for (Instruction* inst : indirect_decorations) { switch (inst->opcode()) { - case spv::Op::OpGroupDecorate: + case SpvOpGroupDecorate: context->ForgetUses(inst); // add |to| to list of decorated id's inst->AddOperand( Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to})); context->AnalyzeUses(inst); break; - case spv::Op::OpGroupMemberDecorate: { + case SpvOpGroupMemberDecorate: { context->ForgetUses(inst); // for each (id == from), add (to, literal) as operands const uint32_t num_operands = inst->NumOperands(); @@ -561,13 +554,13 @@ void DecorationManager::CloneDecorations(uint32_t from, uint32_t to) { void DecorationManager::CloneDecorations( uint32_t from, uint32_t to, - const std::vector& decorations_to_copy) { + const std::vector& decorations_to_copy) { const auto decoration_list = id_to_decoration_insts_.find(from); if (decoration_list == id_to_decoration_insts_.end()) return; auto context = module_->context(); for (Instruction* inst : decoration_list->second.direct_decorations) { if (std::find(decorations_to_copy.begin(), decorations_to_copy.end(), - spv::Decoration(inst->GetSingleWordInOperand(1))) == + inst->GetSingleWordInOperand(1)) == decorations_to_copy.end()) { continue; } @@ -586,11 +579,11 @@ void DecorationManager::CloneDecorations( decoration_list->second.indirect_decorations; for (Instruction* inst : indirect_decorations) { switch (inst->opcode()) { - case spv::Op::OpGroupDecorate: + case SpvOpGroupDecorate: CloneDecorations(inst->GetSingleWordInOperand(0), to, decorations_to_copy); break; - case spv::Op::OpGroupMemberDecorate: { + case SpvOpGroupMemberDecorate: { assert(false && "The source id is not suppose to be a type."); break; } @@ -606,19 +599,18 @@ void DecorationManager::RemoveDecoration(Instruction* inst) { }; switch (inst->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorate: { + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorate: { const auto target_id = inst->GetSingleWordInOperand(0u); auto const iter = id_to_decoration_insts_.find(target_id); if (iter == id_to_decoration_insts_.end()) return; remove_from_container(iter->second.direct_decorations); } break; - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: { - const uint32_t stride = - inst->opcode() == spv::Op::OpGroupDecorate ? 1u : 2u; + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: { + const uint32_t stride = inst->opcode() == SpvOpGroupDecorate ? 1u : 2u; for (uint32_t i = 1u; i < inst->NumInOperands(); i += stride) { const auto target_id = inst->GetSingleWordInOperand(i); auto const iter = id_to_decoration_insts_.find(target_id); diff --git a/source/opt/decoration_manager.h b/source/opt/decoration_manager.h index 2be016a7..fe78f2ce 100644 --- a/source/opt/decoration_manager.h +++ b/source/opt/decoration_manager.h @@ -71,14 +71,14 @@ class DecorationManager { bool include_linkage); std::vector GetDecorationsFor(uint32_t id, bool include_linkage) const; - // Returns whether two IDs have the same decorations. Two - // spv::Op::OpGroupDecorate instructions that apply the same decorations but - // to different IDs, still count as being the same. + // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate + // instructions that apply the same decorations but to different IDs, still + // count as being the same. bool HaveTheSameDecorations(uint32_t id1, uint32_t id2) const; - // Returns whether two IDs have the same decorations. Two - // spv::Op::OpGroupDecorate instructions that apply the same decorations but - // to different IDs, still count as being the same. + // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate + // instructions that apply the same decorations but to different IDs, still + // count as being the same. bool HaveSubsetOfDecorations(uint32_t id1, uint32_t id2) const; // Returns whether the two decorations instructions are the same and are @@ -92,21 +92,20 @@ class DecorationManager { // Returns whether a decoration instruction for |id| with decoration // |decoration| exists or not. - bool HasDecoration(uint32_t id, uint32_t decoration) const; - bool HasDecoration(uint32_t id, spv::Decoration decoration) const; + bool HasDecoration(uint32_t id, uint32_t decoration); // |f| is run on each decoration instruction for |id| with decoration // |decoration|. Processed are all decorations which target |id| either // directly or indirectly by Decoration Groups. void ForEachDecoration(uint32_t id, uint32_t decoration, - std::function f) const; + std::function f); // |f| is run on each decoration instruction for |id| with decoration // |decoration|. Processes all decoration which target |id| either directly or // indirectly through decoration groups. If |f| returns false, iteration is // terminated and this function returns false. bool WhileEachDecoration(uint32_t id, uint32_t decoration, - std::function f) const; + std::function f); // |f| is run on each decoration instruction for |id| with decoration // |decoration|. Processes all decoration which target |id| either directly or @@ -124,15 +123,14 @@ class DecorationManager { // Same as above, but only clone the decoration if the decoration operand is // in |decorations_to_copy|. This function has the extra restriction that // |from| and |to| must not be an object, not a type. - void CloneDecorations( - uint32_t from, uint32_t to, - const std::vector& decorations_to_copy); + void CloneDecorations(uint32_t from, uint32_t to, + const std::vector& decorations_to_copy); // Informs the decoration manager of a new decoration that it needs to track. void AddDecoration(Instruction* inst); // Add decoration with |opcode| and operands |opnds|. - void AddDecoration(spv::Op opcode, const std::vector opnds); + void AddDecoration(SpvOp opcode, const std::vector opnds); // Add |decoration| of |inst_id| to module. void AddDecoration(uint32_t inst_id, uint32_t decoration); @@ -142,7 +140,7 @@ class DecorationManager { uint32_t decoration_value); // Add |decoration, decoration_value| of |inst_id, member| to module. - void AddMemberDecoration(uint32_t inst_id, uint32_t member, + void AddMemberDecoration(uint32_t member, uint32_t inst_id, uint32_t decoration, uint32_t decoration_value); friend bool operator==(const DecorationManager&, const DecorationManager&); @@ -197,9 +195,9 @@ class DecorationManager { // Mapping from ids to the instructions applying a decoration to those ids. // In other words, for each id you get all decoration instructions - // referencing that id, be it directly (spv::Op::OpDecorate, - // spv::Op::OpMemberDecorate and spv::Op::OpDecorateId), or indirectly - // (spv::Op::OpGroupDecorate, spv::Op::OpMemberGroupDecorate). + // referencing that id, be it directly (SpvOpDecorate, SpvOpMemberDecorate + // and SpvOpDecorateId), or indirectly (SpvOpGroupDecorate, + // SpvOpMemberGroupDecorate). std::unordered_map id_to_decoration_insts_; // The enclosing module. Module* module_; diff --git a/source/opt/desc_sroa.cpp b/source/opt/desc_sroa.cpp index 8da0c864..b130ca80 100644 --- a/source/opt/desc_sroa.cpp +++ b/source/opt/desc_sroa.cpp @@ -22,9 +22,8 @@ namespace opt { namespace { bool IsDecorationBinding(Instruction* inst) { - if (inst->opcode() != spv::Op::OpDecorate) return false; - return spv::Decoration(inst->GetSingleWordInOperand(1u)) == - spv::Decoration::Binding; + if (inst->opcode() != SpvOpDecorate) return false; + return inst->GetSingleWordInOperand(1u) == SpvDecorationBinding; } } // namespace @@ -57,7 +56,7 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) { bool failed = !get_def_use_mgr()->WhileEachUser( var->result_id(), [this, &access_chain_work_list, &load_work_list](Instruction* use) { - if (use->opcode() == spv::Op::OpName) { + if (use->opcode() == SpvOpName) { return true; } @@ -66,11 +65,11 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) { } switch (use->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: access_chain_work_list.push_back(use); return true; - case spv::Op::OpLoad: + case SpvOpLoad: load_work_list.push_back(use); return true; default: @@ -185,7 +184,7 @@ void DescriptorScalarReplacement::CopyDecorationsForNewVariable( // Handle OpMemberDecorate instructions. for (auto old_decoration : get_decoration_mgr()->GetDecorationsFor( old_var_type->result_id(), true)) { - assert(old_decoration->opcode() == spv::Op::OpMemberDecorate); + assert(old_decoration->opcode() == SpvOpMemberDecorate); if (old_decoration->GetSingleWordInOperand(1u) != index) continue; CreateNewDecorationForMemberDecorate(old_decoration, new_var_id); } @@ -213,8 +212,8 @@ uint32_t DescriptorScalarReplacement::GetNewBindingForElement( void DescriptorScalarReplacement::CreateNewDecorationForNewVariable( Instruction* old_decoration, uint32_t new_var_id, uint32_t new_binding) { - assert(old_decoration->opcode() == spv::Op::OpDecorate || - old_decoration->opcode() == spv::Op::OpDecorateString); + assert(old_decoration->opcode() == SpvOpDecorate || + old_decoration->opcode() == SpvOpDecorateString); std::unique_ptr new_decoration(old_decoration->Clone(context())); new_decoration->SetInOperand(0, {new_var_id}); @@ -232,25 +231,25 @@ void DescriptorScalarReplacement::CreateNewDecorationForMemberDecorate( auto new_decorate_operand_end = old_member_decoration->end(); operands.insert(operands.end(), new_decorate_operand_begin, new_decorate_operand_end); - get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, std::move(operands)); + get_decoration_mgr()->AddDecoration(SpvOpDecorate, std::move(operands)); } uint32_t DescriptorScalarReplacement::CreateReplacementVariable( Instruction* var, uint32_t idx) { // The storage class for the new variable is the same as the original. - spv::StorageClass storage_class = - static_cast(var->GetSingleWordInOperand(0)); + SpvStorageClass storage_class = + static_cast(var->GetSingleWordInOperand(0)); // The type for the new variable will be a pointer to type of the elements of // the array. uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + assert(ptr_type_inst->opcode() == SpvOpTypePointer && "Variable should be a pointer to an array or structure."); uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* pointee_type_inst = get_def_use_mgr()->GetDef(pointee_type_id); - const bool is_array = pointee_type_inst->opcode() == spv::Op::OpTypeArray; - const bool is_struct = pointee_type_inst->opcode() == spv::Op::OpTypeStruct; + const bool is_array = pointee_type_inst->opcode() == SpvOpTypeArray; + const bool is_struct = pointee_type_inst->opcode() == SpvOpTypeStruct; assert((is_array || is_struct) && "Variable should be a pointer to an array or structure."); @@ -264,7 +263,7 @@ uint32_t DescriptorScalarReplacement::CreateReplacementVariable( // Create the variable. uint32_t id = TakeNextId(); std::unique_ptr variable( - new Instruction(context(), spv::Op::OpVariable, ptr_element_type_id, id, + new Instruction(context(), SpvOpVariable, ptr_element_type_id, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(storage_class)}}})); @@ -294,7 +293,7 @@ uint32_t DescriptorScalarReplacement::CreateReplacementVariable( } std::unique_ptr new_name(new Instruction( - context(), spv::Op::OpName, 0, 0, + context(), SpvOpName, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {id}}, {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); @@ -316,14 +315,14 @@ uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType( Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); // If it's a pointer, look at the underlying type. - if (type_inst->opcode() == spv::Op::OpTypePointer) { + if (type_inst->opcode() == SpvOpTypePointer) { type_id = type_inst->GetSingleWordInOperand(1); type_inst = get_def_use_mgr()->GetDef(type_id); } // Arrays consume N*M binding numbers where N is the array length, and M is // the number of bindings used by each array element. - if (type_inst->opcode() == spv::Op::OpTypeArray) { + if (type_inst->opcode() == SpvOpTypeArray) { uint32_t element_type_id = type_inst->GetSingleWordInOperand(0); uint32_t length_id = type_inst->GetSingleWordInOperand(1); const analysis::Constant* length_const = @@ -336,7 +335,7 @@ uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType( // The number of bindings consumed by a structure is the sum of the bindings // used by its members. - if (type_inst->opcode() == spv::Op::OpTypeStruct && + if (type_inst->opcode() == SpvOpTypeStruct && !descsroautil::IsTypeOfStructuredBuffer(context(), type_inst)) { uint32_t sum = 0; for (uint32_t i = 0; i < type_inst->NumInOperands(); i++) @@ -354,12 +353,12 @@ bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var, // |value| is the OpLoad instruction that has loaded |var|. // The function expects all users of |value| to be OpCompositeExtract // instructions. Otherwise the function returns false with an error message. - assert(value->opcode() == spv::Op::OpLoad); + assert(value->opcode() == SpvOpLoad); assert(value->GetSingleWordInOperand(0) == var->result_id()); std::vector work_list; bool failed = !get_def_use_mgr()->WhileEachUser( value->result_id(), [this, &work_list](Instruction* use) { - if (use->opcode() != spv::Op::OpCompositeExtract) { + if (use->opcode() != SpvOpCompositeExtract) { context()->EmitErrorMessage( "Variable cannot be replaced: invalid instruction", use); return false; @@ -385,7 +384,7 @@ bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var, bool DescriptorScalarReplacement::ReplaceCompositeExtract( Instruction* var, Instruction* extract) { - assert(extract->opcode() == spv::Op::OpCompositeExtract); + assert(extract->opcode() == SpvOpCompositeExtract); // We're currently only supporting extractions of one index at a time. If we // need to, we can handle cases with multiple indexes in the future. if (extract->NumInOperands() != 2) { @@ -401,7 +400,7 @@ bool DescriptorScalarReplacement::ReplaceCompositeExtract( // OpCompositeExtract. uint32_t load_id = TakeNextId(); std::unique_ptr load( - new Instruction(context(), spv::Op::OpLoad, extract->type_id(), load_id, + new Instruction(context(), SpvOpLoad, extract->type_id(), load_id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {replacement_var}}})); Instruction* load_instr = load.get(); diff --git a/source/opt/desc_sroa_util.cpp b/source/opt/desc_sroa_util.cpp index dba3de9c..1954e2cc 100644 --- a/source/opt/desc_sroa_util.cpp +++ b/source/opt/desc_sroa_util.cpp @@ -17,11 +17,12 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kOpAccessChainInOperandIndexes = 1; + +const uint32_t kOpAccessChainInOperandIndexes = 1; // Returns the length of array type |type|. uint32_t GetLengthOfArrayType(IRContext* context, Instruction* type) { - assert(type->opcode() == spv::Op::OpTypeArray && "type must be array"); + assert(type->opcode() == SpvOpTypeArray && "type must be array"); uint32_t length_id = type->GetSingleWordInOperand(1); const analysis::Constant* length_const = context->get_constant_mgr()->FindDeclaredConstant(length_id); @@ -34,20 +35,20 @@ uint32_t GetLengthOfArrayType(IRContext* context, Instruction* type) { namespace descsroautil { bool IsDescriptorArray(IRContext* context, Instruction* var) { - if (var->opcode() != spv::Op::OpVariable) { + if (var->opcode() != SpvOpVariable) { return false; } uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); - if (ptr_type_inst->opcode() != spv::Op::OpTypePointer) { + if (ptr_type_inst->opcode() != SpvOpTypePointer) { return false; } uint32_t var_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* var_type_inst = context->get_def_use_mgr()->GetDef(var_type_id); - if (var_type_inst->opcode() != spv::Op::OpTypeArray && - var_type_inst->opcode() != spv::Op::OpTypeStruct) { + if (var_type_inst->opcode() != SpvOpTypeArray && + var_type_inst->opcode() != SpvOpTypeStruct) { return false; } @@ -58,23 +59,23 @@ bool IsDescriptorArray(IRContext* context, Instruction* var) { } if (!context->get_decoration_mgr()->HasDecoration( - var->result_id(), uint32_t(spv::Decoration::DescriptorSet))) { + var->result_id(), SpvDecorationDescriptorSet)) { return false; } - return context->get_decoration_mgr()->HasDecoration( - var->result_id(), uint32_t(spv::Decoration::Binding)); + return context->get_decoration_mgr()->HasDecoration(var->result_id(), + SpvDecorationBinding); } bool IsTypeOfStructuredBuffer(IRContext* context, const Instruction* type) { - if (type->opcode() != spv::Op::OpTypeStruct) { + if (type->opcode() != SpvOpTypeStruct) { return false; } // All buffers have offset decorations for members of their structure types. // This is how we distinguish it from a structure of descriptors. - return context->get_decoration_mgr()->HasDecoration( - type->result_id(), uint32_t(spv::Decoration::Offset)); + return context->get_decoration_mgr()->HasDecoration(type->result_id(), + SpvDecorationOffset); } const analysis::Constant* GetAccessChainIndexAsConst( @@ -98,15 +99,15 @@ uint32_t GetNumberOfElementsForArrayOrStruct(IRContext* context, Instruction* var) { uint32_t ptr_type_id = var->type_id(); Instruction* ptr_type_inst = context->get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + assert(ptr_type_inst->opcode() == SpvOpTypePointer && "Variable should be a pointer to an array or structure."); uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1); Instruction* pointee_type_inst = context->get_def_use_mgr()->GetDef(pointee_type_id); - if (pointee_type_inst->opcode() == spv::Op::OpTypeArray) { + if (pointee_type_inst->opcode() == SpvOpTypeArray) { return GetLengthOfArrayType(context, pointee_type_inst); } - assert(pointee_type_inst->opcode() == spv::Op::OpTypeStruct && + assert(pointee_type_inst->opcode() == SpvOpTypeStruct && "Variable should be a pointer to an array or structure."); return pointee_type_inst->NumInOperands(); } diff --git a/source/opt/dominator_analysis.cpp b/source/opt/dominator_analysis.cpp index eb6dfc9e..b692d26a 100644 --- a/source/opt/dominator_analysis.cpp +++ b/source/opt/dominator_analysis.cpp @@ -64,7 +64,7 @@ bool DominatorAnalysisBase::Dominates(Instruction* a, Instruction* b) const { // We handle OpLabel instructions explicitly since they are not stored in the // instruction list. - if (current->opcode() == spv::Op::OpLabel) { + if (current->opcode() == SpvOpLabel) { return true; } diff --git a/source/opt/dominator_tree.cpp b/source/opt/dominator_tree.cpp index 3c161a9b..2680be2a 100644 --- a/source/opt/dominator_tree.cpp +++ b/source/opt/dominator_tree.cpp @@ -55,8 +55,8 @@ namespace { // called on each node traversed BEFORE their children. template -void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, - PreLambda pre, PostLambda post) { +static void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, + PreLambda pre, PostLambda post) { auto no_terminal_blocks = [](const BBType*) { return false; }; CFA::DepthFirstTraversal(bb, successors, pre, post, no_terminal_blocks); @@ -73,8 +73,9 @@ void DepthFirstSearch(const BBType* bb, SuccessorLambda successors, // PostLambda - Lamdba matching the signature of 'void (const BBType*)' will be // called on each node traversed after their children. template -void DepthFirstSearchPostOrder(const BBType* bb, SuccessorLambda successors, - PostLambda post) { +static void DepthFirstSearchPostOrder(const BBType* bb, + SuccessorLambda successors, + PostLambda post) { // Ignore preorder operation. auto nop_preorder = [](const BBType*) {}; DepthFirstSearch(bb, successors, nop_preorder, post); diff --git a/source/opt/eliminate_dead_constant_pass.cpp b/source/opt/eliminate_dead_constant_pass.cpp index 500fd8af..d368bd14 100644 --- a/source/opt/eliminate_dead_constant_pass.cpp +++ b/source/opt/eliminate_dead_constant_pass.cpp @@ -20,6 +20,7 @@ #include #include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" #include "source/opt/log.h" #include "source/opt/reflect.h" @@ -39,7 +40,7 @@ Pass::Status EliminateDeadConstantPass::Process() { context()->get_def_use_mgr()->ForEachUse( const_id, [&count](Instruction* user, uint32_t index) { (void)index; - spv::Op op = user->opcode(); + SpvOp op = user->opcode(); if (!(IsAnnotationInst(op) || IsDebug1Inst(op) || IsDebug2Inst(op) || IsDebug3Inst(op))) { ++count; @@ -58,9 +59,9 @@ Pass::Status EliminateDeadConstantPass::Process() { Instruction* inst = *working_list.begin(); // Back propagate if the instruction contains IDs in its operands. switch (inst->opcode()) { - case spv::Op::OpConstantComposite: - case spv::Op::OpSpecConstantComposite: - case spv::Op::OpSpecConstantOp: + case SpvOp::SpvOpConstantComposite: + case SpvOp::SpvOpSpecConstantComposite: + case SpvOp::SpvOpSpecConstantOp: for (uint32_t i = 0; i < inst->NumInOperands(); i++) { // SpecConstantOp instruction contains 'opcode' as its operand. Need // to exclude such operands when decreasing uses. diff --git a/source/opt/eliminate_dead_functions_util.cpp b/source/opt/eliminate_dead_functions_util.cpp index e95b7f6a..1379120f 100644 --- a/source/opt/eliminate_dead_functions_util.cpp +++ b/source/opt/eliminate_dead_functions_util.cpp @@ -28,18 +28,16 @@ Module::iterator EliminateFunction(IRContext* context, ->ForEachInst( [context, first_func, func_iter, &seen_func_end, &to_kill](Instruction* inst) { - if (inst->opcode() == spv::Op::OpFunctionEnd) { + if (inst->opcode() == SpvOpFunctionEnd) { seen_func_end = true; } // Move non-semantic instructions to the previous function or // global values if this is the first function. - if (seen_func_end && inst->opcode() == spv::Op::OpExtInst) { + if (seen_func_end && inst->opcode() == SpvOpExtInst) { assert(inst->IsNonSemanticInstruction()); if (to_kill.find(inst) != to_kill.end()) return; std::unique_ptr clone(inst->Clone(context)); - // Clear uses of "inst" to in case this moves a dependent chain of - // instructions. - context->get_def_use_mgr()->ClearInst(inst); + context->ForgetUses(inst); context->AnalyzeDefUse(clone.get()); if (first_func) { context->AddGlobalValue(std::move(clone)); diff --git a/source/opt/eliminate_dead_input_components_pass.cpp b/source/opt/eliminate_dead_input_components_pass.cpp new file mode 100644 index 00000000..aa2776bb --- /dev/null +++ b/source/opt/eliminate_dead_input_components_pass.cpp @@ -0,0 +1,189 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// 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 "source/opt/eliminate_dead_input_components_pass.h" + +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" +#include "source/opt/ir_context.h" +#include "source/util/bit_vector.h" + +namespace { + +const uint32_t kAccessChainBaseInIdx = 0; +const uint32_t kAccessChainIndex0InIdx = 1; +const uint32_t kConstantValueInIdx = 0; +const uint32_t kVariableStorageClassInIdx = 0; + +} // namespace + +namespace spvtools { +namespace opt { + +Pass::Status EliminateDeadInputComponentsPass::Process() { + // Current functionality assumes shader capability + if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) + return Status::SuccessWithoutChange; + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + bool modified = false; + std::vector> arrays_to_change; + for (auto& var : context()->types_values()) { + if (var.opcode() != SpvOpVariable) { + continue; + } + analysis::Type* var_type = type_mgr->GetType(var.type_id()); + analysis::Pointer* ptr_type = var_type->AsPointer(); + if (ptr_type == nullptr) { + continue; + } + if (ptr_type->storage_class() != SpvStorageClassInput) { + continue; + } + const analysis::Array* arr_type = ptr_type->pointee_type()->AsArray(); + if (arr_type != nullptr) { + unsigned arr_len_id = arr_type->LengthId(); + Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id); + if (arr_len_inst->opcode() != SpvOpConstant) { + continue; + } + // SPIR-V requires array size is >= 1, so this works for signed or + // unsigned size + unsigned original_max = + arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1; + unsigned max_idx = FindMaxIndex(var, original_max); + if (max_idx != original_max) { + ChangeArrayLength(var, max_idx + 1); + modified = true; + } + continue; + } + const analysis::Struct* struct_type = ptr_type->pointee_type()->AsStruct(); + if (struct_type == nullptr) continue; + const auto elt_types = struct_type->element_types(); + unsigned original_max = static_cast(elt_types.size()) - 1; + unsigned max_idx = FindMaxIndex(var, original_max); + if (max_idx != original_max) { + ChangeStructLength(var, max_idx + 1); + modified = true; + } + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +unsigned EliminateDeadInputComponentsPass::FindMaxIndex(Instruction& var, + unsigned original_max) { + unsigned max = 0; + bool seen_non_const_ac = false; + assert(var.opcode() == SpvOpVariable && "must be variable"); + context()->get_def_use_mgr()->WhileEachUser( + var.result_id(), [&max, &seen_non_const_ac, var, this](Instruction* use) { + auto use_opcode = use->opcode(); + if (use_opcode == SpvOpLoad || use_opcode == SpvOpCopyMemory || + use_opcode == SpvOpCopyMemorySized || + use_opcode == SpvOpCopyObject) { + seen_non_const_ac = true; + return false; + } + if (use->opcode() != SpvOpAccessChain && + use->opcode() != SpvOpInBoundsAccessChain) { + return true; + } + // OpAccessChain with no indices currently not optimized + if (use->NumInOperands() == 1) { + seen_non_const_ac = true; + return false; + } + unsigned base_id = use->GetSingleWordInOperand(kAccessChainBaseInIdx); + USE_ASSERT(base_id == var.result_id() && "unexpected base"); + unsigned idx_id = use->GetSingleWordInOperand(kAccessChainIndex0InIdx); + Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id); + if (idx_inst->opcode() != SpvOpConstant) { + seen_non_const_ac = true; + return false; + } + unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx); + if (value > max) max = value; + return true; + }); + return seen_non_const_ac ? original_max : max; +} + +void EliminateDeadInputComponentsPass::ChangeArrayLength(Instruction& arr_var, + unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(arr_var.type_id())->AsPointer(); + const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray(); + assert(arr_ty && "expecting array type"); + uint32_t length_id = const_mgr->GetUIntConst(length); + analysis::Array new_arr_ty(arr_ty->element_type(), + arr_ty->GetConstantLengthInfo(length_id, length)); + analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty); + analysis::Pointer new_ptr_ty(reg_new_arr_ty, SpvStorageClassInput); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + arr_var.SetResultType(new_ptr_ty_id); + def_use_mgr->AnalyzeInstUse(&arr_var); + // Move arr_var after its new type to preserve order + USE_ASSERT(arr_var.GetSingleWordInOperand(kVariableStorageClassInIdx) != + SpvStorageClassFunction && + "cannot move Function variable"); + Instruction* new_ptr_ty_inst = def_use_mgr->GetDef(new_ptr_ty_id); + arr_var.RemoveFromList(); + arr_var.InsertAfter(new_ptr_ty_inst); +} + +void EliminateDeadInputComponentsPass::ChangeStructLength( + Instruction& struct_var, unsigned length) { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Pointer* ptr_type = + type_mgr->GetType(struct_var.type_id())->AsPointer(); + const analysis::Struct* struct_ty = ptr_type->pointee_type()->AsStruct(); + assert(struct_ty && "expecting struct type"); + const auto orig_elt_types = struct_ty->element_types(); + std::vector new_elt_types; + for (unsigned u = 0; u < length; ++u) + new_elt_types.push_back(orig_elt_types[u]); + analysis::Struct new_struct_ty(new_elt_types); + analysis::Type* reg_new_struct_ty = + type_mgr->GetRegisteredType(&new_struct_ty); + uint32_t new_struct_ty_id = type_mgr->GetTypeInstruction(reg_new_struct_ty); + uint32_t old_struct_ty_id = type_mgr->GetTypeInstruction(struct_ty); + analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); + deco_mgr->CloneDecorations(old_struct_ty_id, new_struct_ty_id); + analysis::Pointer new_ptr_ty(reg_new_struct_ty, SpvStorageClassInput); + analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); + uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); + struct_var.SetResultType(new_ptr_ty_id); + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + def_use_mgr->AnalyzeInstUse(&struct_var); + // Move struct_var after its new type to preserve order + USE_ASSERT(struct_var.GetSingleWordInOperand(kVariableStorageClassInIdx) != + SpvStorageClassFunction && + "cannot move Function variable"); + Instruction* new_ptr_ty_inst = def_use_mgr->GetDef(new_ptr_ty_id); + struct_var.RemoveFromList(); + struct_var.InsertAfter(new_ptr_ty_inst); +} + +} // namespace opt +} // namespace spvtools diff --git a/source/opt/eliminate_dead_io_components_pass.h b/source/opt/eliminate_dead_input_components_pass.h old mode 100755 new mode 100644 similarity index 69% rename from source/opt/eliminate_dead_io_components_pass.h rename to source/opt/eliminate_dead_input_components_pass.h index ef4dfb71..a3a133c2 --- a/source/opt/eliminate_dead_io_components_pass.h +++ b/source/opt/eliminate_dead_input_components_pass.h @@ -26,15 +26,14 @@ namespace spvtools { namespace opt { // See optimizer.hpp for documentation. -class EliminateDeadIOComponentsPass : public Pass { +class EliminateDeadInputComponentsPass : public Pass { public: - explicit EliminateDeadIOComponentsPass(spv::StorageClass elim_sclass, - bool safe_mode = true) - : elim_sclass_(elim_sclass), safe_mode_(safe_mode) {} + explicit EliminateDeadInputComponentsPass() {} const char* name() const override { return "eliminate-dead-input-components"; } + Status Process() override; // Return the mask of preserved Analyses. @@ -51,22 +50,13 @@ class EliminateDeadIOComponentsPass : public Pass { // Find the max constant used to index the variable declared by |var| // through OpAccessChain or OpInBoundsAccessChain. If any non-constant // indices or non-Op*AccessChain use of |var|, return |original_max|. - unsigned FindMaxIndex(const Instruction& var, const unsigned original_max, - const bool skip_first_index = false); + unsigned FindMaxIndex(Instruction& var, unsigned original_max); // Change the length of the array |inst| to |length| void ChangeArrayLength(Instruction& inst, unsigned length); - // Change the length of the struct in |io_var| to |length|. |io_var| - // is either the struct or a per-vertex-array of the struct. - void ChangeIOVarStructLength(Instruction& io_var, unsigned length); - - // Storage class to be optimized. Must be Input or Output. - spv::StorageClass elim_sclass_; - - // Only make changes that will not cause interface incompatibility if done - // standalone. Currently this is only Input variables in vertex shaders. - bool safe_mode_; + // Change the length of the struct |struct_var| to |length| + void ChangeStructLength(Instruction& struct_var, unsigned length); }; } // namespace opt diff --git a/source/opt/eliminate_dead_io_components_pass.cpp b/source/opt/eliminate_dead_io_components_pass.cpp deleted file mode 100755 index 5553a336..00000000 --- a/source/opt/eliminate_dead_io_components_pass.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "source/opt/eliminate_dead_io_components_pass.h" - -#include - -#include "source/opt/instruction.h" -#include "source/opt/ir_context.h" -#include "source/util/bit_vector.h" - -namespace spvtools { -namespace opt { -namespace { -constexpr uint32_t kAccessChainBaseInIdx = 0; -constexpr uint32_t kAccessChainIndex0InIdx = 1; -constexpr uint32_t kAccessChainIndex1InIdx = 2; -constexpr uint32_t kConstantValueInIdx = 0; -} // namespace - -Pass::Status EliminateDeadIOComponentsPass::Process() { - // Only process input and output variables - if (elim_sclass_ != spv::StorageClass::Input && - elim_sclass_ != spv::StorageClass::Output) { - if (consumer()) { - std::string message = - "EliminateDeadIOComponentsPass only valid for input and output " - "variables."; - consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); - } - return Status::Failure; - } - // If safe mode, only process Input variables in vertex shader - const auto stage = context()->GetStage(); - if (safe_mode_ && !(stage == spv::ExecutionModel::Vertex && - elim_sclass_ == spv::StorageClass::Input)) - return Status::SuccessWithoutChange; - // Current functionality assumes shader capability. - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) - return Status::SuccessWithoutChange; - // Current functionality assumes vert, frag, tesc, tese or geom shader. - // TODO(issue #4988): Add GLCompute. - if (stage != spv::ExecutionModel::Vertex && - stage != spv::ExecutionModel::Fragment && - stage != spv::ExecutionModel::TessellationControl && - stage != spv::ExecutionModel::TessellationEvaluation && - stage != spv::ExecutionModel::Geometry) - return Status::SuccessWithoutChange; - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - bool modified = false; - std::vector vars_to_move; - for (auto& var : context()->types_values()) { - if (var.opcode() != spv::Op::OpVariable) { - continue; - } - analysis::Type* var_type = type_mgr->GetType(var.type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - if (ptr_type == nullptr) { - continue; - } - const auto sclass = ptr_type->storage_class(); - if (sclass != elim_sclass_) { - continue; - } - // For tesc, or input variables in tese or geom shaders, - // there is a outer per-vertex-array that must be ignored - // for the purposes of this analysis/optimization. Do the - // analysis on the inner type in these cases. - bool skip_first_index = false; - auto core_type = ptr_type->pointee_type(); - if (stage == spv::ExecutionModel::TessellationControl || - (sclass == spv::StorageClass::Input && - (stage == spv::ExecutionModel::TessellationEvaluation || - stage == spv::ExecutionModel::Geometry))) { - auto arr_type = core_type->AsArray(); - if (!arr_type) continue; - core_type = arr_type->element_type(); - skip_first_index = true; - } - const analysis::Array* arr_type = core_type->AsArray(); - if (arr_type != nullptr) { - // Only process array if input of vertex shader, or output of - // fragment shader. Otherwise, if one shader has a runtime index and the - // other does not, interface incompatibility can occur. - if (!((sclass == spv::StorageClass::Input && - stage == spv::ExecutionModel::Vertex) || - (sclass == spv::StorageClass::Output && - stage == spv::ExecutionModel::Fragment))) - continue; - unsigned arr_len_id = arr_type->LengthId(); - Instruction* arr_len_inst = def_use_mgr->GetDef(arr_len_id); - if (arr_len_inst->opcode() != spv::Op::OpConstant) { - continue; - } - // SPIR-V requires array size is >= 1, so this works for signed or - // unsigned size. - unsigned original_max = - arr_len_inst->GetSingleWordInOperand(kConstantValueInIdx) - 1; - unsigned max_idx = FindMaxIndex(var, original_max); - if (max_idx != original_max) { - ChangeArrayLength(var, max_idx + 1); - vars_to_move.push_back(&var); - modified = true; - } - continue; - } - const analysis::Struct* struct_type = core_type->AsStruct(); - if (struct_type == nullptr) continue; - const auto elt_types = struct_type->element_types(); - unsigned original_max = static_cast(elt_types.size()) - 1; - unsigned max_idx = FindMaxIndex(var, original_max, skip_first_index); - if (max_idx != original_max) { - ChangeIOVarStructLength(var, max_idx + 1); - vars_to_move.push_back(&var); - modified = true; - } - } - - // Move changed vars after their new type instruction to preserve backward - // referencing. - for (auto var : vars_to_move) { - auto type_id = var->type_id(); - auto type_inst = def_use_mgr->GetDef(type_id); - var->RemoveFromList(); - var->InsertAfter(type_inst); - } - - return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -unsigned EliminateDeadIOComponentsPass::FindMaxIndex( - const Instruction& var, const unsigned original_max, - const bool skip_first_index) { - unsigned max = 0; - bool seen_non_const_ac = false; - assert(var.opcode() == spv::Op::OpVariable && "must be variable"); - context()->get_def_use_mgr()->WhileEachUser( - var.result_id(), [&max, &seen_non_const_ac, var, skip_first_index, - this](Instruction* use) { - auto use_opcode = use->opcode(); - if (use_opcode == spv::Op::OpLoad || use_opcode == spv::Op::OpStore || - use_opcode == spv::Op::OpCopyMemory || - use_opcode == spv::Op::OpCopyMemorySized || - use_opcode == spv::Op::OpCopyObject) { - seen_non_const_ac = true; - return false; - } - if (use->opcode() != spv::Op::OpAccessChain && - use->opcode() != spv::Op::OpInBoundsAccessChain) { - return true; - } - // OpAccessChain with no indices currently not optimized - if (use->NumInOperands() == 1 || - (skip_first_index && use->NumInOperands() == 2)) { - seen_non_const_ac = true; - return false; - } - const unsigned base_id = - use->GetSingleWordInOperand(kAccessChainBaseInIdx); - USE_ASSERT(base_id == var.result_id() && "unexpected base"); - const unsigned in_idx = skip_first_index ? kAccessChainIndex1InIdx - : kAccessChainIndex0InIdx; - const unsigned idx_id = use->GetSingleWordInOperand(in_idx); - Instruction* idx_inst = context()->get_def_use_mgr()->GetDef(idx_id); - if (idx_inst->opcode() != spv::Op::OpConstant) { - seen_non_const_ac = true; - return false; - } - unsigned value = idx_inst->GetSingleWordInOperand(kConstantValueInIdx); - if (value > max) max = value; - return true; - }); - return seen_non_const_ac ? original_max : max; -} - -void EliminateDeadIOComponentsPass::ChangeArrayLength(Instruction& arr_var, - unsigned length) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::Pointer* ptr_type = - type_mgr->GetType(arr_var.type_id())->AsPointer(); - const analysis::Array* arr_ty = ptr_type->pointee_type()->AsArray(); - assert(arr_ty && "expecting array type"); - uint32_t length_id = const_mgr->GetUIntConstId(length); - analysis::Array new_arr_ty(arr_ty->element_type(), - arr_ty->GetConstantLengthInfo(length_id, length)); - analysis::Type* reg_new_arr_ty = type_mgr->GetRegisteredType(&new_arr_ty); - analysis::Pointer new_ptr_ty(reg_new_arr_ty, ptr_type->storage_class()); - analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); - uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); - arr_var.SetResultType(new_ptr_ty_id); - def_use_mgr->AnalyzeInstUse(&arr_var); -} - -void EliminateDeadIOComponentsPass::ChangeIOVarStructLength(Instruction& io_var, - unsigned length) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::Pointer* ptr_type = - type_mgr->GetType(io_var.type_id())->AsPointer(); - auto core_type = ptr_type->pointee_type(); - // Check for per-vertex-array of struct from tesc, tese and geom and grab - // embedded struct type. - const auto arr_type = core_type->AsArray(); - if (arr_type) core_type = arr_type->element_type(); - const analysis::Struct* struct_ty = core_type->AsStruct(); - assert(struct_ty && "expecting struct type"); - const auto orig_elt_types = struct_ty->element_types(); - std::vector new_elt_types; - for (unsigned u = 0; u < length; ++u) - new_elt_types.push_back(orig_elt_types[u]); - analysis::Struct new_struct_ty(new_elt_types); - uint32_t old_struct_ty_id = type_mgr->GetTypeInstruction(struct_ty); - std::vector decorations = - context()->get_decoration_mgr()->GetDecorationsFor(old_struct_ty_id, - true); - for (auto dec : decorations) { - if (dec->opcode() == spv::Op::OpMemberDecorate) { - uint32_t midx = dec->GetSingleWordInOperand(1); - if (midx >= length) continue; - } - type_mgr->AttachDecoration(*dec, &new_struct_ty); - } - // Clone name instructions for new struct type - analysis::Type* reg_new_str_ty = type_mgr->GetRegisteredType(&new_struct_ty); - uint32_t new_struct_ty_id = type_mgr->GetTypeInstruction(reg_new_str_ty); - context()->CloneNames(old_struct_ty_id, new_struct_ty_id, length); - // Attach new type to var - analysis::Type* reg_new_var_ty = reg_new_str_ty; - if (arr_type) { - analysis::Array new_arr_ty(reg_new_var_ty, arr_type->length_info()); - reg_new_var_ty = type_mgr->GetRegisteredType(&new_arr_ty); - } - analysis::Pointer new_ptr_ty(reg_new_var_ty, elim_sclass_); - analysis::Type* reg_new_ptr_ty = type_mgr->GetRegisteredType(&new_ptr_ty); - uint32_t new_ptr_ty_id = type_mgr->GetTypeInstruction(reg_new_ptr_ty); - io_var.SetResultType(new_ptr_ty_id); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - def_use_mgr->AnalyzeInstUse(&io_var); -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/eliminate_dead_members_pass.cpp b/source/opt/eliminate_dead_members_pass.cpp index 1c98502e..52aca525 100644 --- a/source/opt/eliminate_dead_members_pass.cpp +++ b/source/opt/eliminate_dead_members_pass.cpp @@ -17,16 +17,17 @@ #include "ir_builder.h" #include "source/opt/ir_context.h" -namespace spvtools { -namespace opt { namespace { -constexpr uint32_t kRemovedMember = 0xFFFFFFFF; -constexpr uint32_t kSpecConstOpOpcodeIdx = 0; +const uint32_t kRemovedMember = 0xFFFFFFFF; +const uint32_t kSpecConstOpOpcodeIdx = 0; constexpr uint32_t kArrayElementTypeIdx = 0; } // namespace +namespace spvtools { +namespace opt { + Pass::Status EliminateDeadMembersPass::Process() { - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) return Status::SuccessWithoutChange; FindLiveMembers(); @@ -40,27 +41,27 @@ void EliminateDeadMembersPass::FindLiveMembers() { // Until we have implemented the rewriting of OpSpecConsantOp instructions, // we have to mark them as fully used just to be safe. for (auto& inst : get_module()->types_values()) { - if (inst.opcode() == spv::Op::OpSpecConstantOp) { - switch (spv::Op(inst.GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { - case spv::Op::OpCompositeExtract: + if (inst.opcode() == SpvOpSpecConstantOp) { + switch (inst.GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) { + case SpvOpCompositeExtract: MarkMembersAsLiveForExtract(&inst); break; - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: // Nothing specific to do. break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: assert(false && "Not implemented yet."); break; default: break; } - } else if (inst.opcode() == spv::Op::OpVariable) { - switch (spv::StorageClass(inst.GetSingleWordInOperand(0))) { - case spv::StorageClass::Input: - case spv::StorageClass::Output: + } else if (inst.opcode() == SpvOpVariable) { + switch (inst.GetSingleWordInOperand(0)) { + case SpvStorageClassInput: + case SpvStorageClassOutput: MarkPointeeTypeAsFullUsed(inst.type_id()); break; default: @@ -85,34 +86,34 @@ void EliminateDeadMembersPass::FindLiveMembers(const Function& function) { void EliminateDeadMembersPass::FindLiveMembers(const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpStore: + case SpvOpStore: MarkMembersAsLiveForStore(inst); break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: MarkMembersAsLiveForCopyMemory(inst); break; - case spv::Op::OpCompositeExtract: + case SpvOpCompositeExtract: MarkMembersAsLiveForExtract(inst); break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: MarkMembersAsLiveForAccessChain(inst); break; - case spv::Op::OpReturnValue: + case SpvOpReturnValue: // This should be an issue only if we are returning from the entry point. // However, for now I will keep it more conservative because functions are // often inlined leaving only the entry points. MarkOperandTypeAsFullyUsed(inst, 0); break; - case spv::Op::OpArrayLength: + case SpvOpArrayLength: MarkMembersAsLiveForArrayLength(inst); break; - case spv::Op::OpLoad: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCompositeConstruct: + case SpvOpLoad: + case SpvOpCompositeInsert: + case SpvOpCompositeConstruct: break; default: // This path is here for safety. All instructions that can reference @@ -130,7 +131,7 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForStore( // memory that is read outside of the shader. Other passes can remove all // store to memory that is not visible outside of the shader, so we do not // complicate the code for now. - assert(inst->opcode() == spv::Op::OpStore); + assert(inst->opcode() == SpvOpStore); uint32_t object_id = inst->GetSingleWordInOperand(1); Instruction* object_inst = context()->get_def_use_mgr()->GetDef(object_id); uint32_t object_type_id = object_inst->type_id(); @@ -142,15 +143,15 @@ void EliminateDeadMembersPass::MarkTypeAsFullyUsed(uint32_t type_id) { assert(type_inst != nullptr); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // Mark every member and its type as fully used. for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { used_members_[type_id].insert(i); MarkTypeAsFullyUsed(type_inst->GetSingleWordInOperand(i)); } break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: MarkTypeAsFullyUsed( type_inst->GetSingleWordInOperand(kArrayElementTypeIdx)); break; @@ -161,7 +162,7 @@ void EliminateDeadMembersPass::MarkTypeAsFullyUsed(uint32_t type_id) { void EliminateDeadMembersPass::MarkPointeeTypeAsFullUsed(uint32_t ptr_type_id) { Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer); + assert(ptr_type_inst->opcode() == SpvOpTypePointer); MarkTypeAsFullyUsed(ptr_type_inst->GetSingleWordInOperand(1)); } @@ -177,13 +178,12 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForCopyMemory( void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( const Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCompositeExtract || - (inst->opcode() == spv::Op::OpSpecConstantOp && - spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == - spv::Op::OpCompositeExtract)); + assert(inst->opcode() == SpvOpCompositeExtract || + (inst->opcode() == SpvOpSpecConstantOp && + inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == + SpvOpCompositeExtract)); - uint32_t first_operand = - (inst->opcode() == spv::Op::OpSpecConstantOp ? 1 : 0); + uint32_t first_operand = (inst->opcode() == SpvOpSpecConstantOp ? 1 : 0); uint32_t composite_id = inst->GetSingleWordInOperand(first_operand); Instruction* composite_inst = get_def_use_mgr()->GetDef(composite_id); uint32_t type_id = composite_inst->type_id(); @@ -192,14 +192,14 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); uint32_t member_idx = inst->GetSingleWordInOperand(i); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: used_members_[type_id].insert(member_idx); type_id = type_inst->GetSingleWordInOperand(member_idx); break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -210,10 +210,10 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForExtract( void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( const Instruction* inst) { - assert(inst->opcode() == spv::Op::OpAccessChain || - inst->opcode() == spv::Op::OpInBoundsAccessChain || - inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); + assert(inst->opcode() == SpvOpAccessChain || + inst->opcode() == SpvOpInBoundsAccessChain || + inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain); uint32_t pointer_id = inst->GetSingleWordInOperand(0); Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); @@ -225,14 +225,14 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( // For a pointer access chain, we need to skip the |element| index. It is not // a reference to the member of a struct, and it does not change the type. - uint32_t i = (inst->opcode() == spv::Op::OpAccessChain || - inst->opcode() == spv::Op::OpInBoundsAccessChain + uint32_t i = (inst->opcode() == SpvOpAccessChain || + inst->opcode() == SpvOpInBoundsAccessChain ? 1 : 2); for (; i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const analysis::IntConstant* member_idx = const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) ->AsIntConstant(); @@ -242,10 +242,10 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain( used_members_[type_id].insert(index); type_id = type_inst->GetSingleWordInOperand(index); } break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -263,7 +263,7 @@ void EliminateDeadMembersPass::MarkOperandTypeAsFullyUsed( void EliminateDeadMembersPass::MarkMembersAsLiveForArrayLength( const Instruction* inst) { - assert(inst->opcode() == spv::Op::OpArrayLength); + assert(inst->opcode() == SpvOpArrayLength); uint32_t object_id = inst->GetSingleWordInOperand(0); Instruction* object_inst = get_def_use_mgr()->GetDef(object_id); uint32_t pointer_type_id = object_inst->type_id(); @@ -278,7 +278,7 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { // First update all of the OpTypeStruct instructions. get_module()->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: modified |= UpdateOpTypeStruct(inst); break; default: @@ -289,47 +289,47 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { // Now update all of the instructions that reference the OpTypeStructs. get_module()->ForEachInst([&modified, this](Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpMemberName: + case SpvOpMemberName: modified |= UpdateOpMemberNameOrDecorate(inst); break; - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: modified |= UpdateOpMemberNameOrDecorate(inst); break; - case spv::Op::OpGroupMemberDecorate: + case SpvOpGroupMemberDecorate: modified |= UpdateOpGroupMemberDecorate(inst); break; - case spv::Op::OpSpecConstantComposite: - case spv::Op::OpConstantComposite: - case spv::Op::OpCompositeConstruct: + case SpvOpSpecConstantComposite: + case SpvOpConstantComposite: + case SpvOpCompositeConstruct: modified |= UpdateConstantComposite(inst); break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: modified |= UpdateAccessChain(inst); break; - case spv::Op::OpCompositeExtract: + case SpvOpCompositeExtract: modified |= UpdateCompsiteExtract(inst); break; - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: modified |= UpdateCompositeInsert(inst); break; - case spv::Op::OpArrayLength: + case SpvOpArrayLength: modified |= UpdateOpArrayLength(inst); break; - case spv::Op::OpSpecConstantOp: - switch (spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx))) { - case spv::Op::OpCompositeExtract: + case SpvOpSpecConstantOp: + switch (inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) { + case SpvOpCompositeExtract: modified |= UpdateCompsiteExtract(inst); break; - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: modified |= UpdateCompositeInsert(inst); break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: assert(false && "Not implemented yet."); break; default: @@ -344,7 +344,7 @@ bool EliminateDeadMembersPass::RemoveDeadMembers() { } bool EliminateDeadMembersPass::UpdateOpTypeStruct(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpTypeStruct); + assert(inst->opcode() == SpvOpTypeStruct); const auto& live_members = used_members_[inst->result_id()]; if (live_members.size() == inst->NumInOperands()) { @@ -362,8 +362,8 @@ bool EliminateDeadMembersPass::UpdateOpTypeStruct(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateOpMemberNameOrDecorate(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpMemberName || - inst->opcode() == spv::Op::OpMemberDecorate); + assert(inst->opcode() == SpvOpMemberName || + inst->opcode() == SpvOpMemberDecorate); uint32_t type_id = inst->GetSingleWordInOperand(0); auto live_members = used_members_.find(type_id); @@ -388,7 +388,7 @@ bool EliminateDeadMembersPass::UpdateOpMemberNameOrDecorate(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateOpGroupMemberDecorate(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpGroupMemberDecorate); + assert(inst->opcode() == SpvOpGroupMemberDecorate); bool modified = false; @@ -429,9 +429,9 @@ bool EliminateDeadMembersPass::UpdateOpGroupMemberDecorate(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateConstantComposite(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpSpecConstantComposite || - inst->opcode() == spv::Op::OpConstantComposite || - inst->opcode() == spv::Op::OpCompositeConstruct); + assert(inst->opcode() == SpvOpSpecConstantComposite || + inst->opcode() == SpvOpConstantComposite || + inst->opcode() == SpvOpCompositeConstruct); uint32_t type_id = inst->type_id(); bool modified = false; @@ -450,10 +450,10 @@ bool EliminateDeadMembersPass::UpdateConstantComposite(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpAccessChain || - inst->opcode() == spv::Op::OpInBoundsAccessChain || - inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain); + assert(inst->opcode() == SpvOpAccessChain || + inst->opcode() == SpvOpInBoundsAccessChain || + inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain); uint32_t pointer_id = inst->GetSingleWordInOperand(0); Instruction* pointer_inst = get_def_use_mgr()->GetDef(pointer_id); @@ -467,8 +467,8 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { new_operands.emplace_back(inst->GetInOperand(0)); // For pointer access chains we want to copy the element operand. - if (inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + if (inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain) { new_operands.emplace_back(inst->GetInOperand(1)); } @@ -476,7 +476,7 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const analysis::IntConstant* member_idx = const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i)) ->AsIntConstant(); @@ -501,10 +501,10 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) { // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); } break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: new_operands.emplace_back(inst->GetInOperand(i)); type_id = type_inst->GetSingleWordInOperand(0); break; @@ -539,13 +539,13 @@ uint32_t EliminateDeadMembersPass::GetNewMemberIndex(uint32_t type_id, } bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCompositeExtract || - (inst->opcode() == spv::Op::OpSpecConstantOp && - spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == - spv::Op::OpCompositeExtract)); + assert(inst->opcode() == SpvOpCompositeExtract || + (inst->opcode() == SpvOpSpecConstantOp && + inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == + SpvOpCompositeExtract)); uint32_t first_operand = 0; - if (inst->opcode() == spv::Op::OpSpecConstantOp) { + if (inst->opcode() == SpvOpSpecConstantOp) { first_operand = 1; } uint32_t object_id = inst->GetSingleWordInOperand(first_operand); @@ -569,15 +569,15 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // The type will have already been rewritten, so use the new member // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: @@ -594,13 +594,13 @@ bool EliminateDeadMembersPass::UpdateCompsiteExtract(Instruction* inst) { } bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCompositeInsert || - (inst->opcode() == spv::Op::OpSpecConstantOp && - spv::Op(inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx)) == - spv::Op::OpCompositeInsert)); + assert(inst->opcode() == SpvOpCompositeInsert || + (inst->opcode() == SpvOpSpecConstantOp && + inst->GetSingleWordInOperand(kSpecConstOpOpcodeIdx) == + SpvOpCompositeInsert)); uint32_t first_operand = 0; - if (inst->opcode() == spv::Op::OpSpecConstantOp) { + if (inst->opcode() == SpvOpSpecConstantOp) { first_operand = 1; } @@ -630,15 +630,15 @@ bool EliminateDeadMembersPass::UpdateCompositeInsert(Instruction* inst) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // The type will have already been rewritten, so use the new member // index. type_id = type_inst->GetSingleWordInOperand(new_member_idx); break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: type_id = type_inst->GetSingleWordInOperand(0); break; default: diff --git a/source/opt/eliminate_dead_output_stores_pass.cpp b/source/opt/eliminate_dead_output_stores_pass.cpp deleted file mode 100755 index 99711a16..00000000 --- a/source/opt/eliminate_dead_output_stores_pass.cpp +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "source/opt/eliminate_dead_output_stores_pass.h" - -#include "source/opt/instruction.h" -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { -namespace { -constexpr uint32_t kDecorationLocationInIdx = 2; -constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; -constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; -constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; -constexpr uint32_t kOpAccessChainIdx0InIdx = 1; -constexpr uint32_t kOpConstantValueInIdx = 0; -} // namespace - -Pass::Status EliminateDeadOutputStoresPass::Process() { - // Current functionality assumes shader capability - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) - return Status::SuccessWithoutChange; - Pass::Status status = DoDeadOutputStoreElimination(); - return status; -} - -void EliminateDeadOutputStoresPass::InitializeElimination() { - kill_list_.clear(); -} - -bool EliminateDeadOutputStoresPass::IsLiveBuiltin(uint32_t bi) { - return live_builtins_->find(bi) != live_builtins_->end(); -} - -bool EliminateDeadOutputStoresPass::AnyLocsAreLive(uint32_t start, - uint32_t count) { - auto finish = start + count; - for (uint32_t u = start; u < finish; ++u) { - if (live_locs_->find(u) != live_locs_->end()) return true; - } - return false; -} - -void EliminateDeadOutputStoresPass::KillAllStoresOfRef(Instruction* ref) { - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - if (ref->opcode() == spv::Op::OpStore) { - kill_list_.push_back(ref); - return; - } - assert((ref->opcode() == spv::Op::OpAccessChain || - ref->opcode() == spv::Op::OpInBoundsAccessChain) && - "unexpected use of output variable"); - def_use_mgr->ForEachUser(ref, [this](Instruction* user) { - if (user->opcode() == spv::Op::OpStore) kill_list_.push_back(user); - }); -} - -void EliminateDeadOutputStoresPass::KillAllDeadStoresOfLocRef( - Instruction* ref, Instruction* var) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); - analysis::LivenessManager* live_mgr = context()->get_liveness_mgr(); - // Find variable location if present. - uint32_t start_loc = 0; - auto var_id = var->result_id(); - bool no_loc = deco_mgr->WhileEachDecoration( - var_id, uint32_t(spv::Decoration::Location), - [&start_loc](const Instruction& deco) { - assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); - start_loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); - return false; - }); - // Find patch decoration if present - bool is_patch = !deco_mgr->WhileEachDecoration( - var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { - if (deco.opcode() != spv::Op::OpDecorate) - assert(false && "unexpected decoration"); - return false; - }); - // Compute offset and final type of reference. If no location found - // or any stored locations are live, return without removing stores. - auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); - assert(ptr_type && "unexpected var type"); - auto var_type = ptr_type->pointee_type(); - uint32_t ref_loc = start_loc; - auto curr_type = var_type; - if (ref->opcode() == spv::Op::OpAccessChain || - ref->opcode() == spv::Op::OpInBoundsAccessChain) { - live_mgr->AnalyzeAccessChainLoc(ref, &curr_type, &ref_loc, &no_loc, - is_patch, /* input */ false); - } - if (no_loc || AnyLocsAreLive(ref_loc, live_mgr->GetLocSize(curr_type))) - return; - // Kill all stores based on this reference - KillAllStoresOfRef(ref); -} - -void EliminateDeadOutputStoresPass::KillAllDeadStoresOfBuiltinRef( - Instruction* ref, Instruction* var) { - auto deco_mgr = context()->get_decoration_mgr(); - auto def_use_mgr = context()->get_def_use_mgr(); - auto type_mgr = context()->get_type_mgr(); - auto live_mgr = context()->get_liveness_mgr(); - // Search for builtin decoration of base variable - uint32_t builtin = uint32_t(spv::BuiltIn::Max); - auto var_id = var->result_id(); - (void)deco_mgr->WhileEachDecoration( - var_id, uint32_t(spv::Decoration::BuiltIn), - [&builtin](const Instruction& deco) { - assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); - builtin = deco.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); - return false; - }); - // If analyzed builtin and not live, kill stores. - if (builtin != uint32_t(spv::BuiltIn::Max)) { - if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) - KillAllStoresOfRef(ref); - return; - } - // Search for builtin decoration on indexed member - auto ref_op = ref->opcode(); - if (ref_op != spv::Op::OpAccessChain && - ref_op != spv::Op::OpInBoundsAccessChain) { - return; - } - uint32_t in_idx = kOpAccessChainIdx0InIdx; - analysis::Type* var_type = type_mgr->GetType(var->type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - auto curr_type = ptr_type->pointee_type(); - auto arr_type = curr_type->AsArray(); - if (arr_type) { - curr_type = arr_type->element_type(); - ++in_idx; - } - auto str_type = curr_type->AsStruct(); - auto str_type_id = type_mgr->GetId(str_type); - auto member_idx_id = ref->GetSingleWordInOperand(in_idx); - auto member_idx_inst = def_use_mgr->GetDef(member_idx_id); - assert(member_idx_inst->opcode() == spv::Op::OpConstant && - "unexpected non-constant index"); - auto ac_idx = member_idx_inst->GetSingleWordInOperand(kOpConstantValueInIdx); - (void)deco_mgr->WhileEachDecoration( - str_type_id, uint32_t(spv::Decoration::BuiltIn), - [ac_idx, &builtin](const Instruction& deco) { - assert(deco.opcode() == spv::Op::OpMemberDecorate && - "unexpected decoration"); - auto deco_idx = - deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx); - if (deco_idx == ac_idx) { - builtin = - deco.GetSingleWordInOperand(kOpDecorateMemberBuiltInLiteralInIdx); - return false; - } - return true; - }); - assert(builtin != uint32_t(spv::BuiltIn::Max) && "builtin not found"); - // If analyzed builtin and not live, kill stores. - if (live_mgr->IsAnalyzedBuiltin(builtin) && !IsLiveBuiltin(builtin)) - KillAllStoresOfRef(ref); -} - -Pass::Status EliminateDeadOutputStoresPass::DoDeadOutputStoreElimination() { - // Current implementation only supports vert, tesc, tese, geom shaders - auto stage = context()->GetStage(); - if (stage != spv::ExecutionModel::Vertex && - stage != spv::ExecutionModel::TessellationControl && - stage != spv::ExecutionModel::TessellationEvaluation && - stage != spv::ExecutionModel::Geometry) - return Status::Failure; - InitializeElimination(); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); - // Process all output variables - for (auto& var : context()->types_values()) { - if (var.opcode() != spv::Op::OpVariable) { - continue; - } - analysis::Type* var_type = type_mgr->GetType(var.type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - if (ptr_type->storage_class() != spv::StorageClass::Output) { - continue; - } - // If builtin decoration on variable, process as builtin. - auto var_id = var.result_id(); - bool is_builtin = false; - if (deco_mgr->HasDecoration(var_id, uint32_t(spv::Decoration::BuiltIn))) { - is_builtin = true; - } else { - // If interface block with builtin members, process as builtin. - // Strip off outer array type if present. - auto curr_type = ptr_type->pointee_type(); - auto arr_type = curr_type->AsArray(); - if (arr_type) curr_type = arr_type->element_type(); - auto str_type = curr_type->AsStruct(); - if (str_type) { - auto str_type_id = type_mgr->GetId(str_type); - if (deco_mgr->HasDecoration(str_type_id, - uint32_t(spv::Decoration::BuiltIn))) - is_builtin = true; - } - } - // For each store or access chain using var, if dead builtin or all its - // locations are dead, kill store or all access chain's stores - def_use_mgr->ForEachUser( - var_id, [this, &var, is_builtin](Instruction* user) { - auto op = user->opcode(); - if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || - op == spv::Op::OpDecorate || user->IsNonSemanticInstruction()) - return; - if (is_builtin) - KillAllDeadStoresOfBuiltinRef(user, &var); - else - KillAllDeadStoresOfLocRef(user, &var); - }); - } - for (auto& kinst : kill_list_) context()->KillInst(kinst); - - return kill_list_.empty() ? Status::SuccessWithoutChange - : Status::SuccessWithChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/eliminate_dead_output_stores_pass.h b/source/opt/eliminate_dead_output_stores_pass.h deleted file mode 100755 index 676d4f4f..00000000 --- a/source/opt/eliminate_dead_output_stores_pass.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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. - -#ifndef SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ -#define SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ - -#include - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// See optimizer.hpp for documentation. -class EliminateDeadOutputStoresPass : public Pass { - public: - explicit EliminateDeadOutputStoresPass( - std::unordered_set* live_locs, - std::unordered_set* live_builtins) - : live_locs_(live_locs), live_builtins_(live_builtins) {} - - const char* name() const override { return "eliminate-dead-output-stores"; } - Status Process() override; - - // Return the mask of preserved Analyses. - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisDefUse | - IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | - IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; - } - - private: - // Initialize elimination - void InitializeElimination(); - - // Do dead output store analysis - Status DoDeadOutputStoreElimination(); - - // Kill all stores resulting from |ref|. - void KillAllStoresOfRef(Instruction* ref); - - // Kill all dead stores resulting from |user| of loc-based |var|. - void KillAllDeadStoresOfLocRef(Instruction* user, Instruction* var); - - // Kill all dead stores resulting from |user| of builtin |var|. - void KillAllDeadStoresOfBuiltinRef(Instruction* user, Instruction* var); - - // Return true if any of |count| locations starting at location |start| are - // live. - bool AnyLocsAreLive(uint32_t start, uint32_t count); - - // Return true if builtin |bi| is live. - bool IsLiveBuiltin(uint32_t bi); - - std::unordered_set* live_locs_; - std::unordered_set* live_builtins_; - - std::vector kill_list_; -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_ELIMINATE_DEAD_OUTPUT_STORES_H_ diff --git a/source/opt/feature_manager.cpp b/source/opt/feature_manager.cpp index 51883706..a5902716 100644 --- a/source/opt/feature_manager.cpp +++ b/source/opt/feature_manager.cpp @@ -14,6 +14,8 @@ #include "source/opt/feature_manager.h" +#include +#include #include #include "source/enum_string_mapping.h" @@ -34,44 +36,42 @@ void FeatureManager::AddExtensions(Module* module) { } void FeatureManager::AddExtension(Instruction* ext) { - assert(ext->opcode() == spv::Op::OpExtension && + assert(ext->opcode() == SpvOpExtension && "Expecting an extension instruction."); const std::string name = ext->GetInOperand(0u).AsString(); Extension extension; if (GetExtensionFromString(name.c_str(), &extension)) { - extensions_.insert(extension); + extensions_.Add(extension); } } void FeatureManager::RemoveExtension(Extension ext) { - if (!extensions_.contains(ext)) return; - extensions_.erase(ext); + if (!extensions_.Contains(ext)) return; + extensions_.Remove(ext); } -void FeatureManager::AddCapability(spv::Capability cap) { - if (capabilities_.contains(cap)) return; +void FeatureManager::AddCapability(SpvCapability cap) { + if (capabilities_.Contains(cap)) return; - capabilities_.insert(cap); + capabilities_.Add(cap); spv_operand_desc desc = {}; - if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, - uint32_t(cap), &desc)) { - for (auto capability : - CapabilitySet(desc->numCapabilities, desc->capabilities)) { - AddCapability(capability); - } + if (SPV_SUCCESS == + grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) { + CapabilitySet(desc->numCapabilities, desc->capabilities) + .ForEach([this](SpvCapability c) { AddCapability(c); }); } } -void FeatureManager::RemoveCapability(spv::Capability cap) { - if (!capabilities_.contains(cap)) return; - capabilities_.erase(cap); +void FeatureManager::RemoveCapability(SpvCapability cap) { + if (!capabilities_.Contains(cap)) return; + capabilities_.Remove(cap); } void FeatureManager::AddCapabilities(Module* module) { for (Instruction& inst : module->capabilities()) { - AddCapability(static_cast(inst.GetSingleWordInOperand(0))); + AddCapability(static_cast(inst.GetSingleWordInOperand(0))); } } diff --git a/source/opt/feature_manager.h b/source/opt/feature_manager.h index d150a2fa..68c8e9a2 100644 --- a/source/opt/feature_manager.h +++ b/source/opt/feature_manager.h @@ -25,19 +25,27 @@ namespace opt { // Tracks features enabled by a module. The IRContext has a FeatureManager. class FeatureManager { public: + explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {} + // Returns true if |ext| is an enabled extension in the module. - bool HasExtension(Extension ext) const { return extensions_.contains(ext); } + bool HasExtension(Extension ext) const { return extensions_.Contains(ext); } + + // Removes the given |extension| from the current FeatureManager. + void RemoveExtension(Extension extension); // Returns true if |cap| is an enabled capability in the module. - bool HasCapability(spv::Capability cap) const { - return capabilities_.contains(cap); + bool HasCapability(SpvCapability cap) const { + return capabilities_.Contains(cap); } - // Returns the capabilities the module declares. - inline const CapabilitySet& GetCapabilities() const { return capabilities_; } + // Removes the given |capability| from the current FeatureManager. + void RemoveCapability(SpvCapability capability); - // Returns the extensions the module imports. - inline const ExtensionSet& GetExtensions() const { return extensions_; } + // Analyzes |module| and records enabled extensions and capabilities. + void Analyze(Module* module); + + CapabilitySet* GetCapabilities() { return &capabilities_; } + const CapabilitySet* GetCapabilities() const { return &capabilities_; } uint32_t GetExtInstImportId_GLSLstd450() const { return extinst_importid_GLSLstd450_; @@ -56,34 +64,23 @@ class FeatureManager { return !(a == b); } - private: - explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {} - - // Analyzes |module| and records enabled extensions and capabilities. - void Analyze(Module* module); + // Adds the given |capability| and all implied capabilities into the current + // FeatureManager. + void AddCapability(SpvCapability capability); // Add the extension |ext| to the feature manager. void AddExtension(Instruction* ext); + // Analyzes |module| and records imported external instruction sets. + void AddExtInstImportIds(Module* module); + + private: // Analyzes |module| and records enabled extensions. void AddExtensions(Module* module); - // Removes the given |extension| from the current FeatureManager. - void RemoveExtension(Extension extension); - - // Adds the given |capability| and all implied capabilities into the current - // FeatureManager. - void AddCapability(spv::Capability capability); - // Analyzes |module| and records enabled capabilities. void AddCapabilities(Module* module); - // Removes the given |capability| from the current FeatureManager. - void RemoveCapability(spv::Capability capability); - - // Analyzes |module| and records imported external instruction sets. - void AddExtInstImportIds(Module* module); - // Auxiliary object for querying SPIR-V grammar facts. const AssemblyGrammar& grammar_; @@ -103,8 +100,6 @@ class FeatureManager { // Common NonSemanticShader100DebugInfo external instruction import ids, // cached for performance. uint32_t extinst_importid_Shader100DebugInfo_ = 0; - - friend class IRContext; }; } // namespace opt diff --git a/source/opt/fix_func_call_arguments.cpp b/source/opt/fix_func_call_arguments.cpp index f3486bed..d140fb4b 100644 --- a/source/opt/fix_func_call_arguments.cpp +++ b/source/opt/fix_func_call_arguments.cpp @@ -29,7 +29,7 @@ Pass::Status FixFuncCallArgumentsPass::Process() { if (ModuleHasASingleFunction()) return Status::SuccessWithoutChange; for (auto& func : *get_module()) { func.ForEachInst([this, &modified](Instruction* inst) { - if (inst->opcode() == spv::Op::OpFunctionCall) { + if (inst->opcode() == SpvOpFunctionCall) { modified |= FixFuncCallArguments(inst); } }); @@ -44,7 +44,7 @@ bool FixFuncCallArgumentsPass::FixFuncCallArguments( Operand& op = func_call_inst->GetInOperand(i); if (op.type != SPV_OPERAND_TYPE_ID) continue; Instruction* operand_inst = get_def_use_mgr()->GetDef(op.AsId()); - if (operand_inst->opcode() == spv::Op::OpAccessChain) { + if (operand_inst->opcode() == SpvOpAccessChain) { uint32_t var_id = ReplaceAccessChainFuncCallArguments(func_call_inst, operand_inst); func_call_inst->SetInOperand(i, {var_id}); @@ -71,11 +71,10 @@ uint32_t FixFuncCallArgumentsPass::ReplaceAccessChainFuncCallArguments( Instruction* op_type = get_def_use_mgr()->GetDef(op_ptr_type->GetSingleWordInOperand(1)); uint32_t varType = context()->get_type_mgr()->FindPointerToType( - op_type->result_id(), spv::StorageClass::Function); + op_type->result_id(), SpvStorageClassFunction); // Create new variable builder.SetInsertPoint(variable_insertion_point); - Instruction* var = - builder.AddVariable(varType, uint32_t(spv::StorageClass::Function)); + Instruction* var = builder.AddVariable(varType, SpvStorageClassFunction); // Load access chain to the new variable before function call builder.SetInsertPoint(func_call_inst); diff --git a/source/opt/fix_storage_class.cpp b/source/opt/fix_storage_class.cpp index 564cd1b8..04eb1326 100644 --- a/source/opt/fix_storage_class.cpp +++ b/source/opt/fix_storage_class.cpp @@ -26,7 +26,7 @@ Pass::Status FixStorageClass::Process() { bool modified = false; get_module()->ForEachInst([this, &modified](Instruction* inst) { - if (inst->opcode() == spv::Op::OpVariable) { + if (inst->opcode() == SpvOpVariable) { std::set seen; std::vector> uses; get_def_use_mgr()->ForEachUse(inst, @@ -37,7 +37,7 @@ Pass::Status FixStorageClass::Process() { for (auto& use : uses) { modified |= PropagateStorageClass( use.first, - static_cast(inst->GetSingleWordInOperand(0)), + static_cast(inst->GetSingleWordInOperand(0)), &seen); assert(seen.empty() && "Seen was not properly reset."); modified |= @@ -50,14 +50,14 @@ Pass::Status FixStorageClass::Process() { } bool FixStorageClass::PropagateStorageClass(Instruction* inst, - spv::StorageClass storage_class, + SpvStorageClass storage_class, std::set* seen) { if (!IsPointerResultType(inst)) { return false; } if (IsPointerToStorageClass(inst, storage_class)) { - if (inst->opcode() == spv::Op::OpPhi) { + if (inst->opcode() == SpvOpPhi) { if (!seen->insert(inst->result_id()).second) { return false; } @@ -71,34 +71,34 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst, modified |= PropagateStorageClass(use, storage_class, seen); } - if (inst->opcode() == spv::Op::OpPhi) { + if (inst->opcode() == SpvOpPhi) { seen->erase(inst->result_id()); } return modified; } switch (inst->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpCopyObject: - case spv::Op::OpPhi: - case spv::Op::OpSelect: + case SpvOpAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpCopyObject: + case SpvOpPhi: + case SpvOpSelect: FixInstructionStorageClass(inst, storage_class, seen); return true; - case spv::Op::OpFunctionCall: + case SpvOpFunctionCall: // We cannot be sure of the actual connection between the storage class // of the parameter and the storage class of the result, so we should not // do anything. If the result type needs to be fixed, the function call // should be inlined. return false; - case spv::Op::OpImageTexelPointer: - case spv::Op::OpLoad: - case spv::Op::OpStore: - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: - case spv::Op::OpVariable: - case spv::Op::OpBitcast: + case SpvOpImageTexelPointer: + case SpvOpLoad: + case SpvOpStore: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: + case SpvOpVariable: + case SpvOpBitcast: // Nothing to change for these opcode. The result type is the same // regardless of the storage class of the operand. return false; @@ -109,9 +109,9 @@ bool FixStorageClass::PropagateStorageClass(Instruction* inst, } } -void FixStorageClass::FixInstructionStorageClass( - Instruction* inst, spv::StorageClass storage_class, - std::set* seen) { +void FixStorageClass::FixInstructionStorageClass(Instruction* inst, + SpvStorageClass storage_class, + std::set* seen) { assert(IsPointerResultType(inst) && "The result type of the instruction must be a pointer."); @@ -126,10 +126,10 @@ void FixStorageClass::FixInstructionStorageClass( } void FixStorageClass::ChangeResultStorageClass( - Instruction* inst, spv::StorageClass storage_class) const { + Instruction* inst, SpvStorageClass storage_class) const { analysis::TypeManager* type_mgr = context()->get_type_mgr(); Instruction* result_type_inst = get_def_use_mgr()->GetDef(inst->type_id()); - assert(result_type_inst->opcode() == spv::Op::OpTypePointer); + assert(result_type_inst->opcode() == SpvOpTypePointer); uint32_t pointee_type_id = result_type_inst->GetSingleWordInOperand(1); uint32_t new_result_type_id = type_mgr->FindPointerToType(pointee_type_id, storage_class); @@ -147,7 +147,7 @@ bool FixStorageClass::IsPointerResultType(Instruction* inst) { } bool FixStorageClass::IsPointerToStorageClass(Instruction* inst, - spv::StorageClass storage_class) { + SpvStorageClass storage_class) { analysis::TypeManager* type_mgr = context()->get_type_mgr(); analysis::Type* pType = type_mgr->GetType(inst->type_id()); const analysis::Pointer* result_type = pType->AsPointer(); @@ -180,39 +180,39 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, // particular type, then we want find that type. uint32_t new_type_id = 0; switch (inst->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpInBoundsPtrAccessChain: if (op_idx == 2) { new_type_id = WalkAccessChainType(inst, type_id); } break; - case spv::Op::OpCopyObject: + case SpvOpCopyObject: new_type_id = type_id; break; - case spv::Op::OpPhi: + case SpvOpPhi: if (seen->insert(inst->result_id()).second) { new_type_id = type_id; } break; - case spv::Op::OpSelect: + case SpvOpSelect: if (op_idx > 2) { new_type_id = type_id; } break; - case spv::Op::OpFunctionCall: + case SpvOpFunctionCall: // We cannot be sure of the actual connection between the type // of the parameter and the type of the result, so we should not // do anything. If the result type needs to be fixed, the function call // should be inlined. return false; - case spv::Op::OpLoad: { + case SpvOpLoad: { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); new_type_id = type_inst->GetSingleWordInOperand(1); break; } - case spv::Op::OpStore: { + case SpvOpStore: { uint32_t obj_id = inst->GetSingleWordInOperand(1); Instruction* obj_inst = get_def_use_mgr()->GetDef(obj_id); uint32_t obj_type_id = obj_inst->type_id(); @@ -237,18 +237,18 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, context()->UpdateDefUse(inst); } } break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: // TODO: May need to expand the copy as we do with the stores. break; - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: // TODO: DXC does not seem to generate code that will require changes to // these opcode. The can be implemented when they come up. break; - case spv::Op::OpImageTexelPointer: - case spv::Op::OpBitcast: + case SpvOpImageTexelPointer: + case SpvOpBitcast: // Nothing to change for these opcode. The result type is the same // regardless of the type of the operand. return false; @@ -278,7 +278,7 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, PropagateType(use.first, new_type_id, use.second, seen); } - if (inst->opcode() == spv::Op::OpPhi) { + if (inst->opcode() == SpvOpPhi) { seen->erase(inst->result_id()); } } @@ -288,12 +288,12 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id, uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { uint32_t start_idx = 0; switch (inst->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: start_idx = 1; break; - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: start_idx = 2; break; default: @@ -302,29 +302,23 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { } Instruction* orig_type_inst = get_def_use_mgr()->GetDef(id); - assert(orig_type_inst->opcode() == spv::Op::OpTypePointer); + assert(orig_type_inst->opcode() == SpvOpTypePointer); id = orig_type_inst->GetSingleWordInOperand(1); for (uint32_t i = start_idx; i < inst->NumInOperands(); ++i) { Instruction* type_inst = get_def_use_mgr()->GetDef(id); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeMatrix: + case SpvOpTypeVector: id = type_inst->GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const analysis::Constant* index_const = context()->get_constant_mgr()->FindDeclaredConstant( inst->GetSingleWordInOperand(i)); - // It is highly unlikely that any type would have more fields than could - // be indexed by a 32-bit integer, and GetSingleWordInOperand only takes - // a 32-bit value, so we would not be able to handle it anyway. But the - // specification does allow any scalar integer type, treated as signed, - // so we simply downcast the index to 32-bits. - uint32_t index = - static_cast(index_const->GetSignExtendedValue()); + uint32_t index = index_const->GetU32(); id = type_inst->GetSingleWordInOperand(index); break; } @@ -336,8 +330,8 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) { } return context()->get_type_mgr()->FindPointerToType( - id, static_cast( - orig_type_inst->GetSingleWordInOperand(0))); + id, + static_cast(orig_type_inst->GetSingleWordInOperand(0))); } // namespace opt diff --git a/source/opt/fix_storage_class.h b/source/opt/fix_storage_class.h index 6c67acd3..e72e864a 100644 --- a/source/opt/fix_storage_class.h +++ b/source/opt/fix_storage_class.h @@ -48,7 +48,7 @@ class FixStorageClass : public Pass { // appropriate, and propagates the change to the users of |inst| as well. // Returns true of any changes were made. // |seen| is used to track OpPhi instructions that should not be processed. - bool PropagateStorageClass(Instruction* inst, spv::StorageClass storage_class, + bool PropagateStorageClass(Instruction* inst, SpvStorageClass storage_class, std::set* seen); // Changes the storage class of the result of |inst| to |storage_class|. @@ -58,13 +58,13 @@ class FixStorageClass : public Pass { // |seen| is used to track OpPhi instructions that should not be processed by // |PropagateStorageClass| void FixInstructionStorageClass(Instruction* inst, - spv::StorageClass storage_class, + SpvStorageClass storage_class, std::set* seen); // Changes the storage class of the result of |inst| to |storage_class|. The // result type of |inst| must be a pointer. void ChangeResultStorageClass(Instruction* inst, - spv::StorageClass storage_class) const; + SpvStorageClass storage_class) const; // Returns true if the result type of |inst| is a pointer. bool IsPointerResultType(Instruction* inst); @@ -72,7 +72,7 @@ class FixStorageClass : public Pass { // Returns true if the result of |inst| is a pointer to storage class // |storage_class|. bool IsPointerToStorageClass(Instruction* inst, - spv::StorageClass storage_class); + SpvStorageClass storage_class); // Change |inst| to match that operand |op_idx| now has type |type_id|, and // adjust any uses of |inst| accordingly. Returns true if the code changed. diff --git a/source/opt/flatten_decoration_pass.cpp b/source/opt/flatten_decoration_pass.cpp index c878c097..f4de9116 100644 --- a/source/opt/flatten_decoration_pass.cpp +++ b/source/opt/flatten_decoration_pass.cpp @@ -49,16 +49,16 @@ Pass::Status FlattenDecorationPass::Process() { // Rely on unordered_map::operator[] to create its entries on first access. for (const auto& inst : annotations) { switch (inst.opcode()) { - case spv::Op::OpDecorationGroup: + case SpvOp::SpvOpDecorationGroup: group_ids.insert(inst.result_id()); break; - case spv::Op::OpGroupDecorate: { + case SpvOp::SpvOpGroupDecorate: { Words& words = normal_uses[inst.GetSingleWordInOperand(0)]; for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { words.push_back(inst.GetSingleWordInOperand(i)); } } break; - case spv::Op::OpGroupMemberDecorate: { + case SpvOp::SpvOpGroupMemberDecorate: { Words& words = member_uses[inst.GetSingleWordInOperand(0)]; for (uint32_t i = 1; i < inst.NumInOperandWords(); i++) { words.push_back(inst.GetSingleWordInOperand(i)); @@ -77,12 +77,12 @@ Pass::Status FlattenDecorationPass::Process() { // Should we replace this instruction? bool replace = false; switch (inst_iter->opcode()) { - case spv::Op::OpDecorationGroup: - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: + case SpvOp::SpvOpDecorationGroup: + case SpvOp::SpvOpGroupDecorate: + case SpvOp::SpvOpGroupMemberDecorate: replace = true; break; - case spv::Op::OpDecorate: { + case SpvOp::SpvOpDecorate: { // If this decoration targets a group, then replace it // by sets of normal and member decorations. const uint32_t group = inst_iter->GetSingleWordOperand(0); @@ -115,7 +115,7 @@ Pass::Status FlattenDecorationPass::Process() { operands.insert(operands.end(), decoration_operands_iter, inst_iter->end()); std::unique_ptr new_inst(new Instruction( - context(), spv::Op::OpMemberDecorate, 0, 0, operands)); + context(), SpvOp::SpvOpMemberDecorate, 0, 0, operands)); inst_iter = inst_iter.InsertBefore(std::move(new_inst)); ++inst_iter; replace = true; @@ -146,7 +146,7 @@ Pass::Status FlattenDecorationPass::Process() { if (!group_ids.empty()) { for (auto debug_inst_iter = context()->debug2_begin(); debug_inst_iter != context()->debug2_end();) { - if (debug_inst_iter->opcode() == spv::Op::OpName) { + if (debug_inst_iter->opcode() == SpvOp::SpvOpName) { const uint32_t target = debug_inst_iter->GetSingleWordOperand(0); if (group_ids.count(target)) { debug_inst_iter = debug_inst_iter.Erase(); diff --git a/source/opt/fold.cpp b/source/opt/fold.cpp index c2a97b6e..315741ad 100644 --- a/source/opt/fold.cpp +++ b/source/opt/fold.cpp @@ -21,6 +21,7 @@ #include "source/opt/const_folding_rules.h" #include "source/opt/def_use_manager.h" #include "source/opt/folding_rules.h" +#include "source/opt/ir_builder.h" #include "source/opt/ir_context.h" namespace spvtools { @@ -41,24 +42,23 @@ namespace { } // namespace -uint32_t InstructionFolder::UnaryOperate(spv::Op opcode, - uint32_t operand) const { +uint32_t InstructionFolder::UnaryOperate(SpvOp opcode, uint32_t operand) const { switch (opcode) { // Arthimetics - case spv::Op::OpSNegate: { + case SpvOp::SpvOpSNegate: { int32_t s_operand = static_cast(operand); if (s_operand == std::numeric_limits::min()) { return s_operand; } return -s_operand; } - case spv::Op::OpNot: + case SpvOp::SpvOpNot: return ~operand; - case spv::Op::OpLogicalNot: + case SpvOp::SpvOpLogicalNot: return !static_cast(operand); - case spv::Op::OpUConvert: + case SpvOp::SpvOpUConvert: return operand; - case spv::Op::OpSConvert: + case SpvOp::SpvOpSConvert: return operand; default: assert(false && @@ -67,31 +67,31 @@ uint32_t InstructionFolder::UnaryOperate(spv::Op opcode, } } -uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, +uint32_t InstructionFolder::BinaryOperate(SpvOp opcode, uint32_t a, uint32_t b) const { switch (opcode) { // Arthimetics - case spv::Op::OpIAdd: + case SpvOp::SpvOpIAdd: return a + b; - case spv::Op::OpISub: + case SpvOp::SpvOpISub: return a - b; - case spv::Op::OpIMul: + case SpvOp::SpvOpIMul: return a * b; - case spv::Op::OpUDiv: + case SpvOp::SpvOpUDiv: if (b != 0) { return a / b; } else { // Dividing by 0 is undefined, so we will just pick 0. return 0; } - case spv::Op::OpSDiv: + case SpvOp::SpvOpSDiv: if (b != 0u) { return (static_cast(a)) / (static_cast(b)); } else { // Dividing by 0 is undefined, so we will just pick 0. return 0; } - case spv::Op::OpSRem: { + case SpvOp::SpvOpSRem: { // The sign of non-zero result comes from the first operand: a. This is // guaranteed by C++11 rules for integer division operator. The division // result is rounded toward zero, so the result of '%' has the sign of @@ -103,10 +103,10 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, return 0; } } - case spv::Op::OpSMod: { + case SpvOp::SpvOpSMod: { // The sign of non-zero result comes from the second operand: b if (b != 0u) { - int32_t rem = BinaryOperate(spv::Op::OpSRem, a, b); + int32_t rem = BinaryOperate(SpvOp::SpvOpSRem, a, b); int32_t b_prim = static_cast(b); return (rem + b_prim) % b_prim; } else { @@ -114,7 +114,7 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, return 0; } } - case spv::Op::OpUMod: + case SpvOp::SpvOpUMod: if (b != 0u) { return (a % b); } else { @@ -123,7 +123,7 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, } // Shifting - case spv::Op::OpShiftRightLogical: + case SpvOp::SpvOpShiftRightLogical: if (b >= 32) { // This is undefined behaviour when |b| > 32. Choose 0 for consistency. // When |b| == 32, doing the shift in C++ in undefined, but the result @@ -131,7 +131,7 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, return 0; } return a >> b; - case spv::Op::OpShiftRightArithmetic: + case SpvOp::SpvOpShiftRightArithmetic: if (b > 32) { // This is undefined behaviour. Choose 0 for consistency. return 0; @@ -146,7 +146,7 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, } } return (static_cast(a)) >> b; - case spv::Op::OpShiftLeftLogical: + case SpvOp::SpvOpShiftLeftLogical: if (b >= 32) { // This is undefined behaviour when |b| > 32. Choose 0 for consistency. // When |b| == 32, doing the shift in C++ in undefined, but the result @@ -156,43 +156,43 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, return a << b; // Bitwise operations - case spv::Op::OpBitwiseOr: + case SpvOp::SpvOpBitwiseOr: return a | b; - case spv::Op::OpBitwiseAnd: + case SpvOp::SpvOpBitwiseAnd: return a & b; - case spv::Op::OpBitwiseXor: + case SpvOp::SpvOpBitwiseXor: return a ^ b; // Logical - case spv::Op::OpLogicalEqual: + case SpvOp::SpvOpLogicalEqual: return (static_cast(a)) == (static_cast(b)); - case spv::Op::OpLogicalNotEqual: + case SpvOp::SpvOpLogicalNotEqual: return (static_cast(a)) != (static_cast(b)); - case spv::Op::OpLogicalOr: + case SpvOp::SpvOpLogicalOr: return (static_cast(a)) || (static_cast(b)); - case spv::Op::OpLogicalAnd: + case SpvOp::SpvOpLogicalAnd: return (static_cast(a)) && (static_cast(b)); // Comparison - case spv::Op::OpIEqual: + case SpvOp::SpvOpIEqual: return a == b; - case spv::Op::OpINotEqual: + case SpvOp::SpvOpINotEqual: return a != b; - case spv::Op::OpULessThan: + case SpvOp::SpvOpULessThan: return a < b; - case spv::Op::OpSLessThan: + case SpvOp::SpvOpSLessThan: return (static_cast(a)) < (static_cast(b)); - case spv::Op::OpUGreaterThan: + case SpvOp::SpvOpUGreaterThan: return a > b; - case spv::Op::OpSGreaterThan: + case SpvOp::SpvOpSGreaterThan: return (static_cast(a)) > (static_cast(b)); - case spv::Op::OpULessThanEqual: + case SpvOp::SpvOpULessThanEqual: return a <= b; - case spv::Op::OpSLessThanEqual: + case SpvOp::SpvOpSLessThanEqual: return (static_cast(a)) <= (static_cast(b)); - case spv::Op::OpUGreaterThanEqual: + case SpvOp::SpvOpUGreaterThanEqual: return a >= b; - case spv::Op::OpSGreaterThanEqual: + case SpvOp::SpvOpSGreaterThanEqual: return (static_cast(a)) >= (static_cast(b)); default: assert(false && @@ -201,10 +201,10 @@ uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a, } } -uint32_t InstructionFolder::TernaryOperate(spv::Op opcode, uint32_t a, - uint32_t b, uint32_t c) const { +uint32_t InstructionFolder::TernaryOperate(SpvOp opcode, uint32_t a, uint32_t b, + uint32_t c) const { switch (opcode) { - case spv::Op::OpSelect: + case SpvOp::SpvOpSelect: return (static_cast(a)) ? b : c; default: assert(false && @@ -214,7 +214,7 @@ uint32_t InstructionFolder::TernaryOperate(spv::Op opcode, uint32_t a, } uint32_t InstructionFolder::OperateWords( - spv::Op opcode, const std::vector& operand_words) const { + SpvOp opcode, const std::vector& operand_words) const { switch (operand_words.size()) { case 1: return UnaryOperate(opcode, operand_words.front()); @@ -233,7 +233,7 @@ bool InstructionFolder::FoldInstructionInternal(Instruction* inst) const { auto identity_map = [](uint32_t id) { return id; }; Instruction* folded_inst = FoldInstructionToConstant(inst, identity_map); if (folded_inst != nullptr) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {folded_inst->result_id()}}}); return true; } @@ -256,7 +256,7 @@ bool InstructionFolder::FoldInstructionInternal(Instruction* inst) const { // result in 32 bit word. Scalar constants with longer than 32-bit width are // not accepted in this function. uint32_t InstructionFolder::FoldScalars( - spv::Op opcode, + SpvOp opcode, const std::vector& operands) const { assert(IsFoldableOpcode(opcode) && "Unhandled instruction opcode in FoldScalars"); @@ -282,7 +282,7 @@ uint32_t InstructionFolder::FoldScalars( bool InstructionFolder::FoldBinaryIntegerOpToConstant( Instruction* inst, const std::function& id_map, uint32_t* result) const { - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); analysis::ConstantManager* const_manger = context_->get_constant_mgr(); uint32_t ids[2]; @@ -300,7 +300,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( switch (opcode) { // Arthimetics - case spv::Op::OpIMul: + case SpvOp::SpvOpIMul: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr && constants[i]->IsZero()) { *result = 0; @@ -308,11 +308,11 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( } } break; - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpUMod: + case SpvOp::SpvOpUDiv: + case SpvOp::SpvOpSDiv: + case SpvOp::SpvOpSRem: + case SpvOp::SpvOpSMod: + case SpvOp::SpvOpUMod: // This changes undefined behaviour (ie divide by 0) into a 0. for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr && constants[i]->IsZero()) { @@ -323,8 +323,8 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Shifting - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftLeftLogical: + case SpvOp::SpvOpShiftRightLogical: + case SpvOp::SpvOpShiftLeftLogical: if (constants[1] != nullptr) { // When shifting by a value larger than the size of the result, the // result is undefined. We are setting the undefined behaviour to a @@ -339,7 +339,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Bitwise operations - case spv::Op::OpBitwiseOr: + case SpvOp::SpvOpBitwiseOr: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { // TODO: Change the mask against a value based on the bit width of the @@ -353,7 +353,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( } } break; - case spv::Op::OpBitwiseAnd: + case SpvOp::SpvOpBitwiseAnd: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (constants[i]->IsZero()) { @@ -365,7 +365,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( break; // Comparison - case spv::Op::OpULessThan: + case SpvOp::SpvOpULessThan: if (constants[0] != nullptr && constants[0]->GetU32BitValue() == UINT32_MAX) { *result = false; @@ -376,7 +376,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpSLessThan: + case SpvOp::SpvOpSLessThan: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MAX) { *result = false; @@ -388,7 +388,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpUGreaterThan: + case SpvOp::SpvOpUGreaterThan: if (constants[0] != nullptr && constants[0]->IsZero()) { *result = false; return true; @@ -399,7 +399,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpSGreaterThan: + case SpvOp::SpvOpSGreaterThan: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MIN) { *result = false; @@ -411,7 +411,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpULessThanEqual: + case SpvOp::SpvOpULessThanEqual: if (constants[0] != nullptr && constants[0]->IsZero()) { *result = true; return true; @@ -422,7 +422,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpSLessThanEqual: + case SpvOp::SpvOpSLessThanEqual: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MIN) { *result = true; @@ -434,7 +434,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpUGreaterThanEqual: + case SpvOp::SpvOpUGreaterThanEqual: if (constants[0] != nullptr && constants[0]->GetU32BitValue() == UINT32_MAX) { *result = true; @@ -445,7 +445,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( return true; } break; - case spv::Op::OpSGreaterThanEqual: + case SpvOp::SpvOpSGreaterThanEqual: if (constants[0] != nullptr && constants[0]->GetS32BitValue() == INT32_MAX) { *result = true; @@ -466,7 +466,7 @@ bool InstructionFolder::FoldBinaryIntegerOpToConstant( bool InstructionFolder::FoldBinaryBooleanOpToConstant( Instruction* inst, const std::function& id_map, uint32_t* result) const { - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); analysis::ConstantManager* const_manger = context_->get_constant_mgr(); uint32_t ids[2]; @@ -484,7 +484,7 @@ bool InstructionFolder::FoldBinaryBooleanOpToConstant( switch (opcode) { // Logical - case spv::Op::OpLogicalOr: + case SpvOp::SpvOpLogicalOr: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (constants[i]->value()) { @@ -494,7 +494,7 @@ bool InstructionFolder::FoldBinaryBooleanOpToConstant( } } break; - case spv::Op::OpLogicalAnd: + case SpvOp::SpvOpLogicalAnd: for (uint32_t i = 0; i < 2; i++) { if (constants[i] != nullptr) { if (!constants[i]->value()) { @@ -526,7 +526,7 @@ bool InstructionFolder::FoldIntegerOpToConstant( } std::vector InstructionFolder::FoldVectors( - spv::Op opcode, uint32_t num_dims, + SpvOp opcode, uint32_t num_dims, const std::vector& operands) const { assert(IsFoldableOpcode(opcode) && "Unhandled instruction opcode in FoldVectors"); @@ -570,44 +570,44 @@ std::vector InstructionFolder::FoldVectors( return result; } -bool InstructionFolder::IsFoldableOpcode(spv::Op opcode) const { +bool InstructionFolder::IsFoldableOpcode(SpvOp opcode) const { // NOTE: Extend to more opcodes as new cases are handled in the folder // functions. switch (opcode) { - case spv::Op::OpBitwiseAnd: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpIAdd: - case spv::Op::OpIEqual: - case spv::Op::OpIMul: - case spv::Op::OpINotEqual: - case spv::Op::OpISub: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNot: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpNot: - case spv::Op::OpSDiv: - case spv::Op::OpSelect: - case spv::Op::OpSGreaterThan: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpSLessThan: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpSMod: - case spv::Op::OpSNegate: - case spv::Op::OpSRem: - case spv::Op::OpSConvert: - case spv::Op::OpUConvert: - case spv::Op::OpUDiv: - case spv::Op::OpUGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpUMod: + case SpvOp::SpvOpBitwiseAnd: + case SpvOp::SpvOpBitwiseOr: + case SpvOp::SpvOpBitwiseXor: + case SpvOp::SpvOpIAdd: + case SpvOp::SpvOpIEqual: + case SpvOp::SpvOpIMul: + case SpvOp::SpvOpINotEqual: + case SpvOp::SpvOpISub: + case SpvOp::SpvOpLogicalAnd: + case SpvOp::SpvOpLogicalEqual: + case SpvOp::SpvOpLogicalNot: + case SpvOp::SpvOpLogicalNotEqual: + case SpvOp::SpvOpLogicalOr: + case SpvOp::SpvOpNot: + case SpvOp::SpvOpSDiv: + case SpvOp::SpvOpSelect: + case SpvOp::SpvOpSGreaterThan: + case SpvOp::SpvOpSGreaterThanEqual: + case SpvOp::SpvOpShiftLeftLogical: + case SpvOp::SpvOpShiftRightArithmetic: + case SpvOp::SpvOpShiftRightLogical: + case SpvOp::SpvOpSLessThan: + case SpvOp::SpvOpSLessThanEqual: + case SpvOp::SpvOpSMod: + case SpvOp::SpvOpSNegate: + case SpvOp::SpvOpSRem: + case SpvOp::SpvOpSConvert: + case SpvOp::SpvOpUConvert: + case SpvOp::SpvOpUDiv: + case SpvOp::SpvOpUGreaterThan: + case SpvOp::SpvOpUGreaterThanEqual: + case SpvOp::SpvOpULessThan: + case SpvOp::SpvOpULessThanEqual: + case SpvOp::SpvOpUMod: return true; default: return false; @@ -627,8 +627,7 @@ Instruction* InstructionFolder::FoldInstructionToConstant( Instruction* inst, std::function id_map) const { analysis::ConstantManager* const_mgr = context_->get_constant_mgr(); - if (!inst->IsFoldableByFoldScalar() && !inst->IsFoldableByFoldVector() && - !GetConstantFoldingRules().HasFoldingRule(inst)) { + if (!inst->IsFoldableByFoldScalar() && !HasConstFoldingRule(inst)) { return nullptr; } // Collect the values of the constant parameters. @@ -662,87 +661,45 @@ Instruction* InstructionFolder::FoldInstructionToConstant( } } + uint32_t result_val = 0; bool successful = false; - // If all parameters are constant, fold the instruction to a constant. - if (inst->IsFoldableByFoldScalar()) { - uint32_t result_val = 0; - - if (!missing_constants) { - result_val = FoldScalars(inst->opcode(), constants); - successful = true; - } - - if (!successful) { - successful = FoldIntegerOpToConstant(inst, id_map, &result_val); - } - - if (successful) { - const analysis::Constant* result_const = - const_mgr->GetConstant(const_mgr->GetType(inst), {result_val}); - Instruction* folded_inst = - const_mgr->GetDefiningInstruction(result_const, inst->type_id()); - return folded_inst; - } - } else if (inst->IsFoldableByFoldVector()) { - std::vector result_val; - - if (!missing_constants) { - if (Instruction* inst_type = - context_->get_def_use_mgr()->GetDef(inst->type_id())) { - result_val = FoldVectors( - inst->opcode(), inst_type->GetSingleWordInOperand(1), constants); - successful = true; - } - } - - if (successful) { - const analysis::Constant* result_const = - const_mgr->GetNumericVectorConstantWithWords( - const_mgr->GetType(inst)->AsVector(), result_val); - Instruction* folded_inst = - const_mgr->GetDefiningInstruction(result_const, inst->type_id()); - return folded_inst; - } + if (!missing_constants && inst->IsFoldableByFoldScalar()) { + result_val = FoldScalars(inst->opcode(), constants); + successful = true; } + if (!successful && inst->IsFoldableByFoldScalar()) { + successful = FoldIntegerOpToConstant(inst, id_map, &result_val); + } + + if (successful) { + const analysis::Constant* result_const = + const_mgr->GetConstant(const_mgr->GetType(inst), {result_val}); + Instruction* folded_inst = + const_mgr->GetDefiningInstruction(result_const, inst->type_id()); + return folded_inst; + } return nullptr; } bool InstructionFolder::IsFoldableType(Instruction* type_inst) const { - return IsFoldableScalarType(type_inst) || IsFoldableVectorType(type_inst); -} - -bool InstructionFolder::IsFoldableScalarType(Instruction* type_inst) const { // Support 32-bit integers. - if (type_inst->opcode() == spv::Op::OpTypeInt) { + if (type_inst->opcode() == SpvOpTypeInt) { return type_inst->GetSingleWordInOperand(0) == 32; } // Support booleans. - if (type_inst->opcode() == spv::Op::OpTypeBool) { + if (type_inst->opcode() == SpvOpTypeBool) { return true; } // Nothing else yet. return false; } -bool InstructionFolder::IsFoldableVectorType(Instruction* type_inst) const { - // Support vectors with foldable components - if (type_inst->opcode() == spv::Op::OpTypeVector) { - uint32_t component_type_id = type_inst->GetSingleWordInOperand(0); - Instruction* def_component_type = - context_->get_def_use_mgr()->GetDef(component_type_id); - return def_component_type != nullptr && - IsFoldableScalarType(def_component_type); - } - // Nothing else yet. - return false; -} - bool InstructionFolder::FoldInstruction(Instruction* inst) const { bool modified = false; Instruction* folded_inst(inst); - while (folded_inst->opcode() != spv::Op::OpCopyObject && + while (folded_inst->opcode() != SpvOpCopyObject && FoldInstructionInternal(&*folded_inst)) { modified = true; } diff --git a/source/opt/fold.h b/source/opt/fold.h index 42da65e4..9e7c4705 100644 --- a/source/opt/fold.h +++ b/source/opt/fold.h @@ -55,7 +55,7 @@ class InstructionFolder { // IsFoldableOpcode test. If any error occurs during folding, the folder will // fail with a call to assert. uint32_t FoldScalars( - spv::Op opcode, + SpvOp opcode, const std::vector& operands) const; // Returns the result of performing an operation with the given |opcode| over @@ -72,12 +72,12 @@ class InstructionFolder { // IsFoldableOpcode test. If any error occurs during folding, the folder will // fail with a call to assert. std::vector FoldVectors( - spv::Op opcode, uint32_t num_dims, + SpvOp opcode, uint32_t num_dims, const std::vector& operands) const; // Returns true if |opcode| represents an operation handled by FoldScalars or // FoldVectors. - bool IsFoldableOpcode(spv::Op opcode) const; + bool IsFoldableOpcode(SpvOp opcode) const; // Returns true if |cst| is supported by FoldScalars and FoldVectors. bool IsFoldableConstant(const analysis::Constant* cst) const; @@ -86,14 +86,6 @@ class InstructionFolder { // result type is |type_inst|. bool IsFoldableType(Instruction* type_inst) const; - // Returns true if |FoldInstructionToConstant| could fold an instruction whose - // result type is |type_inst|. - bool IsFoldableScalarType(Instruction* type_inst) const; - - // Returns true if |FoldInstructionToConstant| could fold an instruction whose - // result type is |type_inst|. - bool IsFoldableVectorType(Instruction* type_inst) const; - // Tries to fold |inst| to a single constant, when the input ids to |inst| // have been substituted using |id_map|. Returns a pointer to the OpConstant* // instruction if successful. If necessary, a new constant instruction is @@ -134,22 +126,22 @@ class InstructionFolder { // Returns the single-word result from performing the given unary operation on // the operand value which is passed in as a 32-bit word. - uint32_t UnaryOperate(spv::Op opcode, uint32_t operand) const; + uint32_t UnaryOperate(SpvOp opcode, uint32_t operand) const; // Returns the single-word result from performing the given binary operation // on the operand values which are passed in as two 32-bit word. - uint32_t BinaryOperate(spv::Op opcode, uint32_t a, uint32_t b) const; + uint32_t BinaryOperate(SpvOp opcode, uint32_t a, uint32_t b) const; // Returns the single-word result from performing the given ternary operation // on the operand values which are passed in as three 32-bit word. - uint32_t TernaryOperate(spv::Op opcode, uint32_t a, uint32_t b, + uint32_t TernaryOperate(SpvOp opcode, uint32_t a, uint32_t b, uint32_t c) const; // Returns the single-word result from performing the given operation on the // operand words. This only works with 32-bit operations and uses boolean // convention that 0u is false, and anything else is boolean true. // TODO(qining): Support operands other than 32-bit wide. - uint32_t OperateWords(spv::Op opcode, + uint32_t OperateWords(SpvOp opcode, const std::vector& operand_words) const; bool FoldInstructionInternal(Instruction* inst) const; diff --git a/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/source/opt/fold_spec_constant_op_and_composite_pass.cpp index 770e1fe5..7a518701 100644 --- a/source/opt/fold_spec_constant_op_and_composite_pass.cpp +++ b/source/opt/fold_spec_constant_op_and_composite_pass.cpp @@ -15,9 +15,12 @@ #include "source/opt/fold_spec_constant_op_and_composite_pass.h" #include +#include #include #include "source/opt/constants.h" +#include "source/opt/fold.h" +#include "source/opt/ir_context.h" #include "source/util/make_unique.h" namespace spvtools { @@ -63,14 +66,14 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { if (const_mgr->GetType(inst) && !const_mgr->GetType(inst)->decoration_empty()) continue; - switch (spv::Op opcode = inst->opcode()) { + switch (SpvOp opcode = inst->opcode()) { // Records the values of Normal Constants. - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: - case spv::Op::OpConstant: - case spv::Op::OpConstantNull: - case spv::Op::OpConstantComposite: - case spv::Op::OpSpecConstantComposite: { + case SpvOp::SpvOpConstantTrue: + case SpvOp::SpvOpConstantFalse: + case SpvOp::SpvOpConstant: + case SpvOp::SpvOpConstantNull: + case SpvOp::SpvOpConstantComposite: + case SpvOp::SpvOpSpecConstantComposite: { // A Constant instance will be created if the given instruction is a // Normal Constant whose value(s) are fixed. Note that for a composite // Spec Constant defined with OpSpecConstantComposite instruction, if @@ -81,8 +84,8 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { if (auto const_value = const_mgr->GetConstantFromInst(inst)) { // Need to replace the OpSpecConstantComposite instruction with a // corresponding OpConstantComposite instruction. - if (opcode == spv::Op::OpSpecConstantComposite) { - inst->SetOpcode(spv::Op::OpConstantComposite); + if (opcode == SpvOp::SpvOpSpecConstantComposite) { + inst->SetOpcode(SpvOp::SpvOpConstantComposite); modified = true; } const_mgr->MapConstantToInst(const_value, inst); @@ -96,7 +99,7 @@ Pass::Status FoldSpecConstantOpAndCompositePass::Process() { // Constants will be added to id_to_const_val_ and const_val_to_id_ so // that we can use the new Normal Constants when folding following Spec // Constants. - case spv::Op::OpSpecConstantOp: + case SpvOp::SpvOpSpecConstantOp: modified |= ProcessOpSpecConstantOp(&inst_iter); break; default: @@ -115,11 +118,11 @@ bool FoldSpecConstantOpAndCompositePass::ProcessOpSpecConstantOp( "The first in-operand of OpSpecConstantOp instruction must be of " "SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER type"); - switch (static_cast(inst->GetSingleWordInOperand(0))) { - case spv::Op::OpCompositeExtract: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeInsert: - case spv::Op::OpQuantizeToF16: + switch (static_cast(inst->GetSingleWordInOperand(0))) { + case SpvOp::SpvOpCompositeExtract: + case SpvOp::SpvOpVectorShuffle: + case SpvOp::SpvOpCompositeInsert: + case SpvOp::SpvOpQuantizeToF16: folded_inst = FoldWithInstructionFolder(pos); break; default: @@ -162,7 +165,7 @@ Instruction* FoldSpecConstantOpAndCompositePass::FoldWithInstructionFolder( // instruction and pass it to the instruction folder. std::unique_ptr inst((*inst_iter_ptr)->Clone(context())); inst->SetOpcode( - static_cast((*inst_iter_ptr)->GetSingleWordInOperand(0))); + static_cast((*inst_iter_ptr)->GetSingleWordInOperand(0))); inst->RemoveOperand(2); // We want the current instruction to be replaced by an |OpConstant*| @@ -176,9 +179,8 @@ Instruction* FoldSpecConstantOpAndCompositePass::FoldWithInstructionFolder( Instruction* new_const_inst = context()->get_instruction_folder().FoldInstructionToConstant( inst.get(), identity_map); - - // new_const_inst == null indicates we cannot fold this spec constant - if (!new_const_inst) return nullptr; + assert(new_const_inst != nullptr && + "Failed to fold instruction that must be folded."); // Get the instruction before |pos| to insert after. |pos| cannot be the // first instruction in the list because its type has to come first. @@ -287,7 +289,7 @@ Instruction* FoldSpecConstantOpAndCompositePass::DoComponentWiseOperation( const Instruction* inst = &**pos; analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); const analysis::Type* result_type = const_mgr->GetType(inst); - spv::Op spec_opcode = static_cast(inst->GetSingleWordInOperand(0)); + SpvOp spec_opcode = static_cast(inst->GetSingleWordInOperand(0)); // Check and collect operands. std::vector operands; diff --git a/source/opt/folding_rules.cpp b/source/opt/folding_rules.cpp index 5c68e291..3d803add 100644 --- a/source/opt/folding_rules.cpp +++ b/source/opt/folding_rules.cpp @@ -14,6 +14,7 @@ #include "source/opt/folding_rules.h" +#include #include #include #include @@ -26,15 +27,15 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kExtractCompositeIdInIdx = 0; -constexpr uint32_t kInsertObjectIdInIdx = 0; -constexpr uint32_t kInsertCompositeIdInIdx = 1; -constexpr uint32_t kExtInstSetIdInIdx = 0; -constexpr uint32_t kExtInstInstructionInIdx = 1; -constexpr uint32_t kFMixXIdInIdx = 2; -constexpr uint32_t kFMixYIdInIdx = 3; -constexpr uint32_t kFMixAIdInIdx = 4; -constexpr uint32_t kStoreObjectInIdx = 1; +const uint32_t kExtractCompositeIdInIdx = 0; +const uint32_t kInsertObjectIdInIdx = 0; +const uint32_t kInsertCompositeIdInIdx = 1; +const uint32_t kExtInstSetIdInIdx = 0; +const uint32_t kExtInstInstructionInIdx = 1; +const uint32_t kFMixXIdInIdx = 2; +const uint32_t kFMixYIdInIdx = 3; +const uint32_t kFMixAIdInIdx = 4; +const uint32_t kStoreObjectInIdx = 1; // Some image instructions may contain an "image operands" argument. // Returns the operand index for the "image operands". @@ -42,33 +43,33 @@ constexpr uint32_t kStoreObjectInIdx = 1; int32_t ImageOperandsMaskInOperandIndex(Instruction* inst) { const auto opcode = inst->opcode(); switch (opcode) { - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageFetch: - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseRead: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageFetch: + case SpvOpImageRead: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseRead: return inst->NumOperands() > 4 ? 2 : -1; - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: return inst->NumOperands() > 5 ? 3 : -1; - case spv::Op::OpImageWrite: + case SpvOpImageWrite: return inst->NumOperands() > 3 ? 3 : -1; default: return -1; @@ -303,7 +304,7 @@ uint32_t Reciprocal(analysis::ConstantManager* const_mgr, FoldingRule ReciprocalFDiv() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFDiv); + assert(inst->opcode() == SpvOpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -332,7 +333,7 @@ FoldingRule ReciprocalFDiv() { // Don't fold a null constant. return false; } - inst->SetOpcode(spv::Op::OpFMul); + inst->SetOpcode(SpvOpFMul); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0u)}}, {SPV_OPERAND_TYPE_ID, {id}}}); @@ -347,8 +348,7 @@ FoldingRule ReciprocalFDiv() { FoldingRule MergeNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFNegate || - inst->opcode() == spv::Op::OpSNegate); + assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); (void)constants; const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -362,7 +362,7 @@ FoldingRule MergeNegateArithmetic() { if (op_inst->opcode() == inst->opcode()) { // Elide negates. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0u)}}}); return true; @@ -382,8 +382,7 @@ FoldingRule MergeNegateArithmetic() { FoldingRule MergeNegateMulDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFNegate || - inst->opcode() == spv::Op::OpSNegate); + assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); (void)constants; analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = @@ -399,10 +398,9 @@ FoldingRule MergeNegateMulDivArithmetic() { uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; - spv::Op opcode = op_inst->opcode(); - if (opcode == spv::Op::OpFMul || opcode == spv::Op::OpFDiv || - opcode == spv::Op::OpIMul || opcode == spv::Op::OpSDiv || - opcode == spv::Op::OpUDiv) { + SpvOp opcode = op_inst->opcode(); + if (opcode == SpvOpFMul || opcode == SpvOpFDiv || opcode == SpvOpIMul || + opcode == SpvOpSDiv || opcode == SpvOpUDiv) { std::vector op_constants = const_mgr->GetOperandConstants(op_inst); // Merge negate into mul or div if one operand is constant. @@ -415,8 +413,7 @@ FoldingRule MergeNegateMulDivArithmetic() { : op_inst->GetSingleWordInOperand(1u); // Change this instruction to a mul/div. inst->SetOpcode(op_inst->opcode()); - if (opcode == spv::Op::OpFDiv || opcode == spv::Op::OpUDiv || - opcode == spv::Op::OpSDiv) { + if (opcode == SpvOpFDiv || opcode == SpvOpUDiv || opcode == SpvOpSDiv) { uint32_t op0 = zero_is_variable ? non_const_id : neg_id; uint32_t op1 = zero_is_variable ? neg_id : non_const_id; inst->SetInOperands( @@ -443,8 +440,7 @@ FoldingRule MergeNegateMulDivArithmetic() { FoldingRule MergeNegateAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFNegate || - inst->opcode() == spv::Op::OpSNegate); + assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate); (void)constants; analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = @@ -460,16 +456,14 @@ FoldingRule MergeNegateAddSubArithmetic() { uint32_t width = ElementWidth(type); if (width != 32 && width != 64) return false; - if (op_inst->opcode() == spv::Op::OpFAdd || - op_inst->opcode() == spv::Op::OpFSub || - op_inst->opcode() == spv::Op::OpIAdd || - op_inst->opcode() == spv::Op::OpISub) { + if (op_inst->opcode() == SpvOpFAdd || op_inst->opcode() == SpvOpFSub || + op_inst->opcode() == SpvOpIAdd || op_inst->opcode() == SpvOpISub) { std::vector op_constants = const_mgr->GetOperandConstants(op_inst); if (op_constants[0] || op_constants[1]) { bool zero_is_variable = op_constants[0] == nullptr; - bool is_add = (op_inst->opcode() == spv::Op::OpFAdd) || - (op_inst->opcode() == spv::Op::OpIAdd); + bool is_add = (op_inst->opcode() == SpvOpFAdd) || + (op_inst->opcode() == SpvOpIAdd); bool swap_operands = !is_add || zero_is_variable; bool negate_const = is_add; const analysis::Constant* c = ConstInput(op_constants); @@ -487,8 +481,7 @@ FoldingRule MergeNegateAddSubArithmetic() { uint32_t op1 = zero_is_variable ? const_id : op_inst->GetSingleWordInOperand(1u); if (swap_operands) std::swap(op0, op1); - inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub - : spv::Op::OpISub); + inst->SetOpcode(HasFloatingPoint(type) ? SpvOpFSub : SpvOpISub); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op0}}, {SPV_OPERAND_TYPE_ID, {op1}}}); return true; @@ -519,7 +512,7 @@ bool HasZero(const analysis::Constant* c) { // id. Returns 0 if the result is not a valid value. The input types must be // Float. uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, - spv::Op opcode, + SpvOp opcode, const analysis::Constant* input1, const analysis::Constant* input2) { const analysis::Type* type = input1->type(); @@ -542,17 +535,17 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, } \ static_assert(true, "require extra semicolon") switch (opcode) { - case spv::Op::OpFMul: + case SpvOpFMul: FOLD_OP(*); break; - case spv::Op::OpFDiv: + case SpvOpFDiv: if (HasZero(input2)) return 0; FOLD_OP(/); break; - case spv::Op::OpFAdd: + case SpvOpFAdd: FOLD_OP(+); break; - case spv::Op::OpFSub: + case SpvOpFSub: FOLD_OP(-); break; default: @@ -568,8 +561,7 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr, // id. Returns 0 if the result is not a valid value. The input types must be // Integers. uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, - spv::Op opcode, - const analysis::Constant* input1, + SpvOp opcode, const analysis::Constant* input1, const analysis::Constant* input2) { assert(input1->type()->AsInteger()); const analysis::Integer* type = input1->type()->AsInteger(); @@ -590,17 +582,17 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, } \ static_assert(true, "require extra semicolon") switch (opcode) { - case spv::Op::OpIMul: + case SpvOpIMul: FOLD_OP(*); break; - case spv::Op::OpSDiv: - case spv::Op::OpUDiv: + case SpvOpSDiv: + case SpvOpUDiv: assert(false && "Should not merge integer division"); break; - case spv::Op::OpIAdd: + case SpvOpIAdd: FOLD_OP(+); break; - case spv::Op::OpISub: + case SpvOpISub: FOLD_OP(-); break; default: @@ -615,7 +607,7 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr, // Performs |input1| |opcode| |input2| and returns the merged constant result // id. Returns 0 if the result is not a valid value. The input types must be // Integers, Floats or Vectors of such. -uint32_t PerformOperation(analysis::ConstantManager* const_mgr, spv::Op opcode, +uint32_t PerformOperation(analysis::ConstantManager* const_mgr, SpvOp opcode, const analysis::Constant* input1, const analysis::Constant* input2) { assert(input1 && input2); @@ -675,8 +667,7 @@ uint32_t PerformOperation(analysis::ConstantManager* const_mgr, spv::Op opcode, FoldingRule MergeMulMulArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFMul || - inst->opcode() == spv::Op::OpIMul); + assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -728,7 +719,7 @@ FoldingRule MergeMulMulArithmetic() { FoldingRule MergeMulDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFMul); + assert(inst->opcode() == SpvOpFMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -742,10 +733,10 @@ FoldingRule MergeMulDivArithmetic() { for (uint32_t i = 0; i < 2; i++) { uint32_t op_id = inst->GetSingleWordInOperand(i); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() == spv::Op::OpFDiv) { + if (op_inst->opcode() == SpvOpFDiv) { if (op_inst->GetSingleWordInOperand(1) == inst->GetSingleWordInOperand(1 - i)) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(0)}}}); return true; @@ -758,7 +749,7 @@ FoldingRule MergeMulDivArithmetic() { Instruction* other_inst = NonConstInput(context, constants[0], inst); if (!other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFDiv) { + if (other_inst->opcode() == SpvOpFDiv) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -802,8 +793,7 @@ FoldingRule MergeMulDivArithmetic() { FoldingRule MergeMulNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFMul || - inst->opcode() == spv::Op::OpIMul); + assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -819,8 +809,8 @@ FoldingRule MergeMulNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFNegate || - other_inst->opcode() == spv::Op::OpSNegate) { + if (other_inst->opcode() == SpvOpFNegate || + other_inst->opcode() == SpvOpSNegate) { uint32_t neg_id = NegateConstant(const_mgr, const_input1); inst->SetInOperands( @@ -843,7 +833,7 @@ FoldingRule MergeMulNegateArithmetic() { FoldingRule MergeDivDivArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFDiv); + assert(inst->opcode() == SpvOpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -866,10 +856,10 @@ FoldingRule MergeDivDivArithmetic() { bool other_first_is_variable = other_constants[0] == nullptr; - spv::Op merge_op = inst->opcode(); + SpvOp merge_op = inst->opcode(); if (other_first_is_variable) { // Constants magnify. - merge_op = spv::Op::OpFMul; + merge_op = SpvOpFMul; } // This is an x / (*) case. Swap the inputs. Doesn't harm multiply @@ -883,10 +873,10 @@ FoldingRule MergeDivDivArithmetic() { ? other_inst->GetSingleWordInOperand(0u) : other_inst->GetSingleWordInOperand(1u); - spv::Op op = inst->opcode(); + SpvOp op = inst->opcode(); if (!first_is_variable && !other_first_is_variable) { // Effectively div of 1/x, so change to multiply. - op = spv::Op::OpFMul; + op = SpvOpFMul; } uint32_t op1 = merged_id; @@ -914,7 +904,7 @@ FoldingRule MergeDivDivArithmetic() { FoldingRule MergeDivMulArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFDiv); + assert(inst->opcode() == SpvOpFDiv); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -928,11 +918,11 @@ FoldingRule MergeDivMulArithmetic() { uint32_t op_id = inst->GetSingleWordInOperand(0); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() == spv::Op::OpFMul) { + if (op_inst->opcode() == SpvOpFMul) { for (uint32_t i = 0; i < 2; i++) { if (op_inst->GetSingleWordInOperand(i) == inst->GetSingleWordInOperand(1)) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {op_inst->GetSingleWordInOperand(1 - i)}}}); return true; @@ -946,7 +936,7 @@ FoldingRule MergeDivMulArithmetic() { if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; - if (other_inst->opcode() == spv::Op::OpFMul) { + if (other_inst->opcode() == SpvOpFMul) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -986,7 +976,7 @@ FoldingRule MergeDivMulArithmetic() { FoldingRule MergeDivNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFDiv); + assert(inst->opcode() == SpvOpFDiv); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); if (!inst->IsFloatingPointFoldingAllowed()) return false; @@ -996,7 +986,7 @@ FoldingRule MergeDivNegateArithmetic() { if (!other_inst->IsFloatingPointFoldingAllowed()) return false; bool first_is_variable = constants[0] == nullptr; - if (other_inst->opcode() == spv::Op::OpFNegate) { + if (other_inst->opcode() == SpvOpFNegate) { uint32_t neg_id = NegateConstant(const_mgr, const_input1); if (first_is_variable) { @@ -1022,8 +1012,7 @@ FoldingRule MergeDivNegateArithmetic() { FoldingRule MergeAddNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFAdd || - inst->opcode() == spv::Op::OpIAdd); + assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1035,10 +1024,9 @@ FoldingRule MergeAddNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpSNegate || - other_inst->opcode() == spv::Op::OpFNegate) { - inst->SetOpcode(HasFloatingPoint(type) ? spv::Op::OpFSub - : spv::Op::OpISub); + if (other_inst->opcode() == SpvOpSNegate || + other_inst->opcode() == SpvOpFNegate) { + inst->SetOpcode(HasFloatingPoint(type) ? SpvOpFSub : SpvOpISub); uint32_t const_id = constants[0] ? inst->GetSingleWordInOperand(0u) : inst->GetSingleWordInOperand(1u); inst->SetInOperands( @@ -1057,8 +1045,7 @@ FoldingRule MergeAddNegateArithmetic() { FoldingRule MergeSubNegateArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFSub || - inst->opcode() == spv::Op::OpISub); + assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); @@ -1074,15 +1061,15 @@ FoldingRule MergeSubNegateArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpSNegate || - other_inst->opcode() == spv::Op::OpFNegate) { + if (other_inst->opcode() == SpvOpSNegate || + other_inst->opcode() == SpvOpFNegate) { uint32_t op1 = 0; uint32_t op2 = 0; - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); if (constants[0] != nullptr) { op1 = other_inst->GetSingleWordInOperand(0u); op2 = inst->GetSingleWordInOperand(0u); - opcode = HasFloatingPoint(type) ? spv::Op::OpFAdd : spv::Op::OpIAdd; + opcode = HasFloatingPoint(type) ? SpvOpFAdd : SpvOpIAdd; } else { op1 = NegateConstant(const_mgr, const_input1); op2 = other_inst->GetSingleWordInOperand(0u); @@ -1106,8 +1093,7 @@ FoldingRule MergeSubNegateArithmetic() { FoldingRule MergeAddAddArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFAdd || - inst->opcode() == spv::Op::OpIAdd); + assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1123,8 +1109,8 @@ FoldingRule MergeAddAddArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFAdd || - other_inst->opcode() == spv::Op::OpIAdd) { + if (other_inst->opcode() == SpvOpFAdd || + other_inst->opcode() == SpvOpIAdd) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1154,8 +1140,7 @@ FoldingRule MergeAddAddArithmetic() { FoldingRule MergeAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFAdd || - inst->opcode() == spv::Op::OpIAdd); + assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1171,15 +1156,15 @@ FoldingRule MergeAddSubArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFSub || - other_inst->opcode() == spv::Op::OpISub) { + if (other_inst->opcode() == SpvOpFSub || + other_inst->opcode() == SpvOpISub) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); if (!const_input2) return false; bool first_is_variable = other_constants[0] == nullptr; - spv::Op op = inst->opcode(); + SpvOp op = inst->opcode(); uint32_t op1 = 0; uint32_t op2 = 0; if (first_is_variable) { @@ -1214,8 +1199,7 @@ FoldingRule MergeAddSubArithmetic() { FoldingRule MergeSubAddArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFSub || - inst->opcode() == spv::Op::OpISub); + assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1231,8 +1215,8 @@ FoldingRule MergeSubAddArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFAdd || - other_inst->opcode() == spv::Op::OpIAdd) { + if (other_inst->opcode() == SpvOpFAdd || + other_inst->opcode() == SpvOpIAdd) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1247,7 +1231,7 @@ FoldingRule MergeSubAddArithmetic() { // Subtract the constants. uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(), const_input1, const_input2); - spv::Op op = inst->opcode(); + SpvOp op = inst->opcode(); uint32_t op1 = 0; uint32_t op2 = 0; if (constants[0] == nullptr) { @@ -1280,8 +1264,7 @@ FoldingRule MergeSubAddArithmetic() { FoldingRule MergeSubSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFSub || - inst->opcode() == spv::Op::OpISub); + assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -1297,8 +1280,8 @@ FoldingRule MergeSubSubArithmetic() { if (uses_float && !other_inst->IsFloatingPointFoldingAllowed()) return false; - if (other_inst->opcode() == spv::Op::OpFSub || - other_inst->opcode() == spv::Op::OpISub) { + if (other_inst->opcode() == SpvOpFSub || + other_inst->opcode() == SpvOpISub) { std::vector other_constants = const_mgr->GetOperandConstants(other_inst); const analysis::Constant* const_input2 = ConstInput(other_constants); @@ -1309,9 +1292,9 @@ FoldingRule MergeSubSubArithmetic() { // Merge the constants. uint32_t merged_id = 0; - spv::Op merge_op = inst->opcode(); + SpvOp merge_op = inst->opcode(); if (other_constants[0] == nullptr) { - merge_op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; + merge_op = uses_float ? SpvOpFAdd : SpvOpIAdd; } else if (constants[0] == nullptr) { std::swap(const_input1, const_input2); } @@ -1319,10 +1302,10 @@ FoldingRule MergeSubSubArithmetic() { PerformOperation(const_mgr, merge_op, const_input1, const_input2); if (merged_id == 0) return false; - spv::Op op = inst->opcode(); + SpvOp op = inst->opcode(); if (constants[0] != nullptr && other_constants[0] != nullptr) { // Change the operation. - op = uses_float ? spv::Op::OpFAdd : spv::Op::OpIAdd; + op = uses_float ? SpvOpFAdd : SpvOpIAdd; } uint32_t op1 = 0; @@ -1350,14 +1333,13 @@ bool MergeGenericAddendSub(uint32_t addend, uint32_t sub, Instruction* inst) { IRContext* context = inst->context(); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); Instruction* sub_inst = def_use_mgr->GetDef(sub); - if (sub_inst->opcode() != spv::Op::OpFSub && - sub_inst->opcode() != spv::Op::OpISub) + if (sub_inst->opcode() != SpvOpFSub && sub_inst->opcode() != SpvOpISub) return false; - if (sub_inst->opcode() == spv::Op::OpFSub && + if (sub_inst->opcode() == SpvOpFSub && !sub_inst->IsFloatingPointFoldingAllowed()) return false; if (addend != sub_inst->GetSingleWordInOperand(1)) return false; - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {sub_inst->GetSingleWordInOperand(0)}}}); context->UpdateDefUse(inst); @@ -1373,8 +1355,7 @@ bool MergeGenericAddendSub(uint32_t addend, uint32_t sub, Instruction* inst) { FoldingRule MergeGenericAddSubArithmetic() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpFAdd || - inst->opcode() == spv::Op::OpIAdd); + assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1402,8 +1383,7 @@ bool FactorAddMulsOpnds(uint32_t factor0_0, uint32_t factor0_1, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); Instruction* new_add_inst = ir_builder.AddBinaryOp( inst->type_id(), inst->opcode(), factor0_1, factor1_1); - inst->SetOpcode(inst->opcode() == spv::Op::OpFAdd ? spv::Op::OpFMul - : spv::Op::OpIMul); + inst->SetOpcode(inst->opcode() == SpvOpFAdd ? SpvOpFMul : SpvOpIMul); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {factor0_0}}, {SPV_OPERAND_TYPE_ID, {new_add_inst->result_id()}}}); context->UpdateDefUse(inst); @@ -1415,8 +1395,7 @@ bool FactorAddMulsOpnds(uint32_t factor0_0, uint32_t factor0_1, FoldingRule FactorAddMuls() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpFAdd || - inst->opcode() == spv::Op::OpIAdd); + assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd); const analysis::Type* type = context->get_type_mgr()->GetType(inst->type_id()); bool uses_float = HasFloatingPoint(type); @@ -1425,13 +1404,13 @@ FoldingRule FactorAddMuls() { analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t add_op0 = inst->GetSingleWordInOperand(0); Instruction* add_op0_inst = def_use_mgr->GetDef(add_op0); - if (add_op0_inst->opcode() != spv::Op::OpFMul && - add_op0_inst->opcode() != spv::Op::OpIMul) + if (add_op0_inst->opcode() != SpvOpFMul && + add_op0_inst->opcode() != SpvOpIMul) return false; uint32_t add_op1 = inst->GetSingleWordInOperand(1); Instruction* add_op1_inst = def_use_mgr->GetDef(add_op1); - if (add_op1_inst->opcode() != spv::Op::OpFMul && - add_op1_inst->opcode() != spv::Op::OpIMul) + if (add_op1_inst->opcode() != SpvOpFMul && + add_op1_inst->opcode() != SpvOpIMul) return false; // Only perform this optimization if both of the muls only have one use. @@ -1439,7 +1418,7 @@ FoldingRule FactorAddMuls() { if (def_use_mgr->NumUses(add_op0_inst) > 1) return false; if (def_use_mgr->NumUses(add_op1_inst) > 1) return false; - if (add_op0_inst->opcode() == spv::Op::OpFMul && + if (add_op0_inst->opcode() == SpvOpFMul && (!add_op0_inst->IsFloatingPointFoldingAllowed() || !add_op1_inst->IsFloatingPointFoldingAllowed())) return false; @@ -1478,7 +1457,7 @@ void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); operands.push_back({SPV_OPERAND_TYPE_ID, {a}}); - inst->SetOpcode(spv::Op::OpExtInst); + inst->SetOpcode(SpvOpExtInst); inst->SetInOperands(std::move(operands)); } @@ -1489,7 +1468,7 @@ void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { // a + (x * y) = Fma x y a bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpFAdd); + assert(inst->opcode() == SpvOpFAdd); if (!inst->IsFloatingPointFoldingAllowed()) { return false; @@ -1500,7 +1479,7 @@ bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, uint32_t op_id = inst->GetSingleWordInOperand(i); Instruction* op_inst = def_use_mgr->GetDef(op_id); - if (op_inst->opcode() != spv::Op::OpFMul) { + if (op_inst->opcode() != SpvOpFMul) { continue; } @@ -1535,7 +1514,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, sub->context(), sub, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), spv::Op::OpFNegate, + Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), SpvOpFNegate, negate_addition ? a : x); uint32_t neg_op = neg->result_id(); // -a : -x @@ -1546,7 +1525,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? neg_op : a}}); - sub->SetOpcode(spv::Op::OpExtInst); + sub->SetOpcode(SpvOpExtInst); sub->SetInOperands(std::move(operands)); } @@ -1557,7 +1536,7 @@ void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, // a - (x * y) = Fma -x y a bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, const std::vector&) { - assert(sub->opcode() == spv::Op::OpFSub); + assert(sub->opcode() == SpvOpFSub); if (!sub->IsFloatingPointFoldingAllowed()) { return false; @@ -1568,7 +1547,7 @@ bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, uint32_t op_id = sub->GetSingleWordInOperand(i); Instruction* mul = def_use_mgr->GetDef(op_id); - if (mul->opcode() != spv::Op::OpFMul) { + if (mul->opcode() != SpvOpFMul) { continue; } @@ -1588,8 +1567,7 @@ bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, FoldingRule IntMultipleBy1() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpIMul && - "Wrong opcode. Should be OpIMul."); + assert(inst->opcode() == SpvOpIMul && "Wrong opcode. Should be OpIMul."); for (uint32_t i = 0; i < 2; i++) { if (constants[i] == nullptr) { continue; @@ -1601,7 +1579,7 @@ FoldingRule IntMultipleBy1() { bool is_one = (width == 32) ? int_constant->GetU32BitValue() == 1u : int_constant->GetU64BitValue() == 1ull; if (is_one) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1 - i)}}}); return true; @@ -1618,7 +1596,7 @@ FoldingRule IntMultipleBy1() { uint32_t GetNumOfElementsContributedByOperand(IRContext* context, const Instruction* inst, uint32_t index) { - assert(inst->opcode() == spv::Op::OpCompositeConstruct); + assert(inst->opcode() == SpvOpCompositeConstruct); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); @@ -1649,17 +1627,14 @@ uint32_t GetNumOfElementsContributedByOperand(IRContext* context, // out-of-bounds. |inst| must be an |OpCompositeConstruct| instruction. std::vector GetExtractOperandsForElementOfCompositeConstruct( IRContext* context, const Instruction* inst, uint32_t result_index) { - assert(inst->opcode() == spv::Op::OpCompositeConstruct); + assert(inst->opcode() == SpvOpCompositeConstruct); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); analysis::Type* result_type = type_mgr->GetType(inst->type_id()); if (result_type->AsVector() == nullptr) { - if (result_index < inst->NumInOperands()) { - uint32_t id = inst->GetSingleWordInOperand(result_index); - return {Operand(SPV_OPERAND_TYPE_ID, {id})}; - } - return {}; + uint32_t id = inst->GetSingleWordInOperand(result_index); + return {Operand(SPV_OPERAND_TYPE_ID, {id})}; } // If the result type is a vector, then vector operands are concatenated. @@ -1691,7 +1666,7 @@ bool CompositeConstructFeedingExtract( const std::vector&) { // If the input to an OpCompositeExtract is an OpCompositeConstruct, // then we can simply use the appropriate element in the construction. - assert(inst->opcode() == spv::Op::OpCompositeExtract && + assert(inst->opcode() == SpvOpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -1703,7 +1678,7 @@ bool CompositeConstructFeedingExtract( uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != spv::Op::OpCompositeConstruct) { + if (cinst->opcode() != SpvOpCompositeConstruct) { return false; } @@ -1725,7 +1700,7 @@ bool CompositeConstructFeedingExtract( if (operands.size() == 1) { // If there were no extra indices, then we have the final object. No need // to extract any more. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); } inst->SetInOperands(std::move(operands)); @@ -1763,8 +1738,8 @@ const analysis::Type* GetElementType(uint32_t type_id, bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { assert(inst_1->opcode() == inst_2->opcode() && "Expecting the opcodes to be the same."); - assert((inst_1->opcode() == spv::Op::OpCompositeInsert || - inst_1->opcode() == spv::Op::OpCompositeExtract) && + assert((inst_1->opcode() == SpvOpCompositeInsert || + inst_1->opcode() == SpvOpCompositeExtract) && "Instructions must be OpCompositeInsert or OpCompositeExtract."); if (inst_1->NumInOperands() != inst_2->NumInOperands()) { @@ -1772,7 +1747,7 @@ bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { } uint32_t first_index_position = - (inst_1->opcode() == spv::Op::OpCompositeInsert ? 2 : 1); + (inst_1->opcode() == SpvOpCompositeInsert ? 2 : 1); for (uint32_t i = first_index_position; i < inst_1->NumInOperands() - 1; i++) { if (inst_1->GetSingleWordInOperand(i) != @@ -1791,7 +1766,7 @@ bool HaveSameIndexesExceptForLast(Instruction* inst_1, Instruction* inst_2) { bool CompositeExtractFeedingConstruct( IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpCompositeConstruct && + assert(inst->opcode() == SpvOpCompositeConstruct && "Wrong opcode. Should be OpCompositeConstruct."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t original_id = 0; @@ -1813,7 +1788,7 @@ bool CompositeExtractFeedingConstruct( first_element_inst = element_inst; } - if (element_inst->opcode() != spv::Op::OpCompositeExtract) { + if (element_inst->opcode() != SpvOpCompositeExtract) { return false; } @@ -1853,14 +1828,14 @@ bool CompositeExtractFeedingConstruct( if (first_element_inst->NumInOperands() == 2) { // Simplify by using the original object. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {original_id}}}); return true; } // Copies the original id and all indexes except for the last to the new // extract instruction. - inst->SetOpcode(spv::Op::OpCompositeExtract); + inst->SetOpcode(SpvOpCompositeExtract); inst->SetInOperands(std::vector(first_element_inst->begin() + 2, first_element_inst->end() - 1)); return true; @@ -1869,13 +1844,13 @@ bool CompositeExtractFeedingConstruct( FoldingRule InsertFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpCompositeExtract && + assert(inst->opcode() == SpvOpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != spv::Op::OpCompositeInsert) { + if (cinst->opcode() != SpvOpCompositeInsert) { return false; } @@ -1895,7 +1870,7 @@ FoldingRule InsertFeedingExtract() { // We are extracting the element that was inserted. if (i == inst->NumInOperands() && i + 1 == cinst->NumInOperands()) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}}}); @@ -1944,14 +1919,14 @@ FoldingRule InsertFeedingExtract() { FoldingRule VectorShuffleFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpCompositeExtract && + assert(inst->opcode() == SpvOpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::TypeManager* type_mgr = context->get_type_mgr(); uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* cinst = def_use_mgr->GetDef(cid); - if (cinst->opcode() != spv::Op::OpVectorShuffle) { + if (cinst->opcode() != SpvOpVectorShuffle) { return false; } @@ -1972,7 +1947,7 @@ FoldingRule VectorShuffleFeedingExtract() { // Extracting an undefined value so fold this extract into an undef. const uint32_t undef_literal_value = 0xffffffff; if (new_index == undef_literal_value) { - inst->SetOpcode(spv::Op::OpUndef); + inst->SetOpcode(SpvOpUndef); inst->SetInOperands({}); return true; } @@ -2000,7 +1975,7 @@ FoldingRule VectorShuffleFeedingExtract() { FoldingRule FMixFeedingExtract() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpCompositeExtract && + assert(inst->opcode() == SpvOpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -2009,7 +1984,7 @@ FoldingRule FMixFeedingExtract() { inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* composite_inst = def_use_mgr->GetDef(composite_id); - if (composite_inst->opcode() != spv::Op::OpExtInst) { + if (composite_inst->opcode() != SpvOpExtInst) { return false; } @@ -2029,7 +2004,7 @@ FoldingRule FMixFeedingExtract() { a->SetInOperand(kExtractCompositeIdInIdx, {a_id}); context->get_instruction_folder().FoldInstruction(a.get()); - if (a->opcode() != spv::Op::OpCopyObject) { + if (a->opcode() != SpvOpCopyObject) { return false; } @@ -2067,8 +2042,7 @@ FoldingRule FMixFeedingExtract() { } // Returns the number of elements in the composite type |type|. Returns 0 if -// |type| is a scalar value. Return UINT32_MAX when the size is unknown at -// compile time. +// |type| is a scalar value. uint32_t GetNumberOfElements(const analysis::Type* type) { if (auto* vector_type = type->AsVector()) { return vector_type->element_count(); @@ -2080,27 +2054,21 @@ uint32_t GetNumberOfElements(const analysis::Type* type) { return static_cast(struct_type->element_types().size()); } if (auto* array_type = type->AsArray()) { - if (array_type->length_info().words[0] == - analysis::Array::LengthInfo::kConstant && - array_type->length_info().words.size() == 2) { - return array_type->length_info().words[1]; - } - return UINT32_MAX; + return array_type->length_info().words[0]; } return 0; } // Returns a map with the set of values that were inserted into an object by // the chain of OpCompositeInsertInstruction starting with |inst|. -// The map will map the index to the value inserted at that index. An empty map -// will be returned if the map could not be properly generated. +// The map will map the index to the value inserted at that index. std::map GetInsertedValues(Instruction* inst) { analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr(); std::map values_inserted; Instruction* current_inst = inst; - while (current_inst->opcode() == spv::Op::OpCompositeInsert) { + while (current_inst->opcode() == SpvOpCompositeInsert) { if (current_inst->NumInOperands() > inst->NumInOperands()) { - // This is to catch the case + // This is the catch the case // %2 = OpCompositeInsert %m2x2int %v2int_1_0 %m2x2int_undef 0 // %3 = OpCompositeInsert %m2x2int %int_4 %2 0 0 // %4 = OpCompositeInsert %m2x2int %v2int_2_3 %3 1 @@ -2140,7 +2108,7 @@ bool DoInsertedValuesCoverEntireObject( // Returns the type of the element that immediately contains the element being // inserted by the OpCompositeInsert instruction |inst|. const analysis::Type* GetContainerType(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCompositeInsert); + assert(inst->opcode() == SpvOpCompositeInsert); analysis::TypeManager* type_mgr = inst->context()->get_type_mgr(); return GetElementType(inst->type_id(), inst->begin() + 4, inst->end() - 1, type_mgr); @@ -2172,7 +2140,7 @@ Instruction* BuildCompositeConstruct( // instruction is replaced with an OpCopyObject instead. void InsertConstructedObject(Instruction* inst, const Instruction* construct) { if (inst->NumInOperands() == 3) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {construct->result_id()}}}); } else { inst->SetInOperand(kInsertObjectIdInIdx, {construct->result_id()}); @@ -2185,7 +2153,7 @@ void InsertConstructedObject(Instruction* inst, const Instruction* construct) { bool CompositeInsertToCompositeConstruct( IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpCompositeInsert && + assert(inst->opcode() == SpvOpCompositeInsert && "Wrong opcode. Should be OpCompositeInsert."); if (inst->NumInOperands() < 3) return false; @@ -2211,8 +2179,7 @@ FoldingRule RedundantPhi() { // itself, can be replaced by the value itself. return [](IRContext*, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpPhi && - "Wrong opcode. Should be OpPhi."); + assert(inst->opcode() == SpvOpPhi && "Wrong opcode. Should be OpPhi."); uint32_t incoming_value = 0; @@ -2236,7 +2203,7 @@ FoldingRule RedundantPhi() { } // We have a single incoming value. Simplify using that value. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {incoming_value}}}); return true; }; @@ -2245,7 +2212,7 @@ FoldingRule RedundantPhi() { FoldingRule BitCastScalarOrVector() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpBitcast && constants.size() == 1); + assert(inst->opcode() == SpvOpBitcast && constants.size() == 1); if (constants[0] == nullptr) return false; const analysis::Type* type = @@ -2265,7 +2232,7 @@ FoldingRule BitCastScalarOrVector() { auto new_feeder_id = const_mgr->GetDefiningInstruction(bitcasted_constant, inst->type_id()) ->result_id(); - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {new_feeder_id}}}); return true; }; @@ -2276,7 +2243,7 @@ FoldingRule RedundantSelect() { // constant can be replaced by one of the values return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpSelect && + assert(inst->opcode() == SpvOpSelect && "Wrong opcode. Should be OpSelect."); assert(inst->NumInOperands() == 3); assert(constants.size() == 3); @@ -2286,14 +2253,14 @@ FoldingRule RedundantSelect() { if (true_id == false_id) { // Both results are the same, condition doesn't matter - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {true_id}}}); return true; } else if (constants[0]) { const analysis::Type* type = constants[0]->type(); if (type->AsBool()) { // Scalar constant value, select the corresponding value. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); if (constants[0]->AsNullConstant() || !constants[0]->AsBoolConstant()->value()) { inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); @@ -2305,7 +2272,7 @@ FoldingRule RedundantSelect() { assert(type->AsVector()); if (constants[0]->AsNullConstant()) { // All values come from false id. - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {false_id}}}); return true; } else { @@ -2332,7 +2299,7 @@ FoldingRule RedundantSelect() { } } - inst->SetOpcode(spv::Op::OpVectorShuffle); + inst->SetOpcode(SpvOpVectorShuffle); inst->SetInOperands(std::move(ops)); return true; } @@ -2392,8 +2359,7 @@ FloatConstantKind getFloatConstantKind(const analysis::Constant* constant) { FoldingRule RedundantFAdd() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFAdd && - "Wrong opcode. Should be OpFAdd."); + assert(inst->opcode() == SpvOpFAdd && "Wrong opcode. Should be OpFAdd."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2404,7 +2370,7 @@ FoldingRule RedundantFAdd() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::Zero ? 1 : 0)}}}); @@ -2418,8 +2384,7 @@ FoldingRule RedundantFAdd() { FoldingRule RedundantFSub() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFSub && - "Wrong opcode. Should be OpFSub."); + assert(inst->opcode() == SpvOpFSub && "Wrong opcode. Should be OpFSub."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2430,14 +2395,14 @@ FoldingRule RedundantFSub() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero) { - inst->SetOpcode(spv::Op::OpFNegate); + inst->SetOpcode(SpvOpFNegate); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1)}}}); return true; } if (kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; @@ -2450,8 +2415,7 @@ FoldingRule RedundantFSub() { FoldingRule RedundantFMul() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFMul && - "Wrong opcode. Should be OpFMul."); + assert(inst->opcode() == SpvOpFMul && "Wrong opcode. Should be OpFMul."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2462,7 +2426,7 @@ FoldingRule RedundantFMul() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero || kind1 == FloatConstantKind::Zero) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::Zero ? 0 : 1)}}}); @@ -2470,7 +2434,7 @@ FoldingRule RedundantFMul() { } if (kind0 == FloatConstantKind::One || kind1 == FloatConstantKind::One) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand( kind0 == FloatConstantKind::One ? 1 : 0)}}}); @@ -2484,8 +2448,7 @@ FoldingRule RedundantFMul() { FoldingRule RedundantFDiv() { return [](IRContext*, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpFDiv && - "Wrong opcode. Should be OpFDiv."); + assert(inst->opcode() == SpvOpFDiv && "Wrong opcode. Should be OpFDiv."); assert(constants.size() == 2); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2496,14 +2459,14 @@ FoldingRule RedundantFDiv() { FloatConstantKind kind1 = getFloatConstantKind(constants[1]); if (kind0 == FloatConstantKind::Zero) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; } if (kind1 == FloatConstantKind::One) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(0)}}}); return true; @@ -2516,7 +2479,7 @@ FoldingRule RedundantFDiv() { FoldingRule RedundantFMix() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpExtInst && + assert(inst->opcode() == SpvOpExtInst && "Wrong opcode. Should be OpExtInst."); if (!inst->IsFloatingPointFoldingAllowed()) { @@ -2534,7 +2497,7 @@ FoldingRule RedundantFMix() { FloatConstantKind kind4 = getFloatConstantKind(constants[4]); if (kind4 == FloatConstantKind::Zero || kind4 == FloatConstantKind::One) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); inst->SetInOperands( {{SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(kind4 == FloatConstantKind::Zero @@ -2552,8 +2515,7 @@ FoldingRule RedundantFMix() { FoldingRule RedundantIAdd() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpIAdd && - "Wrong opcode. Should be OpIAdd."); + assert(inst->opcode() == SpvOpIAdd && "Wrong opcode. Should be OpIAdd."); uint32_t operand = std::numeric_limits::max(); const analysis::Type* operand_type = nullptr; @@ -2569,9 +2531,9 @@ FoldingRule RedundantIAdd() { const analysis::Type* inst_type = context->get_type_mgr()->GetType(inst->type_id()); if (inst_type->IsSame(operand_type)) { - inst->SetOpcode(spv::Op::OpCopyObject); + inst->SetOpcode(SpvOpCopyObject); } else { - inst->SetOpcode(spv::Op::OpBitcast); + inst->SetOpcode(SpvOpBitcast); } inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {operand}}}); return true; @@ -2585,8 +2547,7 @@ FoldingRule RedundantIAdd() { FoldingRule DotProductDoingExtract() { return [](IRContext* context, Instruction* inst, const std::vector& constants) { - assert(inst->opcode() == spv::Op::OpDot && - "Wrong opcode. Should be OpDot."); + assert(inst->opcode() == SpvOpDot && "Wrong opcode. Should be OpDot."); analysis::ConstantManager* const_mgr = context->get_constant_mgr(); @@ -2612,7 +2573,7 @@ FoldingRule DotProductDoingExtract() { std::vector components; components = constants[i]->GetVectorComponents(const_mgr); - constexpr uint32_t kNotFound = std::numeric_limits::max(); + const uint32_t kNotFound = std::numeric_limits::max(); uint32_t component_with_one = kNotFound; bool all_others_zero = true; @@ -2645,7 +2606,7 @@ FoldingRule DotProductDoingExtract() { operands.push_back( {SPV_OPERAND_TYPE_LITERAL_INTEGER, {component_with_one}}); - inst->SetOpcode(spv::Op::OpCompositeExtract); + inst->SetOpcode(SpvOpCompositeExtract); inst->SetInOperands(std::move(operands)); return true; } @@ -2660,22 +2621,20 @@ FoldingRule DotProductDoingExtract() { FoldingRule StoringUndef() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpStore && - "Wrong opcode. Should be OpStore."); + assert(inst->opcode() == SpvOpStore && "Wrong opcode. Should be OpStore."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); // If this is a volatile store, the store cannot be removed. if (inst->NumInOperands() == 3) { - if (inst->GetSingleWordInOperand(2) & - uint32_t(spv::MemoryAccessMask::Volatile)) { + if (inst->GetSingleWordInOperand(2) & SpvMemoryAccessVolatileMask) { return false; } } uint32_t object_id = inst->GetSingleWordInOperand(kStoreObjectInIdx); Instruction* object_inst = def_use_mgr->GetDef(object_id); - if (object_inst->opcode() == spv::Op::OpUndef) { + if (object_inst->opcode() == SpvOpUndef) { inst->ToNop(); return true; } @@ -2686,7 +2645,7 @@ FoldingRule StoringUndef() { FoldingRule VectorShuffleFeedingShuffle() { return [](IRContext* context, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpVectorShuffle && + assert(inst->opcode() == SpvOpVectorShuffle && "Wrong opcode. Should be OpVectorShuffle."); analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); @@ -2699,13 +2658,13 @@ FoldingRule VectorShuffleFeedingShuffle() { uint32_t op0_length = op0_type->element_count(); bool feeder_is_op0 = true; - if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { + if (feeding_shuffle_inst->opcode() != SpvOpVectorShuffle) { feeding_shuffle_inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(1)); feeder_is_op0 = false; } - if (feeding_shuffle_inst->opcode() != spv::Op::OpVectorShuffle) { + if (feeding_shuffle_inst->opcode() != SpvOpVectorShuffle) { return false; } @@ -2816,7 +2775,7 @@ FoldingRule VectorShuffleFeedingShuffle() { FoldingRule RemoveRedundantOperands() { return [](IRContext*, Instruction* inst, const std::vector&) { - assert(inst->opcode() == spv::Op::OpEntryPoint && + assert(inst->opcode() == SpvOpEntryPoint && "Wrong opcode. Should be OpEntryPoint."); bool has_redundant_operand = false; std::unordered_set seen_operands; @@ -2849,56 +2808,46 @@ FoldingRule UpdateImageOperands() { const std::vector& constants) { const auto opcode = inst->opcode(); (void)opcode; - assert((opcode == spv::Op::OpImageSampleImplicitLod || - opcode == spv::Op::OpImageSampleExplicitLod || - opcode == spv::Op::OpImageSampleDrefImplicitLod || - opcode == spv::Op::OpImageSampleDrefExplicitLod || - opcode == spv::Op::OpImageSampleProjImplicitLod || - opcode == spv::Op::OpImageSampleProjExplicitLod || - opcode == spv::Op::OpImageSampleProjDrefImplicitLod || - opcode == spv::Op::OpImageSampleProjDrefExplicitLod || - opcode == spv::Op::OpImageFetch || - opcode == spv::Op::OpImageGather || - opcode == spv::Op::OpImageDrefGather || - opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || - opcode == spv::Op::OpImageSparseSampleImplicitLod || - opcode == spv::Op::OpImageSparseSampleExplicitLod || - opcode == spv::Op::OpImageSparseSampleDrefImplicitLod || - opcode == spv::Op::OpImageSparseSampleDrefExplicitLod || - opcode == spv::Op::OpImageSparseSampleProjImplicitLod || - opcode == spv::Op::OpImageSparseSampleProjExplicitLod || - opcode == spv::Op::OpImageSparseSampleProjDrefImplicitLod || - opcode == spv::Op::OpImageSparseSampleProjDrefExplicitLod || - opcode == spv::Op::OpImageSparseFetch || - opcode == spv::Op::OpImageSparseGather || - opcode == spv::Op::OpImageSparseDrefGather || - opcode == spv::Op::OpImageSparseRead) && + assert((opcode == SpvOpImageSampleImplicitLod || + opcode == SpvOpImageSampleExplicitLod || + opcode == SpvOpImageSampleDrefImplicitLod || + opcode == SpvOpImageSampleDrefExplicitLod || + opcode == SpvOpImageSampleProjImplicitLod || + opcode == SpvOpImageSampleProjExplicitLod || + opcode == SpvOpImageSampleProjDrefImplicitLod || + opcode == SpvOpImageSampleProjDrefExplicitLod || + opcode == SpvOpImageFetch || opcode == SpvOpImageGather || + opcode == SpvOpImageDrefGather || opcode == SpvOpImageRead || + opcode == SpvOpImageWrite || + opcode == SpvOpImageSparseSampleImplicitLod || + opcode == SpvOpImageSparseSampleExplicitLod || + opcode == SpvOpImageSparseSampleDrefImplicitLod || + opcode == SpvOpImageSparseSampleDrefExplicitLod || + opcode == SpvOpImageSparseSampleProjImplicitLod || + opcode == SpvOpImageSparseSampleProjExplicitLod || + opcode == SpvOpImageSparseSampleProjDrefImplicitLod || + opcode == SpvOpImageSparseSampleProjDrefExplicitLod || + opcode == SpvOpImageSparseFetch || + opcode == SpvOpImageSparseGather || + opcode == SpvOpImageSparseDrefGather || + opcode == SpvOpImageSparseRead) && "Wrong opcode. Should be an image instruction."); int32_t operand_index = ImageOperandsMaskInOperandIndex(inst); if (operand_index >= 0) { auto image_operands = inst->GetSingleWordInOperand(operand_index); - if (image_operands & uint32_t(spv::ImageOperandsMask::Offset)) { + if (image_operands & SpvImageOperandsOffsetMask) { uint32_t offset_operand_index = operand_index + 1; - if (image_operands & uint32_t(spv::ImageOperandsMask::Bias)) - offset_operand_index++; - if (image_operands & uint32_t(spv::ImageOperandsMask::Lod)) - offset_operand_index++; - if (image_operands & uint32_t(spv::ImageOperandsMask::Grad)) + if (image_operands & SpvImageOperandsBiasMask) offset_operand_index++; + if (image_operands & SpvImageOperandsLodMask) offset_operand_index++; + if (image_operands & SpvImageOperandsGradMask) offset_operand_index += 2; - assert(((image_operands & - uint32_t(spv::ImageOperandsMask::ConstOffset)) == 0) && + assert(((image_operands & SpvImageOperandsConstOffsetMask) == 0) && "Offset and ConstOffset may not be used together"); if (offset_operand_index < inst->NumOperands()) { if (constants[offset_operand_index]) { - if (constants[offset_operand_index]->IsZero()) { - inst->RemoveInOperand(offset_operand_index); - } else { - image_operands = image_operands | - uint32_t(spv::ImageOperandsMask::ConstOffset); - } - image_operands = - image_operands & ~uint32_t(spv::ImageOperandsMask::Offset); + image_operands = image_operands | SpvImageOperandsConstOffsetMask; + image_operands = image_operands & ~SpvImageOperandsOffsetMask; inst->SetInOperand(operand_index, {image_operands}); return true; } @@ -2917,119 +2866,108 @@ void FoldingRules::AddFoldingRules() { // Note that the order in which rules are added to the list matters. If a rule // applies to the instruction, the rest of the rules will not be attempted. // Take that into consideration. - rules_[spv::Op::OpBitcast].push_back(BitCastScalarOrVector()); + rules_[SpvOpBitcast].push_back(BitCastScalarOrVector()); - rules_[spv::Op::OpCompositeConstruct].push_back( - CompositeExtractFeedingConstruct); + rules_[SpvOpCompositeConstruct].push_back(CompositeExtractFeedingConstruct); - rules_[spv::Op::OpCompositeExtract].push_back(InsertFeedingExtract()); - rules_[spv::Op::OpCompositeExtract].push_back( - CompositeConstructFeedingExtract); - rules_[spv::Op::OpCompositeExtract].push_back(VectorShuffleFeedingExtract()); - rules_[spv::Op::OpCompositeExtract].push_back(FMixFeedingExtract()); + rules_[SpvOpCompositeExtract].push_back(InsertFeedingExtract()); + rules_[SpvOpCompositeExtract].push_back(CompositeConstructFeedingExtract); + rules_[SpvOpCompositeExtract].push_back(VectorShuffleFeedingExtract()); + rules_[SpvOpCompositeExtract].push_back(FMixFeedingExtract()); - rules_[spv::Op::OpCompositeInsert].push_back( - CompositeInsertToCompositeConstruct); + rules_[SpvOpCompositeInsert].push_back(CompositeInsertToCompositeConstruct); - rules_[spv::Op::OpDot].push_back(DotProductDoingExtract()); + rules_[SpvOpDot].push_back(DotProductDoingExtract()); - rules_[spv::Op::OpEntryPoint].push_back(RemoveRedundantOperands()); + rules_[SpvOpEntryPoint].push_back(RemoveRedundantOperands()); - rules_[spv::Op::OpFAdd].push_back(RedundantFAdd()); - rules_[spv::Op::OpFAdd].push_back(MergeAddNegateArithmetic()); - rules_[spv::Op::OpFAdd].push_back(MergeAddAddArithmetic()); - rules_[spv::Op::OpFAdd].push_back(MergeAddSubArithmetic()); - rules_[spv::Op::OpFAdd].push_back(MergeGenericAddSubArithmetic()); - rules_[spv::Op::OpFAdd].push_back(FactorAddMuls()); - rules_[spv::Op::OpFAdd].push_back(MergeMulAddArithmetic); + rules_[SpvOpFAdd].push_back(RedundantFAdd()); + rules_[SpvOpFAdd].push_back(MergeAddNegateArithmetic()); + rules_[SpvOpFAdd].push_back(MergeAddAddArithmetic()); + rules_[SpvOpFAdd].push_back(MergeAddSubArithmetic()); + rules_[SpvOpFAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[SpvOpFAdd].push_back(FactorAddMuls()); + rules_[SpvOpFAdd].push_back(MergeMulAddArithmetic); - rules_[spv::Op::OpFDiv].push_back(RedundantFDiv()); - rules_[spv::Op::OpFDiv].push_back(ReciprocalFDiv()); - rules_[spv::Op::OpFDiv].push_back(MergeDivDivArithmetic()); - rules_[spv::Op::OpFDiv].push_back(MergeDivMulArithmetic()); - rules_[spv::Op::OpFDiv].push_back(MergeDivNegateArithmetic()); + rules_[SpvOpFDiv].push_back(RedundantFDiv()); + rules_[SpvOpFDiv].push_back(ReciprocalFDiv()); + rules_[SpvOpFDiv].push_back(MergeDivDivArithmetic()); + rules_[SpvOpFDiv].push_back(MergeDivMulArithmetic()); + rules_[SpvOpFDiv].push_back(MergeDivNegateArithmetic()); - rules_[spv::Op::OpFMul].push_back(RedundantFMul()); - rules_[spv::Op::OpFMul].push_back(MergeMulMulArithmetic()); - rules_[spv::Op::OpFMul].push_back(MergeMulDivArithmetic()); - rules_[spv::Op::OpFMul].push_back(MergeMulNegateArithmetic()); + rules_[SpvOpFMul].push_back(RedundantFMul()); + rules_[SpvOpFMul].push_back(MergeMulMulArithmetic()); + rules_[SpvOpFMul].push_back(MergeMulDivArithmetic()); + rules_[SpvOpFMul].push_back(MergeMulNegateArithmetic()); - rules_[spv::Op::OpFNegate].push_back(MergeNegateArithmetic()); - rules_[spv::Op::OpFNegate].push_back(MergeNegateAddSubArithmetic()); - rules_[spv::Op::OpFNegate].push_back(MergeNegateMulDivArithmetic()); + rules_[SpvOpFNegate].push_back(MergeNegateArithmetic()); + rules_[SpvOpFNegate].push_back(MergeNegateAddSubArithmetic()); + rules_[SpvOpFNegate].push_back(MergeNegateMulDivArithmetic()); - rules_[spv::Op::OpFSub].push_back(RedundantFSub()); - rules_[spv::Op::OpFSub].push_back(MergeSubNegateArithmetic()); - rules_[spv::Op::OpFSub].push_back(MergeSubAddArithmetic()); - rules_[spv::Op::OpFSub].push_back(MergeSubSubArithmetic()); - rules_[spv::Op::OpFSub].push_back(MergeMulSubArithmetic); + rules_[SpvOpFSub].push_back(RedundantFSub()); + rules_[SpvOpFSub].push_back(MergeSubNegateArithmetic()); + rules_[SpvOpFSub].push_back(MergeSubAddArithmetic()); + rules_[SpvOpFSub].push_back(MergeSubSubArithmetic()); + rules_[SpvOpFSub].push_back(MergeMulSubArithmetic); - rules_[spv::Op::OpIAdd].push_back(RedundantIAdd()); - rules_[spv::Op::OpIAdd].push_back(MergeAddNegateArithmetic()); - rules_[spv::Op::OpIAdd].push_back(MergeAddAddArithmetic()); - rules_[spv::Op::OpIAdd].push_back(MergeAddSubArithmetic()); - rules_[spv::Op::OpIAdd].push_back(MergeGenericAddSubArithmetic()); - rules_[spv::Op::OpIAdd].push_back(FactorAddMuls()); + rules_[SpvOpIAdd].push_back(RedundantIAdd()); + rules_[SpvOpIAdd].push_back(MergeAddNegateArithmetic()); + rules_[SpvOpIAdd].push_back(MergeAddAddArithmetic()); + rules_[SpvOpIAdd].push_back(MergeAddSubArithmetic()); + rules_[SpvOpIAdd].push_back(MergeGenericAddSubArithmetic()); + rules_[SpvOpIAdd].push_back(FactorAddMuls()); - rules_[spv::Op::OpIMul].push_back(IntMultipleBy1()); - rules_[spv::Op::OpIMul].push_back(MergeMulMulArithmetic()); - rules_[spv::Op::OpIMul].push_back(MergeMulNegateArithmetic()); + rules_[SpvOpIMul].push_back(IntMultipleBy1()); + rules_[SpvOpIMul].push_back(MergeMulMulArithmetic()); + rules_[SpvOpIMul].push_back(MergeMulNegateArithmetic()); - rules_[spv::Op::OpISub].push_back(MergeSubNegateArithmetic()); - rules_[spv::Op::OpISub].push_back(MergeSubAddArithmetic()); - rules_[spv::Op::OpISub].push_back(MergeSubSubArithmetic()); + rules_[SpvOpISub].push_back(MergeSubNegateArithmetic()); + rules_[SpvOpISub].push_back(MergeSubAddArithmetic()); + rules_[SpvOpISub].push_back(MergeSubSubArithmetic()); - rules_[spv::Op::OpPhi].push_back(RedundantPhi()); + rules_[SpvOpPhi].push_back(RedundantPhi()); - rules_[spv::Op::OpSNegate].push_back(MergeNegateArithmetic()); - rules_[spv::Op::OpSNegate].push_back(MergeNegateMulDivArithmetic()); - rules_[spv::Op::OpSNegate].push_back(MergeNegateAddSubArithmetic()); + rules_[SpvOpSNegate].push_back(MergeNegateArithmetic()); + rules_[SpvOpSNegate].push_back(MergeNegateMulDivArithmetic()); + rules_[SpvOpSNegate].push_back(MergeNegateAddSubArithmetic()); - rules_[spv::Op::OpSelect].push_back(RedundantSelect()); + rules_[SpvOpSelect].push_back(RedundantSelect()); - rules_[spv::Op::OpStore].push_back(StoringUndef()); + rules_[SpvOpStore].push_back(StoringUndef()); - rules_[spv::Op::OpVectorShuffle].push_back(VectorShuffleFeedingShuffle()); + rules_[SpvOpVectorShuffle].push_back(VectorShuffleFeedingShuffle()); - rules_[spv::Op::OpImageSampleImplicitLod].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSampleExplicitLod].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSampleDrefImplicitLod].push_back( + rules_[SpvOpImageSampleImplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleExplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleDrefImplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleDrefExplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleProjImplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleProjExplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleProjDrefImplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSampleProjDrefExplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageFetch].push_back(UpdateImageOperands()); + rules_[SpvOpImageGather].push_back(UpdateImageOperands()); + rules_[SpvOpImageDrefGather].push_back(UpdateImageOperands()); + rules_[SpvOpImageRead].push_back(UpdateImageOperands()); + rules_[SpvOpImageWrite].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseSampleImplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseSampleExplicitLod].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseSampleDrefImplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageSampleDrefExplicitLod].push_back( + rules_[SpvOpImageSparseSampleDrefExplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageSampleProjImplicitLod].push_back( + rules_[SpvOpImageSparseSampleProjImplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageSampleProjExplicitLod].push_back( + rules_[SpvOpImageSparseSampleProjExplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageSampleProjDrefImplicitLod].push_back( + rules_[SpvOpImageSparseSampleProjDrefImplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageSampleProjDrefExplicitLod].push_back( + rules_[SpvOpImageSparseSampleProjDrefExplicitLod].push_back( UpdateImageOperands()); - rules_[spv::Op::OpImageFetch].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageGather].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageDrefGather].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageRead].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageWrite].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleImplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleExplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleDrefImplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleDrefExplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleProjImplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleProjExplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleProjDrefImplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseSampleProjDrefExplicitLod].push_back( - UpdateImageOperands()); - rules_[spv::Op::OpImageSparseFetch].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSparseGather].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSparseDrefGather].push_back(UpdateImageOperands()); - rules_[spv::Op::OpImageSparseRead].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseFetch].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseGather].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseDrefGather].push_back(UpdateImageOperands()); + rules_[SpvOpImageSparseRead].push_back(UpdateImageOperands()); FeatureManager* feature_manager = context_->get_feature_mgr(); // Add rules for GLSLstd450 diff --git a/source/opt/folding_rules.h b/source/opt/folding_rules.h index b51e0ce4..f1a86395 100644 --- a/source/opt/folding_rules.h +++ b/source/opt/folding_rules.h @@ -64,7 +64,7 @@ class FoldingRules { virtual ~FoldingRules() = default; const FoldingRuleSet& GetRulesForInstruction(Instruction* inst) const { - if (inst->opcode() != spv::Op::OpExtInst) { + if (inst->opcode() != SpvOpExtInst) { auto it = rules_.find(inst->opcode()); if (it != rules_.end()) { return it->second; @@ -86,14 +86,8 @@ class FoldingRules { virtual void AddFoldingRules(); protected: - struct hasher { - size_t operator()(const spv::Op& op) const noexcept { - return std::hash()(uint32_t(op)); - } - }; - // The folding rules for core instructions. - std::unordered_map rules_; + std::unordered_map rules_; // The folding rules for extended instructions. struct Key { diff --git a/source/opt/freeze_spec_constant_value_pass.cpp b/source/opt/freeze_spec_constant_value_pass.cpp index 3f89e56c..10e98fd8 100644 --- a/source/opt/freeze_spec_constant_value_pass.cpp +++ b/source/opt/freeze_spec_constant_value_pass.cpp @@ -23,21 +23,21 @@ Pass::Status FreezeSpecConstantValuePass::Process() { auto ctx = context(); ctx->module()->ForEachInst([&modified, ctx](Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpSpecConstant: - inst->SetOpcode(spv::Op::OpConstant); + case SpvOp::SpvOpSpecConstant: + inst->SetOpcode(SpvOp::SpvOpConstant); modified = true; break; - case spv::Op::OpSpecConstantTrue: - inst->SetOpcode(spv::Op::OpConstantTrue); + case SpvOp::SpvOpSpecConstantTrue: + inst->SetOpcode(SpvOp::SpvOpConstantTrue); modified = true; break; - case spv::Op::OpSpecConstantFalse: - inst->SetOpcode(spv::Op::OpConstantFalse); + case SpvOp::SpvOpSpecConstantFalse: + inst->SetOpcode(SpvOp::SpvOpConstantFalse); modified = true; break; - case spv::Op::OpDecorate: - if (spv::Decoration(inst->GetSingleWordInOperand(1)) == - spv::Decoration::SpecId) { + case SpvOp::SpvOpDecorate: + if (inst->GetSingleWordInOperand(1) == + SpvDecoration::SpvDecorationSpecId) { ctx->KillInst(inst); modified = true; } diff --git a/source/opt/function.cpp b/source/opt/function.cpp index 2ee88eca..bb51df3f 100644 --- a/source/opt/function.cpp +++ b/source/opt/function.cpp @@ -15,7 +15,9 @@ #include "source/opt/function.h" #include +#include +#include "function.h" #include "ir_context.h" #include "source/util/bit_vector.h" @@ -262,7 +264,7 @@ std::string Function::PrettyPrint(uint32_t options) const { std::ostringstream str; ForEachInst([&str, options](const Instruction* inst) { str << inst->PrettyPrint(options); - if (inst->opcode() != spv::Op::OpFunctionEnd) { + if (inst->opcode() != SpvOpFunctionEnd) { str << std::endl; } }); diff --git a/source/opt/function.h b/source/opt/function.h index 8c0472cd..146cbe34 100644 --- a/source/opt/function.h +++ b/source/opt/function.h @@ -253,7 +253,7 @@ inline void Function::RemoveEmptyBlocks() { auto first_empty = std::remove_if(std::begin(blocks_), std::end(blocks_), [](const std::unique_ptr& bb) -> bool { - return bb->GetLabelInst()->opcode() == spv::Op::OpNop; + return bb->GetLabelInst()->opcode() == SpvOpNop; }); blocks_.erase(first_empty, std::end(blocks_)); } diff --git a/source/opt/graphics_robust_access_pass.cpp b/source/opt/graphics_robust_access_pass.cpp index e765c397..4652d72d 100644 --- a/source/opt/graphics_robust_access_pass.cpp +++ b/source/opt/graphics_robust_access_pass.cpp @@ -141,17 +141,24 @@ #include "graphics_robust_access_pass.h" +#include +#include #include #include +#include #include +#include "constants.h" +#include "def_use_manager.h" #include "function.h" #include "ir_context.h" +#include "module.h" #include "pass.h" #include "source/diagnostic.h" #include "source/util/make_unique.h" #include "spirv-tools/libspirv.h" #include "spirv/unified1/GLSL.std.450.h" +#include "spirv/unified1/spirv.h" #include "type_manager.h" #include "types.h" @@ -187,15 +194,14 @@ spvtools::DiagnosticStream GraphicsRobustAccessPass::Fail() { spv_result_t GraphicsRobustAccessPass::IsCompatibleModule() { auto* feature_mgr = context()->get_feature_mgr(); - if (!feature_mgr->HasCapability(spv::Capability::Shader)) + if (!feature_mgr->HasCapability(SpvCapabilityShader)) return Fail() << "Can only process Shader modules"; - if (feature_mgr->HasCapability(spv::Capability::VariablePointers)) + if (feature_mgr->HasCapability(SpvCapabilityVariablePointers)) return Fail() << "Can't process modules with VariablePointers capability"; - if (feature_mgr->HasCapability( - spv::Capability::VariablePointersStorageBuffer)) + if (feature_mgr->HasCapability(SpvCapabilityVariablePointersStorageBuffer)) return Fail() << "Can't process modules with VariablePointersStorageBuffer " "capability"; - if (feature_mgr->HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { + if (feature_mgr->HasCapability(SpvCapabilityRuntimeDescriptorArrayEXT)) { // These have a RuntimeArray outside of Block-decorated struct. There // is no way to compute the array length from within SPIR-V. return Fail() << "Can't process modules with RuntimeDescriptorArrayEXT " @@ -204,9 +210,8 @@ spv_result_t GraphicsRobustAccessPass::IsCompatibleModule() { { auto* inst = context()->module()->GetMemoryModel(); - const auto addressing_model = - spv::AddressingModel(inst->GetSingleWordOperand(0)); - if (addressing_model != spv::AddressingModel::Logical) + const auto addressing_model = inst->GetSingleWordOperand(0); + if (addressing_model != SpvAddressingModelLogical) return Fail() << "Addressing model must be Logical. Found " << inst->PrettyPrint(); } @@ -232,11 +237,11 @@ bool GraphicsRobustAccessPass::ProcessAFunction(opt::Function* function) { for (auto& block : *function) { for (auto& inst : block) { switch (inst.opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: access_chains.push_back(&inst); break; - case spv::Op::OpImageTexelPointer: + case SpvOpImageTexelPointer: image_texel_pointers.push_back(&inst); break; default: @@ -263,7 +268,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( auto* def_use_mgr = context()->get_def_use_mgr(); auto* type_mgr = context()->get_type_mgr(); const bool have_int64_cap = - context()->get_feature_mgr()->HasCapability(spv::Capability::Int64); + context()->get_feature_mgr()->HasCapability(SpvCapabilityInt64); // Replaces one of the OpAccessChain index operands with a new value. // Updates def-use analysis. @@ -446,7 +451,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( // It doesn't matter if 1 is signed or unsigned. auto* one = GetValueForType(1, wider_type); auto* count_minus_1 = InsertInst( - &inst, spv::Op::OpISub, type_mgr->GetId(wider_type), TakeNextId(), + &inst, SpvOpISub, type_mgr->GetId(wider_type), TakeNextId(), {{SPV_OPERAND_TYPE_ID, {count_inst->result_id()}}, {SPV_OPERAND_TYPE_ID, {one->result_id()}}}); auto* zero = GetValueForType(0, wider_type); @@ -481,15 +486,15 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( Instruction* index_inst = GetDef(index_id); switch (pointee_type->opcode()) { - case spv::Op::OpTypeMatrix: // Use column count - case spv::Op::OpTypeVector: // Use component count + case SpvOpTypeMatrix: // Use column count + case SpvOpTypeVector: // Use component count { const uint32_t count = pointee_type->GetSingleWordOperand(2); clamp_to_literal_count(idx, count); pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); } break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { // The array length can be a spec constant, so go through the general // case. Instruction* array_len = GetDef(pointee_type->GetSingleWordOperand(2)); @@ -497,11 +502,11 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( pointee_type = GetDef(pointee_type->GetSingleWordOperand(1)); } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // SPIR-V requires the index to be an OpConstant. // We need to know the index literal value so we can compute the next // pointee type. - if (index_inst->opcode() != spv::Op::OpConstant || + if (index_inst->opcode() != SpvOpConstant || !constant_mgr->GetConstantFromInst(index_inst) ->type() ->AsInteger()) { @@ -532,7 +537,7 @@ void GraphicsRobustAccessPass::ClampIndicesForAccessChain( // No need to clamp this index. We just checked that it's valid. } break; - case spv::Op::OpTypeRuntimeArray: { + case SpvOpTypeRuntimeArray: { auto* array_len = MakeRuntimeArrayLengthInst(&inst, idx); if (!array_len) { // We've already signaled an error. return; @@ -566,16 +571,16 @@ uint32_t GraphicsRobustAccessPass::GetGlslInsts() { module_status_.glsl_insts_id = TakeNextId(); std::vector words = spvtools::utils::MakeVector(glsl); auto import_inst = MakeUnique( - context(), spv::Op::OpExtInstImport, 0, module_status_.glsl_insts_id, + context(), SpvOpExtInstImport, 0, module_status_.glsl_insts_id, std::initializer_list{ Operand{SPV_OPERAND_TYPE_LITERAL_STRING, std::move(words)}}); Instruction* inst = import_inst.get(); context()->module()->AddExtInstImport(std::move(import_inst)); module_status_.modified = true; context()->AnalyzeDefUse(inst); - // Invalidates the feature manager, since we added an extended instruction - // set import. - context()->ResetFeatureManager(); + // Reanalyze the feature list, since we added an extended instruction + // set improt. + context()->get_feature_mgr()->Analyze(context()->module()); } } return module_status_.glsl_insts_id; @@ -604,8 +609,8 @@ opt::Instruction* opt::GraphicsRobustAccessPass::WidenInteger( auto type_id = context()->get_type_mgr()->GetId(unsigned_type); auto conversion_id = TakeNextId(); auto* conversion = InsertInst( - before_inst, (sign_extend ? spv::Op::OpSConvert : spv::Op::OpUConvert), - type_id, conversion_id, {{SPV_OPERAND_TYPE_ID, {value->result_id()}}}); + before_inst, (sign_extend ? SpvOpSConvert : SpvOpUConvert), type_id, + conversion_id, {{SPV_OPERAND_TYPE_ID, {value->result_id()}}}); return conversion; } @@ -623,7 +628,7 @@ Instruction* GraphicsRobustAccessPass::MakeUMinInst( (void)xwidth; (void)ywidth; auto* smin_inst = InsertInst( - where, spv::Op::OpExtInst, x->type_id(), smin_id, + where, SpvOpExtInst, x->type_id(), smin_id, { {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450UMin}}, @@ -650,7 +655,7 @@ Instruction* GraphicsRobustAccessPass::MakeSClampInst( (void)minwidth; (void)maxwidth; auto* clamp_inst = InsertInst( - where, spv::Op::OpExtInst, x->type_id(), clamp_id, + where, SpvOpExtInst, x->type_id(), clamp_id, { {SPV_OPERAND_TYPE_ID, {glsl_insts_id}}, {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, {GLSLstd450SClamp}}, @@ -684,13 +689,13 @@ Instruction* GraphicsRobustAccessPass::MakeRuntimeArrayLengthInst( Instruction* pointer_to_containing_struct = nullptr; while (steps_remaining > 0) { switch (current_access_chain->opcode()) { - case spv::Op::OpCopyObject: + case SpvOpCopyObject: // Whoops. Walk right through this one. current_access_chain = GetDef(current_access_chain->GetSingleWordInOperand(0)); break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: { + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: { const int first_index_operand = 3; // How many indices in this access chain contribute to getting us // to an element in the runtime array? @@ -788,8 +793,7 @@ Instruction* GraphicsRobustAccessPass::MakeRuntimeArrayLengthInst( analysis::Integer uint_type_for_query(32, false); auto* uint_type = type_mgr->GetRegisteredType(&uint_type_for_query); auto* array_len = InsertInst( - access_chain, spv::Op::OpArrayLength, type_mgr->GetId(uint_type), - array_len_id, + access_chain, SpvOpArrayLength, type_mgr->GetId(uint_type), array_len_id, {{SPV_OPERAND_TYPE_ID, {pointer_to_containing_struct->result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index_of_runtime_array}}}); return array_len; @@ -835,11 +839,11 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // Declare the ImageQuery capability if the module doesn't already have it. auto* feature_mgr = context()->get_feature_mgr(); - if (!feature_mgr->HasCapability(spv::Capability::ImageQuery)) { + if (!feature_mgr->HasCapability(SpvCapabilityImageQuery)) { auto cap = MakeUnique( - context(), spv::Op::OpCapability, 0, 0, + context(), SpvOpCapability, 0, 0, std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, {spv::Capability::ImageQuery}}}); + {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityImageQuery}}}); def_use_mgr->AnalyzeInstDefUse(cap.get()); context()->AddCapability(std::move(cap)); feature_mgr->Analyze(context()->module()); @@ -886,21 +890,21 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const int arrayness_bonus = arrayed ? 1 : 0; int num_coords = 0; switch (dim) { - case spv::Dim::Buffer: + case SpvDimBuffer: case SpvDim1D: num_coords = 1; break; - case spv::Dim::Cube: + case SpvDimCube: // For cube, we need bounds for x, y, but not face. - case spv::Dim::Rect: + case SpvDimRect: case SpvDim2D: num_coords = 2; break; case SpvDim3D: num_coords = 3; break; - case spv::Dim::SubpassData: - case spv::Dim::Max: + case SpvDimSubpassData: + case SpvDimMax: return Fail() << "Invalid image dimension for OpImageTexelPointer: " << int(dim); break; @@ -937,12 +941,12 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const uint32_t image_id = TakeNextId(); auto* image = - InsertInst(image_texel_pointer, spv::Op::OpLoad, image_type_id, image_id, + InsertInst(image_texel_pointer, SpvOpLoad, image_type_id, image_id, {{SPV_OPERAND_TYPE_ID, {image_ptr->result_id()}}}); const uint32_t query_size_id = TakeNextId(); auto* query_size = - InsertInst(image_texel_pointer, spv::Op::OpImageQuerySize, + InsertInst(image_texel_pointer, SpvOpImageQuerySize, type_mgr->GetTypeInstruction(query_size_type), query_size_id, {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); @@ -958,7 +962,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // in the face index ranging from 0 through 5. The inclusive upper bound // on the third coordinate therefore is multiplied by 6. auto* query_size_including_faces = query_size; - if (arrayed && (dim == spv::Dim::Cube)) { + if (arrayed && (dim == SpvDimCube)) { // Multiply the last coordinate by 6. auto* component_6 = constant_mgr->GetConstant(coord_component_type, {6}); const uint32_t component_6_id = @@ -970,7 +974,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( constant_mgr->GetDefiningInstruction(multiplicand); const auto query_size_including_faces_id = TakeNextId(); query_size_including_faces = InsertInst( - image_texel_pointer, spv::Op::OpIMul, + image_texel_pointer, SpvOpIMul, type_mgr->GetTypeInstruction(query_size_type), query_size_including_faces_id, {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, @@ -994,7 +998,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( const uint32_t query_max_including_faces_id = TakeNextId(); auto* query_max_including_faces = InsertInst( - image_texel_pointer, spv::Op::OpISub, + image_texel_pointer, SpvOpISub, type_mgr->GetTypeInstruction(query_size_type), query_max_including_faces_id, {{SPV_OPERAND_TYPE_ID, {query_size_including_faces->result_id()}}, @@ -1012,12 +1016,12 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( // Get the sample count via OpImageQuerySamples const auto query_samples_id = TakeNextId(); auto* query_samples = InsertInst( - image_texel_pointer, spv::Op::OpImageQuerySamples, + image_texel_pointer, SpvOpImageQuerySamples, constant_mgr->GetDefiningInstruction(component_0)->type_id(), query_samples_id, {{SPV_OPERAND_TYPE_ID, {image->result_id()}}}); const auto max_samples_id = TakeNextId(); - auto* max_samples = InsertInst(image_texel_pointer, spv::Op::OpImageQuerySamples, + auto* max_samples = InsertInst(image_texel_pointer, SpvOpImageQuerySamples, query_samples->type_id(), max_samples_id, {{SPV_OPERAND_TYPE_ID, {query_samples_id}}, {SPV_OPERAND_TYPE_ID, {component_1_id}}}); @@ -1039,7 +1043,7 @@ spv_result_t GraphicsRobustAccessPass::ClampCoordinateForImageTexelPointer( } opt::Instruction* GraphicsRobustAccessPass::InsertInst( - opt::Instruction* where_inst, spv::Op opcode, uint32_t type_id, + opt::Instruction* where_inst, SpvOp opcode, uint32_t type_id, uint32_t result_id, const Instruction::OperandList& operands) { module_status_.modified = true; auto* result = where_inst->InsertBefore( diff --git a/source/opt/graphics_robust_access_pass.h b/source/opt/graphics_robust_access_pass.h index a7ffe115..8f4c9dc7 100644 --- a/source/opt/graphics_robust_access_pass.h +++ b/source/opt/graphics_robust_access_pass.h @@ -133,7 +133,7 @@ class GraphicsRobustAccessPass : public Pass { // Returns a new instruction inserted before |where_inst|, and created from // the remaining arguments. Registers the definitions and uses of the new // instruction and also records its block. - opt::Instruction* InsertInst(opt::Instruction* where_inst, spv::Op opcode, + opt::Instruction* InsertInst(opt::Instruction* where_inst, SpvOp opcode, uint32_t type_id, uint32_t result_id, const Instruction::OperandList& operands); diff --git a/source/opt/if_conversion.cpp b/source/opt/if_conversion.cpp index 5912cf12..1232796e 100644 --- a/source/opt/if_conversion.cpp +++ b/source/opt/if_conversion.cpp @@ -23,7 +23,7 @@ namespace spvtools { namespace opt { Pass::Status IfConversion::Process() { - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { return Status::SuccessWithoutChange; } @@ -40,7 +40,7 @@ Pass::Status IfConversion::Process() { // Get an insertion point. auto iter = block.begin(); - while (iter != block.end() && iter->opcode() == spv::Op::OpPhi) { + while (iter != block.end() && iter->opcode() == SpvOpPhi) { ++iter; } @@ -171,26 +171,23 @@ bool IfConversion::CheckBlock(BasicBlock* block, DominatorAnalysis* dominators, *common = dominators->CommonDominator(inc0, inc1); if (!*common || cfg()->IsPseudoEntryBlock(*common)) return false; Instruction* branch = (*common)->terminator(); - if (branch->opcode() != spv::Op::OpBranchConditional) return false; + if (branch->opcode() != SpvOpBranchConditional) return false; auto merge = (*common)->GetMergeInst(); - if (!merge || merge->opcode() != spv::Op::OpSelectionMerge) return false; - if (spv::SelectionControlMask(merge->GetSingleWordInOperand(1)) == - spv::SelectionControlMask::DontFlatten) { + if (!merge || merge->opcode() != SpvOpSelectionMerge) return false; + if (merge->GetSingleWordInOperand(1) == SpvSelectionControlDontFlattenMask) return false; - } if ((*common)->MergeBlockIdIfAny() != block->id()) return false; return true; } bool IfConversion::CheckPhiUsers(Instruction* phi, BasicBlock* block) { - return get_def_use_mgr()->WhileEachUser( - phi, [block, this](Instruction* user) { - if (user->opcode() == spv::Op::OpPhi && - context()->get_instr_block(user) == block) - return false; - return true; - }); + return get_def_use_mgr()->WhileEachUser(phi, [block, + this](Instruction* user) { + if (user->opcode() == SpvOpPhi && context()->get_instr_block(user) == block) + return false; + return true; + }); } uint32_t IfConversion::SplatCondition(analysis::Vector* vec_data_ty, @@ -210,9 +207,9 @@ uint32_t IfConversion::SplatCondition(analysis::Vector* vec_data_ty, bool IfConversion::CheckType(uint32_t id) { Instruction* type = get_def_use_mgr()->GetDef(id); - spv::Op op = type->opcode(); - if (spvOpcodeIsScalarType(op) || op == spv::Op::OpTypePointer || - op == spv::Op::OpTypeVector) + SpvOp op = type->opcode(); + if (spvOpcodeIsScalarType(op) || op == SpvOpTypePointer || + op == SpvOpTypeVector) return true; return false; } @@ -258,7 +255,7 @@ void IfConversion::HoistInstruction(Instruction* inst, BasicBlock* target_block, }); Instruction* insertion_pos = target_block->terminator(); - if ((insertion_pos)->PreviousNode()->opcode() == spv::Op::OpSelectionMerge) { + if ((insertion_pos)->PreviousNode()->opcode() == SpvOpSelectionMerge) { insertion_pos = insertion_pos->PreviousNode(); } inst->RemoveFromList(); diff --git a/source/opt/inline_opaque_pass.cpp b/source/opt/inline_opaque_pass.cpp index 90a4c224..fe9c6799 100644 --- a/source/opt/inline_opaque_pass.cpp +++ b/source/opt/inline_opaque_pass.cpp @@ -21,24 +21,26 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kTypePointerTypeIdInIdx = 1; -} // namespace + +const uint32_t kTypePointerTypeIdInIdx = 1; + +} // anonymous namespace bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { const Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); switch (typeInst->opcode()) { - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampledImage: + case SpvOpTypeSampler: + case SpvOpTypeImage: + case SpvOpTypeSampledImage: return true; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: return IsOpaqueType( typeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx)); default: break; } // TODO(greg-lunarg): Handle arrays containing opaque type - if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; + if (typeInst->opcode() != SpvOpTypeStruct) return false; // Return true if any member is opaque return !typeInst->WhileEachInId([this](const uint32_t* tid) { if (IsOpaqueType(*tid)) return false; diff --git a/source/opt/inline_pass.cpp b/source/opt/inline_pass.cpp index 3f160b24..e14516f7 100644 --- a/source/opt/inline_pass.cpp +++ b/source/opt/inline_pass.cpp @@ -23,24 +23,24 @@ #include "source/opt/reflect.h" #include "source/util/make_unique.h" +// Indices of operands in SPIR-V instructions + +static const int kSpvFunctionCallFunctionId = 2; +static const int kSpvFunctionCallArgumentId = 3; +static const int kSpvReturnValueId = 0; + namespace spvtools { namespace opt { -namespace { -// Indices of operands in SPIR-V instructions -constexpr int kSpvFunctionCallFunctionId = 2; -constexpr int kSpvFunctionCallArgumentId = 3; -constexpr int kSpvReturnValueId = 0; -} // namespace uint32_t InlinePass::AddPointerToType(uint32_t type_id, - spv::StorageClass storage_class) { + SpvStorageClass storage_class) { uint32_t resultId = context()->TakeNextId(); if (resultId == 0) { return resultId; } std::unique_ptr type_inst( - new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, + new Instruction(context(), SpvOpTypePointer, 0, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, {uint32_t(storage_class)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); @@ -48,8 +48,8 @@ uint32_t InlinePass::AddPointerToType(uint32_t type_id, analysis::Type* pointeeTy; std::unique_ptr pointerTy; std::tie(pointeeTy, pointerTy) = - context()->get_type_mgr()->GetTypeAndPointerType( - type_id, spv::StorageClass::Function); + context()->get_type_mgr()->GetTypeAndPointerType(type_id, + SpvStorageClassFunction); context()->get_type_mgr()->RegisterType(resultId, *pointerTy); return resultId; } @@ -57,7 +57,7 @@ uint32_t InlinePass::AddPointerToType(uint32_t type_id, void InlinePass::AddBranch(uint32_t label_id, std::unique_ptr* block_ptr) { std::unique_ptr newBranch( - new Instruction(context(), spv::Op::OpBranch, 0, 0, + new Instruction(context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); (*block_ptr)->AddInstruction(std::move(newBranch)); } @@ -66,7 +66,7 @@ void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, uint32_t false_id, std::unique_ptr* block_ptr) { std::unique_ptr newBranch( - new Instruction(context(), spv::Op::OpBranchConditional, 0, 0, + new Instruction(context(), SpvOpBranchConditional, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); @@ -76,7 +76,7 @@ void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id, std::unique_ptr* block_ptr) { std::unique_ptr newLoopMerge(new Instruction( - context(), spv::Op::OpLoopMerge, 0, 0, + context(), SpvOpLoopMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {0}}})); @@ -88,7 +88,7 @@ void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id, const Instruction* line_inst, const DebugScope& dbg_scope) { std::unique_ptr newStore( - new Instruction(context(), spv::Op::OpStore, 0, 0, + new Instruction(context(), SpvOpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}})); if (line_inst != nullptr) { @@ -103,7 +103,7 @@ void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id, const Instruction* line_inst, const DebugScope& dbg_scope) { std::unique_ptr newLoad( - new Instruction(context(), spv::Op::OpLoad, type_id, resultId, + new Instruction(context(), SpvOpLoad, type_id, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}})); if (line_inst != nullptr) { newLoad->AddDebugLine(line_inst); @@ -114,27 +114,27 @@ void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id, std::unique_ptr InlinePass::NewLabel(uint32_t label_id) { std::unique_ptr newLabel( - new Instruction(context(), spv::Op::OpLabel, 0, label_id, {})); + new Instruction(context(), SpvOpLabel, 0, label_id, {})); return newLabel; } uint32_t InlinePass::GetFalseId() { if (false_id_ != 0) return false_id_; - false_id_ = get_module()->GetGlobalValue(spv::Op::OpConstantFalse); + false_id_ = get_module()->GetGlobalValue(SpvOpConstantFalse); if (false_id_ != 0) return false_id_; - uint32_t boolId = get_module()->GetGlobalValue(spv::Op::OpTypeBool); + uint32_t boolId = get_module()->GetGlobalValue(SpvOpTypeBool); if (boolId == 0) { boolId = context()->TakeNextId(); if (boolId == 0) { return 0; } - get_module()->AddGlobalValue(spv::Op::OpTypeBool, boolId, 0); + get_module()->AddGlobalValue(SpvOpTypeBool, boolId, 0); } false_id_ = context()->TakeNextId(); if (false_id_ == 0) { return 0; } - get_module()->AddGlobalValue(spv::Op::OpConstantFalse, false_id_, boolId); + get_module()->AddGlobalValue(SpvOpConstantFalse, false_id_, boolId); return false_id_; } @@ -157,10 +157,10 @@ bool InlinePass::CloneAndMapLocals( analysis::DebugInlinedAtContext* inlined_at_ctx) { auto callee_block_itr = calleeFn->begin(); auto callee_var_itr = callee_block_itr->begin(); - while (callee_var_itr->opcode() == spv::Op::OpVariable || + while (callee_var_itr->opcode() == SpvOp::SpvOpVariable || callee_var_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { - if (callee_var_itr->opcode() != spv::Op::OpVariable) { + if (callee_var_itr->opcode() != SpvOp::SpvOpVariable) { ++callee_var_itr; continue; } @@ -191,11 +191,10 @@ uint32_t InlinePass::CreateReturnVar( "Cannot create a return variable of type void."); // Find or create ptr to callee return type. uint32_t returnVarTypeId = - type_mgr->FindPointerToType(calleeTypeId, spv::StorageClass::Function); + type_mgr->FindPointerToType(calleeTypeId, SpvStorageClassFunction); if (returnVarTypeId == 0) { - returnVarTypeId = - AddPointerToType(calleeTypeId, spv::StorageClass::Function); + returnVarTypeId = AddPointerToType(calleeTypeId, SpvStorageClassFunction); if (returnVarTypeId == 0) { return 0; } @@ -207,18 +206,17 @@ uint32_t InlinePass::CreateReturnVar( return 0; } - std::unique_ptr var_inst(new Instruction( - context(), spv::Op::OpVariable, returnVarTypeId, returnVarId, - {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, - {(uint32_t)spv::StorageClass::Function}}})); + std::unique_ptr var_inst( + new Instruction(context(), SpvOpVariable, returnVarTypeId, returnVarId, + {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, + {SpvStorageClassFunction}}})); new_vars->push_back(std::move(var_inst)); get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId); return returnVarId; } bool InlinePass::IsSameBlockOp(const Instruction* inst) const { - return inst->opcode() == spv::Op::OpSampledImage || - inst->opcode() == spv::Op::OpImage; + return inst->opcode() == SpvOpSampledImage || inst->opcode() == SpvOpImage; } bool InlinePass::CloneSameBlockOps( @@ -301,9 +299,9 @@ InstructionList::iterator InlinePass::AddStoresForVariableInitializers( std::unique_ptr* new_blk_ptr, UptrVectorIterator callee_first_block_itr) { auto callee_itr = callee_first_block_itr->begin(); - while (callee_itr->opcode() == spv::Op::OpVariable || + while (callee_itr->opcode() == SpvOp::SpvOpVariable || callee_itr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { - if (callee_itr->opcode() == spv::Op::OpVariable && + if (callee_itr->opcode() == SpvOp::SpvOpVariable && callee_itr->NumInOperands() == 2) { assert(callee2caller.count(callee_itr->result_id()) && "Expected the variable to have already been mapped."); @@ -332,8 +330,7 @@ bool InlinePass::InlineSingleInstruction( BasicBlock* new_blk_ptr, const Instruction* inst, uint32_t dbg_inlined_at) { // If we have return, it must be at the end of the callee. We will handle // it at the end. - if (inst->opcode() == spv::Op::OpReturnValue || - inst->opcode() == spv::Op::OpReturn) + if (inst->opcode() == SpvOpReturnValue || inst->opcode() == SpvOpReturn) return true; // Copy callee instruction and remap all input Ids. @@ -369,7 +366,7 @@ std::unique_ptr InlinePass::InlineReturn( analysis::DebugInlinedAtContext* inlined_at_ctx, Function* calleeFn, const Instruction* inst, uint32_t returnVarId) { // Store return value to return variable. - if (inst->opcode() == spv::Op::OpReturnValue) { + if (inst->opcode() == SpvOpReturnValue) { assert(returnVarId != 0); uint32_t valId = inst->GetInOperand(kSpvReturnValueId).words[0]; const auto mapItr = callee2caller.find(valId); @@ -391,8 +388,7 @@ std::unique_ptr InlinePass::InlineReturn( } if (returnLabelId == 0) return new_blk_ptr; - if (inst->opcode() == spv::Op::OpReturn || - inst->opcode() == spv::Op::OpReturnValue) + if (inst->opcode() == SpvOpReturn || inst->opcode() == SpvOpReturnValue) AddBranch(returnLabelId, &new_blk_ptr); new_blocks->push_back(std::move(new_blk_ptr)); return MakeUnique(NewLabel(returnLabelId)); @@ -503,7 +499,7 @@ void InlinePass::MoveLoopMergeInstToFirstBlock( // Insert a modified copy of the loop merge into the first block. auto loop_merge_itr = last->tail(); --loop_merge_itr; - assert(loop_merge_itr->opcode() == spv::Op::OpLoopMerge); + assert(loop_merge_itr->opcode() == SpvOpLoopMerge); std::unique_ptr cp_inst(loop_merge_itr->Clone(context())); first->tail().InsertBefore(std::move(cp_inst)); @@ -700,7 +696,7 @@ bool InlinePass::GenInlineCode( } bool InlinePass::IsInlinableFunctionCall(const Instruction* inst) { - if (inst->opcode() != spv::Op::OpFunctionCall) return false; + if (inst->opcode() != SpvOp::SpvOpFunctionCall) return false; const uint32_t calleeFnId = inst->GetSingleWordOperand(kSpvFunctionCallFunctionId); const auto ci = inlinable_.find(calleeFnId); @@ -742,7 +738,7 @@ void InlinePass::UpdateSucceedingPhis( bool InlinePass::HasNoReturnInLoop(Function* func) { // If control not structured, do not do loop/return analysis // TODO: Analyze returns in non-structured control flow - if (!context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) return false; const auto structured_analysis = context()->GetStructuredCFGAnalysis(); // Search for returns in structured construct. @@ -780,7 +776,7 @@ bool InlinePass::IsInlinableFunction(Function* func) { if (func->cbegin() == func->cend()) return false; // Do not inline functions with DontInline flag. - if (func->control_mask() & uint32_t(spv::FunctionControlMask::DontInline)) { + if (func->control_mask() & SpvFunctionControlDontInlineMask) { return false; } @@ -815,7 +811,7 @@ bool InlinePass::IsInlinableFunction(Function* func) { bool InlinePass::ContainsAbortOtherThanUnreachable(Function* func) const { return !func->WhileEachInst([](Instruction* inst) { - return inst->opcode() == spv::Op::OpUnreachable || + return inst->opcode() == SpvOpUnreachable || !spvOpcodeIsAbort(inst->opcode()); }); } diff --git a/source/opt/inline_pass.h b/source/opt/inline_pass.h index 1c9d60e3..d29c1e07 100644 --- a/source/opt/inline_pass.h +++ b/source/opt/inline_pass.h @@ -44,7 +44,7 @@ class InlinePass : public Pass { // Add pointer to type to module and return resultId. Returns 0 if the type // could not be created. - uint32_t AddPointerToType(uint32_t type_id, spv::StorageClass storage_class); + uint32_t AddPointerToType(uint32_t type_id, SpvStorageClass storage_class); // Add unconditional branch to labelId to end of block block_ptr. void AddBranch(uint32_t labelId, std::unique_ptr* block_ptr); diff --git a/source/opt/inst_bindless_check_pass.cpp b/source/opt/inst_bindless_check_pass.cpp index 8e7d4f83..c2c5d6cb 100644 --- a/source/opt/inst_bindless_check_pass.cpp +++ b/source/opt/inst_bindless_check_pass.cpp @@ -16,128 +16,88 @@ #include "inst_bindless_check_pass.h" -#include "source/spirv_constant.h" +namespace { + +// Input Operand Indices +static const int kSpvImageSampleImageIdInIdx = 0; +static const int kSpvSampledImageImageIdInIdx = 0; +static const int kSpvSampledImageSamplerIdInIdx = 1; +static const int kSpvImageSampledImageIdInIdx = 0; +static const int kSpvCopyObjectOperandIdInIdx = 0; +static const int kSpvLoadPtrIdInIdx = 0; +static const int kSpvAccessChainBaseIdInIdx = 0; +static const int kSpvAccessChainIndex0IdInIdx = 1; +static const int kSpvTypeArrayTypeIdInIdx = 0; +static const int kSpvTypeArrayLengthIdInIdx = 1; +static const int kSpvConstantValueInIdx = 0; +static const int kSpvVariableStorageClassInIdx = 0; +static const int kSpvTypePtrTypeIdInIdx = 1; +static const int kSpvTypeImageDim = 1; +static const int kSpvTypeImageDepth = 2; +static const int kSpvTypeImageArrayed = 3; +static const int kSpvTypeImageMS = 4; +static const int kSpvTypeImageSampled = 5; +} // anonymous namespace namespace spvtools { namespace opt { -namespace { -// Input Operand Indices -constexpr int kSpvImageSampleImageIdInIdx = 0; -constexpr int kSpvSampledImageImageIdInIdx = 0; -constexpr int kSpvSampledImageSamplerIdInIdx = 1; -constexpr int kSpvImageSampledImageIdInIdx = 0; -constexpr int kSpvCopyObjectOperandIdInIdx = 0; -constexpr int kSpvLoadPtrIdInIdx = 0; -constexpr int kSpvAccessChainBaseIdInIdx = 0; -constexpr int kSpvAccessChainIndex0IdInIdx = 1; -constexpr int kSpvTypeArrayTypeIdInIdx = 0; -constexpr int kSpvVariableStorageClassInIdx = 0; -constexpr int kSpvTypePtrTypeIdInIdx = 1; -constexpr int kSpvTypeImageDim = 1; -constexpr int kSpvTypeImageDepth = 2; -constexpr int kSpvTypeImageArrayed = 3; -constexpr int kSpvTypeImageMS = 4; -} // namespace -// This is a stub function for use with Import linkage -// clang-format off -// GLSL: -//bool inst_bindless_check_desc(const uint shader_id, const uint inst_num, const uvec4 stage_info, const uint desc_set, -// const uint binding, const uint desc_index, const uint byte_offset) { -//} -// clang-format on -uint32_t InstBindlessCheckPass::GenDescCheckFunctionId() { - enum { - kShaderId = 0, - kInstructionIndex = 1, - kStageInfo = 2, - kDescSet = 3, - kDescBinding = 4, - kDescIndex = 5, - kByteOffset = 6, - kNumArgs - }; - if (check_desc_func_id_ != 0) { - return check_desc_func_id_; - } - - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - const analysis::Integer* uint_type = GetInteger(32, false); - const analysis::Vector v4uint(uint_type, 4); - const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint); - std::vector param_types(kNumArgs, uint_type); - param_types[2] = v4uint_type; - - const uint32_t func_id = TakeNextId(); - std::unique_ptr func = - StartFunction(func_id, type_mgr->GetBoolType(), param_types); - - func->SetFunctionEnd(EndFunction()); - - static const std::string func_name{"inst_bindless_check_desc"}; - context()->AddFunctionDeclaration(std::move(func)); - context()->AddDebug2Inst(NewName(func_id, func_name)); - std::vector operands{ - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::Decoration::LinkageAttributes)}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING, - utils::MakeVector(func_name.c_str())}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE, - {uint32_t(spv::LinkageType::Import)}}, - }; - get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands); - - check_desc_func_id_ = func_id; - // Make sure function doesn't get processed by - // InstrumentPass::InstProcessCallTreeFromRoots() - param2output_func_id_[3] = func_id; - return check_desc_func_id_; +uint32_t InstBindlessCheckPass::GenDebugReadLength( + uint32_t var_id, InstructionBuilder* builder) { + uint32_t desc_set_idx = + var2desc_set_[var_id] + kDebugInputBindlessOffsetLengths; + uint32_t desc_set_idx_id = builder->GetUintConstantId(desc_set_idx); + uint32_t binding_idx_id = builder->GetUintConstantId(var2binding_[var_id]); + return GenDebugDirectRead({desc_set_idx_id, binding_idx_id}, builder); } -// clang-format off -// GLSL: -// result = inst_bindless_check_desc(shader_id, inst_idx, stage_info, desc_set, binding, desc_idx, offset); -// -// clang-format on -uint32_t InstBindlessCheckPass::GenDescCheckCall( - uint32_t inst_idx, uint32_t stage_idx, uint32_t var_id, - uint32_t desc_idx_id, uint32_t offset_id, InstructionBuilder* builder) { - const uint32_t func_id = GenDescCheckFunctionId(); - const std::vector args = { - builder->GetUintConstantId(shader_id_), - builder->GetUintConstantId(inst_idx), - GenStageInfo(stage_idx, builder), - builder->GetUintConstantId(var2desc_set_[var_id]), - builder->GetUintConstantId(var2binding_[var_id]), - GenUintCastCode(desc_idx_id, builder), - offset_id}; - return GenReadFunctionCall(GetBoolId(), func_id, args, builder); +uint32_t InstBindlessCheckPass::GenDebugReadInit(uint32_t var_id, + uint32_t desc_idx_id, + InstructionBuilder* builder) { + uint32_t binding_idx_id = builder->GetUintConstantId(var2binding_[var_id]); + uint32_t u_desc_idx_id = GenUintCastCode(desc_idx_id, builder); + // If desc index checking is not enabled, we know the offset of initialization + // entries is 1, so we can avoid loading this value and just add 1 to the + // descriptor set. + if (!desc_idx_enabled_) { + uint32_t desc_set_idx_id = + builder->GetUintConstantId(var2desc_set_[var_id] + 1); + return GenDebugDirectRead({desc_set_idx_id, binding_idx_id, u_desc_idx_id}, + builder); + } else { + uint32_t desc_set_base_id = + builder->GetUintConstantId(kDebugInputBindlessInitOffset); + uint32_t desc_set_idx_id = + builder->GetUintConstantId(var2desc_set_[var_id]); + return GenDebugDirectRead( + {desc_set_base_id, desc_set_idx_id, binding_idx_id, u_desc_idx_id}, + builder); + } } uint32_t InstBindlessCheckPass::CloneOriginalImage( uint32_t old_image_id, InstructionBuilder* builder) { Instruction* new_image_inst; Instruction* old_image_inst = get_def_use_mgr()->GetDef(old_image_id); - if (old_image_inst->opcode() == spv::Op::OpLoad) { + if (old_image_inst->opcode() == SpvOpLoad) { new_image_inst = builder->AddLoad( old_image_inst->type_id(), old_image_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx)); - } else if (old_image_inst->opcode() == spv::Op::OpSampledImage) { + } else if (old_image_inst->opcode() == SpvOp::SpvOpSampledImage) { uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx), builder); new_image_inst = builder->AddBinaryOp( - old_image_inst->type_id(), spv::Op::OpSampledImage, clone_id, + old_image_inst->type_id(), SpvOpSampledImage, clone_id, old_image_inst->GetSingleWordInOperand(kSpvSampledImageSamplerIdInIdx)); - } else if (old_image_inst->opcode() == spv::Op::OpImage) { + } else if (old_image_inst->opcode() == SpvOp::SpvOpImage) { uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx), builder); - new_image_inst = builder->AddUnaryOp(old_image_inst->type_id(), - spv::Op::OpImage, clone_id); + new_image_inst = + builder->AddUnaryOp(old_image_inst->type_id(), SpvOpImage, clone_id); } else { - assert(old_image_inst->opcode() == spv::Op::OpCopyObject && + assert(old_image_inst->opcode() == SpvOp::SpvOpCopyObject && "expecting OpCopyObject"); uint32_t clone_id = CloneOriginalImage( old_image_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx), @@ -183,38 +143,38 @@ uint32_t InstBindlessCheckPass::CloneOriginalReference( uint32_t InstBindlessCheckPass::GetImageId(Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageQueryLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageFetch: - case spv::Op::OpImageRead: - case spv::Op::OpImageQueryFormat: - case spv::Op::OpImageQueryOrder: - case spv::Op::OpImageQuerySizeLod: - case spv::Op::OpImageQuerySize: - case spv::Op::OpImageQueryLevels: - case spv::Op::OpImageQuerySamples: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseRead: - case spv::Op::OpImageWrite: + case SpvOp::SpvOpImageSampleImplicitLod: + case SpvOp::SpvOpImageSampleExplicitLod: + case SpvOp::SpvOpImageSampleDrefImplicitLod: + case SpvOp::SpvOpImageSampleDrefExplicitLod: + case SpvOp::SpvOpImageSampleProjImplicitLod: + case SpvOp::SpvOpImageSampleProjExplicitLod: + case SpvOp::SpvOpImageSampleProjDrefImplicitLod: + case SpvOp::SpvOpImageSampleProjDrefExplicitLod: + case SpvOp::SpvOpImageGather: + case SpvOp::SpvOpImageDrefGather: + case SpvOp::SpvOpImageQueryLod: + case SpvOp::SpvOpImageSparseSampleImplicitLod: + case SpvOp::SpvOpImageSparseSampleExplicitLod: + case SpvOp::SpvOpImageSparseSampleDrefImplicitLod: + case SpvOp::SpvOpImageSparseSampleDrefExplicitLod: + case SpvOp::SpvOpImageSparseSampleProjImplicitLod: + case SpvOp::SpvOpImageSparseSampleProjExplicitLod: + case SpvOp::SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOp::SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOp::SpvOpImageSparseGather: + case SpvOp::SpvOpImageSparseDrefGather: + case SpvOp::SpvOpImageFetch: + case SpvOp::SpvOpImageRead: + case SpvOp::SpvOpImageQueryFormat: + case SpvOp::SpvOpImageQueryOrder: + case SpvOp::SpvOpImageQuerySizeLod: + case SpvOp::SpvOpImageQuerySize: + case SpvOp::SpvOpImageQueryLevels: + case SpvOp::SpvOpImageQuerySamples: + case SpvOp::SpvOpImageSparseFetch: + case SpvOp::SpvOpImageSparseRead: + case SpvOp::SpvOpImageWrite: return inst->GetSingleWordInOperand(kSpvImageSampleImageIdInIdx); default: break; @@ -230,58 +190,56 @@ Instruction* InstBindlessCheckPass::GetPointeeTypeInst(Instruction* ptr_inst) { bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, RefAnalysis* ref) { ref->ref_inst = ref_inst; - if (ref_inst->opcode() == spv::Op::OpLoad || - ref_inst->opcode() == spv::Op::OpStore) { + if (ref_inst->opcode() == SpvOpLoad || ref_inst->opcode() == SpvOpStore) { ref->desc_load_id = 0; ref->ptr_id = ref_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); - if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; + if (ptr_inst->opcode() != SpvOp::SpvOpAccessChain) return false; ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); - if (var_inst->opcode() != spv::Op::OpVariable) return false; - spv::StorageClass storage_class = spv::StorageClass( - var_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx)); + if (var_inst->opcode() != SpvOp::SpvOpVariable) return false; + uint32_t storage_class = + var_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx); switch (storage_class) { - case spv::StorageClass::Uniform: - case spv::StorageClass::StorageBuffer: + case SpvStorageClassUniform: + case SpvStorageClassStorageBuffer: break; default: return false; break; } // Check for deprecated storage block form - if (storage_class == spv::StorageClass::Uniform) { + if (storage_class == SpvStorageClassUniform) { uint32_t var_ty_id = var_inst->type_id(); Instruction* var_ty_inst = get_def_use_mgr()->GetDef(var_ty_id); uint32_t ptr_ty_id = var_ty_inst->GetSingleWordInOperand(kSpvTypePtrTypeIdInIdx); Instruction* ptr_ty_inst = get_def_use_mgr()->GetDef(ptr_ty_id); - spv::Op ptr_ty_op = ptr_ty_inst->opcode(); + SpvOp ptr_ty_op = ptr_ty_inst->opcode(); uint32_t block_ty_id = - (ptr_ty_op == spv::Op::OpTypeArray || - ptr_ty_op == spv::Op::OpTypeRuntimeArray) + (ptr_ty_op == SpvOpTypeArray || ptr_ty_op == SpvOpTypeRuntimeArray) ? ptr_ty_inst->GetSingleWordInOperand(kSpvTypeArrayTypeIdInIdx) : ptr_ty_id; assert(get_def_use_mgr()->GetDef(block_ty_id)->opcode() == - spv::Op::OpTypeStruct && + SpvOpTypeStruct && "unexpected block type"); bool block_found = get_decoration_mgr()->FindDecoration( - block_ty_id, uint32_t(spv::Decoration::Block), + block_ty_id, SpvDecorationBlock, [](const Instruction&) { return true; }); if (!block_found) { // If block decoration not found, verify deprecated form of SSBO bool buffer_block_found = get_decoration_mgr()->FindDecoration( - block_ty_id, uint32_t(spv::Decoration::BufferBlock), + block_ty_id, SpvDecorationBufferBlock, [](const Instruction&) { return true; }); USE_ASSERT(buffer_block_found && "block decoration not found"); - storage_class = spv::StorageClass::StorageBuffer; + storage_class = SpvStorageClassStorageBuffer; } } - ref->strg_class = uint32_t(storage_class); + ref->strg_class = storage_class; Instruction* desc_type_inst = GetPointeeTypeInst(var_inst); switch (desc_type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: // A load through a descriptor array will have at least 3 operands. We // do not want to instrument loads of descriptors here which are part of // an image-based reference. @@ -290,18 +248,9 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx); break; default: + ref->desc_idx_id = 0; break; } - auto decos = - context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false); - for (const auto& deco : decos) { - spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); - if (d == spv::Decoration::DescriptorSet) { - ref->set = deco->GetSingleWordInOperand(2u); - } else if (d == spv::Decoration::Binding) { - ref->binding = deco->GetSingleWordInOperand(2u); - } - } return true; } // Reference is not load or store. If not an image-based reference, return. @@ -312,29 +261,29 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, Instruction* desc_load_inst; for (;;) { desc_load_inst = get_def_use_mgr()->GetDef(desc_load_id); - if (desc_load_inst->opcode() == spv::Op::OpSampledImage) + if (desc_load_inst->opcode() == SpvOp::SpvOpSampledImage) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx); - else if (desc_load_inst->opcode() == spv::Op::OpImage) + else if (desc_load_inst->opcode() == SpvOp::SpvOpImage) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx); - else if (desc_load_inst->opcode() == spv::Op::OpCopyObject) + else if (desc_load_inst->opcode() == SpvOp::SpvOpCopyObject) desc_load_id = desc_load_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx); else break; } - if (desc_load_inst->opcode() != spv::Op::OpLoad) { + if (desc_load_inst->opcode() != SpvOp::SpvOpLoad) { // TODO(greg-lunarg): Handle additional possibilities? return false; } ref->desc_load_id = desc_load_id; ref->ptr_id = desc_load_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx); Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id); - if (ptr_inst->opcode() == spv::Op::OpVariable) { + if (ptr_inst->opcode() == SpvOp::SpvOpVariable) { ref->desc_idx_id = 0; ref->var_id = ref->ptr_id; - } else if (ptr_inst->opcode() == spv::Op::OpAccessChain) { + } else if (ptr_inst->opcode() == SpvOp::SpvOpAccessChain) { if (ptr_inst->NumInOperands() != 2) { assert(false && "unexpected bindless index number"); return false; @@ -343,7 +292,7 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, ptr_inst->GetSingleWordInOperand(kSpvAccessChainIndex0IdInIdx); ref->var_id = ptr_inst->GetSingleWordInOperand(kSpvAccessChainBaseIdInIdx); Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id); - if (var_inst->opcode() != spv::Op::OpVariable) { + if (var_inst->opcode() != SpvOpVariable) { assert(false && "unexpected bindless base"); return false; } @@ -351,16 +300,6 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst, // TODO(greg-lunarg): Handle additional possibilities? return false; } - auto decos = - context()->get_decoration_mgr()->GetDecorationsFor(ref->var_id, false); - for (const auto& deco : decos) { - spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); - if (d == spv::Decoration::DescriptorSet) { - ref->set = deco->GetSingleWordInOperand(2u); - } else if (d == spv::Decoration::Binding) { - ref->binding = deco->GetSingleWordInOperand(2u); - } - } return true; } @@ -430,13 +369,13 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, uint32_t buff_ty_id; uint32_t ac_in_idx = 1; switch (desc_ty_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: buff_ty_id = desc_ty_inst->GetSingleWordInOperand(0); ++ac_in_idx; break; default: - assert(desc_ty_inst->opcode() == spv::Op::OpTypeStruct && + assert(desc_ty_inst->opcode() == SpvOpTypeStruct && "unexpected descriptor type"); buff_ty_id = desc_ty_inst->result_id(); break; @@ -454,20 +393,19 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, Instruction* curr_ty_inst = get_def_use_mgr()->GetDef(curr_ty_id); uint32_t curr_offset_id = 0; switch (curr_ty_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: { + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: { // Get array stride and multiply by current index - uint32_t arr_stride = - FindStride(curr_ty_id, uint32_t(spv::Decoration::ArrayStride)); + uint32_t arr_stride = FindStride(curr_ty_id, SpvDecorationArrayStride); uint32_t arr_stride_id = builder->GetUintConstantId(arr_stride); uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), spv::Op::OpIMul, arr_stride_id, curr_idx_32b_id); + GetUintId(), SpvOpIMul, arr_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); // Get element type for next step curr_ty_id = curr_ty_inst->GetSingleWordInOperand(0); } break; - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { assert(matrix_stride != 0 && "missing matrix stride"); matrix_stride_id = builder->GetUintConstantId(matrix_stride); uint32_t vec_ty_id = curr_ty_inst->GetSingleWordInOperand(0); @@ -485,40 +423,40 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, } uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), spv::Op::OpIMul, col_stride_id, curr_idx_32b_id); + GetUintId(), SpvOpIMul, col_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); // Get element type for next step curr_ty_id = vec_ty_id; in_matrix = true; } break; - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { // If inside a row major matrix type, multiply index by matrix stride, // else multiply by component size uint32_t comp_ty_id = curr_ty_inst->GetSingleWordInOperand(0u); uint32_t curr_idx_32b_id = Gen32BitCvtCode(curr_idx_id, builder); if (in_matrix && !col_major) { Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), spv::Op::OpIMul, matrix_stride_id, curr_idx_32b_id); + GetUintId(), SpvOpIMul, matrix_stride_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); } else { uint32_t comp_ty_sz = ByteSize(comp_ty_id, 0u, false, false); uint32_t comp_ty_sz_id = builder->GetUintConstantId(comp_ty_sz); Instruction* curr_offset_inst = builder->AddBinaryOp( - GetUintId(), spv::Op::OpIMul, comp_ty_sz_id, curr_idx_32b_id); + GetUintId(), SpvOpIMul, comp_ty_sz_id, curr_idx_32b_id); curr_offset_id = curr_offset_inst->result_id(); } // Get element type for next step curr_ty_id = comp_ty_id; } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // Get buffer byte offset for the referenced member Instruction* curr_idx_inst = get_def_use_mgr()->GetDef(curr_idx_id); - assert(curr_idx_inst->opcode() == spv::Op::OpConstant && + assert(curr_idx_inst->opcode() == SpvOpConstant && "unexpected struct index"); uint32_t member_idx = curr_idx_inst->GetSingleWordInOperand(0); uint32_t member_offset = 0xdeadbeef; bool found = get_decoration_mgr()->FindDecoration( - curr_ty_id, uint32_t(spv::Decoration::Offset), + curr_ty_id, SpvDecorationOffset, [&member_idx, &member_offset](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -532,7 +470,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, // enclosing struct type at the member index. If none found, reset // stride to 0. found = get_decoration_mgr()->FindDecoration( - curr_ty_id, uint32_t(spv::Decoration::MatrixStride), + curr_ty_id, SpvDecorationMatrixStride, [&member_idx, &matrix_stride](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -542,7 +480,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, if (!found) matrix_stride = 0; // Look for column major decoration found = get_decoration_mgr()->FindDecoration( - curr_ty_id, uint32_t(spv::Decoration::ColMajor), + curr_ty_id, SpvDecorationColMajor, [&member_idx, &col_major](const Instruction& deco_inst) { if (deco_inst.GetSingleWordInOperand(1u) != member_idx) return false; @@ -559,7 +497,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, sum_id = curr_offset_id; else { Instruction* sum_inst = - builder->AddIAdd(GetUintId(), sum_id, curr_offset_id); + builder->AddBinaryOp(GetUintId(), SpvOpIAdd, sum_id, curr_offset_id); sum_id = sum_inst->result_id(); } ++ac_in_idx; @@ -568,12 +506,14 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref, uint32_t bsize = ByteSize(curr_ty_id, matrix_stride, col_major, in_matrix); uint32_t last = bsize - 1; uint32_t last_id = builder->GetUintConstantId(last); - Instruction* sum_inst = builder->AddIAdd(GetUintId(), sum_id, last_id); + Instruction* sum_inst = + builder->AddBinaryOp(GetUintId(), SpvOpIAdd, sum_id, last_id); return sum_inst->result_id(); } void InstBindlessCheckPass::GenCheckCode( - uint32_t check_id, RefAnalysis* ref, + uint32_t check_id, uint32_t error_id, uint32_t offset_id, + uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref, std::vector>* new_blocks) { BasicBlock* back_blk_ptr = &*new_blocks->back(); InstructionBuilder builder( @@ -587,39 +527,44 @@ void InstBindlessCheckPass::GenCheckCode( std::unique_ptr merge_label(NewLabel(merge_blk_id)); std::unique_ptr valid_label(NewLabel(valid_blk_id)); std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); - (void)builder.AddConditionalBranch( - check_id, valid_blk_id, invalid_blk_id, merge_blk_id, - uint32_t(spv::SelectionControlMask::MaskNone)); + (void)builder.AddConditionalBranch(check_id, valid_blk_id, invalid_blk_id, + merge_blk_id, SpvSelectionControlMaskNone); // Gen valid bounds branch std::unique_ptr new_blk_ptr( new BasicBlock(std::move(valid_label))); builder.SetInsertPoint(&*new_blk_ptr); uint32_t new_ref_id = CloneOriginalReference(ref, &builder); - uint32_t null_id = 0; - uint32_t ref_type_id = ref->ref_inst->type_id(); (void)builder.AddBranch(merge_blk_id); new_blocks->push_back(std::move(new_blk_ptr)); // Gen invalid block new_blk_ptr.reset(new BasicBlock(std::move(invalid_label))); builder.SetInsertPoint(&*new_blk_ptr); - - // Generate a ConstantNull, converting to uint64 if the type cannot be a null. - if (new_ref_id != 0) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::Type* ref_type = type_mgr->GetType(ref_type_id); - if (ref_type->AsPointer() != nullptr) { - context()->AddCapability(spv::Capability::Int64); - uint32_t null_u64_id = GetNullId(GetUint64Id()); - Instruction* null_ptr_inst = builder.AddUnaryOp( - ref_type_id, spv::Op::OpConvertUToPtr, null_u64_id); - null_id = null_ptr_inst->result_id(); - } else { - null_id = GetNullId(ref_type_id); - } + uint32_t u_index_id = GenUintCastCode(ref->desc_idx_id, &builder); + if (offset_id != 0) { + // Buffer OOB + uint32_t u_offset_id = GenUintCastCode(offset_id, &builder); + uint32_t u_length_id = GenUintCastCode(length_id, &builder); + GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx, + {error_id, u_index_id, u_offset_id, u_length_id}, + &builder); + } else if (buffer_bounds_enabled_ || texel_buffer_enabled_) { + // Uninitialized Descriptor - Return additional unused zero so all error + // modes will use same debug stream write function + uint32_t u_length_id = GenUintCastCode(length_id, &builder); + GenDebugStreamWrite( + uid2offset_[ref->ref_inst->unique_id()], stage_idx, + {error_id, u_index_id, u_length_id, builder.GetUintConstantId(0)}, + &builder); + } else { + // Uninitialized Descriptor - Normal error return + uint32_t u_length_id = GenUintCastCode(length_id, &builder); + GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx, + {error_id, u_index_id, u_length_id}, &builder); } // Remember last invalid block id uint32_t last_invalid_blk_id = new_blk_ptr->GetLabelInst()->result_id(); // Gen zero for invalid reference + uint32_t ref_type_id = ref->ref_inst->type_id(); (void)builder.AddBranch(merge_blk_id); new_blocks->push_back(std::move(new_blk_ptr)); // Gen merge block @@ -630,7 +575,8 @@ void InstBindlessCheckPass::GenCheckCode( // reference. if (new_ref_id != 0) { Instruction* phi_inst = builder.AddPhi( - ref_type_id, {new_ref_id, valid_blk_id, null_id, last_invalid_blk_id}); + ref_type_id, {new_ref_id, valid_blk_id, GetNullId(ref_type_id), + last_invalid_blk_id}); context()->ReplaceAllUsesWith(ref->ref_inst->result_id(), phi_inst->result_id()); } @@ -638,67 +584,186 @@ void InstBindlessCheckPass::GenCheckCode( context()->KillInst(ref->ref_inst); } -void InstBindlessCheckPass::GenDescCheckCode( +void InstBindlessCheckPass::GenDescIdxCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + // Look for reference through indexed descriptor. If found, analyze and + // save components. If not, return. + RefAnalysis ref; + if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return; + Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id); + if (ptr_inst->opcode() != SpvOp::SpvOpAccessChain) return; + // If index and bound both compile-time constants and index < bound, + // return without changing + Instruction* var_inst = get_def_use_mgr()->GetDef(ref.var_id); + Instruction* desc_type_inst = GetPointeeTypeInst(var_inst); + uint32_t length_id = 0; + if (desc_type_inst->opcode() == SpvOpTypeArray) { + length_id = + desc_type_inst->GetSingleWordInOperand(kSpvTypeArrayLengthIdInIdx); + Instruction* index_inst = get_def_use_mgr()->GetDef(ref.desc_idx_id); + Instruction* length_inst = get_def_use_mgr()->GetDef(length_id); + if (index_inst->opcode() == SpvOpConstant && + length_inst->opcode() == SpvOpConstant && + index_inst->GetSingleWordInOperand(kSpvConstantValueInIdx) < + length_inst->GetSingleWordInOperand(kSpvConstantValueInIdx)) + return; + } else if (!desc_idx_enabled_ || + desc_type_inst->opcode() != SpvOpTypeRuntimeArray) { + return; + } + // Move original block's preceding instructions into first new block + std::unique_ptr new_blk_ptr; + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_blocks->push_back(std::move(new_blk_ptr)); + uint32_t error_id = builder.GetUintConstantId(kInstErrorBindlessBounds); + // If length id not yet set, descriptor array is runtime size so + // generate load of length from stage's debug input buffer. + if (length_id == 0) { + assert(desc_type_inst->opcode() == SpvOpTypeRuntimeArray && + "unexpected bindless type"); + length_id = GenDebugReadLength(ref.var_id, &builder); + } + // Generate full runtime bounds test code with true branch + // being full reference and false branch being debug output and zero + // for the referenced value. + uint32_t desc_idx_32b_id = Gen32BitCvtCode(ref.desc_idx_id, &builder); + uint32_t length_32b_id = Gen32BitCvtCode(length_id, &builder); + Instruction* ult_inst = builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, + desc_idx_32b_id, length_32b_id); + ref.desc_idx_id = desc_idx_32b_id; + GenCheckCode(ult_inst->result_id(), error_id, 0u, length_id, stage_idx, &ref, + new_blocks); + // Move original block's remaining code into remainder/merge block and add + // to new blocks + BasicBlock* back_blk_ptr = &*new_blocks->back(); + MovePostludeCode(ref_block_itr, back_blk_ptr); +} + +void InstBindlessCheckPass::GenDescInitCheckCode( BasicBlock::iterator ref_inst_itr, UptrVectorIterator ref_block_itr, uint32_t stage_idx, std::vector>* new_blocks) { // Look for reference through descriptor. If not, return. RefAnalysis ref; if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return; - std::unique_ptr new_blk_ptr; - // Move original block's preceding instructions into first new block - MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); - InstructionBuilder builder( - context(), &*new_blk_ptr, - IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - new_blocks->push_back(std::move(new_blk_ptr)); // Determine if we can only do initialization check - uint32_t ref_id = builder.GetUintConstantId(0u); - spv::Op op = ref.ref_inst->opcode(); - if (ref.desc_load_id != 0) { - uint32_t num_in_oprnds = ref.ref_inst->NumInOperands(); - if ((op == spv::Op::OpImageRead && num_in_oprnds == 2) || - (op == spv::Op::OpImageFetch && num_in_oprnds == 2) || - (op == spv::Op::OpImageWrite && num_in_oprnds == 3)) { - Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id); - uint32_t image_ty_id = image_inst->type_id(); - Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id); - if (spv::Dim(image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim)) == - spv::Dim::Buffer) { - if ((image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) == 0) && - (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) == - 0) && - (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) == 0)) { - ref_id = GenUintCastCode(ref.ref_inst->GetSingleWordInOperand(1), - &builder); - } - } - } + bool init_check = false; + if (ref.desc_load_id != 0 || !buffer_bounds_enabled_) { + init_check = true; } else { // For now, only do bounds check for non-aggregate types. Otherwise // just do descriptor initialization check. // TODO(greg-lunarg): Do bounds check for aggregate loads and stores Instruction* ref_ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id); Instruction* pte_type_inst = GetPointeeTypeInst(ref_ptr_inst); - spv::Op pte_type_op = pte_type_inst->opcode(); - if (pte_type_op != spv::Op::OpTypeArray && - pte_type_op != spv::Op::OpTypeRuntimeArray && - pte_type_op != spv::Op::OpTypeStruct) { - ref_id = GenLastByteIdx(&ref, &builder); - } + uint32_t pte_type_op = pte_type_inst->opcode(); + if (pte_type_op == SpvOpTypeArray || pte_type_op == SpvOpTypeRuntimeArray || + pte_type_op == SpvOpTypeStruct) + init_check = true; } + // If initialization check and not enabled, return + if (init_check && !desc_init_enabled_) return; + // Move original block's preceding instructions into first new block + std::unique_ptr new_blk_ptr; + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_blocks->push_back(std::move(new_blk_ptr)); + // If initialization check, use reference value of zero. + // Else use the index of the last byte referenced. + uint32_t ref_id = init_check ? builder.GetUintConstantId(0u) + : GenLastByteIdx(&ref, &builder); // Read initialization/bounds from debug input buffer. If index id not yet // set, binding is single descriptor, so set index to constant 0. if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u); - uint32_t check_id = - GenDescCheckCall(ref.ref_inst->unique_id(), stage_idx, ref.var_id, - ref.desc_idx_id, ref_id, &builder); - + uint32_t init_id = GenDebugReadInit(ref.var_id, ref.desc_idx_id, &builder); // Generate runtime initialization/bounds test code with true branch - // being full reference and false branch being zero + // being full reference and false branch being debug output and zero // for the referenced value. - GenCheckCode(check_id, &ref, new_blocks); + Instruction* ult_inst = + builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, ref_id, init_id); + uint32_t error = init_check ? kInstErrorBindlessUninit + : (ref.strg_class == SpvStorageClassUniform + ? kInstErrorBuffOOBUniform + : kInstErrorBuffOOBStorage); + uint32_t error_id = builder.GetUintConstantId(error); + GenCheckCode(ult_inst->result_id(), error_id, init_check ? 0 : ref_id, + init_check ? builder.GetUintConstantId(0u) : init_id, stage_idx, + &ref, new_blocks); + // Move original block's remaining code into remainder/merge block and add + // to new blocks + BasicBlock* back_blk_ptr = &*new_blocks->back(); + MovePostludeCode(ref_block_itr, back_blk_ptr); +} +void InstBindlessCheckPass::GenTexBuffCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks) { + // Only process OpImageRead and OpImageWrite with no optional operands + Instruction* ref_inst = &*ref_inst_itr; + SpvOp op = ref_inst->opcode(); + uint32_t num_in_oprnds = ref_inst->NumInOperands(); + if (!((op == SpvOpImageRead && num_in_oprnds == 2) || + (op == SpvOpImageFetch && num_in_oprnds == 2) || + (op == SpvOpImageWrite && num_in_oprnds == 3))) + return; + // Pull components from descriptor reference + RefAnalysis ref; + if (!AnalyzeDescriptorReference(ref_inst, &ref)) return; + // Only process if image is texel buffer + Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id); + uint32_t image_ty_id = image_inst->type_id(); + Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id); + if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim) != SpvDimBuffer) + return; + if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) != 0) return; + if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) != 0) return; + if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) != 0) return; + // Enable ImageQuery Capability if not yet enabled + if (!get_feature_mgr()->HasCapability(SpvCapabilityImageQuery)) { + std::unique_ptr cap_image_query_inst(new Instruction( + context(), SpvOpCapability, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityImageQuery}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*cap_image_query_inst); + context()->AddCapability(std::move(cap_image_query_inst)); + } + // Move original block's preceding instructions into first new block + std::unique_ptr new_blk_ptr; + MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + new_blocks->push_back(std::move(new_blk_ptr)); + // Get texel coordinate + uint32_t coord_id = + GenUintCastCode(ref_inst->GetSingleWordInOperand(1), &builder); + // If index id not yet set, binding is single descriptor, so set index to + // constant 0. + if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u); + // Get texel buffer size. + Instruction* size_inst = + builder.AddUnaryOp(GetUintId(), SpvOpImageQuerySize, ref.image_id); + uint32_t size_id = size_inst->result_id(); + // Generate runtime initialization/bounds test code with true branch + // being full reference and false branch being debug output and zero + // for the referenced value. + Instruction* ult_inst = + builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, coord_id, size_id); + uint32_t error = + (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageSampled) == 2) + ? kInstErrorBuffOOBStorageTexel + : kInstErrorBuffOOBUniformTexel; + uint32_t error_id = builder.GetUintConstantId(error); + GenCheckCode(ult_inst->result_id(), error_id, coord_id, size_id, stage_idx, + &ref, new_blocks); // Move original block's remaining code into remainder/merge block and add // to new blocks BasicBlock* back_blk_ptr = &*new_blocks->back(); @@ -708,48 +773,56 @@ void InstBindlessCheckPass::GenDescCheckCode( void InstBindlessCheckPass::InitializeInstBindlessCheck() { // Initialize base class InitializeInstrument(); - for (auto& anno : get_module()->annotations()) { - if (anno.opcode() == spv::Op::OpDecorate) { - if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::DescriptorSet) { - var2desc_set_[anno.GetSingleWordInOperand(0u)] = - anno.GetSingleWordInOperand(2u); - } else if (spv::Decoration(anno.GetSingleWordInOperand(1u)) == - spv::Decoration::Binding) { - var2binding_[anno.GetSingleWordInOperand(0u)] = - anno.GetSingleWordInOperand(2u); + // If runtime array length support or buffer bounds checking are enabled, + // create variable mappings. Length support is always enabled if descriptor + // init check is enabled. + if (desc_idx_enabled_ || buffer_bounds_enabled_ || texel_buffer_enabled_) + for (auto& anno : get_module()->annotations()) + if (anno.opcode() == SpvOpDecorate) { + if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet) + var2desc_set_[anno.GetSingleWordInOperand(0u)] = + anno.GetSingleWordInOperand(2u); + else if (anno.GetSingleWordInOperand(1u) == SpvDecorationBinding) + var2binding_[anno.GetSingleWordInOperand(0u)] = + anno.GetSingleWordInOperand(2u); } - } - } } Pass::Status InstBindlessCheckPass::ProcessImpl() { - // The memory model and linkage must always be updated for spirv-link to work - // correctly. - AddStorageBufferExt(); - if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) { - context()->AddExtension("SPV_KHR_physical_storage_buffer"); - } - - context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses); - Instruction* memory_model = get_module()->GetMemoryModel(); - memory_model->SetInOperand( - 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)}); - - context()->AddCapability(spv::Capability::Linkage); - + // Perform bindless bounds check on each entry point function in module InstProcessFunction pfn = [this](BasicBlock::iterator ref_inst_itr, UptrVectorIterator ref_block_itr, uint32_t stage_idx, std::vector>* new_blocks) { - return GenDescCheckCode(ref_inst_itr, ref_block_itr, stage_idx, - new_blocks); + return GenDescIdxCheckCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); }; - - InstProcessEntryPointCallTree(pfn); - // This pass always changes the memory model, so that linking will work - // properly. - return Status::SuccessWithChange; + bool modified = InstProcessEntryPointCallTree(pfn); + if (desc_init_enabled_ || buffer_bounds_enabled_) { + // Perform descriptor initialization and/or buffer bounds check on each + // entry point function in module + pfn = [this](BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + uint32_t stage_idx, + std::vector>* new_blocks) { + return GenDescInitCheckCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); + }; + modified |= InstProcessEntryPointCallTree(pfn); + } + if (texel_buffer_enabled_) { + // Perform texel buffer bounds check on each entry point function in + // module. Generate after descriptor bounds and initialization checks. + pfn = [this](BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, + uint32_t stage_idx, + std::vector>* new_blocks) { + return GenTexBuffCheckCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); + }; + modified |= InstProcessEntryPointCallTree(pfn); + } + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } Pass::Status InstBindlessCheckPass::Process() { diff --git a/source/opt/inst_bindless_check_pass.h b/source/opt/inst_bindless_check_pass.h index 243cba76..e6e6ef4f 100644 --- a/source/opt/inst_bindless_check_pass.h +++ b/source/opt/inst_bindless_check_pass.h @@ -28,8 +28,16 @@ namespace opt { // external design may change as the layer evolves. class InstBindlessCheckPass : public InstrumentPass { public: - InstBindlessCheckPass(uint32_t shader_id) - : InstrumentPass(0, shader_id, true, true) {} + InstBindlessCheckPass(uint32_t desc_set, uint32_t shader_id, + bool desc_idx_enable, bool desc_init_enable, + bool buffer_bounds_enable, bool texel_buffer_enable, + bool opt_direct_reads) + : InstrumentPass(desc_set, shader_id, kInstValidationIdBindless, + opt_direct_reads), + desc_idx_enabled_(desc_idx_enable), + desc_init_enabled_(desc_init_enable), + buffer_bounds_enabled_(buffer_bounds_enable), + texel_buffer_enabled_(texel_buffer_enable) {} ~InstBindlessCheckPass() override = default; @@ -39,31 +47,91 @@ class InstBindlessCheckPass : public InstrumentPass { const char* name() const override { return "inst-bindless-check-pass"; } private: - void GenDescCheckCode(BasicBlock::iterator ref_inst_itr, - UptrVectorIterator ref_block_itr, - uint32_t stage_idx, - std::vector>* new_blocks); + // These functions do bindless checking instrumentation on a single + // instruction which references through a descriptor (ie references into an + // image or buffer). Refer to Vulkan API for further information on + // descriptors. GenDescIdxCheckCode checks that an index into a descriptor + // array (array of images or buffers) is in-bounds. GenDescInitCheckCode + // checks that the referenced descriptor has been initialized, if the + // SPV_EXT_descriptor_indexing extension is enabled, and initialized large + // enough to handle the reference, if RobustBufferAccess is disabled. + // GenDescInitCheckCode checks for uniform and storage buffer overrun. + // GenTexBuffCheckCode checks for texel buffer overrun and should be + // run after GenDescInitCheckCode to first make sure that the descriptor + // is initialized because it uses OpImageQuerySize on the descriptor. + // + // The functions are designed to be passed to + // InstrumentPass::InstProcessEntryPointCallTree(), which applies the + // function to each instruction in a module and replaces the instruction + // if warranted. + // + // If |ref_inst_itr| is a bindless reference, return in |new_blocks| the + // result of instrumenting it with validation code within its block at + // |ref_block_itr|. The validation code first executes a check for the + // specific condition called for. If the check passes, it executes + // the remainder of the reference, otherwise writes a record to the debug + // output buffer stream including |function_idx, instruction_idx, stage_idx| + // and replaces the reference with the null value of the original type. The + // block at |ref_block_itr| can just be replaced with the blocks in + // |new_blocks|, which will contain at least two blocks. The last block will + // comprise all instructions following |ref_inst_itr|, + // preceded by a phi instruction. + // + // These instrumentation functions utilize GenDebugDirectRead() to read data + // from the debug input buffer, specifically the lengths of variable length + // descriptor arrays, and the initialization status of each descriptor. + // The format of the debug input buffer is documented in instrument.hpp. + // + // These instrumentation functions utilize GenDebugStreamWrite() to write its + // error records. The validation-specific part of the error record will + // have the format: + // + // Validation Error Code (=kInstErrorBindlessBounds) + // Descriptor Index + // Descriptor Array Size + // + // The Descriptor Index is the index which has been determined to be + // out-of-bounds. + // + // The Descriptor Array Size is the size of the descriptor array which was + // indexed. + void GenDescIdxCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks); - uint32_t GenDescCheckFunctionId(); + void GenDescInitCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks); - uint32_t GenDescCheckCall(uint32_t inst_idx, uint32_t stage_idx, - uint32_t var_id, uint32_t index_id, - uint32_t byte_offset, InstructionBuilder* builder); + void GenTexBuffCheckCode( + BasicBlock::iterator ref_inst_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, + std::vector>* new_blocks); + + // Generate instructions into |builder| to read length of runtime descriptor + // array |var_id| from debug input buffer and return id of value. + uint32_t GenDebugReadLength(uint32_t var_id, InstructionBuilder* builder); + + // Generate instructions into |builder| to read initialization status of + // descriptor array |image_id| at |index_id| from debug input buffer and + // return id of value. + uint32_t GenDebugReadInit(uint32_t image_id, uint32_t index_id, + InstructionBuilder* builder); // Analysis data for descriptor reference components, generated by // AnalyzeDescriptorReference. It is necessary and sufficient for further // analysis and regeneration of the reference. typedef struct RefAnalysis { - uint32_t desc_load_id{0}; - uint32_t image_id{0}; - uint32_t load_id{0}; - uint32_t ptr_id{0}; - uint32_t var_id{0}; - uint32_t set{0}; - uint32_t binding{0}; - uint32_t desc_idx_id{0}; - uint32_t strg_class{0}; - Instruction* ref_inst{nullptr}; + uint32_t desc_load_id; + uint32_t image_id; + uint32_t load_id; + uint32_t ptr_id; + uint32_t var_id; + uint32_t desc_idx_id; + uint32_t strg_class; + Instruction* ref_inst; } RefAnalysis; // Return size of type |ty_id| in bytes. Use |matrix_stride| and |col_major| @@ -105,7 +173,8 @@ class InstBindlessCheckPass : public InstrumentPass { // writes debug error output utilizing |ref|, |error_id|, |length_id| and // |stage_idx|. Generate merge block for valid and invalid branches. Kill // original reference. - void GenCheckCode(uint32_t check_id, RefAnalysis* ref, + void GenCheckCode(uint32_t check_id, uint32_t error_id, uint32_t offset_id, + uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref, std::vector>* new_blocks); // Initialize state for instrumenting bindless checking @@ -115,13 +184,23 @@ class InstBindlessCheckPass : public InstrumentPass { // GenDescInitCheckCode to every instruction in module. Pass::Status ProcessImpl(); + // Enable instrumentation of runtime array length checking + bool desc_idx_enabled_; + + // Enable instrumentation of descriptor initialization checking + bool desc_init_enabled_; + + // Enable instrumentation of uniform and storage buffer overrun checking + bool buffer_bounds_enabled_; + + // Enable instrumentation of texel buffer overrun checking + bool texel_buffer_enabled_; + // Mapping from variable to descriptor set std::unordered_map var2desc_set_; // Mapping from variable to binding std::unordered_map var2binding_; - - uint32_t check_desc_func_id_{0}; }; } // namespace opt diff --git a/source/opt/inst_buff_addr_check_pass.cpp b/source/opt/inst_buff_addr_check_pass.cpp index e6c55087..3318f88f 100644 --- a/source/opt/inst_buff_addr_check_pass.cpp +++ b/source/opt/inst_buff_addr_check_pass.cpp @@ -22,9 +22,9 @@ namespace opt { uint32_t InstBuffAddrCheckPass::CloneOriginalReference( Instruction* ref_inst, InstructionBuilder* builder) { // Clone original ref with new result id (if load) - assert((ref_inst->opcode() == spv::Op::OpLoad || - ref_inst->opcode() == spv::Op::OpStore) && - "unexpected ref"); + assert( + (ref_inst->opcode() == SpvOpLoad || ref_inst->opcode() == SpvOpStore) && + "unexpected ref"); std::unique_ptr new_ref_inst(ref_inst->Clone(context())); uint32_t ref_result_id = ref_inst->result_id(); uint32_t new_ref_id = 0; @@ -41,24 +41,24 @@ uint32_t InstBuffAddrCheckPass::CloneOriginalReference( } bool InstBuffAddrCheckPass::IsPhysicalBuffAddrReference(Instruction* ref_inst) { - if (ref_inst->opcode() != spv::Op::OpLoad && - ref_inst->opcode() != spv::Op::OpStore) + if (ref_inst->opcode() != SpvOpLoad && ref_inst->opcode() != SpvOpStore) return false; uint32_t ptr_id = ref_inst->GetSingleWordInOperand(0); analysis::DefUseManager* du_mgr = get_def_use_mgr(); Instruction* ptr_inst = du_mgr->GetDef(ptr_id); - if (ptr_inst->opcode() != spv::Op::OpAccessChain) return false; + if (ptr_inst->opcode() != SpvOpAccessChain) return false; uint32_t ptr_ty_id = ptr_inst->type_id(); Instruction* ptr_ty_inst = du_mgr->GetDef(ptr_ty_id); - if (spv::StorageClass(ptr_ty_inst->GetSingleWordInOperand(0)) != - spv::StorageClass::PhysicalStorageBufferEXT) + if (ptr_ty_inst->GetSingleWordInOperand(0) != + SpvStorageClassPhysicalStorageBufferEXT) return false; return true; } // TODO(greg-lunarg): Refactor with InstBindlessCheckPass::GenCheckCode() ?? void InstBuffAddrCheckPass::GenCheckCode( - uint32_t check_id, Instruction* ref_inst, + uint32_t check_id, uint32_t error_id, uint32_t ref_uptr_id, + uint32_t stage_idx, Instruction* ref_inst, std::vector>* new_blocks) { BasicBlock* back_blk_ptr = &*new_blocks->back(); InstructionBuilder builder( @@ -72,9 +72,8 @@ void InstBuffAddrCheckPass::GenCheckCode( std::unique_ptr merge_label(NewLabel(merge_blk_id)); std::unique_ptr valid_label(NewLabel(valid_blk_id)); std::unique_ptr invalid_label(NewLabel(invalid_blk_id)); - (void)builder.AddConditionalBranch( - check_id, valid_blk_id, invalid_blk_id, merge_blk_id, - uint32_t(spv::SelectionControlMask::MaskNone)); + (void)builder.AddConditionalBranch(check_id, valid_blk_id, invalid_blk_id, + merge_blk_id, SpvSelectionControlMaskNone); // Gen valid branch std::unique_ptr new_blk_ptr( new BasicBlock(std::move(valid_label))); @@ -85,6 +84,18 @@ void InstBuffAddrCheckPass::GenCheckCode( // Gen invalid block new_blk_ptr.reset(new BasicBlock(std::move(invalid_label))); builder.SetInsertPoint(&*new_blk_ptr); + // Convert uptr from uint64 to 2 uint32 + Instruction* lo_uptr_inst = + builder.AddUnaryOp(GetUintId(), SpvOpUConvert, ref_uptr_id); + Instruction* rshift_uptr_inst = + builder.AddBinaryOp(GetUint64Id(), SpvOpShiftRightLogical, ref_uptr_id, + builder.GetUintConstantId(32)); + Instruction* hi_uptr_inst = builder.AddUnaryOp(GetUintId(), SpvOpUConvert, + rshift_uptr_inst->result_id()); + GenDebugStreamWrite( + uid2offset_[ref_inst->unique_id()], stage_idx, + {error_id, lo_uptr_inst->result_id(), hi_uptr_inst->result_id()}, + &builder); // Gen zero for invalid load. If pointer type, need to convert uint64 // zero to pointer; cannot create ConstantNull of pointer type. uint32_t null_id = 0; @@ -94,8 +105,8 @@ void InstBuffAddrCheckPass::GenCheckCode( analysis::Type* ref_type = type_mgr->GetType(ref_type_id); if (ref_type->AsPointer() != nullptr) { uint32_t null_u64_id = GetNullId(GetUint64Id()); - Instruction* null_ptr_inst = builder.AddUnaryOp( - ref_type_id, spv::Op::OpConvertUToPtr, null_u64_id); + Instruction* null_ptr_inst = + builder.AddUnaryOp(ref_type_id, SpvOpConvertUToPtr, null_u64_id); null_id = null_ptr_inst->result_id(); } else { null_id = GetNullId(ref_type_id); @@ -119,43 +130,77 @@ void InstBuffAddrCheckPass::GenCheckCode( context()->KillInst(ref_inst); } +uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) { + Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); + switch (type_inst->opcode()) { + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeVector: + return GetTypeLength(type_id); + case SpvOpTypeMatrix: + return GetTypeAlignment(type_inst->GetSingleWordInOperand(0)); + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + return GetTypeAlignment(type_inst->GetSingleWordInOperand(0)); + case SpvOpTypeStruct: { + uint32_t max = 0; + type_inst->ForEachInId([&max, this](const uint32_t* iid) { + uint32_t alignment = GetTypeAlignment(*iid); + max = (alignment > max) ? alignment : max; + }); + return max; + } + case SpvOpTypePointer: + assert(type_inst->GetSingleWordInOperand(0) == + SpvStorageClassPhysicalStorageBufferEXT && + "unexpected pointer type"); + return 8u; + default: + assert(false && "unexpected type"); + return 0; + } +} + uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); switch (type_inst->opcode()) { - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeInt: return type_inst->GetSingleWordInOperand(0) / 8u; - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeVector: { + uint32_t raw_cnt = type_inst->GetSingleWordInOperand(1); + uint32_t adj_cnt = (raw_cnt == 3u) ? 4u : raw_cnt; + return adj_cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0)); + } + case SpvOpTypeMatrix: return type_inst->GetSingleWordInOperand(1) * GetTypeLength(type_inst->GetSingleWordInOperand(0)); - case spv::Op::OpTypePointer: - assert(spv::StorageClass(type_inst->GetSingleWordInOperand(0)) == - spv::StorageClass::PhysicalStorageBufferEXT && + case SpvOpTypePointer: + assert(type_inst->GetSingleWordInOperand(0) == + SpvStorageClassPhysicalStorageBufferEXT && "unexpected pointer type"); return 8u; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { uint32_t const_id = type_inst->GetSingleWordInOperand(1); Instruction* const_inst = get_def_use_mgr()->GetDef(const_id); uint32_t cnt = const_inst->GetSingleWordInOperand(0); return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0)); } - case spv::Op::OpTypeStruct: { - // Figure out the location of the last byte of the last member of the - // structure. - uint32_t last_offset = 0, last_len = 0; - - get_decoration_mgr()->ForEachDecoration( - type_id, uint32_t(spv::Decoration::Offset), - [&last_offset](const Instruction& deco_inst) { - last_offset = deco_inst.GetSingleWordInOperand(3); - }); - type_inst->ForEachInId([&last_len, this](const uint32_t* iid) { - last_len = GetTypeLength(*iid); + case SpvOpTypeStruct: { + uint32_t len = 0; + type_inst->ForEachInId([&len, this](const uint32_t* iid) { + // Align struct length + uint32_t alignment = GetTypeAlignment(*iid); + uint32_t mod = len % alignment; + uint32_t diff = (mod != 0) ? alignment - mod : 0; + len += diff; + // Increment struct length by component length + uint32_t comp_len = GetTypeLength(*iid); + len += comp_len; }); - return last_offset + last_len; + return len; } - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: default: assert(false && "unexpected type"); return 0; @@ -168,91 +213,223 @@ void InstBuffAddrCheckPass::AddParam(uint32_t type_id, uint32_t pid = TakeNextId(); param_vec->push_back(pid); std::unique_ptr param_inst(new Instruction( - get_module()->context(), spv::Op::OpFunctionParameter, type_id, pid, {})); + get_module()->context(), SpvOpFunctionParameter, type_id, pid, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); (*input_func)->AddParameter(std::move(param_inst)); } -// This is a stub function for use with Import linkage -// clang-format off -// GLSL: -//bool inst_bindless_search_and_test(const uint shader_id, const uint inst_num, const uvec4 stage_info, -// const uint64 ref_ptr, const uint length) { -//} -// clang-format on uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() { - enum { - kShaderId = 0, - kInstructionIndex = 1, - kStageInfo = 2, - kRefPtr = 3, - kLength = 4, - kNumArgs - }; - if (search_test_func_id_ != 0) { - return search_test_func_id_; + if (search_test_func_id_ == 0) { + // Generate function "bool search_and_test(uint64_t ref_ptr, uint32_t len)" + // which searches input buffer for buffer which most likely contains the + // pointer value |ref_ptr| and verifies that the entire reference of + // length |len| bytes is contained in the buffer. + search_test_func_id_ = TakeNextId(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + std::vector param_types = { + type_mgr->GetType(GetUint64Id()), type_mgr->GetType(GetUintId())}; + analysis::Function func_ty(type_mgr->GetType(GetBoolId()), param_types); + analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); + std::unique_ptr func_inst( + new Instruction(get_module()->context(), SpvOpFunction, GetBoolId(), + search_test_func_id_, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvFunctionControlMaskNone}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {type_mgr->GetTypeInstruction(reg_func_ty)}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); + std::unique_ptr input_func = + MakeUnique(std::move(func_inst)); + std::vector param_vec; + // Add ref_ptr and length parameters + AddParam(GetUint64Id(), ¶m_vec, &input_func); + AddParam(GetUintId(), ¶m_vec, &input_func); + // Empty first block. + uint32_t first_blk_id = TakeNextId(); + std::unique_ptr first_blk_label(NewLabel(first_blk_id)); + std::unique_ptr first_blk_ptr = + MakeUnique(std::move(first_blk_label)); + InstructionBuilder builder( + context(), &*first_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + uint32_t hdr_blk_id = TakeNextId(); + // Branch to search loop header + std::unique_ptr hdr_blk_label(NewLabel(hdr_blk_id)); + (void)builder.AddInstruction(MakeUnique( + context(), SpvOpBranch, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {hdr_blk_id}}})); + input_func->AddBasicBlock(std::move(first_blk_ptr)); + // Linear search loop header block + // TODO(greg-lunarg): Implement binary search + std::unique_ptr hdr_blk_ptr = + MakeUnique(std::move(hdr_blk_label)); + builder.SetInsertPoint(&*hdr_blk_ptr); + // Phi for search index. Starts with 1. + uint32_t cont_blk_id = TakeNextId(); + std::unique_ptr cont_blk_label(NewLabel(cont_blk_id)); + // Deal with def-use cycle caused by search loop index computation. + // Create Add and Phi instructions first, then do Def analysis on Add. + // Add Phi and Add instructions and do Use analysis later. + uint32_t idx_phi_id = TakeNextId(); + uint32_t idx_inc_id = TakeNextId(); + std::unique_ptr idx_inc_inst(new Instruction( + context(), SpvOpIAdd, GetUintId(), idx_inc_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {idx_phi_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {builder.GetUintConstantId(1u)}}})); + std::unique_ptr idx_phi_inst(new Instruction( + context(), SpvOpPhi, GetUintId(), idx_phi_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {builder.GetUintConstantId(1u)}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {first_blk_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {idx_inc_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cont_blk_id}}})); + get_def_use_mgr()->AnalyzeInstDef(&*idx_inc_inst); + // Add (previously created) search index phi + (void)builder.AddInstruction(std::move(idx_phi_inst)); + // LoopMerge + uint32_t bound_test_blk_id = TakeNextId(); + std::unique_ptr bound_test_blk_label( + NewLabel(bound_test_blk_id)); + (void)builder.AddInstruction(MakeUnique( + context(), SpvOpLoopMerge, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {bound_test_blk_id}}, + {SPV_OPERAND_TYPE_ID, {cont_blk_id}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {SpvLoopControlMaskNone}}})); + // Branch to continue/work block + (void)builder.AddInstruction(MakeUnique( + context(), SpvOpBranch, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {cont_blk_id}}})); + input_func->AddBasicBlock(std::move(hdr_blk_ptr)); + // Continue/Work Block. Read next buffer pointer and break if greater + // than ref_ptr arg. + std::unique_ptr cont_blk_ptr = + MakeUnique(std::move(cont_blk_label)); + builder.SetInsertPoint(&*cont_blk_ptr); + // Add (previously created) search index increment now. + (void)builder.AddInstruction(std::move(idx_inc_inst)); + // Load next buffer address from debug input buffer + uint32_t ibuf_id = GetInputBufferId(); + uint32_t ibuf_ptr_id = GetInputBufferPtrId(); + Instruction* uptr_ac_inst = builder.AddTernaryOp( + ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.GetUintConstantId(kDebugInputDataOffset), idx_inc_id); + uint32_t ibuf_type_id = GetInputBufferTypeId(); + Instruction* uptr_load_inst = + builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, uptr_ac_inst->result_id()); + // If loaded address greater than ref_ptr arg, break, else branch back to + // loop header + Instruction* uptr_test_inst = + builder.AddBinaryOp(GetBoolId(), SpvOpUGreaterThan, + uptr_load_inst->result_id(), param_vec[0]); + (void)builder.AddConditionalBranch(uptr_test_inst->result_id(), + bound_test_blk_id, hdr_blk_id, + kInvalidId, SpvSelectionControlMaskNone); + input_func->AddBasicBlock(std::move(cont_blk_ptr)); + // Bounds test block. Read length of selected buffer and test that + // all len arg bytes are in buffer. + std::unique_ptr bound_test_blk_ptr = + MakeUnique(std::move(bound_test_blk_label)); + builder.SetInsertPoint(&*bound_test_blk_ptr); + // Decrement index to point to previous/candidate buffer address + Instruction* cand_idx_inst = builder.AddBinaryOp( + GetUintId(), SpvOpISub, idx_inc_id, builder.GetUintConstantId(1u)); + // Load candidate buffer address + Instruction* cand_ac_inst = + builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.GetUintConstantId(kDebugInputDataOffset), + cand_idx_inst->result_id()); + Instruction* cand_load_inst = + builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, cand_ac_inst->result_id()); + // Compute offset of ref_ptr from candidate buffer address + Instruction* offset_inst = builder.AddBinaryOp( + ibuf_type_id, SpvOpISub, param_vec[0], cand_load_inst->result_id()); + // Convert ref length to uint64 + Instruction* ref_len_64_inst = + builder.AddUnaryOp(ibuf_type_id, SpvOpUConvert, param_vec[1]); + // Add ref length to ref offset to compute end of reference + Instruction* ref_end_inst = + builder.AddBinaryOp(ibuf_type_id, SpvOpIAdd, offset_inst->result_id(), + ref_len_64_inst->result_id()); + // Load starting index of lengths in input buffer and convert to uint32 + Instruction* len_start_ac_inst = + builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.GetUintConstantId(kDebugInputDataOffset), + builder.GetUintConstantId(0u)); + Instruction* len_start_load_inst = builder.AddUnaryOp( + ibuf_type_id, SpvOpLoad, len_start_ac_inst->result_id()); + Instruction* len_start_32_inst = builder.AddUnaryOp( + GetUintId(), SpvOpUConvert, len_start_load_inst->result_id()); + // Decrement search index to get candidate buffer length index + Instruction* cand_len_idx_inst = + builder.AddBinaryOp(GetUintId(), SpvOpISub, cand_idx_inst->result_id(), + builder.GetUintConstantId(1u)); + // Add candidate length index to start index + Instruction* len_idx_inst = builder.AddBinaryOp( + GetUintId(), SpvOpIAdd, cand_len_idx_inst->result_id(), + len_start_32_inst->result_id()); + // Load candidate buffer length + Instruction* len_ac_inst = + builder.AddTernaryOp(ibuf_ptr_id, SpvOpAccessChain, ibuf_id, + builder.GetUintConstantId(kDebugInputDataOffset), + len_idx_inst->result_id()); + Instruction* len_load_inst = + builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, len_ac_inst->result_id()); + // Test if reference end within candidate buffer length + Instruction* len_test_inst = builder.AddBinaryOp( + GetBoolId(), SpvOpULessThanEqual, ref_end_inst->result_id(), + len_load_inst->result_id()); + // Return test result + (void)builder.AddInstruction(MakeUnique( + context(), SpvOpReturnValue, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {len_test_inst->result_id()}}})); + // Close block + input_func->AddBasicBlock(std::move(bound_test_blk_ptr)); + // Close function and add function to module + std::unique_ptr func_end_inst( + new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); + input_func->SetFunctionEnd(std::move(func_end_inst)); + context()->AddFunction(std::move(input_func)); + context()->AddDebug2Inst( + NewGlobalName(search_test_func_id_, "search_and_test")); } - // Generate function "bool search_and_test(uint64_t ref_ptr, uint32_t len)" - // which searches input buffer for buffer which most likely contains the - // pointer value |ref_ptr| and verifies that the entire reference of - // length |len| bytes is contained in the buffer. - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - const analysis::Integer* uint_type = GetInteger(32, false); - const analysis::Vector v4uint(uint_type, 4); - const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint); - - std::vector param_types = { - uint_type, uint_type, v4uint_type, type_mgr->GetType(GetUint64Id()), - uint_type}; - - const std::string func_name{"inst_buff_addr_search_and_test"}; - const uint32_t func_id = TakeNextId(); - std::unique_ptr func = - StartFunction(func_id, type_mgr->GetBoolType(), param_types); - func->SetFunctionEnd(EndFunction()); - context()->AddFunctionDeclaration(std::move(func)); - context()->AddDebug2Inst(NewName(func_id, func_name)); - - std::vector operands{ - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::Decoration::LinkageAttributes)}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING, - utils::MakeVector(func_name.c_str())}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE, - {uint32_t(spv::LinkageType::Import)}}, - }; - get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands); - - search_test_func_id_ = func_id; return search_test_func_id_; } uint32_t InstBuffAddrCheckPass::GenSearchAndTest(Instruction* ref_inst, InstructionBuilder* builder, - uint32_t* ref_uptr_id, - uint32_t stage_idx) { + uint32_t* ref_uptr_id) { // Enable Int64 if necessary + if (!get_feature_mgr()->HasCapability(SpvCapabilityInt64)) { + std::unique_ptr cap_int64_inst(new Instruction( + context(), SpvOpCapability, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityInt64}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*cap_int64_inst); + context()->AddCapability(std::move(cap_int64_inst)); + } // Convert reference pointer to uint64 - const uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0); + uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0); Instruction* ref_uptr_inst = - builder->AddUnaryOp(GetUint64Id(), spv::Op::OpConvertPtrToU, ref_ptr_id); + builder->AddUnaryOp(GetUint64Id(), SpvOpConvertPtrToU, ref_ptr_id); *ref_uptr_id = ref_uptr_inst->result_id(); // Compute reference length in bytes analysis::DefUseManager* du_mgr = get_def_use_mgr(); Instruction* ref_ptr_inst = du_mgr->GetDef(ref_ptr_id); - const uint32_t ref_ptr_ty_id = ref_ptr_inst->type_id(); + uint32_t ref_ptr_ty_id = ref_ptr_inst->type_id(); Instruction* ref_ptr_ty_inst = du_mgr->GetDef(ref_ptr_ty_id); - const uint32_t ref_len = - GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1)); + uint32_t ref_len = GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1)); + uint32_t ref_len_id = builder->GetUintConstantId(ref_len); // Gen call to search and test function - const uint32_t func_id = GetSearchAndTestFuncId(); - const std::vector args = { - builder->GetUintConstantId(shader_id_), - builder->GetUintConstantId(ref_inst->unique_id()), - GenStageInfo(stage_idx, builder), *ref_uptr_id, - builder->GetUintConstantId(ref_len)}; - return GenReadFunctionCall(GetBoolId(), func_id, args, builder); + const std::vector args = {GetSearchAndTestFuncId(), *ref_uptr_id, + ref_len_id}; + Instruction* call_inst = + builder->AddNaryOp(GetBoolId(), SpvOpFunctionCall, args); + uint32_t retval = call_inst->result_id(); + return retval; } void InstBuffAddrCheckPass::GenBuffAddrCheckCode( @@ -270,16 +447,16 @@ void InstBuffAddrCheckPass::GenBuffAddrCheckCode( context(), &*new_blk_ptr, IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); new_blocks->push_back(std::move(new_blk_ptr)); + uint32_t error_id = builder.GetUintConstantId(kInstErrorBuffAddrUnallocRef); // Generate code to do search and test if all bytes of reference // are within a listed buffer. Return reference pointer converted to uint64. uint32_t ref_uptr_id; - uint32_t valid_id = - GenSearchAndTest(ref_inst, &builder, &ref_uptr_id, stage_idx); + uint32_t valid_id = GenSearchAndTest(ref_inst, &builder, &ref_uptr_id); // Generate test of search results with true branch // being full reference and false branch being debug output and zero // for the referenced value. - GenCheckCode(valid_id, ref_inst, new_blocks); - + GenCheckCode(valid_id, error_id, ref_uptr_id, stage_idx, ref_inst, + new_blocks); // Move original block's remaining code into remainder/merge block and add // to new blocks BasicBlock* back_blk_ptr = &*new_blocks->back(); @@ -294,20 +471,6 @@ void InstBuffAddrCheckPass::InitInstBuffAddrCheck() { } Pass::Status InstBuffAddrCheckPass::ProcessImpl() { - // The memory model and linkage must always be updated for spirv-link to work - // correctly. - AddStorageBufferExt(); - if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) { - context()->AddExtension("SPV_KHR_physical_storage_buffer"); - } - - context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses); - Instruction* memory_model = get_module()->GetMemoryModel(); - memory_model->SetInOperand( - 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)}); - - context()->AddCapability(spv::Capability::Int64); - context()->AddCapability(spv::Capability::Linkage); // Perform bindless bounds check on each entry point function in module InstProcessFunction pfn = [this](BasicBlock::iterator ref_inst_itr, @@ -316,13 +479,14 @@ Pass::Status InstBuffAddrCheckPass::ProcessImpl() { return GenBuffAddrCheckCode(ref_inst_itr, ref_block_itr, stage_idx, new_blocks); }; - InstProcessEntryPointCallTree(pfn); - // This pass always changes the memory model, so that linking will work - // properly. - return Status::SuccessWithChange; + bool modified = InstProcessEntryPointCallTree(pfn); + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } Pass::Status InstBuffAddrCheckPass::Process() { + if (!get_feature_mgr()->HasCapability( + SpvCapabilityPhysicalStorageBufferAddressesEXT)) + return Status::SuccessWithoutChange; InitInstBuffAddrCheck(); return ProcessImpl(); } diff --git a/source/opt/inst_buff_addr_check_pass.h b/source/opt/inst_buff_addr_check_pass.h index f07f98a0..fb43c397 100644 --- a/source/opt/inst_buff_addr_check_pass.h +++ b/source/opt/inst_buff_addr_check_pass.h @@ -29,10 +29,10 @@ namespace opt { class InstBuffAddrCheckPass : public InstrumentPass { public: // For test harness only - InstBuffAddrCheckPass() : InstrumentPass(0, 23, false, true) {} + InstBuffAddrCheckPass() : InstrumentPass(7, 23, kInstValidationIdBuffAddr) {} // For all other interfaces - InstBuffAddrCheckPass(uint32_t shader_id) - : InstrumentPass(0, shader_id, false, true) {} + InstBuffAddrCheckPass(uint32_t desc_set, uint32_t shader_id) + : InstrumentPass(desc_set, shader_id, kInstValidationIdBuffAddr) {} ~InstBuffAddrCheckPass() override = default; @@ -42,6 +42,10 @@ class InstBuffAddrCheckPass : public InstrumentPass { const char* name() const override { return "inst-buff-addr-check-pass"; } private: + // Return byte alignment of type |type_id|. Must be int, float, vector, + // matrix, struct, array or physical pointer. Uses std430 alignment. + uint32_t GetTypeAlignment(uint32_t type_id); + // Return byte length of type |type_id|. Must be int, float, vector, matrix, // struct, array or physical pointer. Uses std430 alignment and sizes. uint32_t GetTypeLength(uint32_t type_id); @@ -58,7 +62,7 @@ class InstBuffAddrCheckPass : public InstrumentPass { // are within the buffer. Returns id of boolean value which is true if // search and test is successful, false otherwise. uint32_t GenSearchAndTest(Instruction* ref_inst, InstructionBuilder* builder, - uint32_t* ref_uptr_id, uint32_t stage_idx); + uint32_t* ref_uptr_id); // This function does checking instrumentation on a single // instruction which references through a physical storage buffer address. @@ -111,7 +115,8 @@ class InstBuffAddrCheckPass : public InstrumentPass { // writes debug error output utilizing |ref_inst|, |error_id| and // |stage_idx|. Generate merge block for valid and invalid reference blocks. // Kill original reference. - void GenCheckCode(uint32_t check_id, Instruction* ref_inst, + void GenCheckCode(uint32_t check_id, uint32_t error_id, uint32_t length_id, + uint32_t stage_idx, Instruction* ref_inst, std::vector>* new_blocks); // Initialize state for instrumenting physical buffer address checking diff --git a/source/opt/inst_debug_printf_pass.cpp b/source/opt/inst_debug_printf_pass.cpp index abd25e93..4218138f 100644 --- a/source/opt/inst_debug_printf_pass.cpp +++ b/source/opt/inst_debug_printf_pass.cpp @@ -16,7 +16,6 @@ #include "inst_debug_printf_pass.h" -#include "source/spirv_constant.h" #include "source/util/string_utils.h" #include "spirv/unified1/NonSemanticDebugPrintf.h" @@ -35,8 +34,8 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, const analysis::Type* c_ty = v_ty->element_type(); uint32_t c_ty_id = type_mgr->GetId(c_ty); for (uint32_t c = 0; c < v_ty->element_count(); ++c) { - Instruction* c_inst = - builder->AddCompositeExtract(c_ty_id, val_inst->result_id(), {c}); + Instruction* c_inst = builder->AddIdLiteralOp( + c_ty_id, SpvOpCompositeExtract, val_inst->result_id(), c); GenOutputValues(c_inst, val_ids, builder); } return; @@ -45,8 +44,8 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, // Select between uint32 zero or one uint32_t zero_id = builder->GetUintConstantId(0); uint32_t one_id = builder->GetUintConstantId(1); - Instruction* sel_inst = builder->AddSelect( - GetUintId(), val_inst->result_id(), one_id, zero_id); + Instruction* sel_inst = builder->AddTernaryOp( + GetUintId(), SpvOpSelect, val_inst->result_id(), one_id, zero_id); val_ids->push_back(sel_inst->result_id()); return; } @@ -56,21 +55,21 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, case 16: { // Convert float16 to float32 and recurse Instruction* f32_inst = builder->AddUnaryOp( - GetFloatId(), spv::Op::OpFConvert, val_inst->result_id()); + GetFloatId(), SpvOpFConvert, val_inst->result_id()); GenOutputValues(f32_inst, val_ids, builder); return; } case 64: { // Bitcast float64 to uint64 and recurse Instruction* ui64_inst = builder->AddUnaryOp( - GetUint64Id(), spv::Op::OpBitcast, val_inst->result_id()); + GetUint64Id(), SpvOpBitcast, val_inst->result_id()); GenOutputValues(ui64_inst, val_ids, builder); return; } case 32: { // Bitcase float32 to uint32 - Instruction* bc_inst = builder->AddUnaryOp( - GetUintId(), spv::Op::OpBitcast, val_inst->result_id()); + Instruction* bc_inst = builder->AddUnaryOp(GetUintId(), SpvOpBitcast, + val_inst->result_id()); val_ids->push_back(bc_inst->result_id()); return; } @@ -86,17 +85,17 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui64_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint64 to uint64 - ui64_inst = builder->AddUnaryOp(GetUint64Id(), spv::Op::OpBitcast, + ui64_inst = builder->AddUnaryOp(GetUint64Id(), SpvOpBitcast, val_inst->result_id()); } // Break uint64 into 2x uint32 Instruction* lo_ui64_inst = builder->AddUnaryOp( - GetUintId(), spv::Op::OpUConvert, ui64_inst->result_id()); + GetUintId(), SpvOpUConvert, ui64_inst->result_id()); Instruction* rshift_ui64_inst = builder->AddBinaryOp( - GetUint64Id(), spv::Op::OpShiftRightLogical, - ui64_inst->result_id(), builder->GetUintConstantId(32)); + GetUint64Id(), SpvOpShiftRightLogical, ui64_inst->result_id(), + builder->GetUintConstantId(32)); Instruction* hi_ui64_inst = builder->AddUnaryOp( - GetUintId(), spv::Op::OpUConvert, rshift_ui64_inst->result_id()); + GetUintId(), SpvOpUConvert, rshift_ui64_inst->result_id()); val_ids->push_back(lo_ui64_inst->result_id()); val_ids->push_back(hi_ui64_inst->result_id()); return; @@ -105,12 +104,12 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui8_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint8 to uint8 - ui8_inst = builder->AddUnaryOp(GetUint8Id(), spv::Op::OpBitcast, + ui8_inst = builder->AddUnaryOp(GetUint8Id(), SpvOpBitcast, val_inst->result_id()); } // Convert uint8 to uint32 Instruction* ui32_inst = builder->AddUnaryOp( - GetUintId(), spv::Op::OpUConvert, ui8_inst->result_id()); + GetUintId(), SpvOpUConvert, ui8_inst->result_id()); val_ids->push_back(ui32_inst->result_id()); return; } @@ -118,7 +117,7 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, Instruction* ui32_inst = val_inst; if (i_ty->IsSigned()) { // Bitcast sint32 to uint32 - ui32_inst = builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, + ui32_inst = builder->AddUnaryOp(GetUintId(), SpvOpBitcast, val_inst->result_id()); } // uint32 needs no further processing @@ -138,7 +137,7 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst, } void InstDebugPrintfPass::GenOutputCode( - Instruction* printf_inst, + Instruction* printf_inst, uint32_t stage_idx, std::vector>* new_blocks) { BasicBlock* back_blk_ptr = &*new_blocks->back(); InstructionBuilder builder( @@ -159,27 +158,25 @@ void InstDebugPrintfPass::GenOutputCode( return; } Instruction* opnd_inst = get_def_use_mgr()->GetDef(*iid); - if (opnd_inst->opcode() == spv::Op::OpString) { + if (opnd_inst->opcode() == SpvOpString) { uint32_t string_id_id = builder.GetUintConstantId(*iid); val_ids.push_back(string_id_id); } else { GenOutputValues(opnd_inst, &val_ids, &builder); } }); - GenDebugStreamWrite( - builder.GetUintConstantId(shader_id_), - builder.GetUintConstantId(uid2offset_[printf_inst->unique_id()]), val_ids, - &builder); + GenDebugStreamWrite(uid2offset_[printf_inst->unique_id()], stage_idx, val_ids, + &builder); context()->KillInst(printf_inst); } void InstDebugPrintfPass::GenDebugPrintfCode( BasicBlock::iterator ref_inst_itr, - UptrVectorIterator ref_block_itr, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, std::vector>* new_blocks) { // If not DebugPrintf OpExtInst, return. Instruction* printf_inst = &*ref_inst_itr; - if (printf_inst->opcode() != spv::Op::OpExtInst) return; + if (printf_inst->opcode() != SpvOpExtInst) return; if (printf_inst->GetSingleWordInOperand(0) != ext_inst_printf_id_) return; if (printf_inst->GetSingleWordInOperand(1) != NonSemanticDebugPrintfDebugPrintf) @@ -191,7 +188,7 @@ void InstDebugPrintfPass::GenDebugPrintfCode( MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr); new_blocks->push_back(std::move(new_blk_ptr)); // Generate instructions to output printf args to printf buffer - GenOutputCode(printf_inst, new_blocks); + GenOutputCode(printf_inst, stage_idx, new_blocks); // Caller expects at least two blocks with last block containing remaining // code, so end block after instrumentation, create remainder block, and // branch to it @@ -211,243 +208,19 @@ void InstDebugPrintfPass::GenDebugPrintfCode( new_blocks->push_back(std::move(new_blk_ptr)); } -// Return id for output buffer -uint32_t InstDebugPrintfPass::GetOutputBufferId() { - if (output_buffer_id_ == 0) { - // If not created yet, create one - analysis::DecorationManager* deco_mgr = get_decoration_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::RuntimeArray* reg_uint_rarr_ty = GetUintRuntimeArrayType(32); - analysis::Integer* reg_uint_ty = GetInteger(32, false); - analysis::Type* reg_buf_ty = - GetStruct({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty}); - uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty); - // By the Vulkan spec, a pre-existing struct containing a RuntimeArray - // must be a block, and will therefore be decorated with Block. Therefore - // the undecorated type returned here will not be pre-existing and can - // safely be decorated. Since this type is now decorated, it is out of - // sync with the TypeManager and therefore the TypeManager must be - // invalidated after this pass. - assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 && - "used struct type returned"); - deco_mgr->AddDecoration(obufTyId, uint32_t(spv::Decoration::Block)); - deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputFlagsOffset, - uint32_t(spv::Decoration::Offset), 0); - deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset, - uint32_t(spv::Decoration::Offset), 4); - deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset, - uint32_t(spv::Decoration::Offset), 8); - uint32_t obufTyPtrId_ = - type_mgr->FindPointerToType(obufTyId, spv::StorageClass::StorageBuffer); - output_buffer_id_ = TakeNextId(); - std::unique_ptr newVarOp(new Instruction( - context(), spv::Op::OpVariable, obufTyPtrId_, output_buffer_id_, - {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::StorageClass::StorageBuffer)}}})); - context()->AddGlobalValue(std::move(newVarOp)); - context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer")); - context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "flags")); - context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "written_count")); - context()->AddDebug2Inst(NewMemberName(obufTyId, 2, "data")); - context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer")); - deco_mgr->AddDecorationVal( - output_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_); - deco_mgr->AddDecorationVal(output_buffer_id_, - uint32_t(spv::Decoration::Binding), - GetOutputBufferBinding()); - AddStorageBufferExt(); - if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { - // Add the new buffer to all entry points. - for (auto& entry : get_module()->entry_points()) { - entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}}); - context()->AnalyzeUses(&entry); - } - } - } - return output_buffer_id_; -} - -uint32_t InstDebugPrintfPass::GetOutputBufferPtrId() { - if (output_buffer_ptr_id_ == 0) { - output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( - GetUintId(), spv::StorageClass::StorageBuffer); - } - return output_buffer_ptr_id_; -} - -uint32_t InstDebugPrintfPass::GetOutputBufferBinding() { - return kDebugOutputPrintfStream; -} - -void InstDebugPrintfPass::GenDebugOutputFieldCode(uint32_t base_offset_id, - uint32_t field_offset, - uint32_t field_value_id, - InstructionBuilder* builder) { - // Cast value to 32-bit unsigned if necessary - uint32_t val_id = GenUintCastCode(field_value_id, builder); - // Store value - Instruction* data_idx_inst = builder->AddIAdd( - GetUintId(), base_offset_id, builder->GetUintConstantId(field_offset)); - uint32_t buf_id = GetOutputBufferId(); - uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); - Instruction* achain_inst = builder->AddAccessChain( - buf_uint_ptr_id, buf_id, - {builder->GetUintConstantId(kDebugOutputDataOffset), - data_idx_inst->result_id()}); - (void)builder->AddStore(achain_inst->result_id(), val_id); -} - -uint32_t InstDebugPrintfPass::GetStreamWriteFunctionId(uint32_t param_cnt) { - enum { - kShaderId = 0, - kInstructionIndex = 1, - kFirstParam = 2, - }; - // Total param count is common params plus validation-specific - // params - if (param2output_func_id_[param_cnt] == 0) { - // Create function - param2output_func_id_[param_cnt] = TakeNextId(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - - const analysis::Type* uint_type = GetInteger(32, false); - - std::vector param_types(kFirstParam + param_cnt, - uint_type); - std::unique_ptr output_func = StartFunction( - param2output_func_id_[param_cnt], type_mgr->GetVoidType(), param_types); - - std::vector param_ids = AddParameters(*output_func, param_types); - - // Create first block - auto new_blk_ptr = MakeUnique(NewLabel(TakeNextId())); - - InstructionBuilder builder( - context(), &*new_blk_ptr, - IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - // Gen test if debug output buffer size will not be exceeded. - const uint32_t first_param_offset = kInstCommonOutInstructionIdx + 1; - const uint32_t obuf_record_sz = first_param_offset + param_cnt; - const uint32_t buf_id = GetOutputBufferId(); - const uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); - Instruction* obuf_curr_sz_ac_inst = builder.AddAccessChain( - buf_uint_ptr_id, buf_id, - {builder.GetUintConstantId(kDebugOutputSizeOffset)}); - // Fetch the current debug buffer written size atomically, adding the - // size of the record to be written. - uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz); - uint32_t mask_none_id = - builder.GetUintConstantId(uint32_t(spv::MemoryAccessMask::MaskNone)); - uint32_t scope_invok_id = - builder.GetUintConstantId(uint32_t(spv::Scope::Invocation)); - Instruction* obuf_curr_sz_inst = builder.AddQuadOp( - GetUintId(), spv::Op::OpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(), - scope_invok_id, mask_none_id, obuf_record_sz_id); - uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id(); - // Compute new written size - Instruction* obuf_new_sz_inst = - builder.AddIAdd(GetUintId(), obuf_curr_sz_id, - builder.GetUintConstantId(obuf_record_sz)); - // Fetch the data bound - Instruction* obuf_bnd_inst = - builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength, - GetOutputBufferId(), kDebugOutputDataOffset); - // Test that new written size is less than or equal to debug output - // data bound - Instruction* obuf_safe_inst = builder.AddBinaryOp( - GetBoolId(), spv::Op::OpULessThanEqual, obuf_new_sz_inst->result_id(), - obuf_bnd_inst->result_id()); - uint32_t merge_blk_id = TakeNextId(); - uint32_t write_blk_id = TakeNextId(); - std::unique_ptr merge_label(NewLabel(merge_blk_id)); - std::unique_ptr write_label(NewLabel(write_blk_id)); - (void)builder.AddConditionalBranch( - obuf_safe_inst->result_id(), write_blk_id, merge_blk_id, merge_blk_id, - uint32_t(spv::SelectionControlMask::MaskNone)); - // Close safety test block and gen write block - output_func->AddBasicBlock(std::move(new_blk_ptr)); - new_blk_ptr = MakeUnique(std::move(write_label)); - builder.SetInsertPoint(&*new_blk_ptr); - // Generate common and stage-specific debug record members - GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutSize, - builder.GetUintConstantId(obuf_record_sz), - &builder); - // Store Shader Id - GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutShaderId, - param_ids[kShaderId], &builder); - // Store Instruction Idx - GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutInstructionIdx, - param_ids[kInstructionIndex], &builder); - // Gen writes of validation specific data - for (uint32_t i = 0; i < param_cnt; ++i) { - GenDebugOutputFieldCode(obuf_curr_sz_id, first_param_offset + i, - param_ids[kFirstParam + i], &builder); - } - // Close write block and gen merge block - (void)builder.AddBranch(merge_blk_id); - output_func->AddBasicBlock(std::move(new_blk_ptr)); - new_blk_ptr = MakeUnique(std::move(merge_label)); - builder.SetInsertPoint(&*new_blk_ptr); - // Close merge block and function and add function to module - (void)builder.AddNullaryOp(0, spv::Op::OpReturn); - - output_func->AddBasicBlock(std::move(new_blk_ptr)); - output_func->SetFunctionEnd(EndFunction()); - context()->AddFunction(std::move(output_func)); - - std::string name("stream_write_"); - name += std::to_string(param_cnt); - - context()->AddDebug2Inst( - NewGlobalName(param2output_func_id_[param_cnt], name)); - } - return param2output_func_id_[param_cnt]; -} - -void InstDebugPrintfPass::GenDebugStreamWrite( - uint32_t shader_id, uint32_t instruction_idx_id, - const std::vector& validation_ids, InstructionBuilder* builder) { - // Call debug output function. Pass func_idx, instruction_idx and - // validation ids as args. - uint32_t val_id_cnt = static_cast(validation_ids.size()); - std::vector args = {shader_id, instruction_idx_id}; - (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end()); - (void)builder->AddFunctionCall(GetVoidId(), - GetStreamWriteFunctionId(val_id_cnt), args); -} - -std::unique_ptr InstDebugPrintfPass::NewGlobalName( - uint32_t id, const std::string& name_str) { - std::string prefixed_name{"inst_printf_"}; - prefixed_name += name_str; - return NewName(id, prefixed_name); -} - -std::unique_ptr InstDebugPrintfPass::NewMemberName( - uint32_t id, uint32_t member_index, const std::string& name_str) { - return MakeUnique( - context(), spv::Op::OpMemberName, 0, 0, - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {id}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}}, - {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}); -} - void InstDebugPrintfPass::InitializeInstDebugPrintf() { // Initialize base class InitializeInstrument(); - output_buffer_id_ = 0; - output_buffer_ptr_id_ = 0; } Pass::Status InstDebugPrintfPass::ProcessImpl() { // Perform printf instrumentation on each entry point function in module InstProcessFunction pfn = [this](BasicBlock::iterator ref_inst_itr, - UptrVectorIterator ref_block_itr, - [[maybe_unused]] uint32_t stage_idx, + UptrVectorIterator ref_block_itr, uint32_t stage_idx, std::vector>* new_blocks) { - return GenDebugPrintfCode(ref_inst_itr, ref_block_itr, new_blocks); + return GenDebugPrintfCode(ref_inst_itr, ref_block_itr, stage_idx, + new_blocks); }; (void)InstProcessEntryPointCallTree(pfn); // Remove DebugPrintf OpExtInstImport instruction @@ -466,7 +239,15 @@ Pass::Status InstDebugPrintfPass::ProcessImpl() { } } if (!non_sem_set_seen) { - context()->RemoveExtension(kSPV_KHR_non_semantic_info); + for (auto c_itr = context()->module()->extension_begin(); + c_itr != context()->module()->extension_end(); ++c_itr) { + const std::string ext_name = c_itr->GetInOperand(0).AsString(); + if (ext_name == "SPV_KHR_non_semantic_info") { + context()->KillInst(&*c_itr); + break; + } + } + context()->get_feature_mgr()->RemoveExtension(kSPV_KHR_non_semantic_info); } return Status::SuccessWithChange; } diff --git a/source/opt/inst_debug_printf_pass.h b/source/opt/inst_debug_printf_pass.h index 5688d384..70b0a72b 100644 --- a/source/opt/inst_debug_printf_pass.h +++ b/source/opt/inst_debug_printf_pass.h @@ -28,10 +28,10 @@ namespace opt { class InstDebugPrintfPass : public InstrumentPass { public: // For test harness only - InstDebugPrintfPass() : InstrumentPass(7, 23, false, false) {} + InstDebugPrintfPass() : InstrumentPass(7, 23, kInstValidationIdDebugPrintf) {} // For all other interfaces InstDebugPrintfPass(uint32_t desc_set, uint32_t shader_id) - : InstrumentPass(desc_set, shader_id, false, false) {} + : InstrumentPass(desc_set, shader_id, kInstValidationIdDebugPrintf) {} ~InstDebugPrintfPass() override = default; @@ -41,92 +41,12 @@ class InstDebugPrintfPass : public InstrumentPass { const char* name() const override { return "inst-printf-pass"; } private: - // Gen code into |builder| to write |field_value_id| into debug output - // buffer at |base_offset_id| + |field_offset|. - void GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t field_offset, - uint32_t field_value_id, - InstructionBuilder* builder); - - // Generate instructions in |builder| which will atomically fetch and - // increment the size of the debug output buffer stream of the current - // validation and write a record to the end of the stream, if enough space - // in the buffer remains. The record will contain the index of the function - // and instruction within that function |func_idx, instruction_idx| which - // generated the record. Finally, the record will contain validation-specific - // data contained in |validation_ids| which will identify the validation - // error as well as the values involved in the error. - // - // The output buffer binding written to by the code generated by the function - // is determined by the validation id specified when each specific - // instrumentation pass is created. - // - // The output buffer is a sequence of 32-bit values with the following - // format (where all elements are unsigned 32-bit unless otherwise noted): - // - // Size - // Record0 - // Record1 - // Record2 - // ... - // - // Size is the number of 32-bit values that have been written or - // attempted to be written to the output buffer, excluding the Size. It is - // initialized to 0. If the size of attempts to write the buffer exceeds - // the actual size of the buffer, it is possible that this field can exceed - // the actual size of the buffer. - // - // Each Record* is a variable-length sequence of 32-bit values with the - // following format defined using static const offsets in the .cpp file: - // - // Record Size - // Shader ID - // Instruction Index - // ... - // Validation Error Code - // Validation-specific Word 0 - // Validation-specific Word 1 - // Validation-specific Word 2 - // ... - // - // Each record consists of two subsections: members common across all - // validation and members specific to a - // validation. - // - // The Record Size is the number of 32-bit words in the record, including - // the Record Size word. - // - // Shader ID is a value that identifies which shader has generated the - // validation error. It is passed when the instrumentation pass is created. - // - // The Instruction Index is the position of the instruction within the - // SPIR-V file which is in error. - // - // The Validation Error Code specifies the exact error which has occurred. - // These are enumerated with the kInstError* static consts. This allows - // multiple validation layers to use the same, single output buffer. - // - // The Validation-specific Words are a validation-specific number of 32-bit - // words which give further information on the validation error that - // occurred. These are documented further in each file containing the - // validation-specific class which derives from this base class. - // - // Because the code that is generated checks against the size of the buffer - // before writing, the size of the debug out buffer can be used by the - // validation layer to control the number of error records that are written. - void GenDebugStreamWrite(uint32_t shader_id, uint32_t instruction_idx_id, - const std::vector& validation_ids, - InstructionBuilder* builder); - - // Return id for output function. Define if it doesn't exist with - // |val_spec_param_cnt| validation-specific uint32 parameters. - uint32_t GetStreamWriteFunctionId(uint32_t val_spec_param_cnt); - // Generate instructions for OpDebugPrintf. // // If |ref_inst_itr| is an OpDebugPrintf, return in |new_blocks| the result // of replacing it with buffer write instructions within its block at // |ref_block_itr|. The instructions write a record to the printf - // output buffer stream including |function_idx, instruction_idx| + // output buffer stream including |function_idx, instruction_idx, stage_idx| // and removes the OpDebugPrintf. The block at |ref_block_itr| can just be // replaced with the block in |new_blocks|. Besides the buffer writes, this // block will comprise all instructions preceding and following @@ -144,6 +64,7 @@ class InstDebugPrintfPass : public InstrumentPass { // DebugPrintf. void GenDebugPrintfCode(BasicBlock::iterator ref_inst_itr, UptrVectorIterator ref_block_itr, + uint32_t stage_idx, std::vector>* new_blocks); // Generate a sequence of uint32 instructions in |builder| (if necessary) @@ -156,40 +77,16 @@ class InstDebugPrintfPass : public InstrumentPass { // Generate instructions to write a record containing the operands of // |printf_inst| arguments to printf buffer, adding new code to the end of // the last block in |new_blocks|. Kill OpDebugPrintf instruction. - void GenOutputCode(Instruction* printf_inst, + void GenOutputCode(Instruction* printf_inst, uint32_t stage_idx, std::vector>* new_blocks); - // Set the name for a function or global variable, names will be - // prefixed to identify which instrumentation pass generated them. - std::unique_ptr NewGlobalName(uint32_t id, - const std::string& name_str); - - // Set the name for a structure member - std::unique_ptr NewMemberName(uint32_t id, uint32_t member_index, - const std::string& name_str); - - // Return id for debug output buffer - uint32_t GetOutputBufferId(); - - // Return id for buffer uint type - uint32_t GetOutputBufferPtrId(); - - // Return binding for output buffer for current validation. - uint32_t GetOutputBufferBinding(); - // Initialize state for instrumenting bindless checking void InitializeInstDebugPrintf(); // Apply GenDebugPrintfCode to every instruction in module. Pass::Status ProcessImpl(); - uint32_t ext_inst_printf_id_{0}; - - // id for output buffer variable - uint32_t output_buffer_id_{0}; - - // ptr type id for output buffer element - uint32_t output_buffer_ptr_id_{0}; + uint32_t ext_inst_printf_id_; }; } // namespace opt diff --git a/source/opt/instruction.cpp b/source/opt/instruction.cpp index aa4ae26b..e775a992 100644 --- a/source/opt/instruction.cpp +++ b/source/opt/instruction.cpp @@ -24,37 +24,38 @@ namespace spvtools { namespace opt { + namespace { // Indices used to get particular operands out of instructions using InOperand. -constexpr uint32_t kTypeImageDimIndex = 1; -constexpr uint32_t kLoadBaseIndex = 0; -constexpr uint32_t kPointerTypeStorageClassIndex = 0; -constexpr uint32_t kVariableStorageClassIndex = 0; -constexpr uint32_t kTypeImageSampledIndex = 5; +const uint32_t kTypeImageDimIndex = 1; +const uint32_t kLoadBaseIndex = 0; +const uint32_t kPointerTypeStorageClassIndex = 0; +const uint32_t kVariableStorageClassIndex = 0; +const uint32_t kTypeImageSampledIndex = 5; // Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 // extension instructions. -constexpr uint32_t kExtInstSetIdInIdx = 0; -constexpr uint32_t kExtInstInstructionInIdx = 1; -constexpr uint32_t kDebugScopeNumWords = 7; -constexpr uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6; -constexpr uint32_t kDebugNoScopeNumWords = 5; +const uint32_t kExtInstSetIdInIdx = 0; +const uint32_t kExtInstInstructionInIdx = 1; +const uint32_t kDebugScopeNumWords = 7; +const uint32_t kDebugScopeNumWordsWithoutInlinedAt = 6; +const uint32_t kDebugNoScopeNumWords = 5; // Number of operands of an OpBranchConditional instruction // with weights. -constexpr uint32_t kOpBranchConditionalWithWeightsNumOperands = 5; +const uint32_t kOpBranchConditionalWithWeightsNumOperands = 5; } // namespace Instruction::Instruction(IRContext* c) : utils::IntrusiveNodeBase(), context_(c), - opcode_(spv::Op::OpNop), + opcode_(SpvOpNop), has_type_id_(false), has_result_id_(false), unique_id_(c->TakeNextUniqueId()), dbg_scope_(kNoDebugScope, kNoInlinedAt) {} -Instruction::Instruction(IRContext* c, spv::Op op) +Instruction::Instruction(IRContext* c, SpvOp op) : utils::IntrusiveNodeBase(), context_(c), opcode_(op), @@ -67,13 +68,12 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, std::vector&& dbg_line) : utils::IntrusiveNodeBase(), context_(c), - opcode_(static_cast(inst.opcode)), + opcode_(static_cast(inst.opcode)), has_type_id_(inst.type_id != 0), has_result_id_(inst.result_id != 0), unique_id_(c->TakeNextUniqueId()), dbg_line_insts_(std::move(dbg_line)), dbg_scope_(kNoDebugScope, kNoInlinedAt) { - operands_.reserve(inst.num_operands); for (uint32_t i = 0; i < inst.num_operands; ++i) { const auto& current_payload = inst.operands[i]; operands_.emplace_back( @@ -88,12 +88,11 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, const DebugScope& dbg_scope) : utils::IntrusiveNodeBase(), context_(c), - opcode_(static_cast(inst.opcode)), + opcode_(static_cast(inst.opcode)), has_type_id_(inst.type_id != 0), has_result_id_(inst.result_id != 0), unique_id_(c->TakeNextUniqueId()), dbg_scope_(dbg_scope) { - operands_.reserve(inst.num_operands); for (uint32_t i = 0; i < inst.num_operands; ++i) { const auto& current_payload = inst.operands[i]; operands_.emplace_back( @@ -102,7 +101,7 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst, } } -Instruction::Instruction(IRContext* c, spv::Op op, uint32_t ty_id, +Instruction::Instruction(IRContext* c, SpvOp op, uint32_t ty_id, uint32_t res_id, const OperandList& in_operands) : utils::IntrusiveNodeBase(), context_(c), @@ -112,14 +111,6 @@ Instruction::Instruction(IRContext* c, spv::Op op, uint32_t ty_id, unique_id_(c->TakeNextUniqueId()), operands_(), dbg_scope_(kNoDebugScope, kNoInlinedAt) { - size_t operands_size = in_operands.size(); - if (has_type_id_) { - operands_size++; - } - if (has_result_id_) { - operands_size++; - } - operands_.reserve(operands_size); if (has_type_id_) { operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_TYPE_ID, std::initializer_list{ty_id}); @@ -188,7 +179,7 @@ uint32_t Instruction::NumInOperandWords() const { } bool Instruction::HasBranchWeights() const { - if (opcode_ == spv::Op::OpBranchConditional && + if (opcode_ == SpvOpBranchConditional && NumOperands() == kOpBranchConditionalWithWeightsNumOperands) { return true; } @@ -217,13 +208,13 @@ bool Instruction::IsReadOnlyLoad() const { return false; } - if (address_def->opcode() == spv::Op::OpVariable) { + if (address_def->opcode() == SpvOpVariable) { if (address_def->IsReadOnlyPointer()) { return true; } } - if (address_def->opcode() == spv::Op::OpLoad) { + if (address_def->opcode() == SpvOpLoad) { const analysis::Type* address_type = context()->get_type_mgr()->GetType(address_def->type_id()); if (address_type->AsSampledImage() != nullptr) { @@ -244,12 +235,12 @@ Instruction* Instruction::GetBaseAddress() const { bool done = false; while (!done) { switch (base_inst->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: - case spv::Op::OpImageTexelPointer: - case spv::Op::OpCopyObject: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: + case SpvOpImageTexelPointer: + case SpvOpCopyObject: // All of these instructions have the base pointer use a base pointer // in in-operand 0. base = base_inst->GetSingleWordInOperand(0); @@ -264,20 +255,20 @@ Instruction* Instruction::GetBaseAddress() const { } bool Instruction::IsReadOnlyPointer() const { - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Shader)) + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityShader)) return IsReadOnlyPointerShaders(); else return IsReadOnlyPointerKernel(); } bool Instruction::IsVulkanStorageImage() const { - if (opcode() != spv::Op::OpTypePointer) { + if (opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - if (storage_class != spv::StorageClass::UniformConstant) { + uint32_t storage_class = + GetSingleWordInOperand(kPointerTypeStorageClassIndex); + if (storage_class != SpvStorageClassUniformConstant) { return false; } @@ -285,18 +276,17 @@ bool Instruction::IsVulkanStorageImage() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != spv::Op::OpTypeImage) { + if (base_type->opcode() != SpvOpTypeImage) { return false; } - if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == - spv::Dim::Buffer) { + if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) == SpvDimBuffer) { return false; } @@ -306,13 +296,13 @@ bool Instruction::IsVulkanStorageImage() const { } bool Instruction::IsVulkanSampledImage() const { - if (opcode() != spv::Op::OpTypePointer) { + if (opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - if (storage_class != spv::StorageClass::UniformConstant) { + uint32_t storage_class = + GetSingleWordInOperand(kPointerTypeStorageClassIndex); + if (storage_class != SpvStorageClassUniformConstant) { return false; } @@ -320,18 +310,17 @@ bool Instruction::IsVulkanSampledImage() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != spv::Op::OpTypeImage) { + if (base_type->opcode() != SpvOpTypeImage) { return false; } - if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) == - spv::Dim::Buffer) { + if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) == SpvDimBuffer) { return false; } @@ -341,13 +330,13 @@ bool Instruction::IsVulkanSampledImage() const { } bool Instruction::IsVulkanStorageTexelBuffer() const { - if (opcode() != spv::Op::OpTypePointer) { + if (opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - if (storage_class != spv::StorageClass::UniformConstant) { + uint32_t storage_class = + GetSingleWordInOperand(kPointerTypeStorageClassIndex); + if (storage_class != SpvStorageClassUniformConstant) { return false; } @@ -355,18 +344,17 @@ bool Instruction::IsVulkanStorageTexelBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != spv::Op::OpTypeImage) { + if (base_type->opcode() != SpvOpTypeImage) { return false; } - if (spv::Dim(base_type->GetSingleWordInOperand(kTypeImageDimIndex)) != - spv::Dim::Buffer) { + if (base_type->GetSingleWordInOperand(kTypeImageDimIndex) != SpvDimBuffer) { return false; } @@ -378,7 +366,7 @@ bool Instruction::IsVulkanStorageTexelBuffer() const { bool Instruction::IsVulkanStorageBuffer() const { // Is there a difference between a "Storage buffer" and a "dynamic storage // buffer" in SPIR-V and do we care about the difference? - if (opcode() != spv::Op::OpTypePointer) { + if (opcode() != SpvOpTypePointer) { return false; } @@ -386,28 +374,28 @@ bool Instruction::IsVulkanStorageBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != spv::Op::OpTypeStruct) { + if (base_type->opcode() != SpvOpTypeStruct) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - if (storage_class == spv::StorageClass::Uniform) { + uint32_t storage_class = + GetSingleWordInOperand(kPointerTypeStorageClassIndex); + if (storage_class == SpvStorageClassUniform) { bool is_buffer_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), uint32_t(spv::Decoration::BufferBlock), + base_type->result_id(), SpvDecorationBufferBlock, [&is_buffer_block](const Instruction&) { is_buffer_block = true; }); return is_buffer_block; - } else if (storage_class == spv::StorageClass::StorageBuffer) { + } else if (storage_class == SpvStorageClassStorageBuffer) { bool is_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), uint32_t(spv::Decoration::Block), + base_type->result_id(), SpvDecorationBlock, [&is_block](const Instruction&) { is_block = true; }); return is_block; } @@ -415,14 +403,13 @@ bool Instruction::IsVulkanStorageBuffer() const { } bool Instruction::IsVulkanStorageBufferVariable() const { - if (opcode() != spv::Op::OpVariable) { + if (opcode() != SpvOpVariable) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kVariableStorageClassIndex)); - if (storage_class == spv::StorageClass::StorageBuffer || - storage_class == spv::StorageClass::Uniform) { + uint32_t storage_class = GetSingleWordInOperand(kVariableStorageClassIndex); + if (storage_class == SpvStorageClassStorageBuffer || + storage_class == SpvStorageClassUniform) { Instruction* var_type = context()->get_def_use_mgr()->GetDef(type_id()); return var_type != nullptr && var_type->IsVulkanStorageBuffer(); } @@ -431,13 +418,13 @@ bool Instruction::IsVulkanStorageBufferVariable() const { } bool Instruction::IsVulkanUniformBuffer() const { - if (opcode() != spv::Op::OpTypePointer) { + if (opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = - spv::StorageClass(GetSingleWordInOperand(kPointerTypeStorageClassIndex)); - if (storage_class != spv::StorageClass::Uniform) { + uint32_t storage_class = + GetSingleWordInOperand(kPointerTypeStorageClassIndex); + if (storage_class != SpvStorageClassUniform) { return false; } @@ -445,19 +432,19 @@ bool Instruction::IsVulkanUniformBuffer() const { context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1)); // Unpack the optional layer of arraying. - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = context()->get_def_use_mgr()->GetDef( base_type->GetSingleWordInOperand(0)); } - if (base_type->opcode() != spv::Op::OpTypeStruct) { + if (base_type->opcode() != SpvOpTypeStruct) { return false; } bool is_block = false; context()->get_decoration_mgr()->ForEachDecoration( - base_type->result_id(), uint32_t(spv::Decoration::Block), + base_type->result_id(), SpvDecorationBlock, [&is_block](const Instruction&) { is_block = true; }); return is_block; } @@ -468,27 +455,27 @@ bool Instruction::IsReadOnlyPointerShaders() const { } Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); - if (type_def->opcode() != spv::Op::OpTypePointer) { + if (type_def->opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = spv::StorageClass( - type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + uint32_t storage_class = + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex); switch (storage_class) { - case spv::StorageClass::UniformConstant: + case SpvStorageClassUniformConstant: if (!type_def->IsVulkanStorageImage() && !type_def->IsVulkanStorageTexelBuffer()) { return true; } break; - case spv::StorageClass::Uniform: + case SpvStorageClassUniform: if (!type_def->IsVulkanStorageBuffer()) { return true; } break; - case spv::StorageClass::PushConstant: - case spv::StorageClass::Input: + case SpvStorageClassPushConstant: + case SpvStorageClassInput: return true; default: break; @@ -496,7 +483,7 @@ bool Instruction::IsReadOnlyPointerShaders() const { bool is_nonwritable = false; context()->get_decoration_mgr()->ForEachDecoration( - result_id(), uint32_t(spv::Decoration::NonWritable), + result_id(), SpvDecorationNonWritable, [&is_nonwritable](const Instruction&) { is_nonwritable = true; }); return is_nonwritable; } @@ -507,14 +494,14 @@ bool Instruction::IsReadOnlyPointerKernel() const { } Instruction* type_def = context()->get_def_use_mgr()->GetDef(type_id()); - if (type_def->opcode() != spv::Op::OpTypePointer) { + if (type_def->opcode() != SpvOpTypePointer) { return false; } - spv::StorageClass storage_class = spv::StorageClass( - type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex)); + uint32_t storage_class = + type_def->GetSingleWordInOperand(kPointerTypeStorageClassIndex); - return storage_class == spv::StorageClass::UniformConstant; + return storage_class == SpvStorageClassUniformConstant; } void Instruction::UpdateLexicalScope(uint32_t scope) { @@ -577,13 +564,13 @@ bool Instruction::IsDebugLineInst() const { bool Instruction::IsLineInst() const { return IsLine() || IsNoLine(); } bool Instruction::IsLine() const { - if (opcode() == spv::Op::OpLine) return true; + if (opcode() == SpvOpLine) return true; NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); return ext_opt == NonSemanticShaderDebugInfo100DebugLine; } bool Instruction::IsNoLine() const { - if (opcode() == spv::Op::OpNoLine) return true; + if (opcode() == SpvOpNoLine) return true; NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode(); return ext_opt == NonSemanticShaderDebugInfo100DebugNoLine; } @@ -610,35 +597,33 @@ bool Instruction::IsValidBasePointer() const { } Instruction* type = context()->get_def_use_mgr()->GetDef(tid); - if (type->opcode() != spv::Op::OpTypePointer) { + if (type->opcode() != SpvOpTypePointer) { return false; } auto feature_mgr = context()->get_feature_mgr(); - if (feature_mgr->HasCapability(spv::Capability::Addresses)) { + if (feature_mgr->HasCapability(SpvCapabilityAddresses)) { // TODO: The rules here could be more restrictive. return true; } - if (opcode() == spv::Op::OpVariable || - opcode() == spv::Op::OpFunctionParameter) { + if (opcode() == SpvOpVariable || opcode() == SpvOpFunctionParameter) { return true; } // With variable pointers, there are more valid base pointer objects. // Variable pointers implicitly declares Variable pointers storage buffer. - spv::StorageClass storage_class = - static_cast(type->GetSingleWordInOperand(0)); - if ((feature_mgr->HasCapability( - spv::Capability::VariablePointersStorageBuffer) && - storage_class == spv::StorageClass::StorageBuffer) || - (feature_mgr->HasCapability(spv::Capability::VariablePointers) && - storage_class == spv::StorageClass::Workgroup)) { + SpvStorageClass storage_class = + static_cast(type->GetSingleWordInOperand(0)); + if ((feature_mgr->HasCapability(SpvCapabilityVariablePointersStorageBuffer) && + storage_class == SpvStorageClassStorageBuffer) || + (feature_mgr->HasCapability(SpvCapabilityVariablePointers) && + storage_class == SpvStorageClassWorkgroup)) { switch (opcode()) { - case spv::Op::OpPhi: - case spv::Op::OpSelect: - case spv::Op::OpFunctionCall: - case spv::Op::OpConstantNull: + case SpvOpPhi: + case SpvOpSelect: + case SpvOpFunctionCall: + case SpvOpConstantNull: return true; default: break; @@ -656,7 +641,7 @@ bool Instruction::IsValidBasePointer() const { } OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const { - if (opcode() != spv::Op::OpExtInst) { + if (opcode() != SpvOpExtInst) { return OpenCLDebugInfo100InstructionsMax; } @@ -675,7 +660,7 @@ OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const { NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode() const { - if (opcode() != spv::Op::OpExtInst) { + if (opcode() != SpvOpExtInst) { return NonSemanticShaderDebugInfo100InstructionsMax; } @@ -697,7 +682,7 @@ NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode() } CommonDebugInfoInstructions Instruction::GetCommonDebugOpcode() const { - if (opcode() != spv::Op::OpExtInst) { + if (opcode() != SpvOpExtInst) { return CommonDebugInfoInstructionsMax; } @@ -727,31 +712,31 @@ bool Instruction::IsValidBaseImage() const { } Instruction* type = context()->get_def_use_mgr()->GetDef(tid); - return (type->opcode() == spv::Op::OpTypeImage || - type->opcode() == spv::Op::OpTypeSampledImage); + return (type->opcode() == SpvOpTypeImage || + type->opcode() == SpvOpTypeSampledImage); } bool Instruction::IsOpaqueType() const { - if (opcode() == spv::Op::OpTypeStruct) { + if (opcode() == SpvOpTypeStruct) { bool is_opaque = false; ForEachInOperand([&is_opaque, this](const uint32_t* op_id) { Instruction* type_inst = context()->get_def_use_mgr()->GetDef(*op_id); is_opaque |= type_inst->IsOpaqueType(); }); return is_opaque; - } else if (opcode() == spv::Op::OpTypeArray) { + } else if (opcode() == SpvOpTypeArray) { uint32_t sub_type_id = GetSingleWordInOperand(0); Instruction* sub_type_inst = context()->get_def_use_mgr()->GetDef(sub_type_id); return sub_type_inst->IsOpaqueType(); } else { - return opcode() == spv::Op::OpTypeRuntimeArray || + return opcode() == SpvOpTypeRuntimeArray || spvOpcodeIsBaseOpaqueType(opcode()); } } bool Instruction::IsFoldable() const { - return IsFoldableByFoldScalar() || IsFoldableByFoldVector() || + return IsFoldableByFoldScalar() || context()->get_instruction_folder().HasConstFoldingRule(this); } @@ -762,7 +747,7 @@ bool Instruction::IsFoldableByFoldScalar() const { } Instruction* type = context()->get_def_use_mgr()->GetDef(type_id()); - if (!folder.IsFoldableScalarType(type)) { + if (!folder.IsFoldableType(type)) { return false; } @@ -773,52 +758,29 @@ bool Instruction::IsFoldableByFoldScalar() const { Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id); Instruction* def_inst_type = context()->get_def_use_mgr()->GetDef(def_inst->type_id()); - return folder.IsFoldableScalarType(def_inst_type); - }); -} - -bool Instruction::IsFoldableByFoldVector() const { - const InstructionFolder& folder = context()->get_instruction_folder(); - if (!folder.IsFoldableOpcode(opcode())) { - return false; - } - - Instruction* type = context()->get_def_use_mgr()->GetDef(type_id()); - if (!folder.IsFoldableVectorType(type)) { - return false; - } - - // Even if the type of the instruction is foldable, its operands may not be - // foldable (e.g., comparisons of 64bit types). Check that all operand types - // are foldable before accepting the instruction. - return WhileEachInOperand([&folder, this](const uint32_t* op_id) { - Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id); - Instruction* def_inst_type = - context()->get_def_use_mgr()->GetDef(def_inst->type_id()); - return folder.IsFoldableVectorType(def_inst_type); + return folder.IsFoldableType(def_inst_type); }); } bool Instruction::IsFloatingPointFoldingAllowed() const { // TODO: Add the rules for kernels. For now it will be pessimistic. // For now, do not support capabilities introduced by SPV_KHR_float_controls. - if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader) || + if (!context_->get_feature_mgr()->HasCapability(SpvCapabilityShader) || + context_->get_feature_mgr()->HasCapability(SpvCapabilityDenormPreserve) || context_->get_feature_mgr()->HasCapability( - spv::Capability::DenormPreserve) || + SpvCapabilityDenormFlushToZero) || context_->get_feature_mgr()->HasCapability( - spv::Capability::DenormFlushToZero) || + SpvCapabilitySignedZeroInfNanPreserve) || context_->get_feature_mgr()->HasCapability( - spv::Capability::SignedZeroInfNanPreserve) || + SpvCapabilityRoundingModeRTZ) || context_->get_feature_mgr()->HasCapability( - spv::Capability::RoundingModeRTZ) || - context_->get_feature_mgr()->HasCapability( - spv::Capability::RoundingModeRTE)) { + SpvCapabilityRoundingModeRTE)) { return false; } bool is_nocontract = false; context_->get_decoration_mgr()->WhileEachDecoration( - result_id(), uint32_t(spv::Decoration::NoContraction), + result_id(), SpvDecorationNoContraction, [&is_nocontract](const Instruction&) { is_nocontract = true; return false; @@ -854,101 +816,101 @@ void Instruction::Dump() const { bool Instruction::IsOpcodeCodeMotionSafe() const { switch (opcode_) { - case spv::Op::OpNop: - case spv::Op::OpUndef: - case spv::Op::OpLoad: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpArrayLength: - case spv::Op::OpVectorExtractDynamic: - case spv::Op::OpVectorInsertDynamic: - case spv::Op::OpVectorShuffle: - case spv::Op::OpCompositeConstruct: - case spv::Op::OpCompositeExtract: - case spv::Op::OpCompositeInsert: - case spv::Op::OpCopyObject: - case spv::Op::OpTranspose: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: - case spv::Op::OpFConvert: - case spv::Op::OpQuantizeToF16: - case spv::Op::OpBitcast: - case spv::Op::OpSNegate: - case spv::Op::OpFNegate: - case spv::Op::OpIAdd: - case spv::Op::OpFAdd: - case spv::Op::OpISub: - case spv::Op::OpFSub: - case spv::Op::OpIMul: - case spv::Op::OpFMul: - case spv::Op::OpUDiv: - case spv::Op::OpSDiv: - case spv::Op::OpFDiv: - case spv::Op::OpUMod: - case spv::Op::OpSRem: - case spv::Op::OpSMod: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpVectorTimesScalar: - case spv::Op::OpMatrixTimesScalar: - case spv::Op::OpVectorTimesMatrix: - case spv::Op::OpMatrixTimesVector: - case spv::Op::OpMatrixTimesMatrix: - case spv::Op::OpOuterProduct: - case spv::Op::OpDot: - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: - case spv::Op::OpAny: - case spv::Op::OpAll: - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: - case spv::Op::OpLogicalNot: - case spv::Op::OpSelect: - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: - case spv::Op::OpBitFieldInsert: - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: - case spv::Op::OpBitReverse: - case spv::Op::OpBitCount: - case spv::Op::OpSizeOf: + case SpvOpNop: + case SpvOpUndef: + case SpvOpLoad: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpArrayLength: + case SpvOpVectorExtractDynamic: + case SpvOpVectorInsertDynamic: + case SpvOpVectorShuffle: + case SpvOpCompositeConstruct: + case SpvOpCompositeExtract: + case SpvOpCompositeInsert: + case SpvOpCopyObject: + case SpvOpTranspose: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpUConvert: + case SpvOpSConvert: + case SpvOpFConvert: + case SpvOpQuantizeToF16: + case SpvOpBitcast: + case SpvOpSNegate: + case SpvOpFNegate: + case SpvOpIAdd: + case SpvOpFAdd: + case SpvOpISub: + case SpvOpFSub: + case SpvOpIMul: + case SpvOpFMul: + case SpvOpUDiv: + case SpvOpSDiv: + case SpvOpFDiv: + case SpvOpUMod: + case SpvOpSRem: + case SpvOpSMod: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpVectorTimesScalar: + case SpvOpMatrixTimesScalar: + case SpvOpVectorTimesMatrix: + case SpvOpMatrixTimesVector: + case SpvOpMatrixTimesMatrix: + case SpvOpOuterProduct: + case SpvOpDot: + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: + case SpvOpAny: + case SpvOpAll: + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: + case SpvOpLogicalNot: + case SpvOpSelect: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: + case SpvOpBitFieldInsert: + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: + case SpvOpBitReverse: + case SpvOpBitCount: + case SpvOpSizeOf: return true; default: return false; @@ -960,7 +922,7 @@ bool Instruction::IsScalarizable() const { return true; } - if (opcode() == spv::Op::OpExtInst) { + if (opcode() == SpvOpExtInst) { uint32_t instSetId = context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); @@ -1035,16 +997,16 @@ bool Instruction::IsOpcodeSafeToDelete() const { } switch (opcode()) { - case spv::Op::OpDPdx: - case spv::Op::OpDPdy: - case spv::Op::OpFwidth: - case spv::Op::OpDPdxFine: - case spv::Op::OpDPdyFine: - case spv::Op::OpFwidthFine: - case spv::Op::OpDPdxCoarse: - case spv::Op::OpDPdyCoarse: - case spv::Op::OpFwidthCoarse: - case spv::Op::OpImageQueryLod: + case SpvOpDPdx: + case SpvOpDPdy: + case SpvOpFwidth: + case SpvOpDPdxFine: + case SpvOpDPdyFine: + case SpvOpFwidthFine: + case SpvOpDPdxCoarse: + case SpvOpDPdyCoarse: + case SpvOpFwidthCoarse: + case SpvOpImageQueryLod: return true; default: return false; @@ -1053,7 +1015,7 @@ bool Instruction::IsOpcodeSafeToDelete() const { bool Instruction::IsNonSemanticInstruction() const { if (!HasResultId()) return false; - if (opcode() != spv::Op::OpExtInst) return false; + if (opcode() != SpvOpExtInst) return false; auto import_inst = context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(0)); @@ -1073,7 +1035,7 @@ void DebugScope::ToBinary(uint32_t type_id, uint32_t result_id, num_words = kDebugScopeNumWordsWithoutInlinedAt; } std::vector operands = { - (num_words << 16) | static_cast(spv::Op::OpExtInst), + (num_words << 16) | static_cast(SpvOpExtInst), type_id, result_id, ext_set, diff --git a/source/opt/instruction.h b/source/opt/instruction.h index c2617fba..e79c6289 100644 --- a/source/opt/instruction.h +++ b/source/opt/instruction.h @@ -36,8 +36,8 @@ #include "source/util/string_utils.h" #include "spirv-tools/libspirv.h" -constexpr uint32_t kNoDebugScope = 0; -constexpr uint32_t kNoInlinedAt = 0; +const uint32_t kNoDebugScope = 0; +const uint32_t kNoInlinedAt = 0; namespace spvtools { namespace opt { @@ -190,7 +190,7 @@ class Instruction : public utils::IntrusiveNodeBase { Instruction() : utils::IntrusiveNodeBase(), context_(nullptr), - opcode_(spv::Op::OpNop), + opcode_(SpvOpNop), has_type_id_(false), has_result_id_(false), unique_id_(0), @@ -200,7 +200,7 @@ class Instruction : public utils::IntrusiveNodeBase { Instruction(IRContext*); // Creates an instruction with the given opcode |op| and no additional logical // operands. - Instruction(IRContext*, spv::Op); + Instruction(IRContext*, SpvOp); // Creates an instruction using the given spv_parsed_instruction_t |inst|. All // the data inside |inst| will be copied and owned in this instance. And keep // record of line-related debug instructions |dbg_line| ahead of this @@ -213,7 +213,7 @@ class Instruction : public utils::IntrusiveNodeBase { // Creates an instruction with the given opcode |op|, type id: |ty_id|, // result id: |res_id| and input operands: |in_operands|. - Instruction(IRContext* c, spv::Op op, uint32_t ty_id, uint32_t res_id, + Instruction(IRContext* c, SpvOp op, uint32_t ty_id, uint32_t res_id, const OperandList& in_operands); // TODO: I will want to remove these, but will first have to remove the use of @@ -235,12 +235,12 @@ class Instruction : public utils::IntrusiveNodeBase { IRContext* context() const { return context_; } - spv::Op opcode() const { return opcode_; } + SpvOp opcode() const { return opcode_; } // Sets the opcode of this instruction to a specific opcode. Note this may // invalidate the instruction. // TODO(qining): Remove this function when instruction building and insertion // is well implemented. - void SetOpcode(spv::Op op) { opcode_ = op; } + void SetOpcode(SpvOp op) { opcode_ = op; } uint32_t type_id() const { return has_type_id_ ? GetSingleWordOperand(0) : 0; } @@ -294,8 +294,6 @@ class Instruction : public utils::IntrusiveNodeBase { // It is the responsibility of the caller to make sure // that the instruction remains valid. inline void AddOperand(Operand&& operand); - // Adds a copy of |operand| to the list of operands of this instruction. - inline void AddOperand(const Operand& operand); // Gets the |index|-th logical operand as a single SPIR-V word. This method is // not expected to be used with logical operands consisting of multiple SPIR-V // words. @@ -524,10 +522,6 @@ class Instruction : public utils::IntrusiveNodeBase { // constant value by |FoldScalar|. bool IsFoldableByFoldScalar() const; - // Returns true if |this| is an instruction which could be folded into a - // constant value by |FoldVector|. - bool IsFoldableByFoldVector() const; - // Returns true if we are allowed to fold or otherwise manipulate the // instruction that defines |id| in the given context. This includes not // handling NaN values. @@ -631,7 +625,7 @@ class Instruction : public utils::IntrusiveNodeBase { bool IsValidBaseImage() const; IRContext* context_; // IR Context - spv::Op opcode_; // Opcode + SpvOp opcode_; // Opcode bool has_type_id_; // True if the instruction has a type id bool has_result_id_; // True if the instruction has a result id uint32_t unique_id_; // Unique instruction id @@ -682,10 +676,6 @@ inline void Instruction::AddOperand(Operand&& operand) { operands_.push_back(std::move(operand)); } -inline void Instruction::AddOperand(const Operand& operand) { - operands_.push_back(operand); -} - inline void Instruction::SetInOperand(uint32_t index, Operand::OperandData&& data) { SetOperand(index + TypeResultIdCount(), std::move(data)); @@ -742,12 +732,12 @@ inline void Instruction::SetResultType(uint32_t ty_id) { } inline bool Instruction::IsNop() const { - return opcode_ == spv::Op::OpNop && !has_type_id_ && !has_result_id_ && + return opcode_ == SpvOpNop && !has_type_id_ && !has_result_id_ && operands_.empty(); } inline void Instruction::ToNop() { - opcode_ = spv::Op::OpNop; + opcode_ = SpvOpNop; has_type_id_ = false; has_result_id_ = false; operands_.clear(); @@ -889,12 +879,12 @@ inline void Instruction::ForEachInOperand( inline bool Instruction::HasLabels() const { switch (opcode_) { - case spv::Op::OpSelectionMerge: - case spv::Op::OpBranch: - case spv::Op::OpLoopMerge: - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: - case spv::Op::OpPhi: + case SpvOpSelectionMerge: + case SpvOpBranch: + case SpvOpLoopMerge: + case SpvOpBranchConditional: + case SpvOpSwitch: + case SpvOpPhi: return true; break; default: @@ -916,7 +906,7 @@ bool Instruction::IsAtomicWithLoad() const { bool Instruction::IsAtomicOp() const { return spvOpcodeIsAtomicOp(opcode()); } bool Instruction::IsConstant() const { - return IsConstantInst(opcode()) && !IsSpecConstantInst(opcode()); + return IsCompileTimeConstantInst(opcode()); } } // namespace opt } // namespace spvtools diff --git a/source/opt/instrument_pass.cpp b/source/opt/instrument_pass.cpp index b6845a59..d143d595 100644 --- a/source/opt/instrument_pass.cpp +++ b/source/opt/instrument_pass.cpp @@ -19,12 +19,20 @@ #include "source/cfa.h" #include "source/spirv_constant.h" +namespace { + +// Common Parameter Positions +static const int kInstCommonParamInstIdx = 0; +static const int kInstCommonParamCnt = 1; + +// Indices of operands in SPIR-V instructions +static const int kEntryPointExecutionModelInIdx = 0; +static const int kEntryPointFunctionIdInIdx = 1; + +} // anonymous namespace + namespace spvtools { namespace opt { -namespace { -// Indices of operands in SPIR-V instructions -constexpr int kEntryPointFunctionIdInIdx = 1; -} // namespace void InstrumentPass::MovePreludeCode( BasicBlock::iterator ref_inst_itr, @@ -51,6 +59,7 @@ void InstrumentPass::MovePreludeCode( void InstrumentPass::MovePostludeCode( UptrVectorIterator ref_block_itr, BasicBlock* new_blk_ptr) { + // new_blk_ptr->reset(new BasicBlock(NewLabel(ref_block_itr->id()))); // Move contents of original ref block. for (auto cii = ref_block_itr->begin(); cii != ref_block_itr->end(); cii = ref_block_itr->begin()) { @@ -73,62 +82,55 @@ void InstrumentPass::MovePostludeCode( } std::unique_ptr InstrumentPass::NewLabel(uint32_t label_id) { - auto new_label = - MakeUnique(context(), spv::Op::OpLabel, 0, label_id, - std::initializer_list{}); - get_def_use_mgr()->AnalyzeInstDefUse(&*new_label); - return new_label; -} - -std::unique_ptr InstrumentPass::StartFunction( - uint32_t func_id, const analysis::Type* return_type, - const std::vector& param_types) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::Function* func_type = GetFunction(return_type, param_types); - - const std::vector operands{ - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_mgr->GetId(func_type)}}, - }; - auto func_inst = - MakeUnique(context(), spv::Op::OpFunction, - type_mgr->GetId(return_type), func_id, operands); - get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); - return MakeUnique(std::move(func_inst)); -} - -std::unique_ptr InstrumentPass::EndFunction() { - auto end = MakeUnique(context(), spv::Op::OpFunctionEnd, 0, 0, - std::initializer_list{}); - get_def_use_mgr()->AnalyzeInstDefUse(end.get()); - return end; -} - -std::vector InstrumentPass::AddParameters( - Function& func, const std::vector& param_types) { - std::vector param_ids; - param_ids.reserve(param_types.size()); - for (const analysis::Type* param : param_types) { - uint32_t pid = TakeNextId(); - param_ids.push_back(pid); - auto param_inst = - MakeUnique(context(), spv::Op::OpFunctionParameter, - context()->get_type_mgr()->GetId(param), pid, - std::initializer_list{}); - get_def_use_mgr()->AnalyzeInstDefUse(param_inst.get()); - func.AddParameter(std::move(param_inst)); - } - return param_ids; + std::unique_ptr newLabel( + new Instruction(context(), SpvOpLabel, 0, label_id, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*newLabel); + return newLabel; } std::unique_ptr InstrumentPass::NewName( uint32_t id, const std::string& name_str) { - return MakeUnique( - context(), spv::Op::OpName, 0, 0, + std::unique_ptr new_name(new Instruction( + context(), SpvOpName, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {id}}, - {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}); + {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); + + return new_name; +} + +std::unique_ptr InstrumentPass::NewGlobalName( + uint32_t id, const std::string& name_str) { + std::string prefixed_name; + switch (validation_id_) { + case kInstValidationIdBindless: + prefixed_name = "inst_bindless_"; + break; + case kInstValidationIdBuffAddr: + prefixed_name = "inst_buff_addr_"; + break; + case kInstValidationIdDebugPrintf: + prefixed_name = "inst_printf_"; + break; + default: + assert(false); // add new instrumentation pass here + prefixed_name = "inst_pass_"; + break; + } + prefixed_name += name_str; + return NewName(id, prefixed_name); +} + +std::unique_ptr InstrumentPass::NewMemberName( + uint32_t id, uint32_t member_index, const std::string& name_str) { + std::unique_ptr new_name(new Instruction( + context(), SpvOpMemberName, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {id}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}}, + {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}})); + + return new_name; } uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id, @@ -143,10 +145,10 @@ uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id, analysis::Type* val_32b_reg_ty = type_mgr->GetRegisteredType(&val_32b_ty); uint32_t val_32b_reg_ty_id = type_mgr->GetId(val_32b_reg_ty); if (is_signed) - return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpSConvert, val_id) + return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpSConvert, val_id) ->result_id(); else - return builder->AddUnaryOp(val_32b_reg_ty_id, spv::Op::OpUConvert, val_id) + return builder->AddUnaryOp(val_32b_reg_ty_id, SpvOpUConvert, val_id) ->result_id(); } @@ -159,124 +161,195 @@ uint32_t InstrumentPass::GenUintCastCode(uint32_t val_id, uint32_t val_ty_id = get_def_use_mgr()->GetDef(val_32b_id)->type_id(); analysis::Integer* val_ty = type_mgr->GetType(val_ty_id)->AsInteger(); if (!val_ty->IsSigned()) return val_32b_id; - return builder->AddUnaryOp(GetUintId(), spv::Op::OpBitcast, val_32b_id) + return builder->AddUnaryOp(GetUintId(), SpvOpBitcast, val_32b_id) ->result_id(); } +void InstrumentPass::GenDebugOutputFieldCode(uint32_t base_offset_id, + uint32_t field_offset, + uint32_t field_value_id, + InstructionBuilder* builder) { + // Cast value to 32-bit unsigned if necessary + uint32_t val_id = GenUintCastCode(field_value_id, builder); + // Store value + Instruction* data_idx_inst = + builder->AddBinaryOp(GetUintId(), SpvOpIAdd, base_offset_id, + builder->GetUintConstantId(field_offset)); + uint32_t buf_id = GetOutputBufferId(); + uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); + Instruction* achain_inst = + builder->AddTernaryOp(buf_uint_ptr_id, SpvOpAccessChain, buf_id, + builder->GetUintConstantId(kDebugOutputDataOffset), + data_idx_inst->result_id()); + (void)builder->AddBinaryOp(0, SpvOpStore, achain_inst->result_id(), val_id); +} + +void InstrumentPass::GenCommonStreamWriteCode(uint32_t record_sz, + uint32_t inst_id, + uint32_t stage_idx, + uint32_t base_offset_id, + InstructionBuilder* builder) { + // Store record size + GenDebugOutputFieldCode(base_offset_id, kInstCommonOutSize, + builder->GetUintConstantId(record_sz), builder); + // Store Shader Id + GenDebugOutputFieldCode(base_offset_id, kInstCommonOutShaderId, + builder->GetUintConstantId(shader_id_), builder); + // Store Instruction Idx + GenDebugOutputFieldCode(base_offset_id, kInstCommonOutInstructionIdx, inst_id, + builder); + // Store Stage Idx + GenDebugOutputFieldCode(base_offset_id, kInstCommonOutStageIdx, + builder->GetUintConstantId(stage_idx), builder); +} + +void InstrumentPass::GenFragCoordEltDebugOutputCode( + uint32_t base_offset_id, uint32_t uint_frag_coord_id, uint32_t element, + InstructionBuilder* builder) { + Instruction* element_val_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, uint_frag_coord_id, element); + GenDebugOutputFieldCode(base_offset_id, kInstFragOutFragCoordX + element, + element_val_inst->result_id(), builder); +} + uint32_t InstrumentPass::GenVarLoad(uint32_t var_id, InstructionBuilder* builder) { Instruction* var_inst = get_def_use_mgr()->GetDef(var_id); uint32_t type_id = GetPointeeTypeId(var_inst); - Instruction* load_inst = builder->AddLoad(type_id, var_id); + Instruction* load_inst = builder->AddUnaryOp(type_id, SpvOpLoad, var_id); return load_inst->result_id(); } -uint32_t InstrumentPass::GenStageInfo(uint32_t stage_idx, - InstructionBuilder* builder) { - std::vector ids(4, builder->GetUintConstantId(0)); - ids[0] = builder->GetUintConstantId(stage_idx); - // %289 = OpCompositeConstruct %v4uint %uint_0 %285 %288 %uint_0 - // TODO(greg-lunarg): Add support for all stages - switch (spv::ExecutionModel(stage_idx)) { - case spv::ExecutionModel::Vertex: { - // Load and store VertexId and InstanceId - uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::VertexIndex)), - builder); - ids[1] = GenUintCastCode(load_id, builder); +void InstrumentPass::GenBuiltinOutputCode(uint32_t builtin_id, + uint32_t builtin_off, + uint32_t base_offset_id, + InstructionBuilder* builder) { + // Load and store builtin + uint32_t load_id = GenVarLoad(builtin_id, builder); + GenDebugOutputFieldCode(base_offset_id, builtin_off, load_id, builder); +} - load_id = GenVarLoad(context()->GetBuiltinInputVarId( - uint32_t(spv::BuiltIn::InstanceIndex)), - builder); - ids[2] = GenUintCastCode(load_id, builder); +void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx, + uint32_t base_offset_id, + InstructionBuilder* builder) { + // TODO(greg-lunarg): Add support for all stages + switch (stage_idx) { + case SpvExecutionModelVertex: { + // Load and store VertexId and InstanceId + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInVertexIndex), + kInstVertOutVertexIndex, base_offset_id, builder); + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInInstanceIndex), + kInstVertOutInstanceIndex, base_offset_id, builder); } break; - case spv::ExecutionModel::GLCompute: - case spv::ExecutionModel::TaskNV: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::TaskEXT: - case spv::ExecutionModel::MeshEXT: { + case SpvExecutionModelGLCompute: + case SpvExecutionModelTaskNV: + case SpvExecutionModelMeshNV: + case SpvExecutionModelTaskEXT: + case SpvExecutionModelMeshEXT: { // Load and store GlobalInvocationId. - uint32_t load_id = GenVarLoad(context()->GetBuiltinInputVarId(uint32_t( - spv::BuiltIn::GlobalInvocationId)), - builder); - for (uint32_t u = 0; u < 3u; ++u) { - ids[u + 1] = builder->AddCompositeExtract(GetUintId(), load_id, {u}) - ->result_id(); - } + uint32_t load_id = GenVarLoad( + context()->GetBuiltinInputVarId(SpvBuiltInGlobalInvocationId), + builder); + Instruction* x_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, load_id, 0); + Instruction* y_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, load_id, 1); + Instruction* z_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, load_id, 2); + GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdX, + x_inst->result_id(), builder); + GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdY, + y_inst->result_id(), builder); + GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdZ, + z_inst->result_id(), builder); } break; - case spv::ExecutionModel::Geometry: { + case SpvExecutionModelGeometry: { // Load and store PrimitiveId and InvocationId. - uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), - builder); - ids[1] = load_id; - load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), - builder); - ids[2] = GenUintCastCode(load_id, builder); + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + kInstGeomOutPrimitiveId, base_offset_id, builder); + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInInvocationId), + kInstGeomOutInvocationId, base_offset_id, builder); } break; - case spv::ExecutionModel::TessellationControl: { + case SpvExecutionModelTessellationControl: { // Load and store InvocationId and PrimitiveId - uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)), - builder); - ids[1] = GenUintCastCode(load_id, builder); - load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), - builder); - ids[2] = load_id; + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInInvocationId), + kInstTessCtlOutInvocationId, base_offset_id, builder); + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + kInstTessCtlOutPrimitiveId, base_offset_id, builder); } break; - case spv::ExecutionModel::TessellationEvaluation: { + case SpvExecutionModelTessellationEvaluation: { // Load and store PrimitiveId and TessCoord.uv + GenBuiltinOutputCode( + context()->GetBuiltinInputVarId(SpvBuiltInPrimitiveId), + kInstTessEvalOutPrimitiveId, base_offset_id, builder); uint32_t load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)), - builder); - ids[1] = load_id; - load_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::TessCoord)), - builder); + context()->GetBuiltinInputVarId(SpvBuiltInTessCoord), builder); Instruction* uvec3_cast_inst = - builder->AddUnaryOp(GetVec3UintId(), spv::Op::OpBitcast, load_id); + builder->AddUnaryOp(GetVec3UintId(), SpvOpBitcast, load_id); uint32_t uvec3_cast_id = uvec3_cast_inst->result_id(); - for (uint32_t u = 0; u < 2u; ++u) { - ids[u + 2] = - builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {u}) - ->result_id(); - } + Instruction* u_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, uvec3_cast_id, 0); + Instruction* v_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, uvec3_cast_id, 1); + GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordU, + u_inst->result_id(), builder); + GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordV, + v_inst->result_id(), builder); } break; - case spv::ExecutionModel::Fragment: { + case SpvExecutionModelFragment: { // Load FragCoord and convert to Uint - Instruction* frag_coord_inst = builder->AddLoad( - GetVec4FloatId(), - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::FragCoord))); + Instruction* frag_coord_inst = builder->AddUnaryOp( + GetVec4FloatId(), SpvOpLoad, + context()->GetBuiltinInputVarId(SpvBuiltInFragCoord)); Instruction* uint_frag_coord_inst = builder->AddUnaryOp( - GetVec4UintId(), spv::Op::OpBitcast, frag_coord_inst->result_id()); - for (uint32_t u = 0; u < 2u; ++u) { - ids[u + 1] = - builder - ->AddCompositeExtract(GetUintId(), - uint_frag_coord_inst->result_id(), {u}) - ->result_id(); - } + GetVec4UintId(), SpvOpBitcast, frag_coord_inst->result_id()); + for (uint32_t u = 0; u < 2u; ++u) + GenFragCoordEltDebugOutputCode( + base_offset_id, uint_frag_coord_inst->result_id(), u, builder); } break; - case spv::ExecutionModel::RayGenerationNV: - case spv::ExecutionModel::IntersectionNV: - case spv::ExecutionModel::AnyHitNV: - case spv::ExecutionModel::ClosestHitNV: - case spv::ExecutionModel::MissNV: - case spv::ExecutionModel::CallableNV: { + case SpvExecutionModelRayGenerationNV: + case SpvExecutionModelIntersectionNV: + case SpvExecutionModelAnyHitNV: + case SpvExecutionModelClosestHitNV: + case SpvExecutionModelMissNV: + case SpvExecutionModelCallableNV: { // Load and store LaunchIdNV. uint32_t launch_id = GenVarLoad( - context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::LaunchIdNV)), - builder); - for (uint32_t u = 0; u < 3u; ++u) { - ids[u + 1] = builder->AddCompositeExtract(GetUintId(), launch_id, {u}) - ->result_id(); - } + context()->GetBuiltinInputVarId(SpvBuiltInLaunchIdNV), builder); + Instruction* x_launch_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, launch_id, 0); + Instruction* y_launch_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, launch_id, 1); + Instruction* z_launch_inst = builder->AddIdLiteralOp( + GetUintId(), SpvOpCompositeExtract, launch_id, 2); + GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdX, + x_launch_inst->result_id(), builder); + GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdY, + y_launch_inst->result_id(), builder); + GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdZ, + z_launch_inst->result_id(), builder); } break; default: { assert(false && "unsupported stage"); } break; } - return builder->AddCompositeConstruct(GetVec4UintId(), ids)->result_id(); +} + +void InstrumentPass::GenDebugStreamWrite( + uint32_t instruction_idx, uint32_t stage_idx, + const std::vector& validation_ids, InstructionBuilder* builder) { + // Call debug output function. Pass func_idx, instruction_idx and + // validation ids as args. + uint32_t val_id_cnt = static_cast(validation_ids.size()); + uint32_t output_func_id = GetStreamWriteFunctionId(stage_idx, val_id_cnt); + std::vector args = {output_func_id, + builder->GetUintConstantId(instruction_idx)}; + (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end()); + (void)builder->AddNaryOp(GetVoidId(), SpvOpFunctionCall, args); } bool InstrumentPass::AllConstant(const std::vector& ids) { @@ -287,37 +360,38 @@ bool InstrumentPass::AllConstant(const std::vector& ids) { return true; } -uint32_t InstrumentPass::GenReadFunctionCall( - uint32_t return_id, uint32_t func_id, - const std::vector& func_call_args, - InstructionBuilder* ref_builder) { +uint32_t InstrumentPass::GenDebugDirectRead( + const std::vector& offset_ids, InstructionBuilder* ref_builder) { + // Call debug input function. Pass func_idx and offset ids as args. + uint32_t off_id_cnt = static_cast(offset_ids.size()); + uint32_t input_func_id = GetDirectReadFunctionId(off_id_cnt); + std::vector args = {input_func_id}; + (void)args.insert(args.end(), offset_ids.begin(), offset_ids.end()); // If optimizing direct reads and the call has already been generated, // use its result if (opt_direct_reads_) { - uint32_t res_id = call2id_[func_call_args]; + uint32_t res_id = call2id_[args]; if (res_id != 0) return res_id; } - // If the function arguments are all constants, the call can be moved to the - // first block of the function where its result can be reused. One example - // where this is profitable is for uniform buffer references, of which there - // are often many. + // If the offsets are all constants, the call can be moved to the first block + // of the function where its result can be reused. One example where this is + // profitable is for uniform buffer references, of which there are often many. InstructionBuilder builder(ref_builder->GetContext(), &*ref_builder->GetInsertPoint(), ref_builder->GetPreservedAnalysis()); - bool insert_in_first_block = opt_direct_reads_ && AllConstant(func_call_args); + bool insert_in_first_block = opt_direct_reads_ && AllConstant(offset_ids); if (insert_in_first_block) { Instruction* insert_before = &*curr_func_->begin()->tail(); builder.SetInsertPoint(insert_before); } uint32_t res_id = - builder.AddFunctionCall(return_id, func_id, func_call_args)->result_id(); - if (insert_in_first_block) call2id_[func_call_args] = res_id; + builder.AddNaryOp(GetUintId(), SpvOpFunctionCall, args)->result_id(); + if (insert_in_first_block) call2id_[args] = res_id; return res_id; } bool InstrumentPass::IsSameBlockOp(const Instruction* inst) const { - return inst->opcode() == spv::Op::OpSampledImage || - inst->opcode() == spv::Op::OpImage; + return inst->opcode() == SpvOpSampledImage || inst->opcode() == SpvOpImage; } void InstrumentPass::CloneSameBlockOps( @@ -380,74 +454,79 @@ void InstrumentPass::UpdateSucceedingPhis( }); } -analysis::Integer* InstrumentPass::GetInteger(uint32_t width, bool is_signed) { - analysis::Integer i(width, is_signed); - analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&i); - assert(type && type->AsInteger()); - return type->AsInteger(); +uint32_t InstrumentPass::GetOutputBufferPtrId() { + if (output_buffer_ptr_id_ == 0) { + output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( + GetUintId(), SpvStorageClassStorageBuffer); + } + return output_buffer_ptr_id_; } -analysis::Struct* InstrumentPass::GetStruct( - const std::vector& fields) { - analysis::Struct s(fields); - analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&s); - assert(type && type->AsStruct()); - return type->AsStruct(); +uint32_t InstrumentPass::GetInputBufferTypeId() { + return (validation_id_ == kInstValidationIdBuffAddr) ? GetUint64Id() + : GetUintId(); } -analysis::RuntimeArray* InstrumentPass::GetRuntimeArray( - const analysis::Type* element) { - analysis::RuntimeArray r(element); - analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r); - assert(type && type->AsRuntimeArray()); - return type->AsRuntimeArray(); +uint32_t InstrumentPass::GetInputBufferPtrId() { + if (input_buffer_ptr_id_ == 0) { + input_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType( + GetInputBufferTypeId(), SpvStorageClassStorageBuffer); + } + return input_buffer_ptr_id_; } -analysis::Array* InstrumentPass::GetArray(const analysis::Type* element, - uint32_t length) { - uint32_t length_id = context()->get_constant_mgr()->GetUIntConstId(length); - analysis::Array::LengthInfo length_info{ - length_id, {analysis::Array::LengthInfo::Case::kConstant, length}}; - - analysis::Array r(element, length_info); - - analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&r); - assert(type && type->AsArray()); - return type->AsArray(); +uint32_t InstrumentPass::GetOutputBufferBinding() { + switch (validation_id_) { + case kInstValidationIdBindless: + return kDebugOutputBindingStream; + case kInstValidationIdBuffAddr: + return kDebugOutputBindingStream; + case kInstValidationIdDebugPrintf: + return kDebugOutputPrintfStream; + default: + assert(false && "unexpected validation id"); + } + return 0; } -analysis::Function* InstrumentPass::GetFunction( - const analysis::Type* return_val, - const std::vector& args) { - analysis::Function func(return_val, args); - analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&func); - assert(type && type->AsFunction()); - return type->AsFunction(); +uint32_t InstrumentPass::GetInputBufferBinding() { + switch (validation_id_) { + case kInstValidationIdBindless: + return kDebugInputBindingBindless; + case kInstValidationIdBuffAddr: + return kDebugInputBindingBuffAddr; + default: + assert(false && "unexpected validation id"); + } + return 0; } -analysis::RuntimeArray* InstrumentPass::GetUintXRuntimeArrayType( - uint32_t width, analysis::RuntimeArray** rarr_ty) { +analysis::Type* InstrumentPass::GetUintXRuntimeArrayType( + uint32_t width, analysis::Type** rarr_ty) { if (*rarr_ty == nullptr) { - *rarr_ty = GetRuntimeArray(GetInteger(width, false)); - uint32_t uint_arr_ty_id = - context()->get_type_mgr()->GetTypeInstruction(*rarr_ty); + analysis::DecorationManager* deco_mgr = get_decoration_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Integer uint_ty(width, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::RuntimeArray uint_rarr_ty_tmp(reg_uint_ty); + *rarr_ty = type_mgr->GetRegisteredType(&uint_rarr_ty_tmp); + uint32_t uint_arr_ty_id = type_mgr->GetTypeInstruction(*rarr_ty); // By the Vulkan spec, a pre-existing RuntimeArray of uint must be part of // a block, and will therefore be decorated with an ArrayStride. Therefore // the undecorated type returned here will not be pre-existing and can // safely be decorated. Since this type is now decorated, it is out of // sync with the TypeManager and therefore the TypeManager must be // invalidated after this pass. - assert(get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 && + assert(context()->get_def_use_mgr()->NumUses(uint_arr_ty_id) == 0 && "used RuntimeArray type returned"); - get_decoration_mgr()->AddDecorationVal( - uint_arr_ty_id, uint32_t(spv::Decoration::ArrayStride), width / 8u); + deco_mgr->AddDecorationVal(uint_arr_ty_id, SpvDecorationArrayStride, + width / 8u); } return *rarr_ty; } -analysis::RuntimeArray* InstrumentPass::GetUintRuntimeArrayType( - uint32_t width) { - analysis::RuntimeArray** rarr_ty = +analysis::Type* InstrumentPass::GetUintRuntimeArrayType(uint32_t width) { + analysis::Type** rarr_ty = (width == 64) ? &uint64_rarr_ty_ : &uint32_rarr_ty_; return GetUintXRuntimeArrayType(width, rarr_ty); } @@ -460,6 +539,106 @@ void InstrumentPass::AddStorageBufferExt() { storage_buffer_ext_defined_ = true; } +// Return id for output buffer +uint32_t InstrumentPass::GetOutputBufferId() { + if (output_buffer_id_ == 0) { + // If not created yet, create one + analysis::DecorationManager* deco_mgr = get_decoration_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(32); + analysis::Integer uint_ty(32, false); + analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); + analysis::Struct buf_ty({reg_uint_ty, reg_uint_rarr_ty}); + analysis::Type* reg_buf_ty = type_mgr->GetRegisteredType(&buf_ty); + uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty); + // By the Vulkan spec, a pre-existing struct containing a RuntimeArray + // must be a block, and will therefore be decorated with Block. Therefore + // the undecorated type returned here will not be pre-existing and can + // safely be decorated. Since this type is now decorated, it is out of + // sync with the TypeManager and therefore the TypeManager must be + // invalidated after this pass. + assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 && + "used struct type returned"); + deco_mgr->AddDecoration(obufTyId, SpvDecorationBlock); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset, + SpvDecorationOffset, 0); + deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset, + SpvDecorationOffset, 4); + uint32_t obufTyPtrId_ = + type_mgr->FindPointerToType(obufTyId, SpvStorageClassStorageBuffer); + output_buffer_id_ = TakeNextId(); + std::unique_ptr newVarOp(new Instruction( + context(), SpvOpVariable, obufTyPtrId_, output_buffer_id_, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvStorageClassStorageBuffer}}})); + context()->AddGlobalValue(std::move(newVarOp)); + context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "written_count")); + context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "data")); + context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer")); + deco_mgr->AddDecorationVal(output_buffer_id_, SpvDecorationDescriptorSet, + desc_set_); + deco_mgr->AddDecorationVal(output_buffer_id_, SpvDecorationBinding, + GetOutputBufferBinding()); + AddStorageBufferExt(); + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Add the new buffer to all entry points. + for (auto& entry : get_module()->entry_points()) { + entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}}); + context()->AnalyzeUses(&entry); + } + } + } + return output_buffer_id_; +} + +uint32_t InstrumentPass::GetInputBufferId() { + if (input_buffer_id_ == 0) { + // If not created yet, create one + analysis::DecorationManager* deco_mgr = get_decoration_mgr(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + uint32_t width = (validation_id_ == kInstValidationIdBuffAddr) ? 64u : 32u; + analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(width); + analysis::Struct buf_ty({reg_uint_rarr_ty}); + analysis::Type* reg_buf_ty = type_mgr->GetRegisteredType(&buf_ty); + uint32_t ibufTyId = type_mgr->GetTypeInstruction(reg_buf_ty); + // By the Vulkan spec, a pre-existing struct containing a RuntimeArray + // must be a block, and will therefore be decorated with Block. Therefore + // the undecorated type returned here will not be pre-existing and can + // safely be decorated. Since this type is now decorated, it is out of + // sync with the TypeManager and therefore the TypeManager must be + // invalidated after this pass. + assert(context()->get_def_use_mgr()->NumUses(ibufTyId) == 0 && + "used struct type returned"); + deco_mgr->AddDecoration(ibufTyId, SpvDecorationBlock); + deco_mgr->AddMemberDecoration(ibufTyId, 0, SpvDecorationOffset, 0); + uint32_t ibufTyPtrId_ = + type_mgr->FindPointerToType(ibufTyId, SpvStorageClassStorageBuffer); + input_buffer_id_ = TakeNextId(); + std::unique_ptr newVarOp(new Instruction( + context(), SpvOpVariable, ibufTyPtrId_, input_buffer_id_, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvStorageClassStorageBuffer}}})); + context()->AddGlobalValue(std::move(newVarOp)); + context()->AddDebug2Inst(NewGlobalName(ibufTyId, "InputBuffer")); + context()->AddDebug2Inst(NewMemberName(ibufTyId, 0, "data")); + context()->AddDebug2Inst(NewGlobalName(input_buffer_id_, "input_buffer")); + deco_mgr->AddDecorationVal(input_buffer_id_, SpvDecorationDescriptorSet, + desc_set_); + deco_mgr->AddDecorationVal(input_buffer_id_, SpvDecorationBinding, + GetInputBufferBinding()); + AddStorageBufferExt(); + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Add the new buffer to all entry points. + for (auto& entry : get_module()->entry_points()) { + entry.AddOperand({SPV_OPERAND_TYPE_ID, {input_buffer_id_}}); + context()->AnalyzeUses(&entry); + } + } + } + return input_buffer_id_; +} + uint32_t InstrumentPass::GetFloatId() { if (float_id_ == 0) { analysis::TypeManager* type_mgr = context()->get_type_mgr(); @@ -552,6 +731,207 @@ uint32_t InstrumentPass::GetVoidId() { return void_id_; } +uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx, + uint32_t val_spec_param_cnt) { + // Total param count is common params plus validation-specific + // params + uint32_t param_cnt = kInstCommonParamCnt + val_spec_param_cnt; + if (param2output_func_id_[param_cnt] == 0) { + // Create function + param2output_func_id_[param_cnt] = TakeNextId(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + std::vector param_types; + for (uint32_t c = 0; c < param_cnt; ++c) + param_types.push_back(type_mgr->GetType(GetUintId())); + analysis::Function func_ty(type_mgr->GetType(GetVoidId()), param_types); + analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); + std::unique_ptr func_inst( + new Instruction(get_module()->context(), SpvOpFunction, GetVoidId(), + param2output_func_id_[param_cnt], + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvFunctionControlMaskNone}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {type_mgr->GetTypeInstruction(reg_func_ty)}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); + std::unique_ptr output_func = + MakeUnique(std::move(func_inst)); + // Add parameters + std::vector param_vec; + for (uint32_t c = 0; c < param_cnt; ++c) { + uint32_t pid = TakeNextId(); + param_vec.push_back(pid); + std::unique_ptr param_inst( + new Instruction(get_module()->context(), SpvOpFunctionParameter, + GetUintId(), pid, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); + output_func->AddParameter(std::move(param_inst)); + } + // Create first block + uint32_t test_blk_id = TakeNextId(); + std::unique_ptr test_label(NewLabel(test_blk_id)); + std::unique_ptr new_blk_ptr = + MakeUnique(std::move(test_label)); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // Gen test if debug output buffer size will not be exceeded. + uint32_t val_spec_offset = kInstStageOutCnt; + uint32_t obuf_record_sz = val_spec_offset + val_spec_param_cnt; + uint32_t buf_id = GetOutputBufferId(); + uint32_t buf_uint_ptr_id = GetOutputBufferPtrId(); + Instruction* obuf_curr_sz_ac_inst = + builder.AddBinaryOp(buf_uint_ptr_id, SpvOpAccessChain, buf_id, + builder.GetUintConstantId(kDebugOutputSizeOffset)); + // Fetch the current debug buffer written size atomically, adding the + // size of the record to be written. + uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz); + uint32_t mask_none_id = builder.GetUintConstantId(SpvMemoryAccessMaskNone); + uint32_t scope_invok_id = builder.GetUintConstantId(SpvScopeInvocation); + Instruction* obuf_curr_sz_inst = builder.AddQuadOp( + GetUintId(), SpvOpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(), + scope_invok_id, mask_none_id, obuf_record_sz_id); + uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id(); + // Compute new written size + Instruction* obuf_new_sz_inst = + builder.AddBinaryOp(GetUintId(), SpvOpIAdd, obuf_curr_sz_id, + builder.GetUintConstantId(obuf_record_sz)); + // Fetch the data bound + Instruction* obuf_bnd_inst = + builder.AddIdLiteralOp(GetUintId(), SpvOpArrayLength, + GetOutputBufferId(), kDebugOutputDataOffset); + // Test that new written size is less than or equal to debug output + // data bound + Instruction* obuf_safe_inst = builder.AddBinaryOp( + GetBoolId(), SpvOpULessThanEqual, obuf_new_sz_inst->result_id(), + obuf_bnd_inst->result_id()); + uint32_t merge_blk_id = TakeNextId(); + uint32_t write_blk_id = TakeNextId(); + std::unique_ptr merge_label(NewLabel(merge_blk_id)); + std::unique_ptr write_label(NewLabel(write_blk_id)); + (void)builder.AddConditionalBranch(obuf_safe_inst->result_id(), + write_blk_id, merge_blk_id, merge_blk_id, + SpvSelectionControlMaskNone); + // Close safety test block and gen write block + output_func->AddBasicBlock(std::move(new_blk_ptr)); + new_blk_ptr = MakeUnique(std::move(write_label)); + builder.SetInsertPoint(&*new_blk_ptr); + // Generate common and stage-specific debug record members + GenCommonStreamWriteCode(obuf_record_sz, param_vec[kInstCommonParamInstIdx], + stage_idx, obuf_curr_sz_id, &builder); + GenStageStreamWriteCode(stage_idx, obuf_curr_sz_id, &builder); + // Gen writes of validation specific data + for (uint32_t i = 0; i < val_spec_param_cnt; ++i) { + GenDebugOutputFieldCode(obuf_curr_sz_id, val_spec_offset + i, + param_vec[kInstCommonParamCnt + i], &builder); + } + // Close write block and gen merge block + (void)builder.AddBranch(merge_blk_id); + output_func->AddBasicBlock(std::move(new_blk_ptr)); + new_blk_ptr = MakeUnique(std::move(merge_label)); + builder.SetInsertPoint(&*new_blk_ptr); + // Close merge block and function and add function to module + (void)builder.AddNullaryOp(0, SpvOpReturn); + output_func->AddBasicBlock(std::move(new_blk_ptr)); + std::unique_ptr func_end_inst( + new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); + output_func->SetFunctionEnd(std::move(func_end_inst)); + context()->AddFunction(std::move(output_func)); + + std::string name("stream_write_"); + name += std::to_string(param_cnt); + + context()->AddDebug2Inst( + NewGlobalName(param2output_func_id_[param_cnt], name)); + } + return param2output_func_id_[param_cnt]; +} + +uint32_t InstrumentPass::GetDirectReadFunctionId(uint32_t param_cnt) { + uint32_t func_id = param2input_func_id_[param_cnt]; + if (func_id != 0) return func_id; + // Create input function for param_cnt. + func_id = TakeNextId(); + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + std::vector param_types; + for (uint32_t c = 0; c < param_cnt; ++c) + param_types.push_back(type_mgr->GetType(GetUintId())); + uint32_t ibuf_type_id = GetInputBufferTypeId(); + analysis::Function func_ty(type_mgr->GetType(ibuf_type_id), param_types); + analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty); + std::unique_ptr func_inst(new Instruction( + get_module()->context(), SpvOpFunction, ibuf_type_id, func_id, + {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvFunctionControlMaskNone}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, + {type_mgr->GetTypeInstruction(reg_func_ty)}}})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst); + std::unique_ptr input_func = + MakeUnique(std::move(func_inst)); + // Add parameters + std::vector param_vec; + for (uint32_t c = 0; c < param_cnt; ++c) { + uint32_t pid = TakeNextId(); + param_vec.push_back(pid); + std::unique_ptr param_inst(new Instruction( + get_module()->context(), SpvOpFunctionParameter, GetUintId(), pid, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*param_inst); + input_func->AddParameter(std::move(param_inst)); + } + // Create block + uint32_t blk_id = TakeNextId(); + std::unique_ptr blk_label(NewLabel(blk_id)); + std::unique_ptr new_blk_ptr = + MakeUnique(std::move(blk_label)); + InstructionBuilder builder( + context(), &*new_blk_ptr, + IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); + // For each offset parameter, generate new offset with parameter, adding last + // loaded value if it exists, and load value from input buffer at new offset. + // Return last loaded value. + uint32_t buf_id = GetInputBufferId(); + uint32_t buf_ptr_id = GetInputBufferPtrId(); + uint32_t last_value_id = 0; + for (uint32_t p = 0; p < param_cnt; ++p) { + uint32_t offset_id; + if (p == 0) { + offset_id = param_vec[0]; + } else { + if (ibuf_type_id != GetUintId()) { + Instruction* ucvt_inst = + builder.AddUnaryOp(GetUintId(), SpvOpUConvert, last_value_id); + last_value_id = ucvt_inst->result_id(); + } + Instruction* offset_inst = builder.AddBinaryOp( + GetUintId(), SpvOpIAdd, last_value_id, param_vec[p]); + offset_id = offset_inst->result_id(); + } + Instruction* ac_inst = builder.AddTernaryOp( + buf_ptr_id, SpvOpAccessChain, buf_id, + builder.GetUintConstantId(kDebugInputDataOffset), offset_id); + Instruction* load_inst = + builder.AddUnaryOp(ibuf_type_id, SpvOpLoad, ac_inst->result_id()); + last_value_id = load_inst->result_id(); + } + (void)builder.AddInstruction(MakeUnique( + context(), SpvOpReturnValue, 0, 0, + std::initializer_list{{SPV_OPERAND_TYPE_ID, {last_value_id}}})); + // Close block and function and add function to module + input_func->AddBasicBlock(std::move(new_blk_ptr)); + std::unique_ptr func_end_inst( + new Instruction(get_module()->context(), SpvOpFunctionEnd, 0, 0, {})); + get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst); + input_func->SetFunctionEnd(std::move(func_end_inst)); + context()->AddFunction(std::move(input_func)); + + std::string name("direct_read_"); + name += std::to_string(param_cnt); + context()->AddDebug2Inst(NewGlobalName(func_id, name)); + + param2input_func_id_[param_cnt] = func_id; + return func_id; +} + void InstrumentPass::SplitBlock( BasicBlock::iterator inst_itr, UptrVectorIterator block_itr, std::vector>* new_blocks) { @@ -590,7 +970,7 @@ bool InstrumentPass::InstrumentFunction(Function* func, uint32_t stage_idx, // block. This will allow function calls to be inserted into the first // block without interfering with the instrumentation algorithm. if (opt_direct_reads_ && !first_block_split) { - if (ii->opcode() != spv::Op::OpVariable) { + if (ii->opcode() != SpvOpVariable) { SplitBlock(ii, bi, &new_blks); first_block_split = true; } @@ -621,9 +1001,7 @@ bool InstrumentPass::InstrumentFunction(Function* func, uint32_t stage_idx, // Restart instrumenting at beginning of last new block, // but skip over any new phi or copy instruction. ii = bi->begin(); - if (ii->opcode() == spv::Op::OpPhi || - ii->opcode() == spv::Op::OpCopyObject) - ++ii; + if (ii->opcode() == SpvOpPhi || ii->opcode() == SpvOpCopyObject) ++ii; new_blks.clear(); } } @@ -653,54 +1031,63 @@ bool InstrumentPass::InstProcessCallTreeFromRoots(InstProcessFunction& pfn, } bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) { - uint32_t stage_id; - if (use_stage_info_) { - // Make sure all entry points have the same execution model. Do not - // instrument if they do not. - // TODO(greg-lunarg): Handle mixed stages. Technically, a shader module - // can contain entry points with different execution models, although - // such modules will likely be rare as GLSL and HLSL are geared toward - // one model per module. In such cases we will need - // to clone any functions which are in the call trees of entrypoints - // with differing execution models. - spv::ExecutionModel stage = context()->GetStage(); - // Check for supported stages - if (stage != spv::ExecutionModel::Vertex && - stage != spv::ExecutionModel::Fragment && - stage != spv::ExecutionModel::Geometry && - stage != spv::ExecutionModel::GLCompute && - stage != spv::ExecutionModel::TessellationControl && - stage != spv::ExecutionModel::TessellationEvaluation && - stage != spv::ExecutionModel::TaskNV && - stage != spv::ExecutionModel::MeshNV && - stage != spv::ExecutionModel::RayGenerationNV && - stage != spv::ExecutionModel::IntersectionNV && - stage != spv::ExecutionModel::AnyHitNV && - stage != spv::ExecutionModel::ClosestHitNV && - stage != spv::ExecutionModel::MissNV && - stage != spv::ExecutionModel::CallableNV && - stage != spv::ExecutionModel::TaskEXT && - stage != spv::ExecutionModel::MeshEXT) { + // Make sure all entry points have the same execution model. Do not + // instrument if they do not. + // TODO(greg-lunarg): Handle mixed stages. Technically, a shader module + // can contain entry points with different execution models, although + // such modules will likely be rare as GLSL and HLSL are geared toward + // one model per module. In such cases we will need + // to clone any functions which are in the call trees of entrypoints + // with differing execution models. + uint32_t ecnt = 0; + uint32_t stage = SpvExecutionModelMax; + for (auto& e : get_module()->entry_points()) { + if (ecnt == 0) + stage = e.GetSingleWordInOperand(kEntryPointExecutionModelInIdx); + else if (e.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) != + stage) { if (consumer()) { - std::string message = "Stage not supported by instrumentation"; + std::string message = "Mixed stage shader module not supported"; consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); } return false; } - stage_id = static_cast(stage); - } else { - stage_id = 0; + ++ecnt; + } + // Check for supported stages + if (stage != SpvExecutionModelVertex && stage != SpvExecutionModelFragment && + stage != SpvExecutionModelGeometry && + stage != SpvExecutionModelGLCompute && + stage != SpvExecutionModelTessellationControl && + stage != SpvExecutionModelTessellationEvaluation && + stage != SpvExecutionModelTaskNV && stage != SpvExecutionModelMeshNV && + stage != SpvExecutionModelRayGenerationNV && + stage != SpvExecutionModelIntersectionNV && + stage != SpvExecutionModelAnyHitNV && + stage != SpvExecutionModelClosestHitNV && + stage != SpvExecutionModelMissNV && + stage != SpvExecutionModelCallableNV && + stage != SpvExecutionModelTaskEXT && stage != SpvExecutionModelMeshEXT) { + if (consumer()) { + std::string message = "Stage not supported by instrumentation"; + consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str()); + } + return false; } // Add together the roots of all entry points std::queue roots; for (auto& e : get_module()->entry_points()) { roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx)); } - bool modified = InstProcessCallTreeFromRoots(pfn, &roots, stage_id); + bool modified = InstProcessCallTreeFromRoots(pfn, &roots, stage); return modified; } void InstrumentPass::InitializeInstrument() { + output_buffer_id_ = 0; + output_buffer_ptr_id_ = 0; + input_buffer_ptr_id_ = 0; + input_buffer_id_ = 0; float_id_ = 0; v4float_id_ = 0; uint_id_ = 0; diff --git a/source/opt/instrument_pass.h b/source/opt/instrument_pass.h index e4408c93..215b0263 100644 --- a/source/opt/instrument_pass.h +++ b/source/opt/instrument_pass.h @@ -56,6 +56,13 @@ namespace spvtools { namespace opt { +// Validation Ids +// These are used to identify the general validation being done and map to +// its output buffers. +static const uint32_t kInstValidationIdBindless = 0; +static const uint32_t kInstValidationIdBuffAddr = 1; +static const uint32_t kInstValidationIdDebugPrintf = 2; + class InstrumentPass : public Pass { using cbb_ptr = const BasicBlock*; @@ -77,13 +84,13 @@ class InstrumentPass : public Pass { // set |desc_set| for debug input and output buffers and writes |shader_id| // into debug output records. |opt_direct_reads| indicates that the pass // will see direct input buffer reads and should prepare to optimize them. - InstrumentPass(uint32_t desc_set, uint32_t shader_id, bool opt_direct_reads, - bool use_stage_info) + InstrumentPass(uint32_t desc_set, uint32_t shader_id, uint32_t validation_id, + bool opt_direct_reads = false) : Pass(), desc_set_(desc_set), shader_id_(shader_id), - opt_direct_reads_(opt_direct_reads), - use_stage_info_(use_stage_info) {} + validation_id_(validation_id), + opt_direct_reads_(opt_direct_reads) {} // Initialize state for instrumentation of module. void InitializeInstrument(); @@ -105,12 +112,106 @@ class InstrumentPass : public Pass { void MovePostludeCode(UptrVectorIterator ref_block_itr, BasicBlock* new_blk_ptr); + // Generate instructions in |builder| which will atomically fetch and + // increment the size of the debug output buffer stream of the current + // validation and write a record to the end of the stream, if enough space + // in the buffer remains. The record will contain the index of the function + // and instruction within that function |func_idx, instruction_idx| which + // generated the record. It will also contain additional information to + // identify the instance of the shader, depending on the stage |stage_idx| + // of the shader. Finally, the record will contain validation-specific + // data contained in |validation_ids| which will identify the validation + // error as well as the values involved in the error. + // + // The output buffer binding written to by the code generated by the function + // is determined by the validation id specified when each specific + // instrumentation pass is created. + // + // The output buffer is a sequence of 32-bit values with the following + // format (where all elements are unsigned 32-bit unless otherwise noted): + // + // Size + // Record0 + // Record1 + // Record2 + // ... + // + // Size is the number of 32-bit values that have been written or + // attempted to be written to the output buffer, excluding the Size. It is + // initialized to 0. If the size of attempts to write the buffer exceeds + // the actual size of the buffer, it is possible that this field can exceed + // the actual size of the buffer. + // + // Each Record* is a variable-length sequence of 32-bit values with the + // following format defined using static const offsets in the .cpp file: + // + // Record Size + // Shader ID + // Instruction Index + // Stage + // Stage-specific Word 0 + // Stage-specific Word 1 + // ... + // Validation Error Code + // Validation-specific Word 0 + // Validation-specific Word 1 + // Validation-specific Word 2 + // ... + // + // Each record consists of three subsections: members common across all + // validation, members specific to the stage, and members specific to a + // validation. + // + // The Record Size is the number of 32-bit words in the record, including + // the Record Size word. + // + // Shader ID is a value that identifies which shader has generated the + // validation error. It is passed when the instrumentation pass is created. + // + // The Instruction Index is the position of the instruction within the + // SPIR-V file which is in error. + // + // The Stage is the pipeline stage which has generated the error as defined + // by the SpvExecutionModel_ enumeration. This is used to interpret the + // following Stage-specific words. + // + // The Stage-specific Words identify which invocation of the shader generated + // the error. Every stage will write a fixed number of words. Vertex shaders + // will write the Vertex and Instance ID. Fragment shaders will write + // FragCoord.xy. Compute shaders will write the GlobalInvocation ID. + // The tessellation eval shader will write the Primitive ID and TessCoords.uv. + // The tessellation control shader and geometry shader will write the + // Primitive ID and Invocation ID. + // + // The Validation Error Code specifies the exact error which has occurred. + // These are enumerated with the kInstError* static consts. This allows + // multiple validation layers to use the same, single output buffer. + // + // The Validation-specific Words are a validation-specific number of 32-bit + // words which give further information on the validation error that + // occurred. These are documented further in each file containing the + // validation-specific class which derives from this base class. + // + // Because the code that is generated checks against the size of the buffer + // before writing, the size of the debug out buffer can be used by the + // validation layer to control the number of error records that are written. + void GenDebugStreamWrite(uint32_t instruction_idx, uint32_t stage_idx, + const std::vector& validation_ids, + InstructionBuilder* builder); + // Return true if all instructions in |ids| are constants or spec constants. bool AllConstant(const std::vector& ids); - uint32_t GenReadFunctionCall(uint32_t return_id, uint32_t func_id, - const std::vector& args, - InstructionBuilder* builder); + // Generate in |builder| instructions to read the unsigned integer from the + // input buffer specified by the offsets in |offset_ids|. Given offsets + // o0, o1, ... oN, and input buffer ibuf, return the id for the value: + // + // ibuf[...ibuf[ibuf[o0]+o1]...+oN] + // + // The binding and the format of the input buffer is determined by each + // specific validation, which is specified at the creation of the pass. + uint32_t GenDebugDirectRead(const std::vector& offset_ids, + InstructionBuilder* builder); // Generate code to convert integer |value_id| to 32bit, if needed. Return // an id to the 32bit equivalent. @@ -120,15 +221,6 @@ class InstrumentPass : public Pass { // Return an id to the Uint equivalent. uint32_t GenUintCastCode(uint32_t value_id, InstructionBuilder* builder); - std::unique_ptr StartFunction( - uint32_t func_id, const analysis::Type* return_type, - const std::vector& param_types); - - std::vector AddParameters( - Function& func, const std::vector& param_types); - - std::unique_ptr EndFunction(); - // Return new label. std::unique_ptr NewLabel(uint32_t label_id); @@ -136,6 +228,15 @@ class InstrumentPass : public Pass { std::unique_ptr NewName(uint32_t id, const std::string& name_str); + // Set the name for a function or global variable, names will be + // prefixed to identify which instrumentation pass generated them. + std::unique_ptr NewGlobalName(uint32_t id, + const std::string& name_str); + + // Set the name for a structure member + std::unique_ptr NewMemberName(uint32_t id, uint32_t member_index, + const std::string& name_str); + // Return id for 32-bit unsigned type uint32_t GetUintId(); @@ -151,25 +252,37 @@ class InstrumentPass : public Pass { // Return id for void type uint32_t GetVoidId(); - // Get registered type structures - analysis::Integer* GetInteger(uint32_t width, bool is_signed); - analysis::Struct* GetStruct(const std::vector& fields); - analysis::RuntimeArray* GetRuntimeArray(const analysis::Type* element); - analysis::Array* GetArray(const analysis::Type* element, uint32_t size); - analysis::Function* GetFunction( - const analysis::Type* return_val, - const std::vector& args); + // Return pointer to type for runtime array of uint + analysis::Type* GetUintXRuntimeArrayType(uint32_t width, + analysis::Type** rarr_ty); // Return pointer to type for runtime array of uint - analysis::RuntimeArray* GetUintXRuntimeArrayType( - uint32_t width, analysis::RuntimeArray** rarr_ty); + analysis::Type* GetUintRuntimeArrayType(uint32_t width); - // Return pointer to type for runtime array of uint - analysis::RuntimeArray* GetUintRuntimeArrayType(uint32_t width); + // Return id for buffer uint type + uint32_t GetOutputBufferPtrId(); + + // Return id for buffer uint type + uint32_t GetInputBufferTypeId(); + + // Return id for buffer uint type + uint32_t GetInputBufferPtrId(); + + // Return binding for output buffer for current validation. + uint32_t GetOutputBufferBinding(); + + // Return binding for input buffer for current validation. + uint32_t GetInputBufferBinding(); // Add storage buffer extension if needed void AddStorageBufferExt(); + // Return id for debug output buffer + uint32_t GetOutputBufferId(); + + // Return id for debug input buffer + uint32_t GetInputBufferId(); + // Return id for 32-bit float type uint32_t GetFloatId(); @@ -185,6 +298,15 @@ class InstrumentPass : public Pass { // Return id for v3uint type uint32_t GetVec3UintId(); + // Return id for output function. Define if it doesn't exist with + // |val_spec_param_cnt| validation-specific uint32 parameters. + uint32_t GetStreamWriteFunctionId(uint32_t stage_idx, + uint32_t val_spec_param_cnt); + + // Return id for input function taking |param_cnt| uint32 parameters. Define + // if it doesn't exist. + uint32_t GetDirectReadFunctionId(uint32_t param_cnt); + // Split block |block_itr| into two new blocks where the second block // contains |inst_itr| and place in |new_blocks|. void SplitBlock(BasicBlock::iterator inst_itr, @@ -195,8 +317,8 @@ class InstrumentPass : public Pass { // If code is generated for an instruction, replace the instruction's // block with the new blocks that are generated. Continue processing at the // top of the last new block. - virtual bool InstrumentFunction(Function* func, uint32_t stage_idx, - InstProcessFunction& pfn); + bool InstrumentFunction(Function* func, uint32_t stage_idx, + InstProcessFunction& pfn); // Call |pfn| on all functions in the call tree of the function // ids in |roots|. @@ -204,11 +326,40 @@ class InstrumentPass : public Pass { std::queue* roots, uint32_t stage_idx); + // Gen code into |builder| to write |field_value_id| into debug output + // buffer at |base_offset_id| + |field_offset|. + void GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t field_offset, + uint32_t field_value_id, + InstructionBuilder* builder); + + // Generate instructions into |builder| which will write the members + // of the debug output record common for all stages and validations at + // |base_off|. + void GenCommonStreamWriteCode(uint32_t record_sz, uint32_t instruction_idx, + uint32_t stage_idx, uint32_t base_off, + InstructionBuilder* builder); + + // Generate instructions into |builder| which will write + // |uint_frag_coord_id| at |component| of the record at |base_offset_id| of + // the debug output buffer . + void GenFragCoordEltDebugOutputCode(uint32_t base_offset_id, + uint32_t uint_frag_coord_id, + uint32_t component, + InstructionBuilder* builder); + // Generate instructions into |builder| which will load |var_id| and return // its result id. uint32_t GenVarLoad(uint32_t var_id, InstructionBuilder* builder); - uint32_t GenStageInfo(uint32_t stage_idx, InstructionBuilder* builder); + // Generate instructions into |builder| which will load the uint |builtin_id| + // and write it into the debug output buffer at |base_off| + |builtin_off|. + void GenBuiltinOutputCode(uint32_t builtin_id, uint32_t builtin_off, + uint32_t base_off, InstructionBuilder* builder); + + // Generate instructions into |builder| which will write the |stage_idx|- + // specific members of the debug output stream at |base_off|. + void GenStageStreamWriteCode(uint32_t stage_idx, uint32_t base_off, + InstructionBuilder* builder); // Return true if instruction must be in the same block that its result // is used. @@ -244,47 +395,62 @@ class InstrumentPass : public Pass { // Map from instruction's unique id to offset in original file. std::unordered_map uid2offset_; + // result id for OpConstantFalse + uint32_t validation_id_; + + // id for output buffer variable + uint32_t output_buffer_id_; + + // ptr type id for output buffer element + uint32_t output_buffer_ptr_id_; + + // ptr type id for input buffer element + uint32_t input_buffer_ptr_id_; + // id for debug output function std::unordered_map param2output_func_id_; // ids for debug input functions std::unordered_map param2input_func_id_; + // id for input buffer variable + uint32_t input_buffer_id_; + // id for 32-bit float type - uint32_t float_id_{0}; + uint32_t float_id_; // id for v4float type - uint32_t v4float_id_{0}; + uint32_t v4float_id_; // id for v4uint type - uint32_t v4uint_id_{0}; + uint32_t v4uint_id_; // id for v3uint type - uint32_t v3uint_id_{0}; + uint32_t v3uint_id_; // id for 32-bit unsigned type - uint32_t uint_id_{0}; + uint32_t uint_id_; // id for 64-bit unsigned type - uint32_t uint64_id_{0}; + uint32_t uint64_id_; // id for 8-bit unsigned type - uint32_t uint8_id_{0}; + uint32_t uint8_id_; // id for bool type - uint32_t bool_id_{0}; + uint32_t bool_id_; // id for void type - uint32_t void_id_{0}; + uint32_t void_id_; // boolean to remember storage buffer extension - bool storage_buffer_ext_defined_{false}; + bool storage_buffer_ext_defined_; // runtime array of uint type - analysis::RuntimeArray* uint64_rarr_ty_{nullptr}; + analysis::Type* uint64_rarr_ty_; // runtime array of uint type - analysis::RuntimeArray* uint32_rarr_ty_{nullptr}; + analysis::Type* uint32_rarr_ty_; // Pre-instrumentation same-block insts std::unordered_map same_block_pre_; @@ -309,15 +475,11 @@ class InstrumentPass : public Pass { std::unordered_map, uint32_t, vector_hash_> call2id_; // Function currently being instrumented - Function* curr_func_{nullptr}; + Function* curr_func_; // Optimize direct debug input buffer reads. Specifically, move all such // reads with constant args to first block and reuse them. - const bool opt_direct_reads_; - - // Set true if the instrumentation needs to know the current stage. - // Note that this does not work with multi-stage modules. - const bool use_stage_info_; + bool opt_direct_reads_; }; } // namespace opt diff --git a/source/opt/interface_var_sroa.cpp b/source/opt/interface_var_sroa.cpp index 08477cbd..1b2cb363 100644 --- a/source/opt/interface_var_sroa.cpp +++ b/source/opt/interface_var_sroa.cpp @@ -23,28 +23,29 @@ #include "source/opt/type_manager.h" #include "source/util/make_unique.h" +const static uint32_t kOpDecorateDecorationInOperandIndex = 1; +const static uint32_t kOpDecorateLiteralInOperandIndex = 2; +const static uint32_t kOpEntryPointInOperandInterface = 3; +const static uint32_t kOpVariableStorageClassInOperandIndex = 0; +const static uint32_t kOpTypeArrayElemTypeInOperandIndex = 0; +const static uint32_t kOpTypeArrayLengthInOperandIndex = 1; +const static uint32_t kOpTypeMatrixColCountInOperandIndex = 1; +const static uint32_t kOpTypeMatrixColTypeInOperandIndex = 0; +const static uint32_t kOpTypePtrTypeInOperandIndex = 1; +const static uint32_t kOpConstantValueInOperandIndex = 0; + namespace spvtools { namespace opt { namespace { -constexpr uint32_t kOpDecorateDecorationInOperandIndex = 1; -constexpr uint32_t kOpDecorateLiteralInOperandIndex = 2; -constexpr uint32_t kOpEntryPointInOperandInterface = 3; -constexpr uint32_t kOpVariableStorageClassInOperandIndex = 0; -constexpr uint32_t kOpTypeArrayElemTypeInOperandIndex = 0; -constexpr uint32_t kOpTypeArrayLengthInOperandIndex = 1; -constexpr uint32_t kOpTypeMatrixColCountInOperandIndex = 1; -constexpr uint32_t kOpTypeMatrixColTypeInOperandIndex = 0; -constexpr uint32_t kOpTypePtrTypeInOperandIndex = 1; -constexpr uint32_t kOpConstantValueInOperandIndex = 0; // Get the length of the OpTypeArray |array_type|. uint32_t GetArrayLength(analysis::DefUseManager* def_use_mgr, Instruction* array_type) { - assert(array_type->opcode() == spv::Op::OpTypeArray); + assert(array_type->opcode() == SpvOpTypeArray); uint32_t const_int_id = array_type->GetSingleWordInOperand(kOpTypeArrayLengthInOperandIndex); Instruction* array_length_inst = def_use_mgr->GetDef(const_int_id); - assert(array_length_inst->opcode() == spv::Op::OpConstant); + assert(array_length_inst->opcode() == SpvOpConstant); return array_length_inst->GetSingleWordInOperand( kOpConstantValueInOperandIndex); } @@ -52,7 +53,7 @@ uint32_t GetArrayLength(analysis::DefUseManager* def_use_mgr, // Get the element type instruction of the OpTypeArray |array_type|. Instruction* GetArrayElementType(analysis::DefUseManager* def_use_mgr, Instruction* array_type) { - assert(array_type->opcode() == spv::Op::OpTypeArray); + assert(array_type->opcode() == SpvOpTypeArray); uint32_t elem_type_id = array_type->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); return def_use_mgr->GetDef(elem_type_id); @@ -61,7 +62,7 @@ Instruction* GetArrayElementType(analysis::DefUseManager* def_use_mgr, // Get the column type instruction of the OpTypeMatrix |matrix_type|. Instruction* GetMatrixColumnType(analysis::DefUseManager* def_use_mgr, Instruction* matrix_type) { - assert(matrix_type->opcode() == spv::Op::OpTypeMatrix); + assert(matrix_type->opcode() == SpvOpTypeMatrix); uint32_t column_type_id = matrix_type->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); return def_use_mgr->GetDef(column_type_id); @@ -76,14 +77,14 @@ uint32_t GetComponentTypeOfArrayMatrix(analysis::DefUseManager* def_use_mgr, if (depth_to_component == 0) return type_id; Instruction* type_inst = def_use_mgr->GetDef(type_id); - if (type_inst->opcode() == spv::Op::OpTypeArray) { + if (type_inst->opcode() == SpvOpTypeArray) { uint32_t elem_type_id = type_inst->GetSingleWordInOperand(kOpTypeArrayElemTypeInOperandIndex); return GetComponentTypeOfArrayMatrix(def_use_mgr, elem_type_id, depth_to_component - 1); } - assert(type_inst->opcode() == spv::Op::OpTypeMatrix); + assert(type_inst->opcode() == SpvOpTypeMatrix); uint32_t column_type_id = type_inst->GetSingleWordInOperand(kOpTypeMatrixColTypeInOperandIndex); return GetComponentTypeOfArrayMatrix(def_use_mgr, column_type_id, @@ -93,7 +94,7 @@ uint32_t GetComponentTypeOfArrayMatrix(analysis::DefUseManager* def_use_mgr, // Creates an OpDecorate instruction whose Target is |var_id| and Decoration is // |decoration|. Adds |literal| as an extra operand of the instruction. void CreateDecoration(analysis::DecorationManager* decoration_mgr, - uint32_t var_id, spv::Decoration decoration, + uint32_t var_id, SpvDecoration decoration, uint32_t literal) { std::vector operands({ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, @@ -101,7 +102,7 @@ void CreateDecoration(analysis::DecorationManager* decoration_mgr, {static_cast(decoration)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {literal}}, }); - decoration_mgr->AddDecoration(spv::Op::OpDecorate, std::move(operands)); + decoration_mgr->AddDecoration(SpvOpDecorate, std::move(operands)); } // Replaces load instructions with composite construct instructions in all the @@ -127,8 +128,8 @@ void ReplaceLoadWithCompositeConstruct( } // Returns the storage class of the instruction |var|. -spv::StorageClass GetStorageClass(Instruction* var) { - return static_cast( +SpvStorageClass GetStorageClass(Instruction* var) { + return static_cast( var->GetSingleWordInOperand(kOpVariableStorageClassInOperandIndex)); } @@ -136,17 +137,16 @@ spv::StorageClass GetStorageClass(Instruction* var) { bool InterfaceVariableScalarReplacement::HasExtraArrayness( Instruction& entry_point, Instruction* var) { - spv::ExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); - if (execution_model != spv::ExecutionModel::TessellationEvaluation && - execution_model != spv::ExecutionModel::TessellationControl) { + SpvExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); + if (execution_model != SpvExecutionModelTessellationEvaluation && + execution_model != SpvExecutionModelTessellationControl) { return false; } - if (!context()->get_decoration_mgr()->HasDecoration( - var->result_id(), uint32_t(spv::Decoration::Patch))) { - if (execution_model == spv::ExecutionModel::TessellationControl) - return true; - return GetStorageClass(var) != spv::StorageClass::Output; + if (!context()->get_decoration_mgr()->HasDecoration(var->result_id(), + SpvDecorationPatch)) { + if (execution_model == SpvExecutionModelTessellationControl) return true; + return GetStorageClass(var) != SpvStorageClassOutput; } return false; } @@ -163,7 +163,7 @@ bool InterfaceVariableScalarReplacement:: bool InterfaceVariableScalarReplacement::GetVariableLocation( Instruction* var, uint32_t* location) { return !context()->get_decoration_mgr()->WhileEachDecoration( - var->result_id(), uint32_t(spv::Decoration::Location), + var->result_id(), SpvDecorationLocation, [location](const Instruction& inst) { *location = inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); @@ -174,7 +174,7 @@ bool InterfaceVariableScalarReplacement::GetVariableLocation( bool InterfaceVariableScalarReplacement::GetVariableComponent( Instruction* var, uint32_t* component) { return !context()->get_decoration_mgr()->WhileEachDecoration( - var->result_id(), uint32_t(spv::Decoration::Component), + var->result_id(), SpvDecorationComponent, [component](const Instruction& inst) { *component = inst.GetSingleWordInOperand(kOpDecorateLiteralInOperandIndex); @@ -190,11 +190,11 @@ InterfaceVariableScalarReplacement::CollectInterfaceVariables( i < entry_point.NumInOperands(); ++i) { Instruction* interface_var = context()->get_def_use_mgr()->GetDef( entry_point.GetSingleWordInOperand(i)); - assert(interface_var->opcode() == spv::Op::OpVariable); + assert(interface_var->opcode() == SpvOpVariable); - spv::StorageClass storage_class = GetStorageClass(interface_var); - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + SpvStorageClass storage_class = GetStorageClass(interface_var); + if (storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { continue; } @@ -205,10 +205,10 @@ InterfaceVariableScalarReplacement::CollectInterfaceVariables( void InterfaceVariableScalarReplacement::KillInstructionAndUsers( Instruction* inst) { - if (inst->opcode() == spv::Op::OpEntryPoint) { + if (inst->opcode() == SpvOpEntryPoint) { return; } - if (inst->opcode() != spv::Op::OpAccessChain) { + if (inst->opcode() != SpvOpAccessChain) { context()->KillInst(inst); return; } @@ -232,10 +232,10 @@ void InterfaceVariableScalarReplacement::KillLocationAndComponentDecorations( uint32_t var_id) { context()->get_decoration_mgr()->RemoveDecorationsFrom( var_id, [](const Instruction& inst) { - spv::Decoration decoration = spv::Decoration( - inst.GetSingleWordInOperand(kOpDecorateDecorationInOperandIndex)); - return decoration == spv::Decoration::Location || - decoration == spv::Decoration::Component; + uint32_t decoration = + inst.GetSingleWordInOperand(kOpDecorateDecorationInOperandIndex); + return decoration == SpvDecorationLocation || + decoration == SpvDecorationComponent; }); } @@ -307,9 +307,9 @@ void InterfaceVariableScalarReplacement::AddLocationAndComponentDecorations( if (!vars.HasMultipleComponents()) { uint32_t var_id = vars.GetComponentVariable()->result_id(); CreateDecoration(context()->get_decoration_mgr(), var_id, - spv::Decoration::Location, *location); + SpvDecorationLocation, *location); CreateDecoration(context()->get_decoration_mgr(), var_id, - spv::Decoration::Component, component); + SpvDecorationComponent, component); ++(*location); return; } @@ -389,15 +389,15 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( std::unordered_map* loads_to_component_values, std::unordered_map* loads_for_access_chain_to_component_values) { - spv::Op opcode = interface_var_user->opcode(); - if (opcode == spv::Op::OpStore) { + SpvOp opcode = interface_var_user->opcode(); + if (opcode == SpvOpStore) { uint32_t value_id = interface_var_user->GetSingleWordInOperand(1); StoreComponentOfValueToScalarVar(value_id, interface_var_component_indices, scalar_var, extra_array_index, interface_var_user); return true; } - if (opcode == spv::Op::OpLoad) { + if (opcode == SpvOpLoad) { Instruction* scalar_load = LoadScalarVar(scalar_var, extra_array_index, interface_var_user); loads_to_component_values->insert({interface_var_user, scalar_load}); @@ -408,25 +408,25 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( // them only for the first element of the extra array. if (extra_array_index && *extra_array_index != 0) return true; - if (opcode == spv::Op::OpDecorateId || opcode == spv::Op::OpDecorateString || - opcode == spv::Op::OpDecorate) { + if (opcode == SpvOpDecorateId || opcode == SpvOpDecorateString || + opcode == SpvOpDecorate) { CloneAnnotationForVariable(interface_var_user, scalar_var->result_id()); return true; } - if (opcode == spv::Op::OpName) { + if (opcode == SpvOpName) { std::unique_ptr new_inst(interface_var_user->Clone(context())); new_inst->SetInOperand(0, {scalar_var->result_id()}); context()->AddDebug2Inst(std::move(new_inst)); return true; } - if (opcode == spv::Op::OpEntryPoint) { + if (opcode == SpvOpEntryPoint) { return ReplaceInterfaceVarInEntryPoint(interface_var, interface_var_user, scalar_var->result_id()); } - if (opcode == spv::Op::OpAccessChain) { + if (opcode == SpvOpAccessChain) { ReplaceAccessChainWith(interface_var_user, interface_var_component_indices, scalar_var, loads_for_access_chain_to_component_values); @@ -445,8 +445,8 @@ bool InterfaceVariableScalarReplacement::ReplaceComponentOfInterfaceVarWith( void InterfaceVariableScalarReplacement::UseBaseAccessChainForAccessChain( Instruction* access_chain, Instruction* base_access_chain) { - assert(base_access_chain->opcode() == spv::Op::OpAccessChain && - access_chain->opcode() == spv::Op::OpAccessChain && + assert(base_access_chain->opcode() == SpvOpAccessChain && + access_chain->opcode() == SpvOpAccessChain && access_chain->GetSingleWordInOperand(0) == base_access_chain->result_id()); Instruction::OperandList new_operands; @@ -470,10 +470,10 @@ Instruction* InterfaceVariableScalarReplacement::CreateAccessChainToVar( uint32_t ptr_type_id = GetPointerType(*component_type_id, GetStorageClass(var)); - std::unique_ptr new_access_chain(new Instruction( - context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); + std::unique_ptr new_access_chain( + new Instruction(context(), SpvOpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); for (uint32_t index_id : index_ids) { new_access_chain->AddOperand({SPV_OPERAND_TYPE_ID, {index_id}}); } @@ -489,13 +489,13 @@ Instruction* InterfaceVariableScalarReplacement::CreateAccessChainWithIndex( Instruction* insert_before) { uint32_t ptr_type_id = GetPointerType(component_type_id, GetStorageClass(var)); - uint32_t index_id = context()->get_constant_mgr()->GetUIntConstId(index); - std::unique_ptr new_access_chain(new Instruction( - context(), spv::Op::OpAccessChain, ptr_type_id, TakeNextId(), - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}, - {SPV_OPERAND_TYPE_ID, {index_id}}, - })); + uint32_t index_id = context()->get_constant_mgr()->GetUIntConst(index); + std::unique_ptr new_access_chain( + new Instruction(context(), SpvOpAccessChain, ptr_type_id, TakeNextId(), + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_ID, {index_id}}, + })); Instruction* inst = new_access_chain.get(); context()->get_def_use_mgr()->AnalyzeInstDefUse(inst); insert_before->InsertBefore(std::move(new_access_chain)); @@ -519,20 +519,20 @@ void InterfaceVariableScalarReplacement::ReplaceAccessChainWith( [this, access_chain, &indexes, &interface_var_component_indices, scalar_var, loads_to_component_values](Instruction* user) { switch (user->opcode()) { - case spv::Op::OpAccessChain: { + case SpvOpAccessChain: { UseBaseAccessChainForAccessChain(user, access_chain); ReplaceAccessChainWith(user, interface_var_component_indices, scalar_var, loads_to_component_values); return; } - case spv::Op::OpStore: { + case SpvOpStore: { uint32_t value_id = user->GetSingleWordInOperand(1); StoreComponentOfValueToAccessChainToScalarVar( value_id, interface_var_component_indices, scalar_var, indexes, user); return; } - case spv::Op::OpLoad: { + case SpvOpLoad: { Instruction* value = LoadAccessChainToVar(scalar_var, indexes, user); loads_to_component_values->insert({user, value}); @@ -546,9 +546,9 @@ void InterfaceVariableScalarReplacement::ReplaceAccessChainWith( void InterfaceVariableScalarReplacement::CloneAnnotationForVariable( Instruction* annotation_inst, uint32_t var_id) { - assert(annotation_inst->opcode() == spv::Op::OpDecorate || - annotation_inst->opcode() == spv::Op::OpDecorateId || - annotation_inst->opcode() == spv::Op::OpDecorateString); + assert(annotation_inst->opcode() == SpvOpDecorate || + annotation_inst->opcode() == SpvOpDecorateId || + annotation_inst->opcode() == SpvOpDecorateString); std::unique_ptr new_inst(annotation_inst->Clone(context())); new_inst->SetInOperand(0, {var_id}); context()->AddAnnotationInst(std::move(new_inst)); @@ -593,13 +593,13 @@ bool InterfaceVariableScalarReplacement::ReplaceInterfaceVarInEntryPoint( uint32_t InterfaceVariableScalarReplacement::GetPointeeTypeIdOfVar( Instruction* var) { - assert(var->opcode() == spv::Op::OpVariable); + assert(var->opcode() == SpvOpVariable); uint32_t ptr_type_id = var->type_id(); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); Instruction* ptr_type_inst = def_use_mgr->GetDef(ptr_type_id); - assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer && + assert(ptr_type_inst->opcode() == SpvOpTypePointer && "Variable must have a pointer type."); return ptr_type_inst->GetSingleWordInOperand(kOpTypePtrTypeInOperandIndex); } @@ -643,7 +643,7 @@ Instruction* InterfaceVariableScalarReplacement::LoadScalarVar( Instruction* InterfaceVariableScalarReplacement::CreateLoad( uint32_t type_id, Instruction* ptr, Instruction* insert_before) { std::unique_ptr load( - new Instruction(context(), spv::Op::OpLoad, type_id, TakeNextId(), + new Instruction(context(), SpvOpLoad, type_id, TakeNextId(), std::initializer_list{ {SPV_OPERAND_TYPE_ID, {ptr->result_id()}}})); Instruction* load_inst = load.get(); @@ -660,7 +660,7 @@ void InterfaceVariableScalarReplacement::StoreComponentOfValueTo( component_type_id, value_id, component_indices, extra_array_index)); std::unique_ptr new_store( - new Instruction(context(), spv::Op::OpStore)); + new Instruction(context(), SpvOpStore)); new_store->AddOperand({SPV_OPERAND_TYPE_ID, {ptr->result_id()}}); new_store->AddOperand( {SPV_OPERAND_TYPE_ID, {composite_extract->result_id()}}); @@ -678,7 +678,7 @@ Instruction* InterfaceVariableScalarReplacement::CreateCompositeExtract( const std::vector& indexes, const uint32_t* extra_first_index) { uint32_t component_id = TakeNextId(); Instruction* composite_extract = new Instruction( - context(), spv::Op::OpCompositeExtract, type_id, component_id, + context(), SpvOpCompositeExtract, type_id, component_id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {composite_id}}}); if (extra_first_index) { composite_extract->AddOperand( @@ -731,8 +731,8 @@ InterfaceVariableScalarReplacement::CreateCompositeConstructForComponentOfLoad( depth_to_component); } uint32_t new_id = context()->TakeNextId(); - std::unique_ptr new_composite_construct(new Instruction( - context(), spv::Op::OpCompositeConstruct, type_id, new_id, {})); + std::unique_ptr new_composite_construct( + new Instruction(context(), SpvOpCompositeConstruct, type_id, new_id, {})); Instruction* composite_construct = new_composite_construct.get(); def_use_mgr->AnalyzeInstDefUse(composite_construct); @@ -781,7 +781,7 @@ uint32_t InterfaceVariableScalarReplacement::GetArrayType( uint32_t elem_type_id, uint32_t array_length) { analysis::Type* elem_type = context()->get_type_mgr()->GetType(elem_type_id); uint32_t array_length_id = - context()->get_constant_mgr()->GetUIntConstId(array_length); + context()->get_constant_mgr()->GetUIntConst(array_length); analysis::Array array_type( elem_type, analysis::Array::LengthInfo{array_length_id, {0, array_length}}); @@ -789,7 +789,7 @@ uint32_t InterfaceVariableScalarReplacement::GetArrayType( } uint32_t InterfaceVariableScalarReplacement::GetPointerType( - uint32_t type_id, spv::StorageClass storage_class) { + uint32_t type_id, SpvStorageClass storage_class) { analysis::Type* type = context()->get_type_mgr()->GetType(type_id); analysis::Pointer ptr_type(type, storage_class); return context()->get_type_mgr()->GetTypeInstruction(&ptr_type); @@ -797,9 +797,9 @@ uint32_t InterfaceVariableScalarReplacement::GetPointerType( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForArray( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length) { - assert(interface_var_type->opcode() == spv::Op::OpTypeArray); + assert(interface_var_type->opcode() == SpvOpTypeArray); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); uint32_t array_length = GetArrayLength(def_use_mgr, interface_var_type); @@ -818,9 +818,9 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForArray( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForMatrix( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length) { - assert(interface_var_type->opcode() == spv::Op::OpTypeMatrix); + assert(interface_var_type->opcode() == SpvOpTypeMatrix); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); uint32_t column_count = interface_var_type->GetSingleWordInOperand( @@ -841,16 +841,16 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForMatrix( InterfaceVariableScalarReplacement::NestedCompositeComponents InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForReplacement( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length) { // Handle array case. - if (interface_var_type->opcode() == spv::Op::OpTypeArray) { + if (interface_var_type->opcode() == SpvOpTypeArray) { return CreateScalarInterfaceVarsForArray(interface_var_type, storage_class, extra_array_length); } // Handle matrix case. - if (interface_var_type->opcode() == spv::Op::OpTypeMatrix) { + if (interface_var_type->opcode() == SpvOpTypeMatrix) { return CreateScalarInterfaceVarsForMatrix(interface_var_type, storage_class, extra_array_length); } @@ -865,7 +865,7 @@ InterfaceVariableScalarReplacement::CreateScalarInterfaceVarsForReplacement( context()->get_type_mgr()->FindPointerToType(type_id, storage_class); uint32_t id = TakeNextId(); std::unique_ptr variable( - new Instruction(context(), spv::Op::OpVariable, ptr_type_id, id, + new Instruction(context(), SpvOpVariable, ptr_type_id, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(storage_class)}}})); @@ -948,8 +948,8 @@ InterfaceVariableScalarReplacement::ReplaceInterfaceVarsWithScalars( return Pass::Status::Failure; } - if (interface_var_type->opcode() != spv::Op::OpTypeArray && - interface_var_type->opcode() != spv::Op::OpTypeMatrix) { + if (interface_var_type->opcode() != SpvOpTypeArray && + interface_var_type->opcode() != SpvOpTypeMatrix) { continue; } diff --git a/source/opt/interface_var_sroa.h b/source/opt/interface_var_sroa.h index 45ed3717..23baad0a 100644 --- a/source/opt/interface_var_sroa.h +++ b/source/opt/interface_var_sroa.h @@ -90,6 +90,10 @@ class InterfaceVariableScalarReplacement : public Pass { // |component|. Returns true whether the component exists or not. bool GetVariableComponent(Instruction* var, uint32_t* component); + // Returns the interface variable instruction whose result id is + // |interface_var_id|. + Instruction* GetInterfaceVariable(uint32_t interface_var_id); + // Returns the type of |var| as an instruction. Instruction* GetTypeOfVariable(Instruction* var); @@ -111,7 +115,7 @@ class InterfaceVariableScalarReplacement : public Pass { // |extra_array_length| is not zero, adds the extra arrayness to the created // scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForReplacement( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length); // Creates scalar variables with the storage classe |storage_class| to replace @@ -119,7 +123,7 @@ class InterfaceVariableScalarReplacement : public Pass { // If |extra_array_length| is not zero, adds the extra arrayness to all the // scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForArray( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length); // Creates scalar variables with the storage classe |storage_class| to replace @@ -127,7 +131,7 @@ class InterfaceVariableScalarReplacement : public Pass { // with. If |extra_array_length| is not zero, adds the extra arrayness to all // the scalar variables. NestedCompositeComponents CreateScalarInterfaceVarsForMatrix( - Instruction* interface_var_type, spv::StorageClass storage_class, + Instruction* interface_var_type, SpvStorageClass storage_class, uint32_t extra_array_length); // Recursively adds Location and Component decorations to variables in @@ -341,7 +345,7 @@ class InterfaceVariableScalarReplacement : public Pass { // Returns the result id of OpTypePointer instrunction whose Type // operand is |type_id| and Storage Class operand is |storage_class|. - uint32_t GetPointerType(uint32_t type_id, spv::StorageClass storage_class); + uint32_t GetPointerType(uint32_t type_id, SpvStorageClass storage_class); // Kills an instrunction |inst| and its users. void KillInstructionAndUsers(Instruction* inst); diff --git a/source/opt/interp_fixup_pass.cpp b/source/opt/interp_fixup_pass.cpp index 2ec2147d..e8cdd99f 100644 --- a/source/opt/interp_fixup_pass.cpp +++ b/source/opt/interp_fixup_pass.cpp @@ -19,15 +19,17 @@ #include #include +#include "ir_builder.h" #include "source/opt/ir_context.h" #include "type_manager.h" namespace spvtools { namespace opt { + namespace { // Input Operand Indices -constexpr int kSpvVariableStorageClassInIdx = 0; +static const int kSpvVariableStorageClassInIdx = 0; // Folding rule function which attempts to replace |op(OpLoad(a),...)| // by |op(a,...)|, where |op| is one of the GLSLstd450 InterpolateAt* @@ -43,12 +45,12 @@ bool ReplaceInternalInterpolate(IRContext* ctx, Instruction* inst, uint32_t op1_id = inst->GetSingleWordInOperand(2); Instruction* load_inst = ctx->get_def_use_mgr()->GetDef(op1_id); - if (load_inst->opcode() != spv::Op::OpLoad) return false; + if (load_inst->opcode() != SpvOpLoad) return false; Instruction* base_inst = load_inst->GetBaseAddress(); - USE_ASSERT(base_inst->opcode() == spv::Op::OpVariable && - spv::StorageClass(base_inst->GetSingleWordInOperand( - kSpvVariableStorageClassInIdx)) == spv::StorageClass::Input && + USE_ASSERT(base_inst->opcode() == SpvOpVariable && + base_inst->GetSingleWordInOperand(kSpvVariableStorageClassInIdx) == + SpvStorageClassInput && "unexpected interpolant in InterpolateAt*"); uint32_t ptr_id = load_inst->GetSingleWordInOperand(0); diff --git a/source/opt/invocation_interlock_placement_pass.cpp b/source/opt/invocation_interlock_placement_pass.cpp deleted file mode 100755 index 642e2d23..00000000 --- a/source/opt/invocation_interlock_placement_pass.cpp +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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 "source/opt/invocation_interlock_placement_pass.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "source/enum_set.h" -#include "source/enum_string_mapping.h" -#include "source/opt/ir_context.h" -#include "source/opt/reflect.h" -#include "source/spirv_target_env.h" -#include "source/util/string_utils.h" - -namespace spvtools { -namespace opt { - -namespace { -constexpr uint32_t kEntryPointExecutionModelInIdx = 0; -constexpr uint32_t kEntryPointFunctionIdInIdx = 1; -constexpr uint32_t kFunctionCallFunctionIdInIdx = 0; -} // namespace - -bool InvocationInterlockPlacementPass::hasSingleNextBlock(uint32_t block_id, - bool reverse_cfg) { - if (reverse_cfg) { - // We are traversing forward, so check whether there is a single successor. - BasicBlock* block = cfg()->block(block_id); - - switch (block->tail()->opcode()) { - case spv::Op::OpBranchConditional: - return false; - case spv::Op::OpSwitch: - return block->tail()->NumInOperandWords() == 1; - default: - return !block->tail()->IsReturnOrAbort(); - } - } else { - // We are traversing backward, so check whether there is a single - // predecessor. - return cfg()->preds(block_id).size() == 1; - } -} - -void InvocationInterlockPlacementPass::forEachNext( - uint32_t block_id, bool reverse_cfg, std::function f) { - if (reverse_cfg) { - BasicBlock* block = cfg()->block(block_id); - - block->ForEachSuccessorLabel([f](uint32_t succ_id) { f(succ_id); }); - } else { - for (uint32_t pred_id : cfg()->preds(block_id)) { - f(pred_id); - } - } -} - -void InvocationInterlockPlacementPass::addInstructionAtBlockBoundary( - BasicBlock* block, spv::Op opcode, bool at_end) { - if (at_end) { - assert(block->begin()->opcode() != spv::Op::OpPhi && - "addInstructionAtBlockBoundary expects to be called with at_end == " - "true only if there is a single successor to block"); - // Insert a begin instruction at the end of the block. - Instruction* begin_inst = new Instruction(context(), opcode); - begin_inst->InsertAfter(&*--block->tail()); - } else { - assert(block->begin()->opcode() != spv::Op::OpPhi && - "addInstructionAtBlockBoundary expects to be called with at_end == " - "false only if there is a single predecessor to block"); - // Insert an end instruction at the beginning of the block. - Instruction* end_inst = new Instruction(context(), opcode); - end_inst->InsertBefore(&*block->begin()); - } -} - -bool InvocationInterlockPlacementPass::killDuplicateBegin(BasicBlock* block) { - bool found = false; - - return context()->KillInstructionIf( - block->begin(), block->end(), [&found](Instruction* inst) { - if (inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT) { - if (found) { - return true; - } - found = true; - } - return false; - }); -} - -bool InvocationInterlockPlacementPass::killDuplicateEnd(BasicBlock* block) { - std::vector to_kill; - block->ForEachInst([&to_kill](Instruction* inst) { - if (inst->opcode() == spv::Op::OpEndInvocationInterlockEXT) { - to_kill.push_back(inst); - } - }); - - if (to_kill.size() <= 1) { - return false; - } - - to_kill.pop_back(); - - for (Instruction* inst : to_kill) { - context()->KillInst(inst); - } - - return true; -} - -void InvocationInterlockPlacementPass::recordBeginOrEndInFunction( - Function* func) { - if (extracted_functions_.count(func)) { - return; - } - - bool had_begin = false; - bool had_end = false; - - func->ForEachInst([this, &had_begin, &had_end](Instruction* inst) { - switch (inst->opcode()) { - case spv::Op::OpBeginInvocationInterlockEXT: - had_begin = true; - break; - case spv::Op::OpEndInvocationInterlockEXT: - had_end = true; - break; - case spv::Op::OpFunctionCall: { - uint32_t function_id = - inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx); - Function* inner_func = context()->GetFunction(function_id); - recordBeginOrEndInFunction(inner_func); - ExtractionResult result = extracted_functions_[inner_func]; - had_begin = had_begin || result.had_begin; - had_end = had_end || result.had_end; - break; - } - default: - break; - } - }); - - ExtractionResult result = {had_begin, had_end}; - extracted_functions_[func] = result; -} - -bool InvocationInterlockPlacementPass:: - removeBeginAndEndInstructionsFromFunction(Function* func) { - bool modified = false; - func->ForEachInst([this, &modified](Instruction* inst) { - switch (inst->opcode()) { - case spv::Op::OpBeginInvocationInterlockEXT: - context()->KillInst(inst); - modified = true; - break; - case spv::Op::OpEndInvocationInterlockEXT: - context()->KillInst(inst); - modified = true; - break; - default: - break; - } - }); - return modified; -} - -bool InvocationInterlockPlacementPass::extractInstructionsFromCalls( - std::vector blocks) { - bool modified = false; - - for (BasicBlock* block : blocks) { - block->ForEachInst([this, &modified](Instruction* inst) { - if (inst->opcode() == spv::Op::OpFunctionCall) { - uint32_t function_id = - inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx); - Function* func = context()->GetFunction(function_id); - ExtractionResult result = extracted_functions_[func]; - - if (result.had_begin) { - Instruction* new_inst = new Instruction( - context(), spv::Op::OpBeginInvocationInterlockEXT); - new_inst->InsertBefore(inst); - modified = true; - } - if (result.had_end) { - Instruction* new_inst = - new Instruction(context(), spv::Op::OpEndInvocationInterlockEXT); - new_inst->InsertAfter(inst); - modified = true; - } - } - }); - } - return modified; -} - -void InvocationInterlockPlacementPass::recordExistingBeginAndEndBlock( - std::vector blocks) { - for (BasicBlock* block : blocks) { - block->ForEachInst([this, block](Instruction* inst) { - switch (inst->opcode()) { - case spv::Op::OpBeginInvocationInterlockEXT: - begin_.insert(block->id()); - break; - case spv::Op::OpEndInvocationInterlockEXT: - end_.insert(block->id()); - break; - default: - break; - } - }); - } -} - -InvocationInterlockPlacementPass::BlockSet -InvocationInterlockPlacementPass::computeReachableBlocks( - BlockSet& previous_inside, const BlockSet& starting_nodes, - bool reverse_cfg) { - BlockSet inside = starting_nodes; - - std::deque worklist; - worklist.insert(worklist.begin(), starting_nodes.begin(), - starting_nodes.end()); - - while (!worklist.empty()) { - uint32_t block_id = worklist.front(); - worklist.pop_front(); - - forEachNext(block_id, reverse_cfg, - [&inside, &previous_inside, &worklist](uint32_t next_id) { - previous_inside.insert(next_id); - if (inside.insert(next_id).second) { - worklist.push_back(next_id); - } - }); - } - - return inside; -} - -bool InvocationInterlockPlacementPass::removeUnneededInstructions( - BasicBlock* block) { - bool modified = false; - if (!predecessors_after_begin_.count(block->id()) && - after_begin_.count(block->id())) { - // None of the previous blocks are in the critical section, but this block - // is. This can only happen if this block already has at least one begin - // instruction. Leave the first begin instruction, and remove any others. - modified |= killDuplicateBegin(block); - } else if (predecessors_after_begin_.count(block->id())) { - // At least one previous block is in the critical section; remove all - // begin instructions in this block. - modified |= context()->KillInstructionIf( - block->begin(), block->end(), [](Instruction* inst) { - return inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT; - }); - } - - if (!successors_before_end_.count(block->id()) && - before_end_.count(block->id())) { - // Same as above - modified |= killDuplicateEnd(block); - } else if (successors_before_end_.count(block->id())) { - modified |= context()->KillInstructionIf( - block->begin(), block->end(), [](Instruction* inst) { - return inst->opcode() == spv::Op::OpEndInvocationInterlockEXT; - }); - } - return modified; -} - -BasicBlock* InvocationInterlockPlacementPass::splitEdge(BasicBlock* block, - uint32_t succ_id) { - // Create a new block to replace the critical edge. - auto new_succ_temp = MakeUnique( - MakeUnique(context(), spv::Op::OpLabel, 0, TakeNextId(), - std::initializer_list{})); - auto* new_succ = new_succ_temp.get(); - - // Insert the new block into the function. - block->GetParent()->InsertBasicBlockAfter(std::move(new_succ_temp), block); - - new_succ->AddInstruction(MakeUnique( - context(), spv::Op::OpBranch, 0, 0, - std::initializer_list{ - Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {succ_id})})); - - assert(block->tail()->opcode() == spv::Op::OpBranchConditional || - block->tail()->opcode() == spv::Op::OpSwitch); - - // Update the first branch to successor to instead branch to - // the new successor. If there are multiple edges, we arbitrarily choose the - // first time it appears in the list. The other edges to `succ_id` will have - // to be split by another call to `splitEdge`. - block->tail()->WhileEachInId([new_succ, succ_id](uint32_t* branch_id) { - if (*branch_id == succ_id) { - *branch_id = new_succ->id(); - return false; - } - return true; - }); - - return new_succ; -} - -bool InvocationInterlockPlacementPass::placeInstructionsForEdge( - BasicBlock* block, uint32_t next_id, BlockSet& inside, - BlockSet& previous_inside, spv::Op opcode, bool reverse_cfg) { - bool modified = false; - - if (previous_inside.count(next_id) && !inside.count(block->id())) { - // This block is not in the critical section but the next has at least one - // other previous block that is, so this block should be enter it as well. - // We need to add begin or end instructions to the edge. - - modified = true; - - if (hasSingleNextBlock(block->id(), reverse_cfg)) { - // This is the only next block. - - // Additionally, because `next_id` is in `previous_inside`, we know that - // `next_id` has at least one previous block in `inside`. And because - // 'block` is not in `inside`, that means the `next_id` has to have at - // least one other previous block in `inside`. - - // This is solely for a debug assertion. It is essentially recomputing the - // value of `previous_inside` to verify that it was computed correctly - // such that the above statement is true. - bool next_has_previous_inside = false; - // By passing !reverse_cfg to forEachNext, we are actually iterating over - // the previous blocks. - forEachNext(next_id, !reverse_cfg, - [&next_has_previous_inside, inside](uint32_t previous_id) { - if (inside.count(previous_id)) { - next_has_previous_inside = true; - } - }); - assert(next_has_previous_inside && - "`previous_inside` must be the set of blocks with at least one " - "previous block in `inside`"); - - addInstructionAtBlockBoundary(block, opcode, reverse_cfg); - } else { - // This block has multiple next blocks. Split the edge and insert the - // instruction in the new next block. - BasicBlock* new_branch; - if (reverse_cfg) { - new_branch = splitEdge(block, next_id); - } else { - new_branch = splitEdge(cfg()->block(next_id), block->id()); - } - - auto inst = new Instruction(context(), opcode); - inst->InsertBefore(&*new_branch->tail()); - } - } - - return modified; -} - -bool InvocationInterlockPlacementPass::placeInstructions(BasicBlock* block) { - bool modified = false; - - block->ForEachSuccessorLabel([this, block, &modified](uint32_t succ_id) { - modified |= placeInstructionsForEdge( - block, succ_id, after_begin_, predecessors_after_begin_, - spv::Op::OpBeginInvocationInterlockEXT, /* reverse_cfg= */ true); - modified |= placeInstructionsForEdge(cfg()->block(succ_id), block->id(), - before_end_, successors_before_end_, - spv::Op::OpEndInvocationInterlockEXT, - /* reverse_cfg= */ false); - }); - - return modified; -} - -bool InvocationInterlockPlacementPass::processFragmentShaderEntry( - Function* entry_func) { - bool modified = false; - - // Save the original order of blocks in the function, so we don't iterate over - // newly-added blocks. - std::vector original_blocks; - for (auto bi = entry_func->begin(); bi != entry_func->end(); ++bi) { - original_blocks.push_back(&*bi); - } - - modified |= extractInstructionsFromCalls(original_blocks); - recordExistingBeginAndEndBlock(original_blocks); - - after_begin_ = computeReachableBlocks(predecessors_after_begin_, begin_, - /* reverse_cfg= */ true); - before_end_ = computeReachableBlocks(successors_before_end_, end_, - /* reverse_cfg= */ false); - - for (BasicBlock* block : original_blocks) { - modified |= removeUnneededInstructions(block); - modified |= placeInstructions(block); - } - return modified; -} - -bool InvocationInterlockPlacementPass::isFragmentShaderInterlockEnabled() { - if (!context()->get_feature_mgr()->HasExtension( - kSPV_EXT_fragment_shader_interlock)) { - return false; - } - - if (context()->get_feature_mgr()->HasCapability( - spv::Capability::FragmentShaderSampleInterlockEXT)) { - return true; - } - - if (context()->get_feature_mgr()->HasCapability( - spv::Capability::FragmentShaderPixelInterlockEXT)) { - return true; - } - - if (context()->get_feature_mgr()->HasCapability( - spv::Capability::FragmentShaderShadingRateInterlockEXT)) { - return true; - } - - return false; -} - -Pass::Status InvocationInterlockPlacementPass::Process() { - // Skip this pass if the necessary extension or capability is missing - if (!isFragmentShaderInterlockEnabled()) { - return Status::SuccessWithoutChange; - } - - bool modified = false; - - std::unordered_set entry_points; - for (Instruction& entry_inst : context()->module()->entry_points()) { - uint32_t entry_id = - entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx); - entry_points.insert(context()->GetFunction(entry_id)); - } - - for (auto fi = context()->module()->begin(); fi != context()->module()->end(); - ++fi) { - Function* func = &*fi; - recordBeginOrEndInFunction(func); - if (!entry_points.count(func) && extracted_functions_.count(func)) { - modified |= removeBeginAndEndInstructionsFromFunction(func); - } - } - - for (Instruction& entry_inst : context()->module()->entry_points()) { - uint32_t entry_id = - entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx); - Function* entry_func = context()->GetFunction(entry_id); - - auto execution_model = spv::ExecutionModel( - entry_inst.GetSingleWordInOperand(kEntryPointExecutionModelInIdx)); - - if (execution_model != spv::ExecutionModel::Fragment) { - continue; - } - - modified |= processFragmentShaderEntry(entry_func); - } - - return modified ? Pass::Status::SuccessWithChange - : Pass::Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/invocation_interlock_placement_pass.h b/source/opt/invocation_interlock_placement_pass.h deleted file mode 100755 index 4e85be85..00000000 --- a/source/opt/invocation_interlock_placement_pass.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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. - -#ifndef SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ -#define SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ - -#include -#include -#include -#include -#include -#include - -#include "source/enum_set.h" -#include "source/extensions.h" -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" -#include "source/spirv_target_env.h" - -namespace spvtools { -namespace opt { - -// This pass will ensure that an entry point will only have at most one -// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that -// order -class InvocationInterlockPlacementPass : public Pass { - public: - InvocationInterlockPlacementPass() {} - InvocationInterlockPlacementPass(const InvocationInterlockPlacementPass&) = - delete; - InvocationInterlockPlacementPass(InvocationInterlockPlacementPass&&) = delete; - - const char* name() const override { return "dedupe-interlock-invocation"; } - Status Process() override; - - private: - using BlockSet = std::unordered_set; - - // Specifies whether a function originally had a begin or end instruction. - struct ExtractionResult { - bool had_begin : 1; - bool had_end : 2; - }; - - // Check if a block has only a single next block, depending on the directing - // that we are traversing the CFG. If reverse_cfg is true, we are walking - // forward through the CFG, and will return if the block has only one - // successor. Otherwise, we are walking backward through the CFG, and will - // return if the block has only one predecessor. - bool hasSingleNextBlock(uint32_t block_id, bool reverse_cfg); - - // Iterate over each of a block's predecessors or successors, depending on - // direction. If reverse_cfg is true, we are walking forward through the CFG, - // and need to iterate over the successors. Otherwise, we are walking backward - // through the CFG, and need to iterate over the predecessors. - void forEachNext(uint32_t block_id, bool reverse_cfg, - std::function f); - - // Add either a begin or end instruction to the edge of the basic block. If - // at_end is true, add the instruction to the end of the block; otherwise add - // the instruction to the beginning of the basic block. - void addInstructionAtBlockBoundary(BasicBlock* block, spv::Op opcode, - bool at_end); - - // Remove every OpBeginInvocationInterlockEXT instruction in block after the - // first. Returns whether any instructions were removed. - bool killDuplicateBegin(BasicBlock* block); - // Remove every OpBeginInvocationInterlockEXT instruction in block before the - // last. Returns whether any instructions were removed. - bool killDuplicateEnd(BasicBlock* block); - - // Records whether a function will potentially execute a begin or end - // instruction. - void recordBeginOrEndInFunction(Function* func); - - // Recursively removes any begin or end instructions from func and any - // function func calls. Returns whether any instructions were removed. - bool removeBeginAndEndInstructionsFromFunction(Function* func); - - // For every function call in any of the passed blocks, move any begin or end - // instructions outside of the function call. Returns whether any extractions - // occurred. - bool extractInstructionsFromCalls(std::vector blocks); - - // Finds the sets of blocks that contain OpBeginInvocationInterlockEXT and - // OpEndInvocationInterlockEXT, storing them in the member variables begin_ - // and end_ respectively. - void recordExistingBeginAndEndBlock(std::vector blocks); - - // Compute the set of blocks including or after the barrier instruction, and - // the set of blocks with any previous blocks inside the barrier instruction. - // If reverse_cfg is true, move forward through the CFG, computing - // after_begin_ and predecessors_after_begin_computing after_begin_ and - // predecessors_after_begin_, otherwise, move backward through the CFG, - // computing before_end_ and successors_before_end_. - BlockSet computeReachableBlocks(BlockSet& in_set, - const BlockSet& starting_nodes, - bool reverse_cfg); - - // Remove unneeded begin and end instructions in block. - bool removeUnneededInstructions(BasicBlock* block); - - // Given a block which branches to multiple successors, and a specific - // successor, creates a new empty block, and update the branch instruction to - // branch to the new block instead. - BasicBlock* splitEdge(BasicBlock* block, uint32_t succ_id); - - // For the edge from block to next_id, places a begin or end instruction on - // the edge, based on the direction we are walking the CFG, specified in - // reverse_cfg. - bool placeInstructionsForEdge(BasicBlock* block, uint32_t next_id, - BlockSet& inside, BlockSet& previous_inside, - spv::Op opcode, bool reverse_cfg); - // Calls placeInstructionsForEdge for each edge in block. - bool placeInstructions(BasicBlock* block); - - // Processes a single fragment shader entry function. - bool processFragmentShaderEntry(Function* entry_func); - - // Returns whether the module has the SPV_EXT_fragment_shader_interlock - // extension and one of the FragmentShader*InterlockEXT capabilities. - bool isFragmentShaderInterlockEnabled(); - - // Maps a function to whether that function originally held a begin or end - // instruction. - std::unordered_map extracted_functions_; - - // The set of blocks which have an OpBeginInvocationInterlockEXT instruction. - BlockSet begin_; - // The set of blocks which have an OpEndInvocationInterlockEXT instruction. - BlockSet end_; - // The set of blocks which either have a begin instruction, or have a - // predecessor which has a begin instruction. - BlockSet after_begin_; - // The set of blocks which either have an end instruction, or have a successor - // which have an end instruction. - BlockSet before_end_; - // The set of blocks which have a predecessor in after_begin_. - BlockSet predecessors_after_begin_; - // The set of blocks which have a successor in before_end_. - BlockSet successors_before_end_; -}; - -} // namespace opt -} // namespace spvtools -#endif // SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_ diff --git a/source/opt/ir_builder.h b/source/opt/ir_builder.h index f3e0afce..9d4fa8fe 100644 --- a/source/opt/ir_builder.h +++ b/source/opt/ir_builder.h @@ -30,7 +30,7 @@ namespace opt { // In SPIR-V, ids are encoded as uint16_t, this id is guaranteed to be always // invalid. -constexpr uint32_t kInvalidId = std::numeric_limits::max(); +const uint32_t kInvalidId = std::numeric_limits::max(); // Helper class to abstract instruction construction and insertion. // The instruction builder can preserve the following analyses (specified via @@ -58,7 +58,7 @@ class InstructionBuilder { : InstructionBuilder(context, parent_block, parent_block->end(), preserved_analyses) {} - Instruction* AddNullaryOp(uint32_t type_id, spv::Op opcode) { + Instruction* AddNullaryOp(uint32_t type_id, SpvOp opcode) { uint32_t result_id = 0; if (type_id != 0) { result_id = GetContext()->TakeNextId(); @@ -71,7 +71,7 @@ class InstructionBuilder { return AddInstruction(std::move(new_inst)); } - Instruction* AddUnaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1) { + Instruction* AddUnaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1) { uint32_t result_id = 0; if (type_id != 0) { result_id = GetContext()->TakeNextId(); @@ -85,7 +85,7 @@ class InstructionBuilder { return AddInstruction(std::move(newUnOp)); } - Instruction* AddBinaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + Instruction* AddBinaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2) { uint32_t result_id = 0; if (type_id != 0) { @@ -95,14 +95,13 @@ class InstructionBuilder { } } std::unique_ptr newBinOp(new Instruction( - GetContext(), opcode, type_id, - opcode == spv::Op::OpStore ? 0 : result_id, + GetContext(), opcode, type_id, opcode == SpvOpStore ? 0 : result_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand1}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {operand2}}})); return AddInstruction(std::move(newBinOp)); } - Instruction* AddTernaryOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + Instruction* AddTernaryOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3) { uint32_t result_id = 0; if (type_id != 0) { @@ -119,7 +118,7 @@ class InstructionBuilder { return AddInstruction(std::move(newTernOp)); } - Instruction* AddQuadOp(uint32_t type_id, spv::Op opcode, uint32_t operand1, + Instruction* AddQuadOp(uint32_t type_id, SpvOp opcode, uint32_t operand1, uint32_t operand2, uint32_t operand3, uint32_t operand4) { uint32_t result_id = 0; @@ -138,7 +137,7 @@ class InstructionBuilder { return AddInstruction(std::move(newQuadOp)); } - Instruction* AddIdLiteralOp(uint32_t type_id, spv::Op opcode, uint32_t id, + Instruction* AddIdLiteralOp(uint32_t type_id, SpvOp opcode, uint32_t id, uint32_t uliteral) { uint32_t result_id = 0; if (type_id != 0) { @@ -158,7 +157,7 @@ class InstructionBuilder { // |typid| must be the id of the instruction's type. // |operands| must be a sequence of operand ids. // Use |result| for the result id if non-zero. - Instruction* AddNaryOp(uint32_t type_id, spv::Op opcode, + Instruction* AddNaryOp(uint32_t type_id, SpvOp opcode, const std::vector& operands, uint32_t result = 0) { std::vector ops; @@ -175,10 +174,10 @@ class InstructionBuilder { // Creates a new selection merge instruction. // The id |merge_id| is the merge basic block id. Instruction* AddSelectionMerge( - uint32_t merge_id, uint32_t selection_control = static_cast( - spv::SelectionControlMask::MaskNone)) { + uint32_t merge_id, + uint32_t selection_control = SpvSelectionControlMaskNone) { std::unique_ptr new_branch_merge(new Instruction( - GetContext(), spv::Op::OpSelectionMerge, 0, 0, + GetContext(), SpvOpSelectionMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_SELECTION_CONTROL, {selection_control}}})); @@ -190,10 +189,9 @@ class InstructionBuilder { // |continue_id| is the id of the continue block. // |loop_control| are the loop control flags to be added to the instruction. Instruction* AddLoopMerge(uint32_t merge_id, uint32_t continue_id, - uint32_t loop_control = static_cast( - spv::LoopControlMask::MaskNone)) { + uint32_t loop_control = SpvLoopControlMaskNone) { std::unique_ptr new_branch_merge(new Instruction( - GetContext(), spv::Op::OpLoopMerge, 0, 0, + GetContext(), SpvOpLoopMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LOOP_CONTROL, {loop_control}}})); @@ -205,7 +203,7 @@ class InstructionBuilder { // well formed. Instruction* AddBranch(uint32_t label_id) { std::unique_ptr new_branch(new Instruction( - GetContext(), spv::Op::OpBranch, 0, 0, + GetContext(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); return AddInstruction(std::move(new_branch)); } @@ -228,13 +226,12 @@ class InstructionBuilder { Instruction* AddConditionalBranch( uint32_t cond_id, uint32_t true_id, uint32_t false_id, uint32_t merge_id = kInvalidId, - uint32_t selection_control = - static_cast(spv::SelectionControlMask::MaskNone)) { + uint32_t selection_control = SpvSelectionControlMaskNone) { if (merge_id != kInvalidId) { AddSelectionMerge(merge_id, selection_control); } std::unique_ptr new_branch(new Instruction( - GetContext(), spv::Op::OpBranchConditional, 0, 0, + GetContext(), SpvOpBranchConditional, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); @@ -258,8 +255,7 @@ class InstructionBuilder { uint32_t selector_id, uint32_t default_id, const std::vector>& targets, uint32_t merge_id = kInvalidId, - uint32_t selection_control = - static_cast(spv::SelectionControlMask::MaskNone)) { + uint32_t selection_control = SpvSelectionControlMaskNone) { if (merge_id != kInvalidId) { AddSelectionMerge(merge_id, selection_control); } @@ -276,7 +272,7 @@ class InstructionBuilder { Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {target.second}}); } std::unique_ptr new_switch( - new Instruction(GetContext(), spv::Op::OpSwitch, 0, 0, operands)); + new Instruction(GetContext(), SpvOpSwitch, 0, 0, operands)); return AddInstruction(std::move(new_switch)); } @@ -287,7 +283,7 @@ class InstructionBuilder { Instruction* AddPhi(uint32_t type, const std::vector& incomings, uint32_t result = 0) { assert(incomings.size() % 2 == 0 && "A sequence of pairs is expected"); - return AddNaryOp(type, spv::Op::OpPhi, incomings, result); + return AddNaryOp(type, SpvOpPhi, incomings, result); } // Creates an addition instruction. @@ -298,7 +294,7 @@ class InstructionBuilder { Instruction* AddIAdd(uint32_t type, uint32_t op1, uint32_t op2) { // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), spv::Op::OpIAdd, type, GetContext()->TakeNextId(), + GetContext(), SpvOpIAdd, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -312,7 +308,7 @@ class InstructionBuilder { uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), spv::Op::OpULessThan, type, GetContext()->TakeNextId(), + GetContext(), SpvOpULessThan, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -326,7 +322,7 @@ class InstructionBuilder { uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type); // TODO(1841): Handle id overflow. std::unique_ptr inst(new Instruction( - GetContext(), spv::Op::OpSLessThan, type, GetContext()->TakeNextId(), + GetContext(), SpvOpSLessThan, type, GetContext()->TakeNextId(), {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}})); return AddInstruction(std::move(inst)); } @@ -356,7 +352,7 @@ class InstructionBuilder { uint32_t false_value) { // TODO(1841): Handle id overflow. std::unique_ptr select(new Instruction( - GetContext(), spv::Op::OpSelect, type, GetContext()->TakeNextId(), + GetContext(), SpvOpSelect, type, GetContext()->TakeNextId(), std::initializer_list{{SPV_OPERAND_TYPE_ID, {cond}}, {SPV_OPERAND_TYPE_ID, {true_value}}, {SPV_OPERAND_TYPE_ID, {false_value}}})); @@ -382,7 +378,7 @@ class InstructionBuilder { } // TODO(1841): Handle id overflow. std::unique_ptr construct( - new Instruction(GetContext(), spv::Op::OpCompositeConstruct, type, + new Instruction(GetContext(), SpvOpCompositeConstruct, type, GetContext()->TakeNextId(), ops)); return AddInstruction(std::move(construct)); } @@ -440,22 +436,6 @@ class InstructionBuilder { return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant); } - Instruction* GetBoolConstant(bool value) { - analysis::Bool type; - uint32_t type_id = GetContext()->get_type_mgr()->GetTypeInstruction(&type); - analysis::Type* rebuilt_type = - GetContext()->get_type_mgr()->GetType(type_id); - uint32_t word = value; - const analysis::Constant* constant = - GetContext()->get_constant_mgr()->GetConstant(rebuilt_type, {word}); - return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant); - } - - uint32_t GetBoolConstantId(bool value) { - Instruction* inst = GetBoolConstant(value); - return (inst != nullptr ? inst->result_id() : 0); - } - Instruction* AddCompositeExtract(uint32_t type, uint32_t id_of_composite, const std::vector& index_list) { std::vector operands; @@ -467,7 +447,7 @@ class InstructionBuilder { // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpCompositeExtract, type, + new Instruction(GetContext(), SpvOpCompositeExtract, type, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -475,7 +455,7 @@ class InstructionBuilder { // Creates an unreachable instruction. Instruction* AddUnreachable() { std::unique_ptr select( - new Instruction(GetContext(), spv::Op::OpUnreachable, 0, 0, + new Instruction(GetContext(), SpvOpUnreachable, 0, 0, std::initializer_list{})); return AddInstruction(std::move(select)); } @@ -491,25 +471,18 @@ class InstructionBuilder { // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpAccessChain, type_id, + new Instruction(GetContext(), SpvOpAccessChain, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } - Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id, - uint32_t alignment = 0) { + Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id) { std::vector operands; operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}}); - if (alignment != 0) { - operands.push_back( - {SPV_OPERAND_TYPE_MEMORY_ACCESS, - {static_cast(spv::MemoryAccessMask::Aligned)}}); - operands.push_back({SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, {alignment}}); - } // TODO(1841): Handle id overflow. std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpLoad, type_id, + new Instruction(GetContext(), SpvOpLoad, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -518,7 +491,7 @@ class InstructionBuilder { std::vector operands; operands.push_back({SPV_OPERAND_TYPE_ID, {storage_class}}); std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpVariable, type_id, + new Instruction(GetContext(), SpvOpVariable, type_id, GetContext()->TakeNextId(), operands)); return AddInstruction(std::move(new_inst)); } @@ -529,7 +502,7 @@ class InstructionBuilder { operands.push_back({SPV_OPERAND_TYPE_ID, {obj_id}}); std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpStore, 0, 0, operands)); + new Instruction(GetContext(), SpvOpStore, 0, 0, operands)); return AddInstruction(std::move(new_inst)); } @@ -545,9 +518,8 @@ class InstructionBuilder { if (result_id == 0) { return nullptr; } - std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpFunctionCall, result_type, - result_id, operands)); + std::unique_ptr new_inst(new Instruction( + GetContext(), SpvOpFunctionCall, result_type, result_id, operands)); return AddInstruction(std::move(new_inst)); } @@ -566,9 +538,8 @@ class InstructionBuilder { return nullptr; } - std::unique_ptr new_inst( - new Instruction(GetContext(), spv::Op::OpVectorShuffle, result_type, - result_id, operands)); + std::unique_ptr new_inst(new Instruction( + GetContext(), SpvOpVectorShuffle, result_type, result_id, operands)); return AddInstruction(std::move(new_inst)); } @@ -589,7 +560,7 @@ class InstructionBuilder { } std::unique_ptr new_inst(new Instruction( - GetContext(), spv::Op::OpExtInst, result_type, result_id, operands)); + GetContext(), SpvOpExtInst, result_type, result_id, operands)); return AddInstruction(std::move(new_inst)); } diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp index 239d316c..c9c3f1b5 100644 --- a/source/opt/ir_context.cpp +++ b/source/opt/ir_context.cpp @@ -19,23 +19,26 @@ #include "OpenCLDebugInfo100.h" #include "source/latest_version_glsl_std_450_header.h" #include "source/opt/log.h" +#include "source/opt/mem_pass.h" #include "source/opt/reflect.h" -namespace spvtools { -namespace opt { namespace { -constexpr int kSpvDecorateTargetIdInIdx = 0; -constexpr int kSpvDecorateDecorationInIdx = 1; -constexpr int kSpvDecorateBuiltinInIdx = 2; -constexpr int kEntryPointInterfaceInIdx = 3; -constexpr int kEntryPointFunctionIdInIdx = 1; -constexpr int kEntryPointExecutionModelInIdx = 0; + +static const int kSpvDecorateTargetIdInIdx = 0; +static const int kSpvDecorateDecorationInIdx = 1; +static const int kSpvDecorateBuiltinInIdx = 2; +static const int kEntryPointInterfaceInIdx = 3; +static const int kEntryPointFunctionIdInIdx = 1; // Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100 // extension instructions. -constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13; -constexpr uint32_t kDebugGlobalVariableOperandVariableIndex = 11; -} // namespace +static const uint32_t kDebugFunctionOperandFunctionIndex = 13; +static const uint32_t kDebugGlobalVariableOperandVariableIndex = 11; + +} // anonymous namespace + +namespace spvtools { +namespace opt { void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) { set = Analysis(set & ~valid_analyses_); @@ -149,9 +152,6 @@ void IRContext::InvalidateAnalyses(IRContext::Analysis analyses_to_invalidate) { if (analyses_to_invalidate & kAnalysisConstants) { constant_mgr_.reset(nullptr); } - if (analyses_to_invalidate & kAnalysisLiveness) { - liveness_mgr_.reset(nullptr); - } if (analyses_to_invalidate & kAnalysisTypes) { type_mgr_.reset(nullptr); } @@ -195,8 +195,7 @@ Instruction* IRContext::KillInst(Instruction* inst) { if (constant_mgr_ && IsConstantInst(inst->opcode())) { constant_mgr_->RemoveId(inst->result_id()); } - if (inst->opcode() == spv::Op::OpCapability || - inst->opcode() == spv::Op::OpExtension) { + if (inst->opcode() == SpvOpCapability || inst->opcode() == SpvOpExtension) { // We reset the feature manager, instead of updating it, because it is just // as much work. We would have to remove all capabilities implied by this // capability that are not also implied by the remaining OpCapability @@ -220,28 +219,6 @@ Instruction* IRContext::KillInst(Instruction* inst) { return next_instruction; } -bool IRContext::KillInstructionIf(Module::inst_iterator begin, - Module::inst_iterator end, - std::function condition) { - bool removed = false; - for (auto it = begin; it != end;) { - if (!condition(&*it)) { - ++it; - continue; - } - - removed = true; - // `it` is an iterator on an intrusive list. Next is invalidated on the - // current node when an instruction is killed. The iterator must be moved - // forward before deleting the node. - auto instruction = &*it; - ++it; - KillInst(instruction); - } - - return removed; -} - void IRContext::CollectNonSemanticTree( Instruction* inst, std::unordered_set* to_kill) { if (!inst->HasResultId()) return; @@ -273,36 +250,6 @@ bool IRContext::KillDef(uint32_t id) { return false; } -bool IRContext::RemoveCapability(spv::Capability capability) { - const bool removed = KillInstructionIf( - module()->capability_begin(), module()->capability_end(), - [capability](Instruction* inst) { - return static_cast(inst->GetSingleWordOperand(0)) == - capability; - }); - - if (removed && feature_mgr_ != nullptr) { - feature_mgr_->RemoveCapability(capability); - } - - return removed; -} - -bool IRContext::RemoveExtension(Extension extension) { - const std::string_view extensionName = ExtensionToString(extension); - const bool removed = KillInstructionIf( - module()->extension_begin(), module()->extension_end(), - [&extensionName](Instruction* inst) { - return inst->GetOperand(0).AsString() == extensionName; - }); - - if (removed && feature_mgr_ != nullptr) { - feature_mgr_->RemoveExtension(extension); - } - - return removed; -} - bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) { return ReplaceAllUsesWithPredicate(before, after, [](Instruction*) { return true; }); @@ -451,8 +398,8 @@ void IRContext::AnalyzeUses(Instruction* inst) { if (AreAnalysesValid(kAnalysisDebugInfo)) { get_debug_info_mgr()->AnalyzeDebugInst(inst); } - if (id_to_name_ && (inst->opcode() == spv::Op::OpName || - inst->opcode() == spv::Op::OpMemberName)) { + if (id_to_name_ && + (inst->opcode() == SpvOpName || inst->opcode() == SpvOpMemberName)) { id_to_name_->insert({inst->GetSingleWordInOperand(0), inst}); } } @@ -480,7 +427,7 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { const auto opcode = inst->opcode(); const uint32_t id = inst->result_id(); // Kill id of OpFunction from DebugFunction. - if (opcode == spv::Op::OpFunction) { + if (opcode == SpvOpFunction) { for (auto it = module()->ext_inst_debuginfo_begin(); it != module()->ext_inst_debuginfo_end(); ++it) { if (it->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugFunction) @@ -494,7 +441,7 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { } } // Kill id of OpVariable for global variable from DebugGlobalVariable. - if (opcode == spv::Op::OpVariable || IsConstantInst(opcode)) { + if (opcode == SpvOpVariable || IsConstantInst(opcode)) { for (auto it = module()->ext_inst_debuginfo_begin(); it != module()->ext_inst_debuginfo_end(); ++it) { if (it->GetCommonDebugOpcode() != CommonDebugInfoDebugGlobalVariable) @@ -510,259 +457,255 @@ void IRContext::KillOperandFromDebugInstructions(Instruction* inst) { } void IRContext::AddCombinatorsForCapability(uint32_t capability) { - spv::Capability cap = spv::Capability(capability); - if (cap == spv::Capability::Shader) { - combinator_ops_[0].insert( - {(uint32_t)spv::Op::OpNop, - (uint32_t)spv::Op::OpUndef, - (uint32_t)spv::Op::OpConstant, - (uint32_t)spv::Op::OpConstantTrue, - (uint32_t)spv::Op::OpConstantFalse, - (uint32_t)spv::Op::OpConstantComposite, - (uint32_t)spv::Op::OpConstantSampler, - (uint32_t)spv::Op::OpConstantNull, - (uint32_t)spv::Op::OpTypeVoid, - (uint32_t)spv::Op::OpTypeBool, - (uint32_t)spv::Op::OpTypeInt, - (uint32_t)spv::Op::OpTypeFloat, - (uint32_t)spv::Op::OpTypeVector, - (uint32_t)spv::Op::OpTypeMatrix, - (uint32_t)spv::Op::OpTypeImage, - (uint32_t)spv::Op::OpTypeSampler, - (uint32_t)spv::Op::OpTypeSampledImage, - (uint32_t)spv::Op::OpTypeAccelerationStructureNV, - (uint32_t)spv::Op::OpTypeAccelerationStructureKHR, - (uint32_t)spv::Op::OpTypeRayQueryKHR, - (uint32_t)spv::Op::OpTypeHitObjectNV, - (uint32_t)spv::Op::OpTypeArray, - (uint32_t)spv::Op::OpTypeRuntimeArray, - (uint32_t)spv::Op::OpTypeStruct, - (uint32_t)spv::Op::OpTypeOpaque, - (uint32_t)spv::Op::OpTypePointer, - (uint32_t)spv::Op::OpTypeFunction, - (uint32_t)spv::Op::OpTypeEvent, - (uint32_t)spv::Op::OpTypeDeviceEvent, - (uint32_t)spv::Op::OpTypeReserveId, - (uint32_t)spv::Op::OpTypeQueue, - (uint32_t)spv::Op::OpTypePipe, - (uint32_t)spv::Op::OpTypeForwardPointer, - (uint32_t)spv::Op::OpVariable, - (uint32_t)spv::Op::OpImageTexelPointer, - (uint32_t)spv::Op::OpLoad, - (uint32_t)spv::Op::OpAccessChain, - (uint32_t)spv::Op::OpInBoundsAccessChain, - (uint32_t)spv::Op::OpArrayLength, - (uint32_t)spv::Op::OpVectorExtractDynamic, - (uint32_t)spv::Op::OpVectorInsertDynamic, - (uint32_t)spv::Op::OpVectorShuffle, - (uint32_t)spv::Op::OpCompositeConstruct, - (uint32_t)spv::Op::OpCompositeExtract, - (uint32_t)spv::Op::OpCompositeInsert, - (uint32_t)spv::Op::OpCopyObject, - (uint32_t)spv::Op::OpTranspose, - (uint32_t)spv::Op::OpSampledImage, - (uint32_t)spv::Op::OpImageSampleImplicitLod, - (uint32_t)spv::Op::OpImageSampleExplicitLod, - (uint32_t)spv::Op::OpImageSampleDrefImplicitLod, - (uint32_t)spv::Op::OpImageSampleDrefExplicitLod, - (uint32_t)spv::Op::OpImageSampleProjImplicitLod, - (uint32_t)spv::Op::OpImageSampleProjExplicitLod, - (uint32_t)spv::Op::OpImageSampleProjDrefImplicitLod, - (uint32_t)spv::Op::OpImageSampleProjDrefExplicitLod, - (uint32_t)spv::Op::OpImageFetch, - (uint32_t)spv::Op::OpImageGather, - (uint32_t)spv::Op::OpImageDrefGather, - (uint32_t)spv::Op::OpImageRead, - (uint32_t)spv::Op::OpImage, - (uint32_t)spv::Op::OpImageQueryFormat, - (uint32_t)spv::Op::OpImageQueryOrder, - (uint32_t)spv::Op::OpImageQuerySizeLod, - (uint32_t)spv::Op::OpImageQuerySize, - (uint32_t)spv::Op::OpImageQueryLevels, - (uint32_t)spv::Op::OpImageQuerySamples, - (uint32_t)spv::Op::OpConvertFToU, - (uint32_t)spv::Op::OpConvertFToS, - (uint32_t)spv::Op::OpConvertSToF, - (uint32_t)spv::Op::OpConvertUToF, - (uint32_t)spv::Op::OpUConvert, - (uint32_t)spv::Op::OpSConvert, - (uint32_t)spv::Op::OpFConvert, - (uint32_t)spv::Op::OpQuantizeToF16, - (uint32_t)spv::Op::OpBitcast, - (uint32_t)spv::Op::OpSNegate, - (uint32_t)spv::Op::OpFNegate, - (uint32_t)spv::Op::OpIAdd, - (uint32_t)spv::Op::OpFAdd, - (uint32_t)spv::Op::OpISub, - (uint32_t)spv::Op::OpFSub, - (uint32_t)spv::Op::OpIMul, - (uint32_t)spv::Op::OpFMul, - (uint32_t)spv::Op::OpUDiv, - (uint32_t)spv::Op::OpSDiv, - (uint32_t)spv::Op::OpFDiv, - (uint32_t)spv::Op::OpUMod, - (uint32_t)spv::Op::OpSRem, - (uint32_t)spv::Op::OpSMod, - (uint32_t)spv::Op::OpFRem, - (uint32_t)spv::Op::OpFMod, - (uint32_t)spv::Op::OpVectorTimesScalar, - (uint32_t)spv::Op::OpMatrixTimesScalar, - (uint32_t)spv::Op::OpVectorTimesMatrix, - (uint32_t)spv::Op::OpMatrixTimesVector, - (uint32_t)spv::Op::OpMatrixTimesMatrix, - (uint32_t)spv::Op::OpOuterProduct, - (uint32_t)spv::Op::OpDot, - (uint32_t)spv::Op::OpIAddCarry, - (uint32_t)spv::Op::OpISubBorrow, - (uint32_t)spv::Op::OpUMulExtended, - (uint32_t)spv::Op::OpSMulExtended, - (uint32_t)spv::Op::OpAny, - (uint32_t)spv::Op::OpAll, - (uint32_t)spv::Op::OpIsNan, - (uint32_t)spv::Op::OpIsInf, - (uint32_t)spv::Op::OpLogicalEqual, - (uint32_t)spv::Op::OpLogicalNotEqual, - (uint32_t)spv::Op::OpLogicalOr, - (uint32_t)spv::Op::OpLogicalAnd, - (uint32_t)spv::Op::OpLogicalNot, - (uint32_t)spv::Op::OpSelect, - (uint32_t)spv::Op::OpIEqual, - (uint32_t)spv::Op::OpINotEqual, - (uint32_t)spv::Op::OpUGreaterThan, - (uint32_t)spv::Op::OpSGreaterThan, - (uint32_t)spv::Op::OpUGreaterThanEqual, - (uint32_t)spv::Op::OpSGreaterThanEqual, - (uint32_t)spv::Op::OpULessThan, - (uint32_t)spv::Op::OpSLessThan, - (uint32_t)spv::Op::OpULessThanEqual, - (uint32_t)spv::Op::OpSLessThanEqual, - (uint32_t)spv::Op::OpFOrdEqual, - (uint32_t)spv::Op::OpFUnordEqual, - (uint32_t)spv::Op::OpFOrdNotEqual, - (uint32_t)spv::Op::OpFUnordNotEqual, - (uint32_t)spv::Op::OpFOrdLessThan, - (uint32_t)spv::Op::OpFUnordLessThan, - (uint32_t)spv::Op::OpFOrdGreaterThan, - (uint32_t)spv::Op::OpFUnordGreaterThan, - (uint32_t)spv::Op::OpFOrdLessThanEqual, - (uint32_t)spv::Op::OpFUnordLessThanEqual, - (uint32_t)spv::Op::OpFOrdGreaterThanEqual, - (uint32_t)spv::Op::OpFUnordGreaterThanEqual, - (uint32_t)spv::Op::OpShiftRightLogical, - (uint32_t)spv::Op::OpShiftRightArithmetic, - (uint32_t)spv::Op::OpShiftLeftLogical, - (uint32_t)spv::Op::OpBitwiseOr, - (uint32_t)spv::Op::OpBitwiseXor, - (uint32_t)spv::Op::OpBitwiseAnd, - (uint32_t)spv::Op::OpNot, - (uint32_t)spv::Op::OpBitFieldInsert, - (uint32_t)spv::Op::OpBitFieldSExtract, - (uint32_t)spv::Op::OpBitFieldUExtract, - (uint32_t)spv::Op::OpBitReverse, - (uint32_t)spv::Op::OpBitCount, - (uint32_t)spv::Op::OpPhi, - (uint32_t)spv::Op::OpImageSparseSampleImplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleExplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleDrefImplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleDrefExplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleProjImplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleProjExplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleProjDrefImplicitLod, - (uint32_t)spv::Op::OpImageSparseSampleProjDrefExplicitLod, - (uint32_t)spv::Op::OpImageSparseFetch, - (uint32_t)spv::Op::OpImageSparseGather, - (uint32_t)spv::Op::OpImageSparseDrefGather, - (uint32_t)spv::Op::OpImageSparseTexelsResident, - (uint32_t)spv::Op::OpImageSparseRead, - (uint32_t)spv::Op::OpSizeOf}); + if (capability == SpvCapabilityShader) { + combinator_ops_[0].insert({SpvOpNop, + SpvOpUndef, + SpvOpConstant, + SpvOpConstantTrue, + SpvOpConstantFalse, + SpvOpConstantComposite, + SpvOpConstantSampler, + SpvOpConstantNull, + SpvOpTypeVoid, + SpvOpTypeBool, + SpvOpTypeInt, + SpvOpTypeFloat, + SpvOpTypeVector, + SpvOpTypeMatrix, + SpvOpTypeImage, + SpvOpTypeSampler, + SpvOpTypeSampledImage, + SpvOpTypeAccelerationStructureNV, + SpvOpTypeAccelerationStructureKHR, + SpvOpTypeRayQueryKHR, + SpvOpTypeArray, + SpvOpTypeRuntimeArray, + SpvOpTypeStruct, + SpvOpTypeOpaque, + SpvOpTypePointer, + SpvOpTypeFunction, + SpvOpTypeEvent, + SpvOpTypeDeviceEvent, + SpvOpTypeReserveId, + SpvOpTypeQueue, + SpvOpTypePipe, + SpvOpTypeForwardPointer, + SpvOpVariable, + SpvOpImageTexelPointer, + SpvOpLoad, + SpvOpAccessChain, + SpvOpInBoundsAccessChain, + SpvOpArrayLength, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeConstruct, + SpvOpCompositeExtract, + SpvOpCompositeInsert, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpSampledImage, + SpvOpImageSampleImplicitLod, + SpvOpImageSampleExplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageFetch, + SpvOpImageGather, + SpvOpImageDrefGather, + SpvOpImageRead, + SpvOpImage, + SpvOpImageQueryFormat, + SpvOpImageQueryOrder, + SpvOpImageQuerySizeLod, + SpvOpImageQuerySize, + SpvOpImageQueryLevels, + SpvOpImageQuerySamples, + SpvOpConvertFToU, + SpvOpConvertFToS, + SpvOpConvertSToF, + SpvOpConvertUToF, + SpvOpUConvert, + SpvOpSConvert, + SpvOpFConvert, + SpvOpQuantizeToF16, + SpvOpBitcast, + SpvOpSNegate, + SpvOpFNegate, + SpvOpIAdd, + SpvOpFAdd, + SpvOpISub, + SpvOpFSub, + SpvOpIMul, + SpvOpFMul, + SpvOpUDiv, + SpvOpSDiv, + SpvOpFDiv, + SpvOpUMod, + SpvOpSRem, + SpvOpSMod, + SpvOpFRem, + SpvOpFMod, + SpvOpVectorTimesScalar, + SpvOpMatrixTimesScalar, + SpvOpVectorTimesMatrix, + SpvOpMatrixTimesVector, + SpvOpMatrixTimesMatrix, + SpvOpOuterProduct, + SpvOpDot, + SpvOpIAddCarry, + SpvOpISubBorrow, + SpvOpUMulExtended, + SpvOpSMulExtended, + SpvOpAny, + SpvOpAll, + SpvOpIsNan, + SpvOpIsInf, + SpvOpLogicalEqual, + SpvOpLogicalNotEqual, + SpvOpLogicalOr, + SpvOpLogicalAnd, + SpvOpLogicalNot, + SpvOpSelect, + SpvOpIEqual, + SpvOpINotEqual, + SpvOpUGreaterThan, + SpvOpSGreaterThan, + SpvOpUGreaterThanEqual, + SpvOpSGreaterThanEqual, + SpvOpULessThan, + SpvOpSLessThan, + SpvOpULessThanEqual, + SpvOpSLessThanEqual, + SpvOpFOrdEqual, + SpvOpFUnordEqual, + SpvOpFOrdNotEqual, + SpvOpFUnordNotEqual, + SpvOpFOrdLessThan, + SpvOpFUnordLessThan, + SpvOpFOrdGreaterThan, + SpvOpFUnordGreaterThan, + SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpFUnordGreaterThanEqual, + SpvOpShiftRightLogical, + SpvOpShiftRightArithmetic, + SpvOpShiftLeftLogical, + SpvOpBitwiseOr, + SpvOpBitwiseXor, + SpvOpBitwiseAnd, + SpvOpNot, + SpvOpBitFieldInsert, + SpvOpBitFieldSExtract, + SpvOpBitFieldUExtract, + SpvOpBitReverse, + SpvOpBitCount, + SpvOpPhi, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleExplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseFetch, + SpvOpImageSparseGather, + SpvOpImageSparseDrefGather, + SpvOpImageSparseTexelsResident, + SpvOpImageSparseRead, + SpvOpSizeOf}); } } void IRContext::AddCombinatorsForExtension(Instruction* extension) { - assert(extension->opcode() == spv::Op::OpExtInstImport && + assert(extension->opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = extension->GetInOperand(0).AsString(); if (extension_name == "GLSL.std.450") { - combinator_ops_[extension->result_id()] = { - (uint32_t)GLSLstd450Round, - (uint32_t)GLSLstd450RoundEven, - (uint32_t)GLSLstd450Trunc, - (uint32_t)GLSLstd450FAbs, - (uint32_t)GLSLstd450SAbs, - (uint32_t)GLSLstd450FSign, - (uint32_t)GLSLstd450SSign, - (uint32_t)GLSLstd450Floor, - (uint32_t)GLSLstd450Ceil, - (uint32_t)GLSLstd450Fract, - (uint32_t)GLSLstd450Radians, - (uint32_t)GLSLstd450Degrees, - (uint32_t)GLSLstd450Sin, - (uint32_t)GLSLstd450Cos, - (uint32_t)GLSLstd450Tan, - (uint32_t)GLSLstd450Asin, - (uint32_t)GLSLstd450Acos, - (uint32_t)GLSLstd450Atan, - (uint32_t)GLSLstd450Sinh, - (uint32_t)GLSLstd450Cosh, - (uint32_t)GLSLstd450Tanh, - (uint32_t)GLSLstd450Asinh, - (uint32_t)GLSLstd450Acosh, - (uint32_t)GLSLstd450Atanh, - (uint32_t)GLSLstd450Atan2, - (uint32_t)GLSLstd450Pow, - (uint32_t)GLSLstd450Exp, - (uint32_t)GLSLstd450Log, - (uint32_t)GLSLstd450Exp2, - (uint32_t)GLSLstd450Log2, - (uint32_t)GLSLstd450Sqrt, - (uint32_t)GLSLstd450InverseSqrt, - (uint32_t)GLSLstd450Determinant, - (uint32_t)GLSLstd450MatrixInverse, - (uint32_t)GLSLstd450ModfStruct, - (uint32_t)GLSLstd450FMin, - (uint32_t)GLSLstd450UMin, - (uint32_t)GLSLstd450SMin, - (uint32_t)GLSLstd450FMax, - (uint32_t)GLSLstd450UMax, - (uint32_t)GLSLstd450SMax, - (uint32_t)GLSLstd450FClamp, - (uint32_t)GLSLstd450UClamp, - (uint32_t)GLSLstd450SClamp, - (uint32_t)GLSLstd450FMix, - (uint32_t)GLSLstd450IMix, - (uint32_t)GLSLstd450Step, - (uint32_t)GLSLstd450SmoothStep, - (uint32_t)GLSLstd450Fma, - (uint32_t)GLSLstd450FrexpStruct, - (uint32_t)GLSLstd450Ldexp, - (uint32_t)GLSLstd450PackSnorm4x8, - (uint32_t)GLSLstd450PackUnorm4x8, - (uint32_t)GLSLstd450PackSnorm2x16, - (uint32_t)GLSLstd450PackUnorm2x16, - (uint32_t)GLSLstd450PackHalf2x16, - (uint32_t)GLSLstd450PackDouble2x32, - (uint32_t)GLSLstd450UnpackSnorm2x16, - (uint32_t)GLSLstd450UnpackUnorm2x16, - (uint32_t)GLSLstd450UnpackHalf2x16, - (uint32_t)GLSLstd450UnpackSnorm4x8, - (uint32_t)GLSLstd450UnpackUnorm4x8, - (uint32_t)GLSLstd450UnpackDouble2x32, - (uint32_t)GLSLstd450Length, - (uint32_t)GLSLstd450Distance, - (uint32_t)GLSLstd450Cross, - (uint32_t)GLSLstd450Normalize, - (uint32_t)GLSLstd450FaceForward, - (uint32_t)GLSLstd450Reflect, - (uint32_t)GLSLstd450Refract, - (uint32_t)GLSLstd450FindILsb, - (uint32_t)GLSLstd450FindSMsb, - (uint32_t)GLSLstd450FindUMsb, - (uint32_t)GLSLstd450InterpolateAtCentroid, - (uint32_t)GLSLstd450InterpolateAtSample, - (uint32_t)GLSLstd450InterpolateAtOffset, - (uint32_t)GLSLstd450NMin, - (uint32_t)GLSLstd450NMax, - (uint32_t)GLSLstd450NClamp}; + combinator_ops_[extension->result_id()] = {GLSLstd450Round, + GLSLstd450RoundEven, + GLSLstd450Trunc, + GLSLstd450FAbs, + GLSLstd450SAbs, + GLSLstd450FSign, + GLSLstd450SSign, + GLSLstd450Floor, + GLSLstd450Ceil, + GLSLstd450Fract, + GLSLstd450Radians, + GLSLstd450Degrees, + GLSLstd450Sin, + GLSLstd450Cos, + GLSLstd450Tan, + GLSLstd450Asin, + GLSLstd450Acos, + GLSLstd450Atan, + GLSLstd450Sinh, + GLSLstd450Cosh, + GLSLstd450Tanh, + GLSLstd450Asinh, + GLSLstd450Acosh, + GLSLstd450Atanh, + GLSLstd450Atan2, + GLSLstd450Pow, + GLSLstd450Exp, + GLSLstd450Log, + GLSLstd450Exp2, + GLSLstd450Log2, + GLSLstd450Sqrt, + GLSLstd450InverseSqrt, + GLSLstd450Determinant, + GLSLstd450MatrixInverse, + GLSLstd450ModfStruct, + GLSLstd450FMin, + GLSLstd450UMin, + GLSLstd450SMin, + GLSLstd450FMax, + GLSLstd450UMax, + GLSLstd450SMax, + GLSLstd450FClamp, + GLSLstd450UClamp, + GLSLstd450SClamp, + GLSLstd450FMix, + GLSLstd450IMix, + GLSLstd450Step, + GLSLstd450SmoothStep, + GLSLstd450Fma, + GLSLstd450FrexpStruct, + GLSLstd450Ldexp, + GLSLstd450PackSnorm4x8, + GLSLstd450PackUnorm4x8, + GLSLstd450PackSnorm2x16, + GLSLstd450PackUnorm2x16, + GLSLstd450PackHalf2x16, + GLSLstd450PackDouble2x32, + GLSLstd450UnpackSnorm2x16, + GLSLstd450UnpackUnorm2x16, + GLSLstd450UnpackHalf2x16, + GLSLstd450UnpackSnorm4x8, + GLSLstd450UnpackUnorm4x8, + GLSLstd450UnpackDouble2x32, + GLSLstd450Length, + GLSLstd450Distance, + GLSLstd450Cross, + GLSLstd450Normalize, + GLSLstd450FaceForward, + GLSLstd450Reflect, + GLSLstd450Refract, + GLSLstd450FindILsb, + GLSLstd450FindSMsb, + GLSLstd450FindUMsb, + GLSLstd450InterpolateAtCentroid, + GLSLstd450InterpolateAtSample, + GLSLstd450InterpolateAtOffset, + GLSLstd450NMin, + GLSLstd450NMax, + GLSLstd450NClamp}; } else { // Map the result id to the empty set. combinator_ops_[extension->result_id()]; @@ -770,9 +713,8 @@ void IRContext::AddCombinatorsForExtension(Instruction* extension) { } void IRContext::InitializeCombinators() { - for (auto capability : get_feature_mgr()->GetCapabilities()) { - AddCombinatorsForCapability(uint32_t(capability)); - } + get_feature_mgr()->GetCapabilities()->ForEach( + [this](SpvCapability cap) { AddCombinatorsForCapability(cap); }); for (auto& extension : module()->ext_inst_imports()) { AddCombinatorsForExtension(&extension); @@ -782,8 +724,8 @@ void IRContext::InitializeCombinators() { } void IRContext::RemoveFromIdToName(const Instruction* inst) { - if (id_to_name_ && (inst->opcode() == spv::Op::OpName || - inst->opcode() == spv::Op::OpMemberName)) { + if (id_to_name_ && + (inst->opcode() == SpvOpName || inst->opcode() == SpvOpMemberName)) { auto range = id_to_name_->equal_range(inst->GetSingleWordInOperand(0)); for (auto it = range.first; it != range.second; ++it) { if (it->second == inst) { @@ -812,17 +754,15 @@ LoopDescriptor* IRContext::GetLoopDescriptor(const Function* f) { uint32_t IRContext::FindBuiltinInputVar(uint32_t builtin) { for (auto& a : module_->annotations()) { - if (spv::Op(a.opcode()) != spv::Op::OpDecorate) continue; - if (spv::Decoration(a.GetSingleWordInOperand( - kSpvDecorateDecorationInIdx)) != spv::Decoration::BuiltIn) + if (a.opcode() != SpvOpDecorate) continue; + if (a.GetSingleWordInOperand(kSpvDecorateDecorationInIdx) != + SpvDecorationBuiltIn) continue; if (a.GetSingleWordInOperand(kSpvDecorateBuiltinInIdx) != builtin) continue; uint32_t target_id = a.GetSingleWordInOperand(kSpvDecorateTargetIdInIdx); Instruction* b_var = get_def_use_mgr()->GetDef(target_id); - if (b_var->opcode() != spv::Op::OpVariable) continue; - if (spv::StorageClass(b_var->GetSingleWordInOperand(0)) != - spv::StorageClass::Input) - continue; + if (b_var->opcode() != SpvOpVariable) continue; + if (b_var->GetSingleWordInOperand(0) != SpvStorageClassInput) continue; return target_id; } return 0; @@ -858,39 +798,39 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { // TODO(greg-lunarg): Add support for all builtins analysis::TypeManager* type_mgr = get_type_mgr(); analysis::Type* reg_type; - switch (spv::BuiltIn(builtin)) { - case spv::BuiltIn::FragCoord: { + switch (builtin) { + case SpvBuiltInFragCoord: { analysis::Float float_ty(32); analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); analysis::Vector v4float_ty(reg_float_ty, 4); reg_type = type_mgr->GetRegisteredType(&v4float_ty); break; } - case spv::BuiltIn::VertexIndex: - case spv::BuiltIn::InstanceIndex: - case spv::BuiltIn::PrimitiveId: - case spv::BuiltIn::InvocationId: - case spv::BuiltIn::SubgroupLocalInvocationId: { + case SpvBuiltInVertexIndex: + case SpvBuiltInInstanceIndex: + case SpvBuiltInPrimitiveId: + case SpvBuiltInInvocationId: + case SpvBuiltInSubgroupLocalInvocationId: { analysis::Integer uint_ty(32, false); reg_type = type_mgr->GetRegisteredType(&uint_ty); break; } - case spv::BuiltIn::GlobalInvocationId: - case spv::BuiltIn::LaunchIdNV: { + case SpvBuiltInGlobalInvocationId: + case SpvBuiltInLaunchIdNV: { analysis::Integer uint_ty(32, false); analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); analysis::Vector v3uint_ty(reg_uint_ty, 3); reg_type = type_mgr->GetRegisteredType(&v3uint_ty); break; } - case spv::BuiltIn::TessCoord: { + case SpvBuiltInTessCoord: { analysis::Float float_ty(32); analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty); analysis::Vector v3float_ty(reg_float_ty, 3); reg_type = type_mgr->GetRegisteredType(&v3float_ty); break; } - case spv::BuiltIn::SubgroupLtMask: { + case SpvBuiltInSubgroupLtMask: { analysis::Integer uint_ty(32, false); analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty); analysis::Vector v4uint_ty(reg_uint_ty, 4); @@ -904,17 +844,17 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { } uint32_t type_id = type_mgr->GetTypeInstruction(reg_type); uint32_t varTyPtrId = - type_mgr->FindPointerToType(type_id, spv::StorageClass::Input); + type_mgr->FindPointerToType(type_id, SpvStorageClassInput); // TODO(1841): Handle id overflow. var_id = TakeNextId(); std::unique_ptr newVarOp( - new Instruction(this, spv::Op::OpVariable, varTyPtrId, var_id, + new Instruction(this, SpvOpVariable, varTyPtrId, var_id, {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::StorageClass::Input)}}})); + {SpvStorageClassInput}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newVarOp); module()->AddGlobalValue(std::move(newVarOp)); - get_decoration_mgr()->AddDecorationVal( - var_id, uint32_t(spv::Decoration::BuiltIn), builtin); + get_decoration_mgr()->AddDecorationVal(var_id, SpvDecorationBuiltIn, + builtin); AddVarToEntryPoints(var_id); } builtin_var_id_map_[builtin] = var_id; @@ -924,7 +864,7 @@ uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) { void IRContext::AddCalls(const Function* func, std::queue* todo) { for (auto bi = func->begin(); bi != func->end(); ++bi) for (auto ii = bi->begin(); ii != bi->end(); ++ii) - if (ii->opcode() == spv::Op::OpFunctionCall) + if (ii->opcode() == SpvOpFunctionCall) todo->push(ii->GetSingleWordInOperand(0)); } @@ -949,12 +889,12 @@ bool IRContext::ProcessReachableCallTree(ProcessFunction& pfn) { for (auto& a : annotations()) { // TODO: Handle group decorations as well. Currently not generate by any // front-end, but could be coming. - if (a.opcode() == spv::Op::OpDecorate) { - if (spv::Decoration(a.GetSingleWordOperand(1)) == - spv::Decoration::LinkageAttributes) { + if (a.opcode() == SpvOp::SpvOpDecorate) { + if (a.GetSingleWordOperand(1) == + SpvDecoration::SpvDecorationLinkageAttributes) { uint32_t lastOperand = a.NumOperands() - 1; - if (spv::LinkageType(a.GetSingleWordOperand(lastOperand)) == - spv::LinkageType::Export) { + if (a.GetSingleWordOperand(lastOperand) == + SpvLinkageType::SpvLinkageTypeExport) { uint32_t id = a.GetSingleWordOperand(0); if (GetFunction(id)) { roots.push(id); @@ -1118,26 +1058,5 @@ bool IRContext::IsReachable(const opt::BasicBlock& bb) { return GetDominatorAnalysis(enclosing_function) ->Dominates(enclosing_function->entry().get(), &bb); } - -spv::ExecutionModel IRContext::GetStage() { - const auto& entry_points = module()->entry_points(); - if (entry_points.empty()) { - return spv::ExecutionModel::Max; - } - - uint32_t stage = entry_points.begin()->GetSingleWordInOperand( - kEntryPointExecutionModelInIdx); - auto it = std::find_if( - entry_points.begin(), entry_points.end(), [stage](const Instruction& x) { - return x.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) != - stage; - }); - if (it != entry_points.end()) { - EmitErrorMessage("Mixed stage shader module not supported", &(*it)); - } - - return static_cast(stage); -} - } // namespace opt } // namespace spvtools diff --git a/source/opt/ir_context.h b/source/opt/ir_context.h index de3c4106..2f27942b 100644 --- a/source/opt/ir_context.h +++ b/source/opt/ir_context.h @@ -27,7 +27,6 @@ #include #include "source/assembly_grammar.h" -#include "source/enum_string_mapping.h" #include "source/opt/cfg.h" #include "source/opt/constants.h" #include "source/opt/debug_info_manager.h" @@ -36,7 +35,6 @@ #include "source/opt/dominator_analysis.h" #include "source/opt/feature_manager.h" #include "source/opt/fold.h" -#include "source/opt/liveness.h" #include "source/opt/loop_descriptor.h" #include "source/opt/module.h" #include "source/opt/register_pressure.h" @@ -83,7 +81,6 @@ class IRContext { kAnalysisConstants = 1 << 14, kAnalysisTypes = 1 << 15, kAnalysisDebugInfo = 1 << 16, - kAnalysisLiveness = 1 << 17, kAnalysisEnd = 1 << 17 }; @@ -154,19 +151,13 @@ class IRContext { inline IteratorRange capabilities(); inline IteratorRange capabilities() const; - // Iterators for extensions instructions contained in this module. - inline Module::inst_iterator extension_begin(); - inline Module::inst_iterator extension_end(); - inline IteratorRange extensions(); - inline IteratorRange extensions() const; - // Iterators for types, constants and global variables instructions. inline Module::inst_iterator types_values_begin(); inline Module::inst_iterator types_values_end(); inline IteratorRange types_values(); inline IteratorRange types_values() const; - // Iterators for ext_inst import instructions contained in this module. + // Iterators for extension instructions contained in this module. inline Module::inst_iterator ext_inst_import_begin(); inline Module::inst_iterator ext_inst_import_end(); inline IteratorRange ext_inst_imports(); @@ -210,20 +201,13 @@ class IRContext { inline IteratorRange ext_inst_debuginfo() const; // Add |capability| to the module, if it is not already enabled. - inline void AddCapability(spv::Capability capability); + inline void AddCapability(SpvCapability capability); + // Appends a capability instruction to this module. inline void AddCapability(std::unique_ptr&& c); - // Removes instruction declaring `capability` from this module. - // Returns true if the capability was removed, false otherwise. - bool RemoveCapability(spv::Capability capability); - // Appends an extension instruction to this module. inline void AddExtension(const std::string& ext_name); inline void AddExtension(std::unique_ptr&& e); - // Removes instruction declaring `extension` from this module. - // Returns true if the extension was removed, false otherwise. - bool RemoveExtension(Extension extension); - // Appends an extended instruction set instruction to this module. inline void AddExtInstImport(const std::string& name); inline void AddExtInstImport(std::unique_ptr&& e); @@ -252,8 +236,6 @@ class IRContext { inline void AddType(std::unique_ptr&& t); // Appends a constant, global variable, or OpUndef instruction to this module. inline void AddGlobalValue(std::unique_ptr&& v); - // Prepends a function declaration to this module. - inline void AddFunctionDeclaration(std::unique_ptr&& f); // Appends a function to this module. inline void AddFunction(std::unique_ptr&& f); @@ -266,15 +248,6 @@ class IRContext { return def_use_mgr_.get(); } - // Returns a pointer to a liveness manager. If the liveness manager is - // invalid, it is rebuilt first. - analysis::LivenessManager* get_liveness_mgr() { - if (!AreAnalysesValid(kAnalysisLiveness)) { - BuildLivenessManager(); - } - return liveness_mgr_.get(); - } - // Returns a pointer to a value number table. If the liveness analysis is // invalid, it is rebuilt first. ValueNumberTable* GetValueNumberTable() { @@ -394,11 +367,6 @@ class IRContext { // having more than one name. This method returns the first one it finds. inline Instruction* GetMemberName(uint32_t struct_type_id, uint32_t index); - // Copy names from |old_id| to |new_id|. Only copy member name if index is - // less than |max_member_index|. - inline void CloneNames(const uint32_t old_id, const uint32_t new_id, - const uint32_t max_member_index = UINT32_MAX); - // Sets the message consumer to the given |consumer|. |consumer| which will be // invoked every time there is a message to be communicated to the outside. void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); } @@ -438,15 +406,6 @@ class IRContext { // instruction exists. Instruction* KillInst(Instruction* inst); - // Deletes all the instruction in the range [`begin`; `end`[, for which the - // unary predicate `condition` returned true. - // Returns true if at least one instruction was removed, false otherwise. - // - // Pointer and iterator pointing to the deleted instructions become invalid. - // However other pointers and iterators are still valid. - bool KillInstructionIf(Module::inst_iterator begin, Module::inst_iterator end, - std::function condition); - // Collects the non-semantic instruction tree that uses |inst|'s result id // to be killed later. void CollectNonSemanticTree(Instruction* inst, @@ -516,14 +475,14 @@ class IRContext { if (!AreAnalysesValid(kAnalysisCombinators)) { InitializeCombinators(); } - constexpr uint32_t kExtInstSetIdInIndx = 0; - constexpr uint32_t kExtInstInstructionInIndx = 1; + const uint32_t kExtInstSetIdInIndx = 0; + const uint32_t kExtInstInstructionInIndx = 1; - if (inst->opcode() != spv::Op::OpExtInst) { - return combinator_ops_[0].count(uint32_t(inst->opcode())) != 0; + if (inst->opcode() != SpvOpExtInst) { + return combinator_ops_[0].count(inst->opcode()) != 0; } else { uint32_t set = inst->GetSingleWordInOperand(kExtInstSetIdInIndx); - auto op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); + uint32_t op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); return combinator_ops_[set].count(op) != 0; } } @@ -632,7 +591,7 @@ class IRContext { } Function* GetFunction(Instruction* inst) { - if (inst->opcode() != spv::Op::OpFunction) { + if (inst->opcode() != SpvOpFunction) { return nullptr; } return GetFunction(inst->result_id()); @@ -666,21 +625,6 @@ class IRContext { // the function that contains |bb|. bool IsReachable(const opt::BasicBlock& bb); - // Return the stage of the module. Will generate error if entry points don't - // all have the same stage. - spv::ExecutionModel GetStage(); - - // Returns true of the current target environment is at least that of the - // given environment. - bool IsTargetEnvAtLeast(spv_target_env env) { - // A bit of a hack. We assume that the target environments are appended to - // the enum, so that there is an appropriate order. - return syntax_context_->target_env >= env; - } - - // Return the target environment for the current context. - spv_target_env GetTargetEnv() const { return syntax_context_->target_env; } - private: // Builds the def-use manager from scratch, even if it was already valid. void BuildDefUseManager() { @@ -688,12 +632,6 @@ class IRContext { valid_analyses_ = valid_analyses_ | kAnalysisDefUse; } - // Builds the liveness manager from scratch, even if it was already valid. - void BuildLivenessManager() { - liveness_mgr_ = MakeUnique(this); - valid_analyses_ = valid_analyses_ | kAnalysisLiveness; - } - // Builds the instruction-block map for the whole module. void BuildInstrToBlockMapping() { instr_to_block_.clear(); @@ -797,8 +735,7 @@ class IRContext { // Analyzes the features in the owned module. Builds the manager if required. void AnalyzeFeatures() { - feature_mgr_ = - std::unique_ptr(new FeatureManager(grammar_)); + feature_mgr_ = MakeUnique(grammar_); feature_mgr_->Analyze(module()); } @@ -915,9 +852,6 @@ class IRContext { std::unique_ptr struct_cfg_analysis_; - // The liveness manager for |module_|. - std::unique_ptr liveness_mgr_; - // The maximum legal value for the id bound. uint32_t max_id_bound_; @@ -990,22 +924,6 @@ IteratorRange IRContext::capabilities() const { return ((const Module*)module())->capabilities(); } -Module::inst_iterator IRContext::extension_begin() { - return module()->extension_begin(); -} - -Module::inst_iterator IRContext::extension_end() { - return module()->extension_end(); -} - -IteratorRange IRContext::extensions() { - return module()->extensions(); -} - -IteratorRange IRContext::extensions() const { - return ((const Module*)module())->extensions(); -} - Module::inst_iterator IRContext::types_values_begin() { return module()->types_values_begin(); } @@ -1096,10 +1014,10 @@ IteratorRange IRContext::ext_inst_debuginfo() return ((const Module*)module_.get())->ext_inst_debuginfo(); } -void IRContext::AddCapability(spv::Capability capability) { +void IRContext::AddCapability(SpvCapability capability) { if (!get_feature_mgr()->HasCapability(capability)) { std::unique_ptr capability_inst(new Instruction( - this, spv::Op::OpCapability, 0, 0, + this, SpvOpCapability, 0, 0, {{SPV_OPERAND_TYPE_CAPABILITY, {static_cast(capability)}}})); AddCapability(std::move(capability_inst)); } @@ -1109,7 +1027,7 @@ void IRContext::AddCapability(std::unique_ptr&& c) { AddCombinatorsForCapability(c->GetSingleWordInOperand(0)); if (feature_mgr_ != nullptr) { feature_mgr_->AddCapability( - static_cast(c->GetSingleWordInOperand(0))); + static_cast(c->GetSingleWordInOperand(0))); } if (AreAnalysesValid(kAnalysisDefUse)) { get_def_use_mgr()->AnalyzeInstDefUse(c.get()); @@ -1120,7 +1038,7 @@ void IRContext::AddCapability(std::unique_ptr&& c) { void IRContext::AddExtension(const std::string& ext_name) { std::vector ext_words = spvtools::utils::MakeVector(ext_name); AddExtension(std::unique_ptr( - new Instruction(this, spv::Op::OpExtension, 0u, 0u, + new Instruction(this, SpvOpExtension, 0u, 0u, {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); } @@ -1137,7 +1055,7 @@ void IRContext::AddExtension(std::unique_ptr&& e) { void IRContext::AddExtInstImport(const std::string& name) { std::vector ext_words = spvtools::utils::MakeVector(name); AddExtInstImport(std::unique_ptr( - new Instruction(this, spv::Op::OpExtInstImport, 0u, TakeNextId(), + new Instruction(this, SpvOpExtInstImport, 0u, TakeNextId(), {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}}))); } @@ -1170,8 +1088,7 @@ void IRContext::AddDebug1Inst(std::unique_ptr&& d) { void IRContext::AddDebug2Inst(std::unique_ptr&& d) { if (AreAnalysesValid(kAnalysisNameMap)) { - if (d->opcode() == spv::Op::OpName || - d->opcode() == spv::Op::OpMemberName) { + if (d->opcode() == SpvOpName || d->opcode() == SpvOpMemberName) { // OpName and OpMemberName do not have result-ids. The target of the // instruction is at InOperand index 0. id_to_name_->insert({d->GetSingleWordInOperand(0), d.get()}); @@ -1215,10 +1132,6 @@ void IRContext::AddGlobalValue(std::unique_ptr&& v) { module()->AddGlobalValue(std::move(v)); } -void IRContext::AddFunctionDeclaration(std::unique_ptr&& f) { - module()->AddFunctionDeclaration(std::move(f)); -} - void IRContext::AddFunction(std::unique_ptr&& f) { module()->AddFunction(std::move(f)); } @@ -1238,8 +1151,8 @@ void IRContext::UpdateDefUse(Instruction* inst) { void IRContext::BuildIdToNameMap() { id_to_name_ = MakeUnique>(); for (Instruction& debug_inst : debugs2()) { - if (debug_inst.opcode() == spv::Op::OpMemberName || - debug_inst.opcode() == spv::Op::OpName) { + if (debug_inst.opcode() == SpvOpMemberName || + debug_inst.opcode() == SpvOpName) { id_to_name_->insert({debug_inst.GetSingleWordInOperand(0), &debug_inst}); } } @@ -1262,7 +1175,7 @@ Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) { auto result = id_to_name_->equal_range(struct_type_id); for (auto i = result.first; i != result.second; ++i) { auto* name_instr = i->second; - if (name_instr->opcode() == spv::Op::OpMemberName && + if (name_instr->opcode() == SpvOpMemberName && name_instr->GetSingleWordInOperand(1) == index) { return name_instr; } @@ -1270,25 +1183,6 @@ Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) { return nullptr; } -void IRContext::CloneNames(const uint32_t old_id, const uint32_t new_id, - const uint32_t max_member_index) { - std::vector> names_to_add; - auto names = GetNames(old_id); - for (auto n : names) { - Instruction* old_name_inst = n.second; - if (old_name_inst->opcode() == spv::Op::OpMemberName) { - auto midx = old_name_inst->GetSingleWordInOperand(1); - if (midx >= max_member_index) continue; - } - std::unique_ptr new_name_inst(old_name_inst->Clone(this)); - new_name_inst->SetInOperand(0, {new_id}); - names_to_add.push_back(std::move(new_name_inst)); - } - // We can't add the new names when we are iterating over name range above. - // We can add all the new names now. - for (auto& new_name : names_to_add) AddDebug2Inst(std::move(new_name)); -} - } // namespace opt } // namespace spvtools diff --git a/source/opt/ir_loader.cpp b/source/opt/ir_loader.cpp index e9b7bbfc..734ad554 100644 --- a/source/opt/ir_loader.cpp +++ b/source/opt/ir_loader.cpp @@ -24,13 +24,12 @@ #include "source/opt/reflect.h" #include "source/util/make_unique.h" +static const uint32_t kExtInstSetIndex = 4; +static const uint32_t kLexicalScopeIndex = 5; +static const uint32_t kInlinedAtIndex = 6; + namespace spvtools { namespace opt { -namespace { -constexpr uint32_t kExtInstSetIndex = 4; -constexpr uint32_t kLexicalScopeIndex = 5; -constexpr uint32_t kInlinedAtIndex = 6; -} // namespace IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) : consumer_(consumer), @@ -40,9 +39,9 @@ IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) last_dbg_scope_(kNoDebugScope, kNoInlinedAt) {} bool IsLineInst(const spv_parsed_instruction_t* inst) { - const auto opcode = static_cast(inst->opcode); + const auto opcode = static_cast(inst->opcode); if (IsOpLineInst(opcode)) return true; - if (opcode != spv::Op::OpExtInst) return false; + if (opcode != SpvOpExtInst) return false; if (inst->ext_inst_type != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) return false; const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; @@ -64,9 +63,8 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { // If it is a DebugScope or DebugNoScope of debug extension, we do not // create a new instruction, but simply keep the information in // struct DebugScope. - const auto opcode = static_cast(inst->opcode); - if (opcode == spv::Op::OpExtInst && - spvExtInstIsDebugInfo(inst->ext_inst_type)) { + const auto opcode = static_cast(inst->opcode); + if (opcode == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 || inst->ext_inst_type == @@ -132,13 +130,13 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { // Handle function and basic block boundaries first, then normal // instructions. - if (opcode == spv::Op::OpFunction) { + if (opcode == SpvOpFunction) { if (function_ != nullptr) { Error(consumer_, src, loc, "function inside function"); return false; } function_ = MakeUnique(std::move(spv_inst)); - } else if (opcode == spv::Op::OpFunctionEnd) { + } else if (opcode == SpvOpFunctionEnd) { if (function_ == nullptr) { Error(consumer_, src, loc, "OpFunctionEnd without corresponding OpFunction"); @@ -151,7 +149,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { function_->SetFunctionEnd(std::move(spv_inst)); module_->AddFunction(std::move(function_)); function_ = nullptr; - } else if (opcode == spv::Op::OpLabel) { + } else if (opcode == SpvOpLabel) { if (function_ == nullptr) { Error(consumer_, src, loc, "OpLabel outside function"); return false; @@ -181,20 +179,20 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { } else { if (function_ == nullptr) { // Outside function definition SPIRV_ASSERT(consumer_, block_ == nullptr); - if (opcode == spv::Op::OpCapability) { + if (opcode == SpvOpCapability) { module_->AddCapability(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtension) { + } else if (opcode == SpvOpExtension) { module_->AddExtension(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtInstImport) { + } else if (opcode == SpvOpExtInstImport) { module_->AddExtInstImport(std::move(spv_inst)); - } else if (opcode == spv::Op::OpMemoryModel) { + } else if (opcode == SpvOpMemoryModel) { module_->SetMemoryModel(std::move(spv_inst)); - } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { + } else if (opcode == SpvOpSamplerImageAddressingModeNV) { module_->SetSampledImageAddressMode(std::move(spv_inst)); - } else if (opcode == spv::Op::OpEntryPoint) { + } else if (opcode == SpvOpEntryPoint) { module_->AddEntryPoint(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExecutionMode || - opcode == spv::Op::OpExecutionModeId) { + } else if (opcode == SpvOpExecutionMode || + opcode == SpvOpExecutionModeId) { module_->AddExecutionMode(std::move(spv_inst)); } else if (IsDebug1Inst(opcode)) { module_->AddDebug1Inst(std::move(spv_inst)); @@ -206,13 +204,13 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { module_->AddAnnotationInst(std::move(spv_inst)); } else if (IsTypeInst(opcode)) { module_->AddType(std::move(spv_inst)); - } else if (IsConstantInst(opcode) || opcode == spv::Op::OpVariable || - opcode == spv::Op::OpUndef) { + } else if (IsConstantInst(opcode) || opcode == SpvOpVariable || + opcode == SpvOpUndef) { module_->AddGlobalValue(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtInst && + } else if (opcode == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { module_->AddExtInstDebugInfo(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtInst && + } else if (opcode == SpvOpExtInst && spvExtInstIsNonSemantic(inst->ext_inst_type)) { // If there are no functions, add the non-semantic instructions to the // global values. Otherwise append it to the list of the last function. @@ -231,11 +229,11 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { return false; } } else { - if (opcode == spv::Op::OpLoopMerge || opcode == spv::Op::OpSelectionMerge) + if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope) spv_inst->SetDebugScope(last_dbg_scope_); - if (opcode == spv::Op::OpExtInst && + if (opcode == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) { const uint32_t ext_inst_index = inst->words[kExtInstSetIndex]; if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) { @@ -324,7 +322,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { } } else { if (block_ == nullptr) { // Inside function but outside blocks - if (opcode != spv::Op::OpFunctionParameter) { + if (opcode != SpvOpFunctionParameter) { Errorf(consumer_, src, loc, "Non-OpFunctionParameter (opcode: %d) found inside " "function but outside basic block", diff --git a/source/opt/licm_pass.cpp b/source/opt/licm_pass.cpp index f2a6e4df..82851fd2 100644 --- a/source/opt/licm_pass.cpp +++ b/source/opt/licm_pass.cpp @@ -15,6 +15,7 @@ #include "source/opt/licm_pass.h" #include +#include #include "source/opt/module.h" #include "source/opt/pass.h" @@ -84,7 +85,7 @@ Pass::Status LICMPass::AnalyseAndHoistFromBB( bool modified = false; std::function hoist_inst = [this, &loop, &modified](Instruction* inst) { - if (loop->ShouldHoistInstruction(*inst)) { + if (loop->ShouldHoistInstruction(this->context(), inst)) { if (!HoistInstruction(loop, inst)) { return false; } @@ -125,8 +126,8 @@ bool LICMPass::HoistInstruction(Loop* loop, Instruction* inst) { } Instruction* insertion_point = &*pre_header_bb->tail(); Instruction* previous_node = insertion_point->PreviousNode(); - if (previous_node && (previous_node->opcode() == spv::Op::OpLoopMerge || - previous_node->opcode() == spv::Op::OpSelectionMerge)) { + if (previous_node && (previous_node->opcode() == SpvOpLoopMerge || + previous_node->opcode() == SpvOpSelectionMerge)) { insertion_point = previous_node; } diff --git a/source/opt/liveness.cpp b/source/opt/liveness.cpp deleted file mode 100755 index 336f3ae5..00000000 --- a/source/opt/liveness.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "source/opt/liveness.h" - -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { -namespace analysis { -namespace { -constexpr uint32_t kDecorationLocationInIdx = 2; -constexpr uint32_t kOpDecorateMemberMemberInIdx = 1; -constexpr uint32_t kOpDecorateMemberLocationInIdx = 3; -constexpr uint32_t kOpDecorateBuiltInLiteralInIdx = 2; -constexpr uint32_t kOpDecorateMemberBuiltInLiteralInIdx = 3; -} // namespace - -LivenessManager::LivenessManager(IRContext* ctx) : ctx_(ctx), computed_(false) { - // Liveness sets computed when queried -} - -void LivenessManager::InitializeAnalysis() { - live_locs_.clear(); - live_builtins_.clear(); - // Mark all builtins live for frag shader. - if (context()->GetStage() == spv::ExecutionModel::Fragment) { - live_builtins_.insert(uint32_t(spv::BuiltIn::PointSize)); - live_builtins_.insert(uint32_t(spv::BuiltIn::ClipDistance)); - live_builtins_.insert(uint32_t(spv::BuiltIn::CullDistance)); - } -} - -bool LivenessManager::IsAnalyzedBuiltin(uint32_t bi) { - // There are only three builtins that can be analyzed and removed between - // two stages: PointSize, ClipDistance and CullDistance. All others are - // always consumed implicitly by the downstream stage. - const auto builtin = spv::BuiltIn(bi); - return builtin == spv::BuiltIn::PointSize || - builtin == spv::BuiltIn::ClipDistance || - builtin == spv::BuiltIn::CullDistance; -} - -bool LivenessManager::AnalyzeBuiltIn(uint32_t id) { - auto deco_mgr = context()->get_decoration_mgr(); - bool saw_builtin = false; - // Analyze all builtin decorations of |id|. - (void)deco_mgr->ForEachDecoration( - id, uint32_t(spv::Decoration::BuiltIn), - [this, &saw_builtin](const Instruction& deco_inst) { - saw_builtin = true; - // No need to process builtins in frag shader. All assumed used. - if (context()->GetStage() == spv::ExecutionModel::Fragment) return; - uint32_t builtin = uint32_t(spv::BuiltIn::Max); - if (deco_inst.opcode() == spv::Op::OpDecorate) - builtin = - deco_inst.GetSingleWordInOperand(kOpDecorateBuiltInLiteralInIdx); - else if (deco_inst.opcode() == spv::Op::OpMemberDecorate) - builtin = deco_inst.GetSingleWordInOperand( - kOpDecorateMemberBuiltInLiteralInIdx); - else - assert(false && "unexpected decoration"); - if (IsAnalyzedBuiltin(builtin)) live_builtins_.insert(builtin); - }); - return saw_builtin; -} - -void LivenessManager::MarkLocsLive(uint32_t start, uint32_t count) { - auto finish = start + count; - for (uint32_t u = start; u < finish; ++u) { - live_locs_.insert(u); - } -} - -uint32_t LivenessManager::GetLocSize(const analysis::Type* type) const { - auto arr_type = type->AsArray(); - if (arr_type) { - auto comp_type = arr_type->element_type(); - auto len_info = arr_type->length_info(); - assert(len_info.words[0] == analysis::Array::LengthInfo::kConstant && - "unexpected array length"); - auto comp_len = len_info.words[1]; - return comp_len * GetLocSize(comp_type); - } - auto struct_type = type->AsStruct(); - if (struct_type) { - uint32_t size = 0u; - for (auto& el_type : struct_type->element_types()) - size += GetLocSize(el_type); - return size; - } - auto mat_type = type->AsMatrix(); - if (mat_type) { - auto cnt = mat_type->element_count(); - auto comp_type = mat_type->element_type(); - return cnt * GetLocSize(comp_type); - } - auto vec_type = type->AsVector(); - if (vec_type) { - auto comp_type = vec_type->element_type(); - if (comp_type->AsInteger()) return 1; - auto float_type = comp_type->AsFloat(); - assert(float_type && "unexpected vector component type"); - auto width = float_type->width(); - if (width == 32 || width == 16) return 1; - assert(width == 64 && "unexpected float type width"); - auto comp_cnt = vec_type->element_count(); - return (comp_cnt > 2) ? 2 : 1; - } - assert((type->AsInteger() || type->AsFloat()) && "unexpected input type"); - return 1; -} - -const analysis::Type* LivenessManager::GetComponentType( - uint32_t index, const analysis::Type* agg_type) const { - auto arr_type = agg_type->AsArray(); - if (arr_type) return arr_type->element_type(); - auto struct_type = agg_type->AsStruct(); - if (struct_type) return struct_type->element_types()[index]; - auto mat_type = agg_type->AsMatrix(); - if (mat_type) return mat_type->element_type(); - auto vec_type = agg_type->AsVector(); - assert(vec_type && "unexpected non-aggregate type"); - return vec_type->element_type(); -} - -uint32_t LivenessManager::GetLocOffset(uint32_t index, - const analysis::Type* agg_type) const { - auto arr_type = agg_type->AsArray(); - if (arr_type) return index * GetLocSize(arr_type->element_type()); - auto struct_type = agg_type->AsStruct(); - if (struct_type) { - uint32_t offset = 0u; - uint32_t cnt = 0u; - for (auto& el_type : struct_type->element_types()) { - if (cnt == index) break; - offset += GetLocSize(el_type); - ++cnt; - } - return offset; - } - auto mat_type = agg_type->AsMatrix(); - if (mat_type) return index * GetLocSize(mat_type->element_type()); - auto vec_type = agg_type->AsVector(); - assert(vec_type && "unexpected non-aggregate type"); - auto comp_type = vec_type->element_type(); - auto flt_type = comp_type->AsFloat(); - if (flt_type && flt_type->width() == 64u && index >= 2u) return 1; - return 0; -} - -void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, - const analysis::Type** curr_type, - uint32_t* offset, bool* no_loc, - bool is_patch, bool input) { - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); - // For tesc, tese and geom input variables, and tesc output variables, - // first array index does not contribute to offset. - auto stage = context()->GetStage(); - bool skip_first_index = false; - if ((input && (stage == spv::ExecutionModel::TessellationControl || - stage == spv::ExecutionModel::TessellationEvaluation || - stage == spv::ExecutionModel::Geometry)) || - (!input && stage == spv::ExecutionModel::TessellationControl)) - skip_first_index = !is_patch; - uint32_t ocnt = 0; - ac->WhileEachInOperand([this, &ocnt, def_use_mgr, type_mgr, deco_mgr, - curr_type, offset, no_loc, - skip_first_index](const uint32_t* opnd) { - if (ocnt >= 1) { - // Skip first index's contribution to offset if indicated - if (ocnt == 1 && skip_first_index) { - auto arr_type = (*curr_type)->AsArray(); - assert(arr_type && "unexpected wrapper type"); - *curr_type = arr_type->element_type(); - ocnt++; - return true; - } - // If any non-constant index, mark the entire current object and return. - auto idx_inst = def_use_mgr->GetDef(*opnd); - if (idx_inst->opcode() != spv::Op::OpConstant) return false; - // If current type is struct, look for location decoration on member and - // reset offset if found. - auto index = idx_inst->GetSingleWordInOperand(0); - auto str_type = (*curr_type)->AsStruct(); - if (str_type) { - uint32_t loc = 0; - auto str_type_id = type_mgr->GetId(str_type); - bool no_mem_loc = deco_mgr->WhileEachDecoration( - str_type_id, uint32_t(spv::Decoration::Location), - [&loc, index, no_loc](const Instruction& deco) { - assert(deco.opcode() == spv::Op::OpMemberDecorate && - "unexpected decoration"); - if (deco.GetSingleWordInOperand(kOpDecorateMemberMemberInIdx) == - index) { - loc = - deco.GetSingleWordInOperand(kOpDecorateMemberLocationInIdx); - *no_loc = false; - return false; - } - return true; - }); - if (!no_mem_loc) { - *offset = loc; - *curr_type = GetComponentType(index, *curr_type); - ocnt++; - return true; - } - } - - // Update offset and current type based on constant index. - *offset += GetLocOffset(index, *curr_type); - *curr_type = GetComponentType(index, *curr_type); - } - ocnt++; - return true; - }); -} - -void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); - // Find variable location if present. - uint32_t loc = 0; - auto var_id = var->result_id(); - bool no_loc = deco_mgr->WhileEachDecoration( - var_id, uint32_t(spv::Decoration::Location), - [&loc](const Instruction& deco) { - assert(deco.opcode() == spv::Op::OpDecorate && "unexpected decoration"); - loc = deco.GetSingleWordInOperand(kDecorationLocationInIdx); - return false; - }); - // Find patch decoration if present - bool is_patch = !deco_mgr->WhileEachDecoration( - var_id, uint32_t(spv::Decoration::Patch), [](const Instruction& deco) { - if (deco.opcode() != spv::Op::OpDecorate) - assert(false && "unexpected decoration"); - return false; - }); - // If use is a load, mark all locations of var - auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); - assert(ptr_type && "unexpected var type"); - auto var_type = ptr_type->pointee_type(); - if (ref->opcode() == spv::Op::OpLoad) { - assert(!no_loc && "missing input variable location"); - MarkLocsLive(loc, GetLocSize(var_type)); - return; - } - // Mark just those locations indicated by access chain - assert((ref->opcode() == spv::Op::OpAccessChain || - ref->opcode() == spv::Op::OpInBoundsAccessChain) && - "unexpected use of input variable"); - // Traverse access chain, compute location offset and type of reference - // through constant indices and mark those locs live. Assert if no location - // found. - uint32_t offset = loc; - auto curr_type = var_type; - AnalyzeAccessChainLoc(ref, &curr_type, &offset, &no_loc, is_patch); - assert(!no_loc && "missing input variable location"); - MarkLocsLive(offset, GetLocSize(curr_type)); -} - -void LivenessManager::ComputeLiveness() { - InitializeAnalysis(); - analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - // Process all input variables - for (auto& var : context()->types_values()) { - if (var.opcode() != spv::Op::OpVariable) { - continue; - } - analysis::Type* var_type = type_mgr->GetType(var.type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - if (ptr_type->storage_class() != spv::StorageClass::Input) { - continue; - } - // If var is builtin, mark live if analyzed and continue to next variable - auto var_id = var.result_id(); - if (AnalyzeBuiltIn(var_id)) continue; - // If interface block with builtin members, mark live if analyzed and - // continue to next variable. Input interface blocks will only appear - // in tesc, tese and geom shaders. Will need to strip off one level of - // arrayness to get to block type. - auto pte_type = ptr_type->pointee_type(); - auto arr_type = pte_type->AsArray(); - if (arr_type) { - auto elt_type = arr_type->element_type(); - auto str_type = elt_type->AsStruct(); - if (str_type) { - auto str_type_id = type_mgr->GetId(str_type); - if (AnalyzeBuiltIn(str_type_id)) continue; - } - } - // Mark all used locations of var live - def_use_mgr->ForEachUser(var_id, [this, &var](Instruction* user) { - auto op = user->opcode(); - if (op == spv::Op::OpEntryPoint || op == spv::Op::OpName || - op == spv::Op::OpDecorate || user->IsNonSemanticInstruction()) { - return; - } - MarkRefLive(user, &var); - }); - } -} - -void LivenessManager::GetLiveness(std::unordered_set* live_locs, - std::unordered_set* live_builtins) { - if (!computed_) { - ComputeLiveness(); - computed_ = true; - } - *live_locs = live_locs_; - *live_builtins = live_builtins_; -} - -} // namespace analysis -} // namespace opt -} // namespace spvtools diff --git a/source/opt/liveness.h b/source/opt/liveness.h deleted file mode 100755 index 7d8a9fb4..00000000 --- a/source/opt/liveness.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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. - -#ifndef SOURCE_OPT_LIVENESS_H_ -#define SOURCE_OPT_LIVENESS_H_ - -#include -#include - -namespace spvtools { -namespace opt { - -class IRContext; -class Instruction; - -namespace analysis { - -class Type; - -// This class represents the liveness of the input variables of a module -class LivenessManager { - public: - LivenessManager(IRContext* ctx); - - // Copy liveness info into |live_locs| and |builtin_locs|. - void GetLiveness(std::unordered_set* live_locs, - std::unordered_set* live_builtins); - - // Return true if builtin |bi| is being analyzed. - bool IsAnalyzedBuiltin(uint32_t bi); - - // Determine starting loc |offset| and the type |cur_type| of - // access chain |ac|. Set |no_loc| to true if no loc found. - // |is_patch| indicates if patch variable. |input| is true - // if input variable, otherwise output variable. - void AnalyzeAccessChainLoc(const Instruction* ac, - const analysis::Type** curr_type, uint32_t* offset, - bool* no_loc, bool is_patch, bool input = true); - - // Return size of |type_id| in units of locations - uint32_t GetLocSize(const analysis::Type* type) const; - - private: - IRContext* context() const { return ctx_; } - - // Initialize analysis - void InitializeAnalysis(); - - // Analyze |id| for builtin var and struct members. Return true if builtins - // found. - bool AnalyzeBuiltIn(uint32_t id); - - // Mark all live locations resulting from |user| of |var| at |loc|. - void MarkRefLive(const Instruction* user, Instruction* var); - - // Mark |count| locations starting at location |start|. - void MarkLocsLive(uint32_t start, uint32_t count); - - // Return type of component of aggregate type |agg_type| at |index| - const analysis::Type* GetComponentType(uint32_t index, - const analysis::Type* agg_type) const; - - // Return offset of |index| into aggregate type |agg_type| in units of - // input locations - uint32_t GetLocOffset(uint32_t index, const analysis::Type* agg_type) const; - - // Populate live_locs_ and live_builtins_ - void ComputeLiveness(); - - // IR context that owns this liveness manager. - IRContext* ctx_; - - // True if live_locs_ and live_builtins_ are computed - bool computed_; - - // Live locations - std::unordered_set live_locs_; - - // Live builtins - std::unordered_set live_builtins_; -}; - -} // namespace analysis -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_LIVENESS_H_ diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp index ea1bdeeb..d11682f3 100644 --- a/source/opt/local_access_chain_convert_pass.cpp +++ b/source/opt/local_access_chain_convert_pass.cpp @@ -16,19 +16,23 @@ #include "source/opt/local_access_chain_convert_pass.h" +#include "ir_builder.h" #include "ir_context.h" #include "iterator.h" #include "source/util/string_utils.h" namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kStoreValIdInIdx = 1; -constexpr uint32_t kAccessChainPtrIdInIdx = 0; -} // namespace + +const uint32_t kStoreValIdInIdx = 1; +const uint32_t kAccessChainPtrIdInIdx = 0; + +} // anonymous namespace void LocalAccessChainConvertPass::BuildAndAppendInst( - spv::Op opcode, uint32_t typeId, uint32_t resultId, + SpvOp opcode, uint32_t typeId, uint32_t resultId, const std::vector& in_opnds, std::vector>* newInsts) { std::unique_ptr newInst( @@ -47,9 +51,9 @@ uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad( *varId = ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx); const Instruction* varInst = get_def_use_mgr()->GetDef(*varId); - assert(varInst->opcode() == spv::Op::OpVariable); + assert(varInst->opcode() == SpvOpVariable); *varPteTypeId = GetPointeeTypeId(varInst); - BuildAndAppendInst(spv::Op::OpLoad, *varPteTypeId, ldResultId, + BuildAndAppendInst(SpvOpLoad, *varPteTypeId, ldResultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*varId}}}, newInsts); return ldResultId; @@ -104,8 +108,7 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad( new_inst[0]->UpdateDebugInfoFrom(original_load); context()->get_decoration_mgr()->CloneDecorations( - original_load->result_id(), ldResultId, - {spv::Decoration::RelaxedPrecision}); + original_load->result_id(), ldResultId, {SpvDecorationRelaxedPrecision}); original_load->InsertBefore(std::move(new_inst)); context()->get_debug_info_mgr()->AnalyzeDebugInst( original_load->PreviousNode()); @@ -120,7 +123,7 @@ bool LocalAccessChainConvertPass::ReplaceAccessChainLoad( new_operands.emplace_back( Operand({spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}})); AppendConstantOperands(address_inst, &new_operands); - original_load->SetOpcode(spv::Op::OpCompositeExtract); + original_load->SetOpcode(SpvOpCompositeExtract); original_load->ReplaceOperands(new_operands); context()->UpdateDefUse(original_load); return true; @@ -133,7 +136,7 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( // An access chain with no indices is essentially a copy. However, we still // have to create a new store because the old ones will be deleted. BuildAndAppendInst( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}}, @@ -151,7 +154,7 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( } context()->get_decoration_mgr()->CloneDecorations( - varId, ldResultId, {spv::Decoration::RelaxedPrecision}); + varId, ldResultId, {SpvDecorationRelaxedPrecision}); // Build and append Insert const uint32_t insResultId = TakeNextId(); @@ -162,14 +165,14 @@ bool LocalAccessChainConvertPass::GenAccessChainStoreReplacement( {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; AppendConstantOperands(ptrInst, &ins_in_opnds); - BuildAndAppendInst(spv::Op::OpCompositeInsert, varPteTypeId, insResultId, + BuildAndAppendInst(SpvOpCompositeInsert, varPteTypeId, insResultId, ins_in_opnds, newInsts); context()->get_decoration_mgr()->CloneDecorations( - varId, insResultId, {spv::Decoration::RelaxedPrecision}); + varId, insResultId, {SpvDecorationRelaxedPrecision}); // Build and append Store - BuildAndAppendInst(spv::Op::OpStore, 0, 0, + BuildAndAppendInst(SpvOpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, newInsts); @@ -182,7 +185,7 @@ bool LocalAccessChainConvertPass::Is32BitConstantIndexAccessChain( return acp->WhileEachInId([&inIdx, this](const uint32_t* tid) { if (inIdx > 0) { Instruction* opInst = get_def_use_mgr()->GetDef(*tid); - if (opInst->opcode() != spv::Op::OpConstant) return false; + if (opInst->opcode() != SpvOpConstant) return false; const auto* index = context()->get_constant_mgr()->GetConstantFromInst(opInst); int64_t index_value = index->GetSignExtendedValue(); @@ -201,13 +204,13 @@ bool LocalAccessChainConvertPass::HasOnlySupportedRefs(uint32_t ptrId) { user->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) { return true; } - spv::Op op = user->opcode(); - if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + SpvOp op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { if (!HasOnlySupportedRefs(user->result_id())) { return false; } - } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && - op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + } else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && + !IsNonTypeDecorate(op)) { return false; } return true; @@ -222,12 +225,12 @@ void LocalAccessChainConvertPass::FindTargetVars(Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case spv::Op::OpStore: - case spv::Op::OpLoad: { + case SpvOpStore: + case SpvOpLoad: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) break; - const spv::Op op = ptrInst->opcode(); + const SpvOp op = ptrInst->opcode(); // Rule out variables with non-supported refs eg function calls if (!HasOnlySupportedRefs(varId)) { seen_non_target_vars_.insert(varId); @@ -273,7 +276,7 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains( std::vector dead_instructions; for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case spv::Op::OpLoad: { + case SpvOpLoad: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; @@ -283,7 +286,7 @@ Pass::Status LocalAccessChainConvertPass::ConvertLocalAccessChains( } modified = true; } break; - case spv::Op::OpStore: { + case SpvOpStore: { uint32_t varId; Instruction* store = &*ii; Instruction* ptrInst = GetPtr(store, &varId); @@ -344,7 +347,7 @@ bool LocalAccessChainConvertPass::AllExtensionsSupported() const { // for the capability. This pass is only looking at function scope symbols, // so we do not care if there are variable pointers on storage buffers. if (context()->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointers)) + SpvCapabilityVariablePointers)) return false; // If any extension not in allowlist, return false for (auto& ei : get_module()->extensions()) { @@ -356,7 +359,7 @@ bool LocalAccessChainConvertPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == spv::Op::OpExtInstImport && + assert(inst.opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -372,8 +375,7 @@ Pass::Status LocalAccessChainConvertPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == spv::Op::OpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; @@ -397,39 +399,60 @@ Pass::Status LocalAccessChainConvertPass::Process() { void LocalAccessChainConvertPass::InitExtensions() { extensions_allowlist_.clear(); - extensions_allowlist_.insert( - {"SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", "SPV_KHR_8bit_storage", "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", "SPV_EXT_shader_stencil_export", - "SPV_EXT_shader_viewport_index_layer", - "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_fragment_mask", - "SPV_EXT_fragment_fully_covered", "SPV_AMD_gpu_shader_half_float_fetch", - "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", - "SPV_GOOGLE_user_type", "SPV_NV_shader_subgroup_partitioned", - "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", - "SPV_NV_fragment_shader_barycentric", - "SPV_NV_compute_shader_derivatives", "SPV_NV_shader_image_footprint", - "SPV_NV_shading_rate", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", - "SPV_KHR_ray_tracing", "SPV_KHR_ray_query", - "SPV_EXT_fragment_invocation_density", "SPV_KHR_terminate_invocation", - "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_integer_dot_product", - "SPV_EXT_shader_image_int64", "SPV_KHR_non_semantic_info", - "SPV_KHR_uniform_group_instructions", - "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_vulkan_memory_model", - "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock", - "SPV_NV_compute_shader_derivatives"}); + extensions_allowlist_.insert({ + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_GOOGLE_user_type", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_demote_to_helper_invocation", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + }); } bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds( diff --git a/source/opt/local_access_chain_convert_pass.h b/source/opt/local_access_chain_convert_pass.h index 0cda196f..c3731b1c 100644 --- a/source/opt/local_access_chain_convert_pass.h +++ b/source/opt/local_access_chain_convert_pass.h @@ -64,7 +64,7 @@ class LocalAccessChainConvertPass : public MemPass { // Build instruction from |opcode|, |typeId|, |resultId|, and |in_opnds|. // Append to |newInsts|. - void BuildAndAppendInst(spv::Op opcode, uint32_t typeId, uint32_t resultId, + void BuildAndAppendInst(SpvOp opcode, uint32_t typeId, uint32_t resultId, const std::vector& in_opnds, std::vector>* newInsts); diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp index 7502d049..a58e8e4c 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -18,13 +18,16 @@ #include +#include "source/opt/iterator.h" #include "source/util/string_utils.h" namespace spvtools { namespace opt { namespace { -constexpr uint32_t kStoreValIdInIdx = 1; -} // namespace + +const uint32_t kStoreValIdInIdx = 1; + +} // anonymous namespace bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; @@ -34,13 +37,13 @@ bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { dbg_op == CommonDebugInfoDebugValue) { return true; } - spv::Op op = user->opcode(); - if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + SpvOp op = user->opcode(); + if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { if (!HasOnlySupportedRefs(user->result_id())) { return false; } - } else if (op != spv::Op::OpStore && op != spv::Op::OpLoad && - op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + } else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && + !IsNonTypeDecorate(op)) { return false; } return true; @@ -65,7 +68,7 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( for (auto ii = next; ii != bi->end(); ii = next) { ++next; switch (ii->opcode()) { - case spv::Op::OpStore: { + case SpvOpStore: { // Verify store variable is target type uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); @@ -74,7 +77,7 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( // If a store to the whole variable, remember it for succeeding // loads and stores. Otherwise forget any previous store to that // variable. - if (ptrInst->opcode() == spv::Op::OpVariable) { + if (ptrInst->opcode() == SpvOpVariable) { // If a previous store to same variable, mark the store // for deletion if not still used. Don't delete store // if debugging; let ssa-rewrite and DCE handle it @@ -111,14 +114,14 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( var2load_.erase(varId); } } break; - case spv::Op::OpLoad: { + case SpvOpLoad: { // Verify store variable is target type uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) continue; if (!HasOnlySupportedRefs(varId)) continue; uint32_t replId = 0; - if (ptrInst->opcode() == spv::Op::OpVariable) { + if (ptrInst->opcode() == SpvOpVariable) { // If a load from a variable, look for a previous store or // load from that variable and use its value. auto si = var2store_.find(varId); @@ -143,11 +146,11 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( instructions_to_kill.push_back(&*ii); modified = true; } else { - if (ptrInst->opcode() == spv::Op::OpVariable) + if (ptrInst->opcode() == SpvOpVariable) var2load_[varId] = &*ii; // register load } } break; - case spv::Op::OpFunctionCall: { + case SpvOpFunctionCall: { // Conservatively assume all locals are redefined for now. // TODO(): Handle more optimally var2store_.clear(); @@ -189,7 +192,7 @@ bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == spv::Op::OpExtInstImport && + assert(inst.opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -202,15 +205,14 @@ bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() { // Assumes relaxed logical addressing only (see instruction.h). - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) return Status::SuccessWithoutChange; // Do not process if module contains OpGroupDecorate. Additional // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == spv::Op::OpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, // return unmodified. if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; @@ -233,64 +235,60 @@ Pass::Status LocalSingleBlockLoadStoreElimPass::Process() { void LocalSingleBlockLoadStoreElimPass::InitExtensions() { extensions_allowlist_.clear(); - extensions_allowlist_.insert({"SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_8bit_storage", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - "SPV_KHR_variable_pointers", - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", - "SPV_EXT_shader_stencil_export", - "SPV_EXT_shader_viewport_index_layer", - "SPV_AMD_shader_image_load_store_lod", - "SPV_AMD_shader_fragment_mask", - "SPV_EXT_fragment_fully_covered", - "SPV_AMD_gpu_shader_half_float_fetch", - "SPV_GOOGLE_decorate_string", - "SPV_GOOGLE_hlsl_functionality1", - "SPV_GOOGLE_user_type", - "SPV_NV_shader_subgroup_partitioned", - "SPV_EXT_demote_to_helper_invocation", - "SPV_EXT_descriptor_indexing", - "SPV_NV_fragment_shader_barycentric", - "SPV_NV_compute_shader_derivatives", - "SPV_NV_shader_image_footprint", - "SPV_NV_shading_rate", - "SPV_NV_mesh_shader", - "SPV_NV_ray_tracing", - "SPV_KHR_ray_tracing", - "SPV_KHR_ray_query", - "SPV_EXT_fragment_invocation_density", - "SPV_EXT_physical_storage_buffer", - "SPV_KHR_physical_storage_buffer", - "SPV_KHR_terminate_invocation", - "SPV_KHR_subgroup_uniform_control_flow", - "SPV_KHR_integer_dot_product", - "SPV_EXT_shader_image_int64", - "SPV_KHR_non_semantic_info", - "SPV_KHR_uniform_group_instructions", - "SPV_KHR_fragment_shader_barycentric", - "SPV_KHR_vulkan_memory_model", - "SPV_NV_bindless_texture", - "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock", - "SPV_NV_compute_shader_derivatives"}); + extensions_allowlist_.insert({ + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_GOOGLE_user_type", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_demote_to_helper_invocation", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_EXT_physical_storage_buffer", + "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + }); } } // namespace opt diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp index f6fc2760..81648c7b 100644 --- a/source/opt/local_single_store_elim_pass.cpp +++ b/source/opt/local_single_store_elim_pass.cpp @@ -17,14 +17,19 @@ #include "source/opt/local_single_store_elim_pass.h" #include "source/cfa.h" +#include "source/latest_version_glsl_std_450_header.h" +#include "source/opt/iterator.h" #include "source/util/string_utils.h" namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kStoreValIdInIdx = 1; -constexpr uint32_t kVariableInitIdInIdx = 1; -} // namespace + +const uint32_t kStoreValIdInIdx = 1; +const uint32_t kVariableInitIdInIdx = 1; + +} // anonymous namespace bool LocalSingleStoreElimPass::LocalSingleStoreElim(Function* func) { bool modified = false; @@ -32,7 +37,7 @@ bool LocalSingleStoreElimPass::LocalSingleStoreElim(Function* func) { // Check all function scope variables in |func|. BasicBlock* entry_block = &*func->begin(); for (Instruction& inst : *entry_block) { - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { break; } @@ -52,7 +57,7 @@ bool LocalSingleStoreElimPass::AllExtensionsSupported() const { // around unknown extended // instruction sets even if they are non-semantic for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == spv::Op::OpExtInstImport && + assert(inst.opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.") && @@ -65,7 +70,7 @@ bool LocalSingleStoreElimPass::AllExtensionsSupported() const { Pass::Status LocalSingleStoreElimPass::ProcessImpl() { // Assumes relaxed logical addressing only (see instruction.h) - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled @@ -86,61 +91,57 @@ Pass::Status LocalSingleStoreElimPass::Process() { } void LocalSingleStoreElimPass::InitExtensionAllowList() { - extensions_allowlist_.insert({"SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_8bit_storage", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - "SPV_KHR_variable_pointers", - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", - "SPV_EXT_shader_stencil_export", - "SPV_EXT_shader_viewport_index_layer", - "SPV_AMD_shader_image_load_store_lod", - "SPV_AMD_shader_fragment_mask", - "SPV_EXT_fragment_fully_covered", - "SPV_AMD_gpu_shader_half_float_fetch", - "SPV_GOOGLE_decorate_string", - "SPV_GOOGLE_hlsl_functionality1", - "SPV_NV_shader_subgroup_partitioned", - "SPV_EXT_descriptor_indexing", - "SPV_NV_fragment_shader_barycentric", - "SPV_NV_compute_shader_derivatives", - "SPV_NV_shader_image_footprint", - "SPV_NV_shading_rate", - "SPV_NV_mesh_shader", - "SPV_NV_ray_tracing", - "SPV_KHR_ray_query", - "SPV_EXT_fragment_invocation_density", - "SPV_EXT_physical_storage_buffer", - "SPV_KHR_physical_storage_buffer", - "SPV_KHR_terminate_invocation", - "SPV_KHR_subgroup_uniform_control_flow", - "SPV_KHR_integer_dot_product", - "SPV_EXT_shader_image_int64", - "SPV_KHR_non_semantic_info", - "SPV_KHR_uniform_group_instructions", - "SPV_KHR_fragment_shader_barycentric", - "SPV_KHR_vulkan_memory_model", - "SPV_NV_bindless_texture", - "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock", - "SPV_NV_compute_shader_derivatives"}); + extensions_allowlist_.insert({ + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_8bit_storage", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", + "SPV_EXT_shader_stencil_export", + "SPV_EXT_shader_viewport_index_layer", + "SPV_AMD_shader_image_load_store_lod", + "SPV_AMD_shader_fragment_mask", + "SPV_EXT_fragment_fully_covered", + "SPV_AMD_gpu_shader_half_float_fetch", + "SPV_GOOGLE_decorate_string", + "SPV_GOOGLE_hlsl_functionality1", + "SPV_NV_shader_subgroup_partitioned", + "SPV_EXT_descriptor_indexing", + "SPV_NV_fragment_shader_barycentric", + "SPV_NV_compute_shader_derivatives", + "SPV_NV_shader_image_footprint", + "SPV_NV_shading_rate", + "SPV_NV_mesh_shader", + "SPV_NV_ray_tracing", + "SPV_KHR_ray_query", + "SPV_EXT_fragment_invocation_density", + "SPV_EXT_physical_storage_buffer", + "SPV_KHR_terminate_invocation", + "SPV_KHR_subgroup_uniform_control_flow", + "SPV_KHR_integer_dot_product", + "SPV_EXT_shader_image_int64", + "SPV_KHR_non_semantic_info", + "SPV_KHR_uniform_group_instructions", + "SPV_KHR_fragment_shader_barycentric", + }); } bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) { std::vector users; @@ -193,7 +194,7 @@ Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( for (Instruction* user : users) { switch (user->opcode()) { - case spv::Op::OpStore: + case SpvOpStore: // Since we are in the relaxed addressing mode, the use has to be the // base address of the store, and not the value being store. Otherwise, // we would have a pointer to a pointer to function scope memory, which @@ -205,19 +206,19 @@ Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( return nullptr; } break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: if (FeedsAStore(user)) { // Has a partial store. Cannot propagate that. return nullptr; } break; - case spv::Op::OpLoad: - case spv::Op::OpImageTexelPointer: - case spv::Op::OpName: - case spv::Op::OpCopyObject: + case SpvOpLoad: + case SpvOpImageTexelPointer: + case SpvOpName: + case SpvOpCopyObject: break; - case spv::Op::OpExtInst: { + case SpvOpExtInst: { auto dbg_op = user->GetCommonDebugOpcode(); if (dbg_op == CommonDebugInfoDebugDeclare || dbg_op == CommonDebugInfoDebugValue) { @@ -242,7 +243,7 @@ void LocalSingleStoreElimPass::FindUses( analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); def_use_mgr->ForEachUser(var_inst, [users, this](Instruction* user) { users->push_back(user); - if (user->opcode() == spv::Op::OpCopyObject) { + if (user->opcode() == SpvOpCopyObject) { FindUses(user, users); } }); @@ -252,15 +253,15 @@ bool LocalSingleStoreElimPass::FeedsAStore(Instruction* inst) const { analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); return !def_use_mgr->WhileEachUser(inst, [this](Instruction* user) { switch (user->opcode()) { - case spv::Op::OpStore: + case SpvOpStore: return false; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpCopyObject: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpCopyObject: return !FeedsAStore(user); - case spv::Op::OpLoad: - case spv::Op::OpImageTexelPointer: - case spv::Op::OpName: + case SpvOpLoad: + case SpvOpImageTexelPointer: + case SpvOpName: return true; default: // Don't know if this instruction modifies the variable. @@ -278,7 +279,7 @@ bool LocalSingleStoreElimPass::RewriteLoads( context()->GetDominatorAnalysis(store_block->GetParent()); uint32_t stored_id; - if (store_inst->opcode() == spv::Op::OpStore) + if (store_inst->opcode() == SpvOpStore) stored_id = store_inst->GetSingleWordInOperand(kStoreValIdInIdx); else stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx); @@ -286,12 +287,12 @@ bool LocalSingleStoreElimPass::RewriteLoads( *all_rewritten = true; bool modified = false; for (Instruction* use : uses) { - if (use->opcode() == spv::Op::OpStore) continue; + if (use->opcode() == SpvOpStore) continue; auto dbg_op = use->GetCommonDebugOpcode(); if (dbg_op == CommonDebugInfoDebugDeclare || dbg_op == CommonDebugInfoDebugValue) continue; - if (use->opcode() == spv::Op::OpLoad && + if (use->opcode() == SpvOpLoad && dominator_analysis->Dominates(store_inst, use)) { modified = true; context()->KillNamesAndDecorates(use->result_id()); diff --git a/source/opt/log.h b/source/opt/log.h index 4fb66fd4..68051002 100644 --- a/source/opt/log.h +++ b/source/opt/log.h @@ -23,7 +23,7 @@ #include "spirv-tools/libspirv.hpp" // Asserts the given condition is true. Otherwise, sends a message to the -// consumer and exits the program with failure code. Accepts the following +// consumer and exits the problem with failure code. Accepts the following // formats: // // SPIRV_ASSERT(, ); @@ -36,9 +36,7 @@ #if !defined(NDEBUG) #define SPIRV_ASSERT(consumer, ...) SPIRV_ASSERT_IMPL(consumer, __VA_ARGS__) #else -// Adding a use to avoid errors in the release build related to unused -// consumers. -#define SPIRV_ASSERT(consumer, ...) (void)(consumer) +#define SPIRV_ASSERT(consumer, ...) #endif // Logs a debug message to the consumer. Accepts the following formats: @@ -51,11 +49,26 @@ #if !defined(NDEBUG) && defined(SPIRV_LOG_DEBUG) #define SPIRV_DEBUG(consumer, ...) SPIRV_DEBUG_IMPL(consumer, __VA_ARGS__) #else -// Adding a use to avoid errors in the release build related to unused -// consumers. -#define SPIRV_DEBUG(consumer, ...) (void)(consumer) +#define SPIRV_DEBUG(consumer, ...) #endif +// Logs an error message to the consumer saying the given feature is +// unimplemented. +#define SPIRV_UNIMPLEMENTED(consumer, feature) \ + do { \ + spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \ + {static_cast(__LINE__), 0, 0}, \ + "unimplemented: " feature); \ + } while (0) + +// Logs an error message to the consumer saying the code location +// should be unreachable. +#define SPIRV_UNREACHABLE(consumer) \ + do { \ + spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \ + {static_cast(__LINE__), 0, 0}, "unreachable"); \ + } while (0) + // Helper macros for concatenating arguments. #define SPIRV_CONCATENATE(a, b) SPIRV_CONCATENATE_(a, b) #define SPIRV_CONCATENATE_(a, b) a##b diff --git a/source/opt/loop_dependence.cpp b/source/opt/loop_dependence.cpp index e41c044a..d8de699b 100644 --- a/source/opt/loop_dependence.cpp +++ b/source/opt/loop_dependence.cpp @@ -15,12 +15,14 @@ #include "source/opt/loop_dependence.h" #include +#include #include #include #include #include #include "source/opt/instruction.h" +#include "source/opt/scalar_analysis.h" #include "source/opt/scalar_analysis_nodes.h" namespace spvtools { @@ -190,8 +192,8 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, Instruction* destination_access_chain = GetOperandDefinition(destination, 0); auto num_access_chains = - (source_access_chain->opcode() == spv::Op::OpAccessChain) + - (destination_access_chain->opcode() == spv::Op::OpAccessChain); + (source_access_chain->opcode() == SpvOpAccessChain) + + (destination_access_chain->opcode() == SpvOpAccessChain); // If neither is an access chain, then they are load/store to a variable. if (num_access_chains == 0) { @@ -209,8 +211,7 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, // If only one is an access chain, it could be accessing a part of a struct if (num_access_chains == 1) { - auto source_is_chain = - source_access_chain->opcode() == spv::Op::OpAccessChain; + auto source_is_chain = source_access_chain->opcode() == SpvOpAccessChain; auto access_chain = source_is_chain ? source_access_chain : destination_access_chain; auto variable = @@ -237,8 +238,8 @@ bool LoopDependenceAnalysis::GetDependence(const Instruction* source, GetOperandDefinition(destination_access_chain, 0); // Nested access chains are not supported yet, bail out. - if (source_array->opcode() == spv::Op::OpAccessChain || - destination_array->opcode() == spv::Op::OpAccessChain) { + if (source_array->opcode() == SpvOpAccessChain || + destination_array->opcode() == SpvOpAccessChain) { for (auto& entry : distance_vector->GetEntries()) { entry = DistanceEntry(); } diff --git a/source/opt/loop_dependence_helpers.cpp b/source/opt/loop_dependence_helpers.cpp index 5d7d9940..de27a0a7 100644 --- a/source/opt/loop_dependence_helpers.cpp +++ b/source/opt/loop_dependence_helpers.cpp @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "source/opt/loop_dependence.h" + #include #include #include @@ -21,7 +23,7 @@ #include "source/opt/basic_block.h" #include "source/opt/instruction.h" -#include "source/opt/loop_dependence.h" +#include "source/opt/scalar_analysis.h" #include "source/opt/scalar_analysis_nodes.h" namespace spvtools { @@ -52,20 +54,20 @@ SENode* LoopDependenceAnalysis::GetLowerBound(const Loop* loop) { } Instruction* lower_inst = GetOperandDefinition(cond_inst, 0); switch (cond_inst->opcode()) { - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: { + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: { // If we have a phi we are looking at the induction variable. We look // through the phi to the initial value of the phi upon entering the loop. - if (lower_inst->opcode() == spv::Op::OpPhi) { + if (lower_inst->opcode() == SpvOpPhi) { lower_inst = GetOperandDefinition(lower_inst, 0); // We don't handle looking through multiple phis. - if (lower_inst->opcode() == spv::Op::OpPhi) { + if (lower_inst->opcode() == SpvOpPhi) { return nullptr; } } @@ -84,8 +86,8 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { } Instruction* upper_inst = GetOperandDefinition(cond_inst, 1); switch (cond_inst->opcode()) { - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: { + case SpvOpULessThan: + case SpvOpSLessThan: { // When we have a < condition we must subtract 1 from the analyzed upper // instruction. SENode* upper_bound = scalar_evolution_.SimplifyExpression( @@ -94,8 +96,8 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { scalar_evolution_.CreateConstant(1))); return upper_bound; } - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: { + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: { // When we have a > condition we must add 1 to the analyzed upper // instruction. SENode* upper_bound = @@ -104,10 +106,10 @@ SENode* LoopDependenceAnalysis::GetUpperBound(const Loop* loop) { scalar_evolution_.CreateConstant(1))); return upper_bound; } - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: { + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: { // We don't need to modify the results of analyzing when we have <= or >=. SENode* upper_bound = scalar_evolution_.SimplifyExpression( scalar_evolution_.AnalyzeInstruction(upper_inst)); diff --git a/source/opt/loop_descriptor.cpp b/source/opt/loop_descriptor.cpp index cbfc2e75..13982d18 100644 --- a/source/opt/loop_descriptor.cpp +++ b/source/opt/loop_descriptor.cpp @@ -15,14 +15,17 @@ #include "source/opt/loop_descriptor.h" #include +#include #include #include +#include #include #include #include "source/opt/cfg.h" #include "source/opt/constants.h" #include "source/opt/dominator_tree.h" +#include "source/opt/ir_builder.h" #include "source/opt/ir_context.h" #include "source/opt/iterator.h" #include "source/opt/tree_iterator.h" @@ -36,7 +39,7 @@ namespace opt { Instruction* Loop::GetInductionStepOperation( const Instruction* induction) const { // Induction must be a phi instruction. - assert(induction->opcode() == spv::Op::OpPhi); + assert(induction->opcode() == SpvOpPhi); Instruction* step = nullptr; @@ -72,8 +75,8 @@ Instruction* Loop::GetInductionStepOperation( return nullptr; } - if (def_use_manager->GetDef(lhs)->opcode() != spv::Op::OpConstant && - def_use_manager->GetDef(rhs)->opcode() != spv::Op::OpConstant) { + if (def_use_manager->GetDef(lhs)->opcode() != SpvOp::SpvOpConstant && + def_use_manager->GetDef(rhs)->opcode() != SpvOp::SpvOpConstant) { return nullptr; } @@ -82,31 +85,31 @@ Instruction* Loop::GetInductionStepOperation( // Returns true if the |step| operation is an induction variable step operation // which is currently handled. -bool Loop::IsSupportedStepOp(spv::Op step) const { +bool Loop::IsSupportedStepOp(SpvOp step) const { switch (step) { - case spv::Op::OpISub: - case spv::Op::OpIAdd: + case SpvOp::SpvOpISub: + case SpvOp::SpvOpIAdd: return true; default: return false; } } -bool Loop::IsSupportedCondition(spv::Op condition) const { +bool Loop::IsSupportedCondition(SpvOp condition) const { switch (condition) { // < - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: + case SpvOp::SpvOpULessThan: + case SpvOp::SpvOpSLessThan: // > - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: + case SpvOp::SpvOpUGreaterThan: + case SpvOp::SpvOpSGreaterThan: // >= - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpUGreaterThanEqual: + case SpvOp::SpvOpSGreaterThanEqual: + case SpvOp::SpvOpUGreaterThanEqual: // <= - case spv::Op::OpSLessThanEqual: - case spv::Op::OpULessThanEqual: + case SpvOp::SpvOpSLessThanEqual: + case SpvOp::SpvOpULessThanEqual: return true; default: @@ -114,8 +117,7 @@ bool Loop::IsSupportedCondition(spv::Op condition) const { } } -int64_t Loop::GetResidualConditionValue(spv::Op condition, - int64_t initial_value, +int64_t Loop::GetResidualConditionValue(SpvOp condition, int64_t initial_value, int64_t step_value, size_t number_of_iterations, size_t factor) { @@ -126,13 +128,13 @@ int64_t Loop::GetResidualConditionValue(spv::Op condition, // loop where just less than or greater than. Adding or subtracting one should // give a functionally equivalent value. switch (condition) { - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpUGreaterThanEqual: { + case SpvOp::SpvOpSGreaterThanEqual: + case SpvOp::SpvOpUGreaterThanEqual: { remainder -= 1; break; } - case spv::Op::OpSLessThanEqual: - case spv::Op::OpULessThanEqual: { + case SpvOp::SpvOpSLessThanEqual: + case SpvOp::SpvOpULessThanEqual: { remainder += 1; break; } @@ -150,7 +152,7 @@ Instruction* Loop::GetConditionInst() const { } Instruction* branch_conditional = &*condition_block->tail(); if (!branch_conditional || - branch_conditional->opcode() != spv::Op::OpBranchConditional) { + branch_conditional->opcode() != SpvOpBranchConditional) { return nullptr; } Instruction* condition_inst = context_->get_def_use_mgr()->GetDef( @@ -316,7 +318,7 @@ void Loop::SetMergeBlock(BasicBlock* merge) { void Loop::SetPreHeaderBlock(BasicBlock* preheader) { if (preheader) { assert(!IsInsideLoop(preheader) && "The preheader block is in the loop"); - assert(preheader->tail()->opcode() == spv::Op::OpBranch && + assert(preheader->tail()->opcode() == SpvOpBranch && "The preheader block does not unconditionally branch to the header " "block"); assert(preheader->tail()->GetSingleWordOperand(0) == @@ -385,7 +387,7 @@ void Loop::GetMergingBlocks( namespace { -inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) { +static inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) { for (Instruction& inst : *bb) { if (!inst.IsBranch() && !context->IsCombinatorInstruction(&inst)) return false; @@ -441,7 +443,7 @@ bool Loop::IsLCSSA() const { BasicBlock* parent = ir_context->get_instr_block(use); assert(parent && "Invalid analysis"); if (IsInsideLoop(parent)) return true; - if (use->opcode() != spv::Op::OpPhi) return false; + if (use->opcode() != SpvOpPhi) return false; return exit_blocks.count(parent->id()); })) return false; @@ -450,20 +452,25 @@ bool Loop::IsLCSSA() const { return true; } -bool Loop::ShouldHoistInstruction(const Instruction& inst) const { - return inst.IsOpcodeCodeMotionSafe() && AreAllOperandsOutsideLoop(inst) && - (!inst.IsLoad() || inst.IsReadOnlyLoad()); +bool Loop::ShouldHoistInstruction(IRContext* context, Instruction* inst) { + return AreAllOperandsOutsideLoop(context, inst) && + inst->IsOpcodeCodeMotionSafe(); } -bool Loop::AreAllOperandsOutsideLoop(const Instruction& inst) const { - analysis::DefUseManager* def_use_mgr = GetContext()->get_def_use_mgr(); +bool Loop::AreAllOperandsOutsideLoop(IRContext* context, Instruction* inst) { + analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); + bool all_outside_loop = true; - const std::function operand_outside_loop = - [this, &def_use_mgr](const uint32_t* id) { - return !this->IsInsideLoop(def_use_mgr->GetDef(*id)); + const std::function operand_outside_loop = + [this, &def_use_mgr, &all_outside_loop](uint32_t* id) { + if (this->IsInsideLoop(def_use_mgr->GetDef(*id))) { + all_outside_loop = false; + return; + } }; - return inst.WhileEachInId(operand_outside_loop); + inst->ForEachInId(operand_outside_loop); + return all_outside_loop; } void Loop::ComputeLoopStructuredOrder( @@ -479,7 +486,7 @@ void Loop::ComputeLoopStructuredOrder( ordered_loop_blocks->push_back(loop_preheader_); bool is_shader = - context_->get_feature_mgr()->HasCapability(spv::Capability::Shader); + context_->get_feature_mgr()->HasCapability(SpvCapabilityShader); if (!is_shader) { cfg.ForEachBlockInReversePostOrder( loop_header_, [ordered_loop_blocks, this](BasicBlock* bb) { @@ -640,7 +647,7 @@ BasicBlock* Loop::FindConditionBlock() const { const Instruction& branch = *bb->ctail(); // Make sure the branch is a conditional branch. - if (branch.opcode() != spv::Op::OpBranchConditional) return nullptr; + if (branch.opcode() != SpvOpBranchConditional) return nullptr; // Make sure one of the two possible branches is to the merge block. if (branch.GetSingleWordInOperand(1) == loop_merge_->id() || @@ -709,7 +716,7 @@ bool Loop::FindNumberOfIterations(const Instruction* induction, } // If this is a subtraction step we should negate the step value. - if (step_inst->opcode() == spv::Op::OpISub) { + if (step_inst->opcode() == SpvOp::SpvOpISub) { step_value = -step_value; } @@ -746,7 +753,7 @@ bool Loop::FindNumberOfIterations(const Instruction* induction, // |step_value| where diff is calculated differently according to the // |condition| and uses the |condition_value| and |init_value|. If diff / // |step_value| is NOT cleanly divisible then we add one to the sum. -int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, +int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value, int64_t init_value, int64_t step_value) const { if (step_value == 0) { return 0; @@ -755,8 +762,8 @@ int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, int64_t diff = 0; switch (condition) { - case spv::Op::OpSLessThan: - case spv::Op::OpULessThan: { + case SpvOp::SpvOpSLessThan: + case SpvOp::SpvOpULessThan: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value < condition_value)) return 0; @@ -771,8 +778,8 @@ int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, break; } - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThan: { + case SpvOp::SpvOpSGreaterThan: + case SpvOp::SpvOpUGreaterThan: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value > condition_value)) return 0; @@ -788,12 +795,12 @@ int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, break; } - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpUGreaterThanEqual: { + case SpvOp::SpvOpSGreaterThanEqual: + case SpvOp::SpvOpUGreaterThanEqual: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value >= condition_value)) return 0; - // We subtract one to make it the same as spv::Op::OpGreaterThan as it is + // We subtract one to make it the same as SpvOpGreaterThan as it is // functionally equivalent. diff = init_value - (condition_value - 1); @@ -807,13 +814,13 @@ int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, break; } - case spv::Op::OpSLessThanEqual: - case spv::Op::OpULessThanEqual: { + case SpvOp::SpvOpSLessThanEqual: + case SpvOp::SpvOpULessThanEqual: { // If the condition is not met to begin with the loop will never iterate. if (!(init_value <= condition_value)) return 0; - // We add one to make it the same as spv::Op::OpLessThan as it is - // functionally equivalent. + // We add one to make it the same as SpvOpLessThan as it is functionally + // equivalent. diff = (condition_value + 1) - init_value; // If the operation is a less than operation then the diff and step must @@ -847,7 +854,7 @@ int64_t Loop::GetIterations(spv::Op condition, int64_t condition_value, void Loop::GetInductionVariables( std::vector& induction_variables) const { for (Instruction& inst : *loop_header_) { - if (inst.opcode() == spv::Op::OpPhi) { + if (inst.opcode() == SpvOp::SpvOpPhi) { induction_variables.push_back(&inst); } } @@ -860,7 +867,7 @@ Instruction* Loop::FindConditionVariable( Instruction* induction = nullptr; // Verify that the branch instruction is a conditional branch. - if (branch_inst.opcode() == spv::Op::OpBranchConditional) { + if (branch_inst.opcode() == SpvOp::SpvOpBranchConditional) { // From the branch instruction find the branch condition. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); @@ -876,8 +883,7 @@ Instruction* Loop::FindConditionVariable( def_use_manager->GetDef(condition->GetSingleWordOperand(2)); // Make sure the variable instruction used is a phi. - if (!variable_inst || variable_inst->opcode() != spv::Op::OpPhi) - return nullptr; + if (!variable_inst || variable_inst->opcode() != SpvOpPhi) return nullptr; // Make sure the phi instruction only has two incoming blocks. Each // incoming block will be represented by two in operands in the phi diff --git a/source/opt/loop_descriptor.h b/source/opt/loop_descriptor.h index d451496e..df012274 100644 --- a/source/opt/loop_descriptor.h +++ b/source/opt/loop_descriptor.h @@ -296,12 +296,12 @@ class Loop { // as a nested child loop. inline void SetParent(Loop* parent) { parent_ = parent; } - // Returns true is the instruction is invariant and safe to move wrt loop. - bool ShouldHoistInstruction(const Instruction& inst) const; + // Returns true is the instruction is invariant and safe to move wrt loop + bool ShouldHoistInstruction(IRContext* context, Instruction* inst); // Returns true if all operands of inst are in basic blocks not contained in - // loop. - bool AreAllOperandsOutsideLoop(const Instruction& inst) const; + // loop + bool AreAllOperandsOutsideLoop(IRContext* context, Instruction* inst); // Extract the initial value from the |induction| variable and store it in // |value|. If the function couldn't find the initial value of |induction| @@ -316,12 +316,12 @@ class Loop { // Returns true if we can deduce the number of loop iterations in the step // operation |step|. IsSupportedCondition must also be true for the condition // instruction. - bool IsSupportedStepOp(spv::Op step) const; + bool IsSupportedStepOp(SpvOp step) const; // Returns true if we can deduce the number of loop iterations in the // condition operation |condition|. IsSupportedStepOp must also be true for // the step instruction. - bool IsSupportedCondition(spv::Op condition) const; + bool IsSupportedCondition(SpvOp condition) const; // Creates the list of the loop's basic block in structured order and store // the result in |ordered_loop_blocks|. If |include_pre_header| is true, the @@ -335,7 +335,7 @@ class Loop { // Given the loop |condition|, |initial_value|, |step_value|, the trip count // |number_of_iterations|, and the |unroll_factor| requested, get the new // condition value for the residual loop. - static int64_t GetResidualConditionValue(spv::Op condition, + static int64_t GetResidualConditionValue(SpvOp condition, int64_t initial_value, int64_t step_value, size_t number_of_iterations, @@ -400,7 +400,7 @@ class Loop { // the induction variable. This method will return the number of iterations in // a loop with those values for a given |condition|. Returns 0 if the number // of iterations could not be computed. - int64_t GetIterations(spv::Op condition, int64_t condition_value, + int64_t GetIterations(SpvOp condition, int64_t condition_value, int64_t init_value, int64_t step_value) const; // This is to allow for loops to be removed mid iteration without invalidating diff --git a/source/opt/loop_fission.cpp b/source/opt/loop_fission.cpp index 2ae05c3c..b4df8c62 100644 --- a/source/opt/loop_fission.cpp +++ b/source/opt/loop_fission.cpp @@ -110,10 +110,10 @@ class LoopFissionImpl { }; bool LoopFissionImpl::MovableInstruction(const Instruction& inst) const { - return inst.opcode() == spv::Op::OpLoad || - inst.opcode() == spv::Op::OpStore || - inst.opcode() == spv::Op::OpSelectionMerge || - inst.opcode() == spv::Op::OpPhi || inst.IsOpcodeCodeMotionSafe(); + return inst.opcode() == SpvOp::SpvOpLoad || + inst.opcode() == SpvOp::SpvOpStore || + inst.opcode() == SpvOp::SpvOpSelectionMerge || + inst.opcode() == SpvOp::SpvOpPhi || inst.IsOpcodeCodeMotionSafe(); } void LoopFissionImpl::TraverseUseDef(Instruction* inst, @@ -143,14 +143,14 @@ void LoopFissionImpl::TraverseUseDef(Instruction* inst, // same labels (i.e phis). We already preempt the inclusion of // OpSelectionMerge by adding related instructions to the seen_instructions_ // set. - if (user->opcode() == spv::Op::OpLoopMerge || - user->opcode() == spv::Op::OpLabel) + if (user->opcode() == SpvOp::SpvOpLoopMerge || + user->opcode() == SpvOp::SpvOpLabel) return; // If the |report_loads| flag is set, set the class field // load_used_in_condition_ to false. This is used to check that none of the // condition checks in the loop rely on loads. - if (user->opcode() == spv::Op::OpLoad && report_loads) { + if (user->opcode() == SpvOp::SpvOpLoad && report_loads) { load_used_in_condition_ = true; } @@ -167,7 +167,7 @@ void LoopFissionImpl::TraverseUseDef(Instruction* inst, user->ForEachInOperand(traverse_operand); // For the first traversal we want to ignore the users of the phi. - if (ignore_phi_users && user->opcode() == spv::Op::OpPhi) return; + if (ignore_phi_users && user->opcode() == SpvOp::SpvOpPhi) return; // Traverse each user with this lambda. def_use->ForEachUser(user, traverser_functor); @@ -214,7 +214,7 @@ bool LoopFissionImpl::GroupInstructionsByUseDef() { for (Instruction& inst : block) { // Ignore all instructions related to control flow. - if (inst.opcode() == spv::Op::OpSelectionMerge || inst.IsBranch()) { + if (inst.opcode() == SpvOp::SpvOpSelectionMerge || inst.IsBranch()) { TraverseUseDef(&inst, &instructions_to_ignore, true, true); } } @@ -229,8 +229,8 @@ bool LoopFissionImpl::GroupInstructionsByUseDef() { for (Instruction& inst : block) { // Record the order that each load/store is seen. - if (inst.opcode() == spv::Op::OpLoad || - inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpLoad || + inst.opcode() == SpvOp::SpvOpStore) { instruction_order_[&inst] = instruction_order_.size(); } @@ -292,9 +292,9 @@ bool LoopFissionImpl::CanPerformSplit() { // Populate the above lists. for (Instruction* inst : cloned_loop_instructions_) { - if (inst->opcode() == spv::Op::OpStore) { + if (inst->opcode() == SpvOp::SpvOpStore) { set_one_stores.push_back(inst); - } else if (inst->opcode() == spv::Op::OpLoad) { + } else if (inst->opcode() == SpvOp::SpvOpLoad) { set_one_loads.push_back(inst); } @@ -316,7 +316,7 @@ bool LoopFissionImpl::CanPerformSplit() { // Look at the dependency between the loads in the original and stores in // the cloned loops. - if (inst->opcode() == spv::Op::OpLoad) { + if (inst->opcode() == SpvOp::SpvOpLoad) { for (Instruction* store : set_one_stores) { DistanceVector vec{loop_depth}; @@ -334,7 +334,7 @@ bool LoopFissionImpl::CanPerformSplit() { } } } - } else if (inst->opcode() == spv::Op::OpStore) { + } else if (inst->opcode() == SpvOp::SpvOpStore) { for (Instruction* load : set_one_loads) { DistanceVector vec{loop_depth}; @@ -387,7 +387,7 @@ Loop* LoopFissionImpl::SplitLoop() { if (cloned_loop_instructions_.count(&inst) == 1 && original_loop_instructions_.count(&inst) == 0) { instructions_to_kill.push_back(&inst); - if (inst.opcode() == spv::Op::OpPhi) { + if (inst.opcode() == SpvOp::SpvOpPhi) { context_->ReplaceAllUsesWith( inst.result_id(), clone_results.value_map_[inst.result_id()]); } diff --git a/source/opt/loop_fusion.cpp b/source/opt/loop_fusion.cpp index dc635530..f3aab283 100644 --- a/source/opt/loop_fusion.cpp +++ b/source/opt/loop_fusion.cpp @@ -23,6 +23,7 @@ namespace spvtools { namespace opt { + namespace { // Append all the loops nested in |loop| to |loops|. @@ -192,15 +193,14 @@ bool LoopFusion::AreCompatible() { // in LCSSA form. for (auto block : block_to_check) { for (auto& inst : *block) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOpStore) { // Get the definition of the target to check it's function scope so // there are no observable side effects. auto variable = context_->get_def_use_mgr()->GetDef(inst.GetSingleWordInOperand(0)); - if (variable->opcode() != spv::Op::OpVariable || - spv::StorageClass(variable->GetSingleWordInOperand(0)) != - spv::StorageClass::Function) { + if (variable->opcode() != SpvOpVariable || + variable->GetSingleWordInOperand(0) != SpvStorageClassFunction) { return false; } @@ -209,7 +209,7 @@ bool LoopFusion::AreCompatible() { context_->get_def_use_mgr()->ForEachUse( inst.GetSingleWordInOperand(0), [&is_used](Instruction* use_inst, uint32_t) { - if (use_inst->opcode() == spv::Op::OpLoad) { + if (use_inst->opcode() == SpvOpLoad) { is_used = true; } }); @@ -217,11 +217,11 @@ bool LoopFusion::AreCompatible() { if (is_used) { return false; } - } else if (inst.opcode() == spv::Op::OpPhi) { + } else if (inst.opcode() == SpvOpPhi) { if (inst.NumInOperands() != 2) { return false; } - } else if (inst.opcode() != spv::Op::OpBranch) { + } else if (inst.opcode() != SpvOpBranch) { return false; } } @@ -234,12 +234,10 @@ bool LoopFusion::ContainsBarriersOrFunctionCalls(Loop* loop) { for (const auto& block : loop->GetBlocks()) { for (const auto& inst : *containing_function_->FindBlock(block)) { auto opcode = inst.opcode(); - if (opcode == spv::Op::OpFunctionCall || - opcode == spv::Op::OpControlBarrier || - opcode == spv::Op::OpMemoryBarrier || - opcode == spv::Op::OpTypeNamedBarrier || - opcode == spv::Op::OpNamedBarrierInitialize || - opcode == spv::Op::OpMemoryNamedBarrier) { + if (opcode == SpvOpFunctionCall || opcode == SpvOpControlBarrier || + opcode == SpvOpMemoryBarrier || opcode == SpvOpTypeNamedBarrier || + opcode == SpvOpNamedBarrierInitialize || + opcode == SpvOpMemoryNamedBarrier) { return true; } } @@ -346,7 +344,7 @@ std::map> LoopFusion::LocationToMemOps( auto access_location = context_->get_def_use_mgr()->GetDef( instruction->GetSingleWordInOperand(0)); - while (access_location->opcode() == spv::Op::OpAccessChain) { + while (access_location->opcode() == SpvOpAccessChain) { access_location = context_->get_def_use_mgr()->GetDef( access_location->GetSingleWordInOperand(0)); } @@ -368,9 +366,9 @@ LoopFusion::GetLoadsAndStoresInLoop(Loop* loop) { } for (auto& instruction : *containing_function_->FindBlock(block_id)) { - if (instruction.opcode() == spv::Op::OpLoad) { + if (instruction.opcode() == SpvOpLoad) { loads.push_back(&instruction); - } else if (instruction.opcode() == spv::Op::OpStore) { + } else if (instruction.opcode() == SpvOpStore) { stores.push_back(&instruction); } } @@ -558,7 +556,7 @@ void LoopFusion::Fuse() { // Update merge block id in the header of |loop_0_| to the merge block of // |loop_1_|. loop_0_->GetHeaderBlock()->ForEachInst([this](Instruction* inst) { - if (inst->opcode() == spv::Op::OpLoopMerge) { + if (inst->opcode() == SpvOpLoopMerge) { inst->SetInOperand(0, {loop_1_->GetMergeBlock()->id()}); } }); @@ -566,7 +564,7 @@ void LoopFusion::Fuse() { // Update condition branch target in |loop_0_| to the merge block of // |loop_1_|. condition_block_of_0->ForEachInst([this](Instruction* inst) { - if (inst->opcode() == spv::Op::OpBranchConditional) { + if (inst->opcode() == SpvOpBranchConditional) { auto loop_0_merge_block_id = loop_0_->GetMergeBlock()->id(); if (inst->GetSingleWordInOperand(1) == loop_0_merge_block_id) { @@ -581,8 +579,7 @@ void LoopFusion::Fuse() { // the header of |loop_1_| to the header of |loop_0_|. std::vector instructions_to_move{}; for (auto& instruction : *loop_1_->GetHeaderBlock()) { - if (instruction.opcode() == spv::Op::OpPhi && - &instruction != induction_1_) { + if (instruction.opcode() == SpvOpPhi && &instruction != induction_1_) { instructions_to_move.push_back(&instruction); } } diff --git a/source/opt/loop_fusion_pass.cpp b/source/opt/loop_fusion_pass.cpp index 097430fc..bd8444ae 100644 --- a/source/opt/loop_fusion_pass.cpp +++ b/source/opt/loop_fusion_pass.cpp @@ -14,6 +14,7 @@ #include "source/opt/loop_fusion_pass.h" +#include "source/opt/ir_context.h" #include "source/opt/loop_descriptor.h" #include "source/opt/loop_fusion.h" #include "source/opt/register_pressure.h" diff --git a/source/opt/loop_peeling.cpp b/source/opt/loop_peeling.cpp index 25c6db12..34f0a8d2 100644 --- a/source/opt/loop_peeling.cpp +++ b/source/opt/loop_peeling.cpp @@ -12,37 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/loop_peeling.h" - +#include #include #include +#include #include #include #include "source/opt/ir_builder.h" #include "source/opt/ir_context.h" #include "source/opt/loop_descriptor.h" +#include "source/opt/loop_peeling.h" #include "source/opt/loop_utils.h" #include "source/opt/scalar_analysis.h" #include "source/opt/scalar_analysis_nodes.h" namespace spvtools { namespace opt { -namespace { -// Gather the set of blocks for all the path from |entry| to |root|. -void GetBlocksInPath(uint32_t block, uint32_t entry, - std::unordered_set* blocks_in_path, - const CFG& cfg) { - for (uint32_t pid : cfg.preds(block)) { - if (blocks_in_path->insert(pid).second) { - if (pid != entry) { - GetBlocksInPath(pid, entry, blocks_in_path, cfg); - } - } - } -} -} // namespace - size_t LoopPeelingPass::code_grow_threshold_ = 1000; void LoopPeeling::DuplicateAndConnectLoop( @@ -200,7 +186,7 @@ void LoopPeeling::GetIteratorUpdateOperations( operations->insert(iterator); iterator->ForEachInId([def_use_mgr, loop, operations, this](uint32_t* id) { Instruction* insn = def_use_mgr->GetDef(*id); - if (insn->opcode() == spv::Op::OpLabel) { + if (insn->opcode() == SpvOpLabel) { return; } if (operations->count(insn)) { @@ -213,6 +199,19 @@ void LoopPeeling::GetIteratorUpdateOperations( }); } +// Gather the set of blocks for all the path from |entry| to |root|. +static void GetBlocksInPath(uint32_t block, uint32_t entry, + std::unordered_set* blocks_in_path, + const CFG& cfg) { + for (uint32_t pid : cfg.preds(block)) { + if (blocks_in_path->insert(pid).second) { + if (pid != entry) { + GetBlocksInPath(pid, entry, blocks_in_path, cfg); + } + } + } +} + bool LoopPeeling::IsConditionCheckSideEffectFree() const { CFG& cfg = *context_->cfg(); @@ -232,9 +231,9 @@ bool LoopPeeling::IsConditionCheckSideEffectFree() const { if (!bb->WhileEachInst([this](Instruction* insn) { if (insn->IsBranch()) return true; switch (insn->opcode()) { - case spv::Op::OpLabel: - case spv::Op::OpSelectionMerge: - case spv::Op::OpLoopMerge: + case SpvOpLabel: + case SpvOpSelectionMerge: + case SpvOpLoopMerge: return true; default: break; @@ -323,7 +322,7 @@ void LoopPeeling::FixExitCondition( BasicBlock* condition_block = cfg.block(condition_block_id); Instruction* exit_condition = condition_block->terminator(); - assert(exit_condition->opcode() == spv::Op::OpBranchConditional); + assert(exit_condition->opcode() == SpvOpBranchConditional); BasicBlock::iterator insert_point = condition_block->tail(); if (condition_block->GetMergeInst()) { --insert_point; @@ -351,7 +350,7 @@ BasicBlock* LoopPeeling::CreateBlockBefore(BasicBlock* bb) { // TODO(1841): Handle id overflow. std::unique_ptr new_bb = MakeUnique(std::unique_ptr(new Instruction( - context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))); + context_, SpvOpLabel, 0, context_->TakeNextId(), {}))); // Update the loop descriptor. Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb]; if (in_loop) { @@ -792,18 +791,18 @@ uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstNonLoopInvariantOperand( return 0; } -static bool IsHandledCondition(spv::Op opcode) { +static bool IsHandledCondition(SpvOp opcode) { switch (opcode) { - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: + case SpvOpULessThan: + case SpvOpSLessThan: + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: return true; default: return false; @@ -812,7 +811,7 @@ static bool IsHandledCondition(spv::Op opcode) { LoopPeelingPass::LoopPeelingInfo::Direction LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { - if (bb->terminator()->opcode() != spv::Op::OpBranchConditional) { + if (bb->terminator()->opcode() != SpvOpBranchConditional) { return GetNoneDirection(); } @@ -887,27 +886,27 @@ LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(BasicBlock* bb) const { switch (condition->opcode()) { default: return GetNoneDirection(); - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: + case SpvOpIEqual: + case SpvOpINotEqual: return HandleEquality(lhs, rhs); - case spv::Op::OpUGreaterThan: - case spv::Op::OpSGreaterThan: { + case SpvOpUGreaterThan: + case SpvOpSGreaterThan: { cmp_operator = CmpOperator::kGT; break; } - case spv::Op::OpULessThan: - case spv::Op::OpSLessThan: { + case SpvOpULessThan: + case SpvOpSLessThan: { cmp_operator = CmpOperator::kLT; break; } // We add one to transform >= into > and <= into <. - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpSGreaterThanEqual: { + case SpvOpUGreaterThanEqual: + case SpvOpSGreaterThanEqual: { cmp_operator = CmpOperator::kGE; break; } - case spv::Op::OpULessThanEqual: - case spv::Op::OpSLessThanEqual: { + case SpvOpULessThanEqual: + case SpvOpSLessThanEqual: { cmp_operator = CmpOperator::kLE; break; } diff --git a/source/opt/loop_unroller.cpp b/source/opt/loop_unroller.cpp index d9e34f24..6f4e6f41 100644 --- a/source/opt/loop_unroller.cpp +++ b/source/opt/loop_unroller.cpp @@ -15,6 +15,7 @@ #include "source/opt/loop_unroller.h" #include +#include #include #include #include @@ -67,10 +68,10 @@ namespace opt { namespace { // Loop control constant value for DontUnroll flag. -constexpr uint32_t kLoopControlDontUnrollIndex = 2; +static const uint32_t kLoopControlDontUnrollIndex = 2; // Operand index of the loop control parameter of the OpLoopMerge. -constexpr uint32_t kLoopControlIndex = 2; +static const uint32_t kLoopControlIndex = 2; // This utility class encapsulates some of the state we need to maintain between // loop unrolls. Specifically it maintains key blocks and the induction variable @@ -335,7 +336,8 @@ class LoopUnrollerUtilsImpl { // Retrieve the index of the OpPhi instruction |phi| which corresponds to the // incoming |block| id. -uint32_t GetPhiIndexFromLabel(const BasicBlock* block, const Instruction* phi) { +static uint32_t GetPhiIndexFromLabel(const BasicBlock* block, + const Instruction* phi) { for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) { if (block->id() == phi->GetSingleWordInOperand(i)) { return i; @@ -380,7 +382,7 @@ void LoopUnrollerUtilsImpl::PartiallyUnrollResidualFactor(Loop* loop, size_t factor) { // TODO(1841): Handle id overflow. std::unique_ptr new_label{new Instruction( - context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; + context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})}; std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; new_exit_bb->SetParent(&function_); @@ -989,7 +991,7 @@ bool LoopUtils::CanPerformUnroll() { // Check that we can find and process the induction variable. const Instruction* induction = loop_->FindConditionVariable(condition); - if (!induction || induction->opcode() != spv::Op::OpPhi) return false; + if (!induction || induction->opcode() != SpvOpPhi) return false; // Check that we can find the number of loop iterations. if (!loop_->FindNumberOfIterations(induction, &*condition->ctail(), nullptr)) @@ -1000,7 +1002,7 @@ bool LoopUtils::CanPerformUnroll() { // iteration counts. This can cause timeouts and memouts during fuzzing that // are not classed as bugs. To avoid this noise, loop unrolling is not applied // to loops with large iteration counts when fuzzing. - constexpr size_t kFuzzerIterationLimit = 100; + const size_t kFuzzerIterationLimit = 100; size_t num_iterations; loop_->FindNumberOfIterations(induction, &*condition->ctail(), &num_iterations); @@ -1013,7 +1015,7 @@ bool LoopUtils::CanPerformUnroll() { // block. const Instruction& branch = *loop_->GetLatchBlock()->ctail(); bool branching_assumption = - branch.opcode() == spv::Op::OpBranch && + branch.opcode() == SpvOpBranch && branch.GetSingleWordInOperand(0) == loop_->GetHeaderBlock()->id(); if (!branching_assumption) { return false; @@ -1041,10 +1043,10 @@ bool LoopUtils::CanPerformUnroll() { // exit the loop. for (uint32_t label_id : loop_->GetBlocks()) { const BasicBlock* block = context_->cfg()->block(label_id); - if (block->ctail()->opcode() == spv::Op::OpKill || - block->ctail()->opcode() == spv::Op::OpReturn || - block->ctail()->opcode() == spv::Op::OpReturnValue || - block->ctail()->opcode() == spv::Op::OpTerminateInvocation) { + if (block->ctail()->opcode() == SpvOp::SpvOpKill || + block->ctail()->opcode() == SpvOp::SpvOpReturn || + block->ctail()->opcode() == SpvOp::SpvOpReturnValue || + block->ctail()->opcode() == SpvOp::SpvOpTerminateInvocation) { return false; } } diff --git a/source/opt/loop_unswitch_pass.cpp b/source/opt/loop_unswitch_pass.cpp index 41f1a804..1ee7e5e2 100644 --- a/source/opt/loop_unswitch_pass.cpp +++ b/source/opt/loop_unswitch_pass.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,12 +31,18 @@ #include "source/opt/ir_builder.h" #include "source/opt/ir_context.h" #include "source/opt/loop_descriptor.h" + #include "source/opt/loop_utils.h" namespace spvtools { namespace opt { namespace { -constexpr uint32_t kTypePointerStorageClassInIdx = 0; + +static const uint32_t kTypePointerStorageClassInIdx = 0; + +} // anonymous namespace + +namespace { // This class handle the unswitch procedure for a given loop. // The unswitch will not happen if: @@ -70,7 +77,7 @@ class LoopUnswitch { } if (bb->terminator()->IsBranch() && - bb->terminator()->opcode() != spv::Op::OpBranch) { + bb->terminator()->opcode() != SpvOpBranch) { if (IsConditionNonConstantLoopInvariant(bb->terminator())) { switch_block_ = bb; break; @@ -97,7 +104,7 @@ class LoopUnswitch { // TODO(1841): Handle id overflow. BasicBlock* bb = &*ip.InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); + context_, SpvOpLabel, 0, context_->TakeNextId(), {}))))); bb->SetParent(function_); def_use_mgr->AnalyzeInstDef(bb->GetLabelInst()); context_->set_instr_block(bb->GetLabelInst(), bb); @@ -106,7 +113,7 @@ class LoopUnswitch { } Instruction* GetValueForDefaultPathForSwitch(Instruction* switch_inst) { - assert(switch_inst->opcode() == spv::Op::OpSwitch && + assert(switch_inst->opcode() == SpvOpSwitch && "The given instructoin must be an OpSwitch."); // Find a value that can be used to select the default path. @@ -284,7 +291,7 @@ class LoopUnswitch { ///////////////////////////// Instruction* iv_condition = &*switch_block_->tail(); - spv::Op iv_opcode = iv_condition->opcode(); + SpvOp iv_opcode = iv_condition->opcode(); Instruction* condition = def_use_mgr->GetDef(iv_condition->GetOperand(0).words[0]); @@ -297,7 +304,7 @@ class LoopUnswitch { std::vector> constant_branch; // Special case for the original loop Instruction* original_loop_constant_value; - if (iv_opcode == spv::Op::OpBranchConditional) { + if (iv_opcode == SpvOpBranchConditional) { constant_branch.emplace_back( cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant(cond_type, {0})), nullptr); @@ -394,7 +401,7 @@ class LoopUnswitch { // Delete the old jump context_->KillInst(&*if_block->tail()); InstructionBuilder builder(context_, if_block); - if (iv_opcode == spv::Op::OpBranchConditional) { + if (iv_opcode == SpvOpBranchConditional) { assert(constant_branch.size() == 1); builder.AddConditionalBranch( condition->result_id(), original_loop_target->id(), @@ -502,8 +509,7 @@ class LoopUnswitch { bool& is_uniform = dynamically_uniform_[var->result_id()]; is_uniform = false; - dec_mgr->WhileEachDecoration(var->result_id(), - uint32_t(spv::Decoration::Uniform), + dec_mgr->WhileEachDecoration(var->result_id(), SpvDecorationUniform, [&is_uniform](const Instruction&) { is_uniform = true; return false; @@ -520,14 +526,14 @@ class LoopUnswitch { if (!post_dom_tree.Dominates(parent->id(), entry->id())) { return is_uniform = false; } - if (var->opcode() == spv::Op::OpLoad) { + if (var->opcode() == SpvOpLoad) { const uint32_t PtrTypeId = def_use_mgr->GetDef(var->GetSingleWordInOperand(0))->type_id(); const Instruction* PtrTypeInst = def_use_mgr->GetDef(PtrTypeId); - auto storage_class = spv::StorageClass( - PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx)); - if (storage_class != spv::StorageClass::Uniform && - storage_class != spv::StorageClass::UniformConstant) { + uint32_t storage_class = + PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx); + if (storage_class != SpvStorageClassUniform && + storage_class != SpvStorageClassUniformConstant) { return is_uniform = false; } } else { @@ -547,7 +553,7 @@ class LoopUnswitch { // dynamically uniform. bool IsConditionNonConstantLoopInvariant(Instruction* insn) { assert(insn->IsBranch()); - assert(insn->opcode() != spv::Op::OpBranch); + assert(insn->opcode() != SpvOpBranch); analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); Instruction* condition = def_use_mgr->GetDef(insn->GetOperand(0).words[0]); diff --git a/source/opt/loop_utils.cpp b/source/opt/loop_utils.cpp index 20494e12..8c6d355d 100644 --- a/source/opt/loop_utils.cpp +++ b/source/opt/loop_utils.cpp @@ -28,11 +28,12 @@ namespace spvtools { namespace opt { + namespace { // Return true if |bb| is dominated by at least one block in |exits| -inline bool DominatesAnExit(BasicBlock* bb, - const std::unordered_set& exits, - const DominatorTree& dom_tree) { +static inline bool DominatesAnExit(BasicBlock* bb, + const std::unordered_set& exits, + const DominatorTree& dom_tree) { for (BasicBlock* e_bb : exits) if (dom_tree.Dominates(bb, e_bb)) return true; return false; @@ -70,10 +71,10 @@ class LCSSARewriter { // UpdateManagers. void RewriteUse(BasicBlock* bb, Instruction* user, uint32_t operand_index) { assert( - (user->opcode() != spv::Op::OpPhi || bb != GetParent(user)) && + (user->opcode() != SpvOpPhi || bb != GetParent(user)) && "The root basic block must be the incoming edge if |user| is a phi " "instruction"); - assert((user->opcode() == spv::Op::OpPhi || bb == GetParent(user)) && + assert((user->opcode() == SpvOpPhi || bb == GetParent(user)) && "The root basic block must be the instruction parent if |user| is " "not " "phi instruction"); @@ -292,7 +293,7 @@ inline void MakeSetClosedSSA(IRContext* context, Function* function, assert(use_parent); if (blocks.count(use_parent->id())) return; - if (use->opcode() == spv::Op::OpPhi) { + if (use->opcode() == SpvOpPhi) { // If the use is a Phi instruction and the incoming block is // coming from the loop, then that's consistent with LCSSA form. if (exit_bb.count(use_parent)) { @@ -354,7 +355,7 @@ void LoopUtils::CreateLoopDedicatedExits() { // TODO(1841): Handle id overflow. BasicBlock& exit = *insert_pt.InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {}))))); + context_, SpvOpLabel, 0, context_->TakeNextId(), {}))))); exit.SetParent(function); // Redirect in loop predecessors to |exit| block. @@ -493,7 +494,7 @@ Loop* LoopUtils::CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result) { // Create a new exit block/label for the new loop. // TODO(1841): Handle id overflow. std::unique_ptr new_label{new Instruction( - context_, spv::Op::OpLabel, 0, context_->TakeNextId(), {})}; + context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})}; std::unique_ptr new_exit_bb{new BasicBlock(std::move(new_label))}; new_exit_bb->SetParent(loop_->GetMergeBlock()->GetParent()); @@ -679,9 +680,9 @@ void CodeMetrics::Analyze(const Loop& loop) { const BasicBlock* bb = cfg.block(id); size_t bb_size = 0; bb->ForEachInst([&bb_size](const Instruction* insn) { - if (insn->opcode() == spv::Op::OpLabel) return; + if (insn->opcode() == SpvOpLabel) return; if (insn->IsNop()) return; - if (insn->opcode() == spv::Op::OpPhi) return; + if (insn->opcode() == SpvOpPhi) return; bb_size++; }); block_sizes_[bb->id()] = bb_size; diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp index 9972c4f7..ca4889b7 100644 --- a/source/opt/mem_pass.cpp +++ b/source/opt/mem_pass.cpp @@ -22,27 +22,32 @@ #include "source/cfa.h" #include "source/opt/basic_block.h" +#include "source/opt/dominator_analysis.h" #include "source/opt/ir_context.h" +#include "source/opt/iterator.h" namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kCopyObjectOperandInIdx = 0; -constexpr uint32_t kTypePointerStorageClassInIdx = 0; -constexpr uint32_t kTypePointerTypeIdInIdx = 1; + +const uint32_t kCopyObjectOperandInIdx = 0; +const uint32_t kTypePointerStorageClassInIdx = 0; +const uint32_t kTypePointerTypeIdInIdx = 1; + } // namespace bool MemPass::IsBaseTargetType(const Instruction* typeInst) const { switch (typeInst->opcode()) { - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeBool: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypePointer: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeBool: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeImage: + case SpvOpTypeSampler: + case SpvOpTypeSampledImage: + case SpvOpTypePointer: return true; default: break; @@ -52,14 +57,14 @@ bool MemPass::IsBaseTargetType(const Instruction* typeInst) const { bool MemPass::IsTargetType(const Instruction* typeInst) const { if (IsBaseTargetType(typeInst)) return true; - if (typeInst->opcode() == spv::Op::OpTypeArray) { + if (typeInst->opcode() == SpvOpTypeArray) { if (!IsTargetType( get_def_use_mgr()->GetDef(typeInst->GetSingleWordOperand(1)))) { return false; } return true; } - if (typeInst->opcode() != spv::Op::OpTypeStruct) return false; + if (typeInst->opcode() != SpvOpTypeStruct) return false; // All struct members must be math type return typeInst->WhileEachInId([this](const uint32_t* tid) { Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid); @@ -68,29 +73,23 @@ bool MemPass::IsTargetType(const Instruction* typeInst) const { }); } -bool MemPass::IsNonPtrAccessChain(const spv::Op opcode) const { - return opcode == spv::Op::OpAccessChain || - opcode == spv::Op::OpInBoundsAccessChain; +bool MemPass::IsNonPtrAccessChain(const SpvOp opcode) const { + return opcode == SpvOpAccessChain || opcode == SpvOpInBoundsAccessChain; } bool MemPass::IsPtr(uint32_t ptrId) { uint32_t varId = ptrId; Instruction* ptrInst = get_def_use_mgr()->GetDef(varId); - if (ptrInst->opcode() == spv::Op::OpFunction) { - // A function is not a pointer, but it's return type could be, which will - // erroneously lead to this function returning true later on - return false; - } - while (ptrInst->opcode() == spv::Op::OpCopyObject) { + while (ptrInst->opcode() == SpvOpCopyObject) { varId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx); ptrInst = get_def_use_mgr()->GetDef(varId); } - const spv::Op op = ptrInst->opcode(); - if (op == spv::Op::OpVariable || IsNonPtrAccessChain(op)) return true; + const SpvOp op = ptrInst->opcode(); + if (op == SpvOpVariable || IsNonPtrAccessChain(op)) return true; const uint32_t varTypeId = ptrInst->type_id(); if (varTypeId == 0) return false; const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - return varTypeInst->opcode() == spv::Op::OpTypePointer; + return varTypeInst->opcode() == SpvOpTypePointer; } Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { @@ -98,24 +97,24 @@ Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId); Instruction* varInst; - if (ptrInst->opcode() == spv::Op::OpConstantNull) { + if (ptrInst->opcode() == SpvOpConstantNull) { *varId = 0; return ptrInst; } - if (ptrInst->opcode() != spv::Op::OpVariable && - ptrInst->opcode() != spv::Op::OpFunctionParameter) { + if (ptrInst->opcode() != SpvOpVariable && + ptrInst->opcode() != SpvOpFunctionParameter) { varInst = ptrInst->GetBaseAddress(); } else { varInst = ptrInst; } - if (varInst->opcode() == spv::Op::OpVariable) { + if (varInst->opcode() == SpvOpVariable) { *varId = varInst->result_id(); } else { *varId = 0; } - while (ptrInst->opcode() == spv::Op::OpCopyObject) { + while (ptrInst->opcode() == SpvOpCopyObject) { uint32_t temp = ptrInst->GetSingleWordInOperand(0); ptrInst = get_def_use_mgr()->GetDef(temp); } @@ -124,9 +123,8 @@ Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) { } Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) { - assert(ip->opcode() == spv::Op::OpStore || ip->opcode() == spv::Op::OpLoad || - ip->opcode() == spv::Op::OpImageTexelPointer || - ip->IsAtomicWithLoad()); + assert(ip->opcode() == SpvOpStore || ip->opcode() == SpvOpLoad || + ip->opcode() == SpvOpImageTexelPointer || ip->IsAtomicWithLoad()); // All of these opcode place the pointer in position 0. const uint32_t ptrId = ip->GetSingleWordInOperand(0); @@ -135,8 +133,8 @@ Instruction* MemPass::GetPtr(Instruction* ip, uint32_t* varId) { bool MemPass::HasOnlyNamesAndDecorates(uint32_t id) const { return get_def_use_mgr()->WhileEachUser(id, [this](Instruction* user) { - spv::Op op = user->opcode(); - if (op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + SpvOp op = user->opcode(); + if (op != SpvOpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -149,15 +147,14 @@ void MemPass::KillAllInsts(BasicBlock* bp, bool killLabel) { bool MemPass::HasLoads(uint32_t varId) const { return !get_def_use_mgr()->WhileEachUser(varId, [this](Instruction* user) { - spv::Op op = user->opcode(); + SpvOp op = user->opcode(); // TODO(): The following is slightly conservative. Could be // better handling of non-store/name. - if (IsNonPtrAccessChain(op) || op == spv::Op::OpCopyObject) { + if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) { if (HasLoads(user->result_id())) { return false; } - } else if (op != spv::Op::OpStore && op != spv::Op::OpName && - !IsNonTypeDecorate(op)) { + } else if (op != SpvOpStore && op != SpvOpName && !IsNonTypeDecorate(op)) { return false; } return true; @@ -167,12 +164,12 @@ bool MemPass::HasLoads(uint32_t varId) const { bool MemPass::IsLiveVar(uint32_t varId) const { const Instruction* varInst = get_def_use_mgr()->GetDef(varId); // assume live if not a variable eg. function parameter - if (varInst->opcode() != spv::Op::OpVariable) return true; + if (varInst->opcode() != SpvOpVariable) return true; // non-function scope vars are live const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( - kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) + if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) != + SpvStorageClassFunction) return true; // test if variable is loaded from return HasLoads(varId); @@ -180,10 +177,10 @@ bool MemPass::IsLiveVar(uint32_t varId) const { void MemPass::AddStores(uint32_t ptr_id, std::queue* insts) { get_def_use_mgr()->ForEachUser(ptr_id, [this, insts](Instruction* user) { - spv::Op op = user->opcode(); + SpvOp op = user->opcode(); if (IsNonPtrAccessChain(op)) { AddStores(user->result_id(), insts); - } else if (op == spv::Op::OpStore) { + } else if (op == SpvOpStore) { insts->push(user); } }); @@ -196,7 +193,7 @@ void MemPass::DCEInst(Instruction* inst, while (!deadInsts.empty()) { Instruction* di = deadInsts.front(); // Don't delete labels - if (di->opcode() == spv::Op::OpLabel) { + if (di->opcode() == SpvOpLabel) { deadInsts.pop(); continue; } @@ -205,7 +202,7 @@ void MemPass::DCEInst(Instruction* inst, di->ForEachInId([&ids](uint32_t* iid) { ids.insert(*iid); }); uint32_t varId = 0; // Remember variable if dead load - if (di->opcode() == spv::Op::OpLoad) (void)GetPtr(di, &varId); + if (di->opcode() == SpvOpLoad) (void)GetPtr(di, &varId); if (call_back) { call_back(di); } @@ -233,9 +230,9 @@ bool MemPass::HasOnlySupportedRefs(uint32_t varId) { dbg_op == CommonDebugInfoDebugValue) { return true; } - spv::Op op = user->opcode(); - if (op != spv::Op::OpStore && op != spv::Op::OpLoad && - op != spv::Op::OpName && !IsNonTypeDecorate(op)) { + SpvOp op = user->opcode(); + if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName && + !IsNonTypeDecorate(op)) { return false; } return true; @@ -251,7 +248,7 @@ uint32_t MemPass::Type2Undef(uint32_t type_id) { } std::unique_ptr undef_inst( - new Instruction(context(), spv::Op::OpUndef, type_id, undefId, {})); + new Instruction(context(), SpvOpUndef, type_id, undefId, {})); get_def_use_mgr()->AnalyzeInstDefUse(&*undef_inst); get_module()->AddGlobalValue(std::move(undef_inst)); type2undefs_[type_id] = undefId; @@ -267,11 +264,11 @@ bool MemPass::IsTargetVar(uint32_t varId) { return false; if (seen_target_vars_.find(varId) != seen_target_vars_.end()) return true; const Instruction* varInst = get_def_use_mgr()->GetDef(varId); - if (varInst->opcode() != spv::Op::OpVariable) return false; + if (varInst->opcode() != SpvOpVariable) return false; const uint32_t varTypeId = varInst->type_id(); const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( - kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) { + if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) != + SpvStorageClassFunction) { seen_non_target_vars_.insert(varId); return false; } @@ -492,8 +489,8 @@ void MemPass::CollectTargetVars(Function* func) { for (auto& blk : *func) { for (auto& inst : blk) { switch (inst.opcode()) { - case spv::Op::OpStore: - case spv::Op::OpLoad: { + case SpvOpStore: + case SpvOpLoad: { uint32_t varId; (void)GetPtr(&inst, &varId); if (!IsTargetVar(varId)) break; diff --git a/source/opt/mem_pass.h b/source/opt/mem_pass.h index aef9e5ff..5a77670d 100644 --- a/source/opt/mem_pass.h +++ b/source/opt/mem_pass.h @@ -80,7 +80,7 @@ class MemPass : public Pass { bool IsTargetType(const Instruction* typeInst) const; // Returns true if |opcode| is a non-ptr access chain op - bool IsNonPtrAccessChain(const spv::Op opcode) const; + bool IsNonPtrAccessChain(const SpvOp opcode) const; // Given the id |ptrId|, return true if the top-most non-CopyObj is // a variable, a non-ptr access chain or a parameter of pointer type. @@ -117,8 +117,8 @@ class MemPass : public Pass { bool CFGCleanup(Function* func); // Return true if |op| is supported decorate. - inline bool IsNonTypeDecorate(spv::Op op) const { - return (op == spv::Op::OpDecorate || op == spv::Op::OpDecorateId); + inline bool IsNonTypeDecorate(uint32_t op) const { + return (op == SpvOpDecorate || op == SpvOpDecorateId); } // Return the id of an undef value with type |type_id|. Create and insert an diff --git a/source/opt/merge_return_pass.cpp b/source/opt/merge_return_pass.cpp index c262ea07..7710deae 100644 --- a/source/opt/merge_return_pass.cpp +++ b/source/opt/merge_return_pass.cpp @@ -30,7 +30,7 @@ namespace opt { Pass::Status MergeReturnPass::Process() { bool is_shader = - context()->get_feature_mgr()->HasCapability(spv::Capability::Shader); + context()->get_feature_mgr()->HasCapability(SpvCapabilityShader); bool failed = false; ProcessFunction pfn = [&failed, is_shader, this](Function* function) { @@ -74,16 +74,16 @@ Pass::Status MergeReturnPass::Process() { void MergeReturnPass::GenerateState(BasicBlock* block) { if (Instruction* mergeInst = block->GetMergeInst()) { - if (mergeInst->opcode() == spv::Op::OpLoopMerge) { + if (mergeInst->opcode() == SpvOpLoopMerge) { // If new loop, break to this loop merge block state_.emplace_back(mergeInst, mergeInst); } else { auto branchInst = mergeInst->NextNode(); - if (branchInst->opcode() == spv::Op::OpSwitch) { + if (branchInst->opcode() == SpvOpSwitch) { // If switch inside of loop, break to innermost loop merge block. // Otherwise need to break to this switch merge block. auto lastMergeInst = state_.back().BreakMergeInst(); - if (lastMergeInst && lastMergeInst->opcode() == spv::Op::OpLoopMerge) + if (lastMergeInst && lastMergeInst->opcode() == SpvOpLoopMerge) state_.emplace_back(lastMergeInst, mergeInst); else state_.emplace_back(mergeInst, mergeInst); @@ -174,7 +174,7 @@ bool MergeReturnPass::ProcessStructured( void MergeReturnPass::CreateReturnBlock() { // Create a label for the new return block std::unique_ptr return_label( - new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); + new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {})); // Create the new basic block std::unique_ptr return_block( @@ -195,41 +195,37 @@ void MergeReturnPass::CreateReturn(BasicBlock* block) { // Load and return the final return value uint32_t loadId = TakeNextId(); block->AddInstruction(MakeUnique( - context(), spv::Op::OpLoad, function_->type_id(), loadId, + context(), SpvOpLoad, function_->type_id(), loadId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}})); Instruction* var_inst = block->terminator(); context()->AnalyzeDefUse(var_inst); context()->set_instr_block(var_inst, block); context()->get_decoration_mgr()->CloneDecorations( - return_value_->result_id(), loadId, - {spv::Decoration::RelaxedPrecision}); + return_value_->result_id(), loadId, {SpvDecorationRelaxedPrecision}); block->AddInstruction(MakeUnique( - context(), spv::Op::OpReturnValue, 0, 0, + context(), SpvOpReturnValue, 0, 0, std::initializer_list{{SPV_OPERAND_TYPE_ID, {loadId}}})); context()->AnalyzeDefUse(block->terminator()); context()->set_instr_block(block->terminator(), block); } else { - block->AddInstruction( - MakeUnique(context(), spv::Op::OpReturn)); + block->AddInstruction(MakeUnique(context(), SpvOpReturn)); context()->AnalyzeDefUse(block->terminator()); context()->set_instr_block(block->terminator(), block); } } void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) { - spv::Op tail_opcode = block->tail()->opcode(); - if (tail_opcode == spv::Op::OpReturn || - tail_opcode == spv::Op::OpReturnValue) { + SpvOp tail_opcode = block->tail()->opcode(); + if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue) { if (!return_flag_) { AddReturnFlag(); } } - if (tail_opcode == spv::Op::OpReturn || - tail_opcode == spv::Op::OpReturnValue || - tail_opcode == spv::Op::OpUnreachable) { + if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue || + tail_opcode == SpvOpUnreachable) { assert(CurrentState().InBreakable() && "Should be in the placeholder construct."); BranchToBlock(block, CurrentState().BreakMergeId()); @@ -238,8 +234,8 @@ void MergeReturnPass::ProcessStructuredBlock(BasicBlock* block) { } void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) { - if (block->tail()->opcode() == spv::Op::OpReturn || - block->tail()->opcode() == spv::Op::OpReturnValue) { + if (block->tail()->opcode() == SpvOpReturn || + block->tail()->opcode() == SpvOpReturnValue) { RecordReturned(block); RecordReturnValue(block); } @@ -251,7 +247,7 @@ void MergeReturnPass::BranchToBlock(BasicBlock* block, uint32_t target) { UpdatePhiNodes(block, target_block); Instruction* return_inst = block->terminator(); - return_inst->SetOpcode(spv::Op::OpBranch); + return_inst->SetOpcode(SpvOpBranch); return_inst->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {target}}}); context()->get_def_use_mgr()->AnalyzeInstDefUse(return_inst); new_edges_[target_block].insert(block->id()); @@ -280,7 +276,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, &inst, [&users_to_update, &dom_tree, &inst, inst_bb, this](Instruction* user) { BasicBlock* user_bb = nullptr; - if (user->opcode() != spv::Op::OpPhi) { + if (user->opcode() != SpvOpPhi) { user_bb = context()->get_instr_block(user); } else { // For OpPhi, the use should be considered to be in the predecessor. @@ -329,16 +325,15 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, // instruction. If not, the Spir-V will be invalid. Instruction* inst_type = get_def_use_mgr()->GetDef(inst.type_id()); bool regenerateInstruction = false; - if (inst_type->opcode() == spv::Op::OpTypePointer) { + if (inst_type->opcode() == SpvOpTypePointer) { if (!context()->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointers)) { + SpvCapabilityVariablePointers)) { regenerateInstruction = true; } - auto storage_class = - spv::StorageClass(inst_type->GetSingleWordInOperand(0)); - if (storage_class != spv::StorageClass::Workgroup && - storage_class != spv::StorageClass::StorageBuffer) { + uint32_t storage_class = inst_type->GetSingleWordInOperand(0); + if (storage_class != SpvStorageClassWorkgroup && + storage_class != SpvStorageClassStorageBuffer) { regenerateInstruction = true; } } @@ -348,7 +343,7 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block, uint32_t new_id = TakeNextId(); regen_inst->SetResultId(new_id); Instruction* insert_pos = &*merge_block->begin(); - while (insert_pos->opcode() == spv::Op::OpPhi) { + while (insert_pos->opcode() == SpvOpPhi) { insert_pos = insert_pos->NextNode(); } new_phi = insert_pos->InsertBefore(std::move(regen_inst)); @@ -464,7 +459,7 @@ bool MergeReturnPass::BreakFromConstruct( // Leave the phi instructions behind. auto iter = block->begin(); - while (iter->opcode() == spv::Op::OpPhi) { + while (iter->opcode() == SpvOpPhi) { ++iter; } @@ -483,7 +478,7 @@ bool MergeReturnPass::BreakFromConstruct( // If |block| was a continue target for a loop |old_body| is now the correct // continue target. - if (break_merge_inst->opcode() == spv::Op::OpLoopMerge && + if (break_merge_inst->opcode() == SpvOpLoopMerge && break_merge_inst->GetSingleWordInOperand(1) == block->id()) { break_merge_inst->SetInOperand(1, {old_body->id()}); context()->UpdateDefUse(break_merge_inst); @@ -536,8 +531,8 @@ bool MergeReturnPass::BreakFromConstruct( } void MergeReturnPass::RecordReturned(BasicBlock* block) { - if (block->tail()->opcode() != spv::Op::OpReturn && - block->tail()->opcode() != spv::Op::OpReturnValue) + if (block->tail()->opcode() != SpvOpReturn && + block->tail()->opcode() != SpvOpReturnValue) return; assert(return_flag_ && "Did not generate the return flag variable."); @@ -555,7 +550,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) { } std::unique_ptr return_store(new Instruction( - context(), spv::Op::OpStore, 0, 0, + context(), SpvOpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}}, {SPV_OPERAND_TYPE_ID, {constant_true_->result_id()}}})); @@ -568,7 +563,7 @@ void MergeReturnPass::RecordReturned(BasicBlock* block) { void MergeReturnPass::RecordReturnValue(BasicBlock* block) { auto terminator = *block->tail(); - if (terminator.opcode() != spv::Op::OpReturnValue) { + if (terminator.opcode() != SpvOpReturnValue) { return; } @@ -576,7 +571,7 @@ void MergeReturnPass::RecordReturnValue(BasicBlock* block) { "Did not generate the variable to hold the return value."); std::unique_ptr value_store(new Instruction( - context(), spv::Op::OpStore, 0, 0, + context(), SpvOpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}, {SPV_OPERAND_TYPE_ID, {terminator.GetSingleWordInOperand(0u)}}})); @@ -591,19 +586,17 @@ void MergeReturnPass::AddReturnValue() { if (return_value_) return; uint32_t return_type_id = function_->type_id(); - if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == - spv::Op::OpTypeVoid) + if (get_def_use_mgr()->GetDef(return_type_id)->opcode() == SpvOpTypeVoid) return; uint32_t return_ptr_type = context()->get_type_mgr()->FindPointerToType( - return_type_id, spv::StorageClass::Function); + return_type_id, SpvStorageClassFunction); uint32_t var_id = TakeNextId(); - std::unique_ptr returnValue( - new Instruction(context(), spv::Op::OpVariable, return_ptr_type, var_id, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}})); + std::unique_ptr returnValue(new Instruction( + context(), SpvOpVariable, return_ptr_type, var_id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); auto insert_iter = function_->begin()->begin(); insert_iter.InsertBefore(std::move(returnValue)); @@ -613,7 +606,7 @@ void MergeReturnPass::AddReturnValue() { context()->set_instr_block(return_value_, entry_block); context()->get_decoration_mgr()->CloneDecorations( - function_->result_id(), var_id, {spv::Decoration::RelaxedPrecision}); + function_->result_id(), var_id, {SpvDecorationRelaxedPrecision}); } void MergeReturnPass::AddReturnFlag() { @@ -632,14 +625,14 @@ void MergeReturnPass::AddReturnFlag() { const_mgr->GetDefiningInstruction(false_const)->result_id(); uint32_t bool_ptr_id = - type_mgr->FindPointerToType(bool_id, spv::StorageClass::Function); + type_mgr->FindPointerToType(bool_id, SpvStorageClassFunction); uint32_t var_id = TakeNextId(); std::unique_ptr returnFlag(new Instruction( - context(), spv::Op::OpVariable, bool_ptr_id, var_id, - std::initializer_list{{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}, - {SPV_OPERAND_TYPE_ID, {const_false_id}}})); + context(), SpvOpVariable, bool_ptr_id, var_id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, + {SPV_OPERAND_TYPE_ID, {const_false_id}}})); auto insert_iter = function_->begin()->begin(); @@ -655,8 +648,8 @@ std::vector MergeReturnPass::CollectReturnBlocks( std::vector return_blocks; for (auto& block : *function) { Instruction& terminator = *block.tail(); - if (terminator.opcode() == spv::Op::OpReturn || - terminator.opcode() == spv::Op::OpReturnValue) { + if (terminator.opcode() == SpvOpReturn || + terminator.opcode() == SpvOpReturnValue) { return_blocks.push_back(&block); } } @@ -677,7 +670,7 @@ void MergeReturnPass::MergeReturnBlocks( // Create new return. std::vector phi_ops; for (auto block : return_blocks) { - if (block->tail()->opcode() == spv::Op::OpReturnValue) { + if (block->tail()->opcode() == SpvOpReturnValue) { phi_ops.push_back( {SPV_OPERAND_TYPE_ID, {block->tail()->GetSingleWordInOperand(0u)}}); phi_ops.push_back({SPV_OPERAND_TYPE_ID, {block->id()}}); @@ -689,12 +682,12 @@ void MergeReturnPass::MergeReturnBlocks( uint32_t phi_result_id = TakeNextId(); uint32_t phi_type_id = function->type_id(); std::unique_ptr phi_inst(new Instruction( - context(), spv::Op::OpPhi, phi_type_id, phi_result_id, phi_ops)); + context(), SpvOpPhi, phi_type_id, phi_result_id, phi_ops)); ret_block_iter->AddInstruction(std::move(phi_inst)); BasicBlock::iterator phiIter = ret_block_iter->tail(); std::unique_ptr return_inst( - new Instruction(context(), spv::Op::OpReturnValue, 0u, 0u, + new Instruction(context(), SpvOpReturnValue, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {phi_result_id}}})); ret_block_iter->AddInstruction(std::move(return_inst)); BasicBlock::iterator ret = ret_block_iter->tail(); @@ -704,14 +697,14 @@ void MergeReturnPass::MergeReturnBlocks( get_def_use_mgr()->AnalyzeInstDef(&*ret); } else { std::unique_ptr return_inst( - new Instruction(context(), spv::Op::OpReturn)); + new Instruction(context(), SpvOpReturn)); ret_block_iter->AddInstruction(std::move(return_inst)); } // Replace returns with branches for (auto block : return_blocks) { context()->ForgetUses(block->terminator()); - block->tail()->SetOpcode(spv::Op::OpBranch); + block->tail()->SetOpcode(SpvOpBranch); block->tail()->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {return_id}}}); get_def_use_mgr()->AnalyzeInstUse(block->terminator()); get_def_use_mgr()->AnalyzeInstUse(block->GetLabelInst()); @@ -796,7 +789,7 @@ bool MergeReturnPass::AddSingleCaseSwitchAroundFunction() { BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) { std::unique_ptr label( - new Instruction(context(), spv::Op::OpLabel, 0u, TakeNextId(), {})); + new Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {})); // Create the new basic block std::unique_ptr block(new BasicBlock(std::move(label))); @@ -831,7 +824,7 @@ bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) { // block to make sure the OpVariable instructions remain in the entry block. BasicBlock* start_block = &*function_->begin(); auto split_pos = start_block->begin(); - while (split_pos->opcode() == spv::Op::OpVariable) { + while (split_pos->opcode() == SpvOpVariable) { ++split_pos; } @@ -872,7 +865,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) { if (struct_cfg_analysis->IsContinueBlock(bb.id())) { // |bb| must be an empty block ending with a branch to the header. Instruction* inst = &*bb.begin(); - if (inst->opcode() != spv::Op::OpBranch) { + if (inst->opcode() != SpvOpBranch) { return true; } @@ -882,7 +875,7 @@ bool MergeReturnPass::HasNontrivialUnreachableBlocks(Function* function) { } } else if (struct_cfg_analysis->IsMergeBlock(bb.id())) { // |bb| must be an empty block ending with OpUnreachable. - if (bb.begin()->opcode() != spv::Op::OpUnreachable) { + if (bb.begin()->opcode() != SpvOpUnreachable) { return true; } } else { diff --git a/source/opt/module.cpp b/source/opt/module.cpp index a9710c6a..c98af8f5 100644 --- a/source/opt/module.cpp +++ b/source/opt/module.cpp @@ -69,14 +69,14 @@ std::vector Module::GetConstants() const { return const_insts; } -uint32_t Module::GetGlobalValue(spv::Op opcode) const { +uint32_t Module::GetGlobalValue(SpvOp opcode) const { for (auto& inst : types_values_) { if (inst.opcode() == opcode) return inst.result_id(); } return 0; } -void Module::AddGlobalValue(spv::Op opcode, uint32_t result_id, +void Module::AddGlobalValue(SpvOp opcode, uint32_t result_id, uint32_t type_id) { std::unique_ptr newGlobal( new Instruction(context(), opcode, type_id, result_id, {})); @@ -159,6 +159,7 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { if (between_merge_and_branch && i->IsLineInst()) { return; } + between_merge_and_branch = false; if (last_line_inst != nullptr) { // If the current instruction is OpLine or DebugLine and it is the same // as the last line instruction that is still effective (can be applied @@ -180,30 +181,28 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { ->get_feature_mgr() ->GetExtInstImportId_Shader100DebugInfo(); if (shader_set_id != 0) { - binary->push_back((5 << 16) | - static_cast(spv::Op::OpExtInst)); + binary->push_back((5 << 16) | static_cast(SpvOpExtInst)); binary->push_back(context()->get_type_mgr()->GetVoidTypeId()); binary->push_back(context()->TakeNextId()); binary->push_back(shader_set_id); binary->push_back(NonSemanticShaderDebugInfo100DebugNoLine); } else { - binary->push_back((1 << 16) | - static_cast(spv::Op::OpNoLine)); + binary->push_back((1 << 16) | static_cast(SpvOpNoLine)); } last_line_inst = nullptr; } } - if (opcode == spv::Op::OpLabel) { + if (opcode == SpvOpLabel) { between_label_and_phi_var = true; - } else if (opcode != spv::Op::OpVariable && opcode != spv::Op::OpPhi && + } else if (opcode != SpvOpVariable && opcode != SpvOpPhi && !spvtools::opt::IsOpLineInst(opcode)) { between_label_and_phi_var = false; } if (!(skip_nop && i->IsNop())) { const auto& scope = i->GetDebugScope(); - if (scope != last_scope && !between_merge_and_branch) { + if (scope != last_scope) { // Can only emit nonsemantic instructions after all phi instructions // in a block so don't emit scope instructions before phi instructions // for NonSemantic.Shader.DebugInfo.100. @@ -222,11 +221,9 @@ void Module::ToBinary(std::vector* binary, bool skip_nop) const { i->ToBinaryWithoutAttachedDebugInsts(binary); } // Update the last line instruction. - between_merge_and_branch = false; if (spvOpcodeIsBlockTerminator(opcode) || i->IsNoLine()) { last_line_inst = nullptr; - } else if (opcode == spv::Op::OpLoopMerge || - opcode == spv::Op::OpSelectionMerge) { + } else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) { between_merge_and_branch = true; last_line_inst = nullptr; } else if (i->IsLine()) { @@ -275,7 +272,7 @@ uint32_t Module::GetExtInstImportId(const char* extstr) { std::ostream& operator<<(std::ostream& str, const Module& module) { module.ForEachInst([&str](const Instruction* inst) { str << *inst; - if (inst->opcode() != spv::Op::OpFunctionEnd) { + if (inst->opcode() != SpvOpFunctionEnd) { str << std::endl; } }); diff --git a/source/opt/module.h b/source/opt/module.h index 98c16dc4..7a6be460 100644 --- a/source/opt/module.h +++ b/source/opt/module.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -120,9 +119,6 @@ class Module { // Appends a constant, global variable, or OpUndef instruction to this module. inline void AddGlobalValue(std::unique_ptr v); - // Prepends a function declaration to this module. - inline void AddFunctionDeclaration(std::unique_ptr f); - // Appends a function to this module. inline void AddFunction(std::unique_ptr f); @@ -140,10 +136,10 @@ class Module { std::vector GetConstants() const; // Return result id of global value with |opcode|, 0 if not present. - uint32_t GetGlobalValue(spv::Op opcode) const; + uint32_t GetGlobalValue(SpvOp opcode) const; // Add global value with |opcode|, |result_id| and |type_id| - void AddGlobalValue(spv::Op opcode, uint32_t result_id, uint32_t type_id); + void AddGlobalValue(SpvOp opcode, uint32_t result_id, uint32_t type_id); inline uint32_t id_bound() const { return header_.bound; } @@ -383,11 +379,6 @@ inline void Module::AddGlobalValue(std::unique_ptr v) { types_values_.push_back(std::move(v)); } -inline void Module::AddFunctionDeclaration(std::unique_ptr f) { - // function declarations must come before function definitions. - functions_.emplace(functions_.begin(), std::move(f)); -} - inline void Module::AddFunction(std::unique_ptr f) { functions_.emplace_back(std::move(f)); } diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp index d865cf1d..381589b5 100644 --- a/source/opt/optimizer.cpp +++ b/source/opt/optimizer.cpp @@ -15,7 +15,6 @@ #include "spirv-tools/optimizer.hpp" #include -#include #include #include #include @@ -61,7 +60,6 @@ struct Optimizer::Impl { spv_target_env target_env; // Target environment. opt::PassManager pass_manager; // Internal implementation pass manager. - std::unordered_set live_locs; // Arg to debug dead output passes }; Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) { @@ -110,7 +108,7 @@ Optimizer& Optimizer::RegisterPass(PassToken&& p) { // The legalization problem is essentially a very general copy propagation // problem. The optimization we use are all used to either do copy propagation // or enable more copy propagation. -Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { +Optimizer& Optimizer::RegisterLegalizationPasses() { return // Wrap OpKill instructions so all other code can be inlined. RegisterPass(CreateWrapOpKillPass()) @@ -130,16 +128,16 @@ Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { // Propagate the value stored to the loads in very simple cases. .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) .RegisterPass(CreateLocalSingleStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) // Split up aggregates so they are easier to deal with. .RegisterPass(CreateScalarReplacementPass(0)) // Remove loads and stores so everything is in intermediate values. // Takes care of copy propagation of non-members. .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) .RegisterPass(CreateLocalSingleStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateLocalMultiStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) // Propagate constants to get as many constant conditions on branches // as possible. .RegisterPass(CreateCCPPass()) @@ -148,7 +146,7 @@ Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { // Copy propagate members. Cleans up code sequences generated by // scalar replacement. Also important for removing OpPhi nodes. .RegisterPass(CreateSimplificationPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateCopyPropagateArraysPass()) // May need loop unrolling here see // https://github.com/Microsoft/DirectXShaderCompiler/pull/930 @@ -157,35 +155,30 @@ Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { .RegisterPass(CreateVectorDCEPass()) .RegisterPass(CreateDeadInsertElimPass()) .RegisterPass(CreateReduceLoadSizePass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) - .RegisterPass(CreateInterpolateFixupPass()) - .RegisterPass(CreateInvocationInterlockPlacementPass()); + .RegisterPass(CreateAggressiveDCEPass()) + .RegisterPass(CreateInterpolateFixupPass()); } -Optimizer& Optimizer::RegisterLegalizationPasses() { - return RegisterLegalizationPasses(false); -} - -Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) { +Optimizer& Optimizer::RegisterPerformancePasses() { return RegisterPass(CreateWrapOpKillPass()) .RegisterPass(CreateDeadBranchElimPass()) .RegisterPass(CreateMergeReturnPass()) .RegisterPass(CreateInlineExhaustivePass()) .RegisterPass(CreateEliminateDeadFunctionsPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreatePrivateToLocalPass()) .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) .RegisterPass(CreateLocalSingleStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateScalarReplacementPass()) .RegisterPass(CreateLocalAccessChainConvertPass()) .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) .RegisterPass(CreateLocalSingleStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateLocalMultiStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateCCPPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateLoopUnrollPass(true)) .RegisterPass(CreateDeadBranchElimPass()) .RegisterPass(CreateRedundancyEliminationPass()) @@ -195,9 +188,9 @@ Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) { .RegisterPass(CreateLocalAccessChainConvertPass()) .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) .RegisterPass(CreateLocalSingleStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateSSARewritePass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateVectorDCEPass()) .RegisterPass(CreateDeadInsertElimPass()) .RegisterPass(CreateDeadBranchElimPass()) @@ -205,7 +198,7 @@ Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) { .RegisterPass(CreateIfConversionPass()) .RegisterPass(CreateCopyPropagateArraysPass()) .RegisterPass(CreateReduceLoadSizePass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateBlockMergePass()) .RegisterPass(CreateRedundancyEliminationPass()) .RegisterPass(CreateDeadBranchElimPass()) @@ -213,11 +206,7 @@ Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) { .RegisterPass(CreateSimplificationPass()); } -Optimizer& Optimizer::RegisterPerformancePasses() { - return RegisterPerformancePasses(false); -} - -Optimizer& Optimizer::RegisterSizePasses(bool preserve_interface) { +Optimizer& Optimizer::RegisterSizePasses() { return RegisterPass(CreateWrapOpKillPass()) .RegisterPass(CreateDeadBranchElimPass()) .RegisterPass(CreateMergeReturnPass()) @@ -234,12 +223,12 @@ Optimizer& Optimizer::RegisterSizePasses(bool preserve_interface) { .RegisterPass(CreateLocalSingleStoreElimPass()) .RegisterPass(CreateIfConversionPass()) .RegisterPass(CreateSimplificationPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateDeadBranchElimPass()) .RegisterPass(CreateBlockMergePass()) .RegisterPass(CreateLocalAccessChainConvertPass()) .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateCopyPropagateArraysPass()) .RegisterPass(CreateVectorDCEPass()) .RegisterPass(CreateDeadInsertElimPass()) @@ -249,12 +238,10 @@ Optimizer& Optimizer::RegisterSizePasses(bool preserve_interface) { .RegisterPass(CreateLocalMultiStoreElimPass()) .RegisterPass(CreateRedundancyEliminationPass()) .RegisterPass(CreateSimplificationPass()) - .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) + .RegisterPass(CreateAggressiveDCEPass()) .RegisterPass(CreateCFGCleanupPass()); } -Optimizer& Optimizer::RegisterSizePasses() { return RegisterSizePasses(false); } - bool Optimizer::RegisterPassesFromFlags(const std::vector& flags) { for (const auto& flag : flags) { if (!RegisterPassFromFlag(flag)) { @@ -431,26 +418,32 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { RegisterPass(CreateWorkaround1209Pass()); } else if (pass_name == "replace-invalid-opcode") { RegisterPass(CreateReplaceInvalidOpcodePass()); - } else if (pass_name == "inst-bindless-check" || - pass_name == "inst-desc-idx-check" || - pass_name == "inst-buff-oob-check") { - // preserve legacy names - RegisterPass(CreateInstBindlessCheckPass(23)); + } else if (pass_name == "inst-bindless-check") { + RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false)); RegisterPass(CreateSimplificationPass()); RegisterPass(CreateDeadBranchElimPass()); RegisterPass(CreateBlockMergePass()); + RegisterPass(CreateAggressiveDCEPass(true)); + } else if (pass_name == "inst-desc-idx-check") { + RegisterPass(CreateInstBindlessCheckPass(7, 23, true, true)); + RegisterPass(CreateSimplificationPass()); + RegisterPass(CreateDeadBranchElimPass()); + RegisterPass(CreateBlockMergePass()); + RegisterPass(CreateAggressiveDCEPass(true)); + } else if (pass_name == "inst-buff-oob-check") { + RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false, true, true)); + RegisterPass(CreateSimplificationPass()); + RegisterPass(CreateDeadBranchElimPass()); + RegisterPass(CreateBlockMergePass()); + RegisterPass(CreateAggressiveDCEPass(true)); } else if (pass_name == "inst-buff-addr-check") { - RegisterPass(CreateInstBuffAddrCheckPass(23)); + RegisterPass(CreateInstBuffAddrCheckPass(7, 23)); + RegisterPass(CreateAggressiveDCEPass(true)); } else if (pass_name == "convert-relaxed-to-half") { RegisterPass(CreateConvertRelaxedToHalfPass()); } else if (pass_name == "relax-float-ops") { RegisterPass(CreateRelaxFloatOpsPass()); } else if (pass_name == "inst-debug-printf") { - // This private option is not for user consumption. - // It is here to assist in debugging and fixing the debug printf - // instrumentation pass. - // For users who wish to utilize debug printf, see the white paper at - // https://www.lunarg.com/wp-content/uploads/2021/08/Using-Debug-Printf-02August2021.pdf RegisterPass(CreateInstDebugPrintfPass(7, 23)); } else if (pass_name == "simplify-instructions") { RegisterPass(CreateSimplificationPass()); @@ -531,7 +524,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { } else if (pass_name == "remove-dont-inline") { RegisterPass(CreateRemoveDontInlinePass()); } else if (pass_name == "eliminate-dead-input-components") { - RegisterPass(CreateEliminateDeadInputComponentsSafePass()); + RegisterPass(CreateEliminateDeadInputComponentsPass()); } else if (pass_name == "fix-func-call-param") { RegisterPass(CreateFixFuncCallArgumentsPass()); } else if (pass_name == "convert-to-sampled-image") { @@ -554,39 +547,6 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { pass_args.c_str()); return false; } - } else if (pass_name == "switch-descriptorset") { - if (pass_args.size() == 0) { - Error(consumer(), nullptr, {}, - "--switch-descriptorset requires a from:to argument."); - return false; - } - uint32_t from_set = 0, to_set = 0; - const char* start = pass_args.data(); - const char* end = pass_args.data() + pass_args.size(); - - auto result = std::from_chars(start, end, from_set); - if (result.ec != std::errc()) { - Errorf(consumer(), nullptr, {}, - "Invalid argument for --switch-descriptorset: %s", - pass_args.c_str()); - return false; - } - start = result.ptr; - if (start[0] != ':') { - Errorf(consumer(), nullptr, {}, - "Invalid argument for --switch-descriptorset: %s", - pass_args.c_str()); - return false; - } - start++; - result = std::from_chars(start, end, to_set); - if (result.ec != std::errc() || result.ptr != end) { - Errorf(consumer(), nullptr, {}, - "Invalid argument for --switch-descriptorset: %s", - pass_args.c_str()); - return false; - } - RegisterPass(CreateSwitchDescriptorSetPass(from_set, to_set)); } else { Errorf(consumer(), nullptr, {}, "Unknown flag '--%s'. Use --help for a list of valid flags", @@ -826,18 +786,12 @@ Optimizer::PassToken CreateLocalMultiStoreElimPass() { Optimizer::PassToken CreateAggressiveDCEPass() { return MakeUnique( - MakeUnique(false, false)); + MakeUnique(false)); } Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface) { return MakeUnique( - MakeUnique(preserve_interface, false)); -} - -Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, - bool remove_outputs) { - return MakeUnique( - MakeUnique(preserve_interface, remove_outputs)); + MakeUnique(preserve_interface)); } Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass() { @@ -984,9 +938,14 @@ Optimizer::PassToken CreateUpgradeMemoryModelPass() { MakeUnique()); } -Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id) { +Optimizer::PassToken CreateInstBindlessCheckPass( + uint32_t desc_set, uint32_t shader_id, bool desc_length_enable, + bool desc_init_enable, bool buff_oob_enable, bool texbuff_oob_enable) { return MakeUnique( - MakeUnique(shader_id)); + MakeUnique( + desc_set, shader_id, desc_length_enable, desc_init_enable, + buff_oob_enable, texbuff_oob_enable, + desc_length_enable || desc_init_enable || buff_oob_enable)); } Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set, @@ -995,9 +954,10 @@ Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set, MakeUnique(desc_set, shader_id)); } -Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id) { +Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t desc_set, + uint32_t shader_id) { return MakeUnique( - MakeUnique(shader_id)); + MakeUnique(desc_set, shader_id)); } Optimizer::PassToken CreateConvertRelaxedToHalfPass() { @@ -1056,34 +1016,7 @@ Optimizer::PassToken CreateInterpolateFixupPass() { Optimizer::PassToken CreateEliminateDeadInputComponentsPass() { return MakeUnique( - MakeUnique(spv::StorageClass::Input, - /* safe_mode */ false)); -} - -Optimizer::PassToken CreateEliminateDeadOutputComponentsPass() { - return MakeUnique( - MakeUnique(spv::StorageClass::Output, - /* safe_mode */ false)); -} - -Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass() { - return MakeUnique( - MakeUnique(spv::StorageClass::Input, - /* safe_mode */ true)); -} - -Optimizer::PassToken CreateAnalyzeLiveInputPass( - std::unordered_set* live_locs, - std::unordered_set* live_builtins) { - return MakeUnique( - MakeUnique(live_locs, live_builtins)); -} - -Optimizer::PassToken CreateEliminateDeadOutputStoresPass( - std::unordered_set* live_locs, - std::unordered_set* live_builtins) { - return MakeUnique( - MakeUnique(live_locs, live_builtins)); + MakeUnique()); } Optimizer::PassToken CreateConvertToSampledImagePass( @@ -1107,111 +1040,4 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass() { return MakeUnique( MakeUnique()); } - -Optimizer::PassToken CreateTrimCapabilitiesPass() { - return MakeUnique( - MakeUnique()); -} - -Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) { - return MakeUnique( - MakeUnique(from, to)); -} - -Optimizer::PassToken CreateInvocationInterlockPlacementPass() { - return MakeUnique( - MakeUnique()); -} } // namespace spvtools - -extern "C" { - -SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env) { - return reinterpret_cast(new spvtools::Optimizer(env)); -} - -SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer) { - delete reinterpret_cast(optimizer); -} - -SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer( - spv_optimizer_t* optimizer, spv_message_consumer consumer) { - reinterpret_cast(optimizer)-> - SetMessageConsumer( - [consumer](spv_message_level_t level, const char* source, - const spv_position_t& position, const char* message) { - return consumer(level, source, &position, message); - }); -} - -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses( - spv_optimizer_t* optimizer) { - reinterpret_cast(optimizer)-> - RegisterLegalizationPasses(); -} - -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses( - spv_optimizer_t* optimizer) { - reinterpret_cast(optimizer)-> - RegisterPerformancePasses(); -} - -SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses( - spv_optimizer_t* optimizer) { - reinterpret_cast(optimizer)->RegisterSizePasses(); -} - -SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag( - spv_optimizer_t* optimizer, const char* flag) -{ - return reinterpret_cast(optimizer)-> - RegisterPassFromFlag(flag); -} - -SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags( - spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) { - std::vector opt_flags; - for (uint32_t i = 0; i < flag_count; i++) { - opt_flags.emplace_back(flags[i]); - } - - return reinterpret_cast(optimizer)-> - RegisterPassesFromFlags(opt_flags); -} - -SPIRV_TOOLS_EXPORT -spv_result_t spvOptimizerRun(spv_optimizer_t* optimizer, - const uint32_t* binary, - const size_t word_count, - spv_binary* optimized_binary, - const spv_optimizer_options options) { - std::vector optimized; - - if (!reinterpret_cast(optimizer)-> - Run(binary, word_count, &optimized, options)) { - return SPV_ERROR_INTERNAL; - } - - auto result_binary = new spv_binary_t(); - if (!result_binary) { - *optimized_binary = nullptr; - return SPV_ERROR_OUT_OF_MEMORY; - } - - result_binary->code = new uint32_t[optimized.size()]; - if (!result_binary->code) { - delete result_binary; - *optimized_binary = nullptr; - return SPV_ERROR_OUT_OF_MEMORY; - } - result_binary->wordCount = optimized.size(); - - memcpy(result_binary->code, optimized.data(), - optimized.size() * sizeof(uint32_t)); - - *optimized_binary = result_binary; - - return SPV_SUCCESS; -} - -} // extern "C" diff --git a/source/opt/pass.cpp b/source/opt/pass.cpp index 75c37407..017aad10 100644 --- a/source/opt/pass.cpp +++ b/source/opt/pass.cpp @@ -21,8 +21,11 @@ namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kTypePointerTypeIdInIdx = 1; + +const uint32_t kTypePointerTypeIdInIdx = 1; + } // namespace Pass::Pass() : consumer_(nullptr), context_(nullptr), already_run_(false) {} @@ -53,11 +56,11 @@ uint32_t Pass::GetPointeeTypeId(const Instruction* ptrInst) const { Instruction* Pass::GetBaseType(uint32_t ty_id) { Instruction* ty_inst = get_def_use_mgr()->GetDef(ty_id); - if (ty_inst->opcode() == spv::Op::OpTypeMatrix) { + if (ty_inst->opcode() == SpvOpTypeMatrix) { uint32_t vty_id = ty_inst->GetSingleWordInOperand(0); ty_inst = get_def_use_mgr()->GetDef(vty_id); } - if (ty_inst->opcode() == spv::Op::OpTypeVector) { + if (ty_inst->opcode() == SpvOpTypeVector) { uint32_t cty_id = ty_inst->GetSingleWordInOperand(0); ty_inst = get_def_use_mgr()->GetDef(cty_id); } @@ -66,12 +69,12 @@ Instruction* Pass::GetBaseType(uint32_t ty_id) { bool Pass::IsFloat(uint32_t ty_id, uint32_t width) { Instruction* ty_inst = GetBaseType(ty_id); - if (ty_inst->opcode() != spv::Op::OpTypeFloat) return false; + if (ty_inst->opcode() != SpvOpTypeFloat) return false; return ty_inst->GetSingleWordInOperand(0) == width; } uint32_t Pass::GetNullId(uint32_t type_id) { - if (IsFloat(type_id, 16)) context()->AddCapability(spv::Capability::Float16); + if (IsFloat(type_id, 16)) context()->AddCapability(SpvCapabilityFloat16); analysis::TypeManager* type_mgr = context()->get_type_mgr(); analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); const analysis::Type* type = type_mgr->GetType(type_id); diff --git a/source/opt/pass_manager.cpp b/source/opt/pass_manager.cpp index 88de57e5..d3c47e7f 100644 --- a/source/opt/pass_manager.cpp +++ b/source/opt/pass_manager.cpp @@ -18,8 +18,8 @@ #include #include -#include "third_party/spirv-tools/source/opt/ir_context.h" -#include "third_party/spirv-tools/source/util/timer.h" +#include "source/opt/ir_context.h" +#include "source/util/timer.h" #include "spirv-tools/libspirv.hpp" namespace spvtools { diff --git a/source/opt/passes.h b/source/opt/passes.h index 305f5782..21354c77 100644 --- a/source/opt/passes.h +++ b/source/opt/passes.h @@ -19,7 +19,6 @@ #include "source/opt/aggressive_dead_code_elim_pass.h" #include "source/opt/amd_ext_to_khr.h" -#include "source/opt/analyze_live_input_pass.h" #include "source/opt/block_merge_pass.h" #include "source/opt/ccp_pass.h" #include "source/opt/cfg_cleanup_pass.h" @@ -35,9 +34,8 @@ #include "source/opt/desc_sroa.h" #include "source/opt/eliminate_dead_constant_pass.h" #include "source/opt/eliminate_dead_functions_pass.h" -#include "source/opt/eliminate_dead_io_components_pass.h" +#include "source/opt/eliminate_dead_input_components_pass.h" #include "source/opt/eliminate_dead_members_pass.h" -#include "source/opt/eliminate_dead_output_stores_pass.h" #include "source/opt/empty_pass.h" #include "source/opt/fix_func_call_arguments.h" #include "source/opt/fix_storage_class.h" @@ -53,7 +51,6 @@ #include "source/opt/inst_debug_printf_pass.h" #include "source/opt/interface_var_sroa.h" #include "source/opt/interp_fixup_pass.h" -#include "source/opt/invocation_interlock_placement_pass.h" #include "source/opt/licm_pass.h" #include "source/opt/local_access_chain_convert_pass.h" #include "source/opt/local_redundancy_elimination.h" @@ -83,8 +80,6 @@ #include "source/opt/strength_reduction_pass.h" #include "source/opt/strip_debug_info_pass.h" #include "source/opt/strip_nonsemantic_info_pass.h" -#include "source/opt/switch_descriptorset_pass.h" -#include "source/opt/trim_capabilities_pass.h" #include "source/opt/unify_const_pass.h" #include "source/opt/upgrade_memory_model.h" #include "source/opt/vector_dce.h" diff --git a/source/opt/private_to_local_pass.cpp b/source/opt/private_to_local_pass.cpp index 4904e058..80fb4c53 100644 --- a/source/opt/private_to_local_pass.cpp +++ b/source/opt/private_to_local_pass.cpp @@ -24,8 +24,10 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kVariableStorageClassInIdx = 0; -constexpr uint32_t kSpvTypePointerTypeIdInIdx = 1; + +const uint32_t kVariableStorageClassInIdx = 0; +const uint32_t kSpvTypePointerTypeIdInIdx = 1; + } // namespace Pass::Status PrivateToLocalPass::Process() { @@ -33,18 +35,18 @@ Pass::Status PrivateToLocalPass::Process() { // Private variables require the shader capability. If this is not a shader, // there is no work to do. - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Addresses)) + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) return Status::SuccessWithoutChange; std::vector> variables_to_move; std::unordered_set localized_variables; for (auto& inst : context()->types_values()) { - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { continue; } - if (spv::StorageClass(inst.GetSingleWordInOperand( - kVariableStorageClassInIdx)) != spv::StorageClass::Private) { + if (inst.GetSingleWordInOperand(kVariableStorageClassInIdx) != + SpvStorageClassPrivate) { continue; } @@ -121,8 +123,7 @@ bool PrivateToLocalPass::MoveVariable(Instruction* variable, context()->ForgetUses(variable); // Update the storage class of the variable. - variable->SetInOperand(kVariableStorageClassInIdx, - {uint32_t(spv::StorageClass::Function)}); + variable->SetInOperand(kVariableStorageClassInIdx, {SpvStorageClassFunction}); // Update the type as well. uint32_t new_type_id = GetNewType(variable->type_id()); @@ -146,7 +147,7 @@ uint32_t PrivateToLocalPass::GetNewType(uint32_t old_type_id) { uint32_t pointee_type_id = old_type_inst->GetSingleWordInOperand(kSpvTypePointerTypeIdInIdx); uint32_t new_type_id = - type_mgr->FindPointerToType(pointee_type_id, spv::StorageClass::Function); + type_mgr->FindPointerToType(pointee_type_id, SpvStorageClassFunction); if (new_type_id != 0) { context()->UpdateDefUse(context()->get_def_use_mgr()->GetDef(new_type_id)); } @@ -160,17 +161,17 @@ bool PrivateToLocalPass::IsValidUse(const Instruction* inst) const { return true; } switch (inst->opcode()) { - case spv::Op::OpLoad: - case spv::Op::OpStore: - case spv::Op::OpImageTexelPointer: // Treat like a load + case SpvOpLoad: + case SpvOpStore: + case SpvOpImageTexelPointer: // Treat like a load return true; - case spv::Op::OpAccessChain: + case SpvOpAccessChain: return context()->get_def_use_mgr()->WhileEachUser( inst, [this](const Instruction* user) { if (!IsValidUse(user)) return false; return true; }); - case spv::Op::OpName: + case SpvOpName: return true; default: return spvOpcodeIsDecoration(inst->opcode()); @@ -187,13 +188,13 @@ bool PrivateToLocalPass::UpdateUse(Instruction* inst, Instruction* user) { return true; } switch (inst->opcode()) { - case spv::Op::OpLoad: - case spv::Op::OpStore: - case spv::Op::OpImageTexelPointer: // Treat like a load + case SpvOpLoad: + case SpvOpStore: + case SpvOpImageTexelPointer: // Treat like a load // The type is fine because it is the type pointed to, and that does not // change. break; - case spv::Op::OpAccessChain: { + case SpvOpAccessChain: { context()->ForgetUses(inst); uint32_t new_type_id = GetNewType(inst->type_id()); if (new_type_id == 0) { @@ -207,8 +208,8 @@ bool PrivateToLocalPass::UpdateUse(Instruction* inst, Instruction* user) { return false; } } break; - case spv::Op::OpName: - case spv::Op::OpEntryPoint: // entry points will be updated separately. + case SpvOpName: + case SpvOpEntryPoint: // entry points will be updated separately. break; default: assert(spvOpcodeIsDecoration(inst->opcode()) && diff --git a/source/opt/propagator.cpp b/source/opt/propagator.cpp index 9cd6174c..6a1f1aaf 100644 --- a/source/opt/propagator.cpp +++ b/source/opt/propagator.cpp @@ -134,7 +134,7 @@ bool SSAPropagator::Simulate(Instruction* instr) { // defined at an instruction D that should be simulated again, then the output // of D might affect |instr|, so we should simulate |instr| again. bool has_operands_to_simulate = false; - if (instr->opcode() == spv::Op::OpPhi) { + if (instr->opcode() == SpvOpPhi) { // For Phi instructions, an operand causes the Phi to be simulated again if // the operand comes from an edge that has not yet been traversed or if its // definition should be simulated again. @@ -189,7 +189,7 @@ bool SSAPropagator::Simulate(BasicBlock* block) { // statement in it. if (!BlockHasBeenSimulated(block)) { block->ForEachInst([this, &changed](Instruction* instr) { - if (instr->opcode() != spv::Op::OpPhi) { + if (instr->opcode() != SpvOpPhi) { changed |= Simulate(instr); } }); diff --git a/source/opt/propagator.h b/source/opt/propagator.h index 71212c96..ac7c0e7e 100644 --- a/source/opt/propagator.h +++ b/source/opt/propagator.h @@ -153,10 +153,10 @@ struct Edge { // std::map values; // const auto visit_fn = [&ctx, &values](Instruction* instr, // BasicBlock** dest_bb) { -// if (instr->opcode() == spv::Op::OpStore) { +// if (instr->opcode() == SpvOpStore) { // uint32_t rhs_id = instr->GetSingleWordOperand(1); // Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id); -// if (rhs_def->opcode() == spv::Op::OpConstant) { +// if (rhs_def->opcode() == SpvOpConstant) { // uint32_t val = rhs_def->GetSingleWordOperand(2); // values[rhs_id] = val; // return SSAPropagator::kInteresting; diff --git a/source/opt/reduce_load_size.cpp b/source/opt/reduce_load_size.cpp index 73a90f06..56491b2f 100644 --- a/source/opt/reduce_load_size.cpp +++ b/source/opt/reduce_load_size.cpp @@ -22,20 +22,23 @@ #include "source/opt/ir_context.h" #include "source/util/bit_vector.h" +namespace { + +const uint32_t kExtractCompositeIdInIdx = 0; +const uint32_t kVariableStorageClassInIdx = 0; +const uint32_t kLoadPointerInIdx = 0; + +} // namespace + namespace spvtools { namespace opt { -namespace { -constexpr uint32_t kExtractCompositeIdInIdx = 0; -constexpr uint32_t kVariableStorageClassInIdx = 0; -constexpr uint32_t kLoadPointerInIdx = 0; -} // namespace Pass::Status ReduceLoadSize::Process() { bool modified = false; for (auto& func : *get_module()) { func.ForEachInst([&modified, this](Instruction* inst) { - if (inst->opcode() == spv::Op::OpCompositeExtract) { + if (inst->opcode() == SpvOpCompositeExtract) { if (ShouldReplaceExtract(inst)) { modified |= ReplaceExtract(inst); } @@ -47,7 +50,7 @@ Pass::Status ReduceLoadSize::Process() { } bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCompositeExtract && + assert(inst->opcode() == SpvOpCompositeExtract && "Wrong opcode. Should be OpCompositeExtract."); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); analysis::TypeManager* type_mgr = context()->get_type_mgr(); @@ -57,7 +60,7 @@ bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { inst->GetSingleWordInOperand(kExtractCompositeIdInIdx); Instruction* composite_inst = def_use_mgr->GetDef(composite_id); - if (composite_inst->opcode() != spv::Op::OpLoad) { + if (composite_inst->opcode() != SpvOpLoad) { return false; } @@ -68,16 +71,16 @@ bool ReduceLoadSize::ReplaceExtract(Instruction* inst) { } Instruction* var = composite_inst->GetBaseAddress(); - if (var == nullptr || var->opcode() != spv::Op::OpVariable) { + if (var == nullptr || var->opcode() != SpvOpVariable) { return false; } - spv::StorageClass storage_class = static_cast( + SpvStorageClass storage_class = static_cast( var->GetSingleWordInOperand(kVariableStorageClassInIdx)); switch (storage_class) { - case spv::StorageClass::Uniform: - case spv::StorageClass::UniformConstant: - case spv::StorageClass::Input: + case SpvStorageClassUniform: + case SpvStorageClassUniformConstant: + case SpvStorageClassInput: break; default: return false; @@ -121,7 +124,7 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) { Instruction* op_inst = def_use_mgr->GetDef( inst->GetSingleWordInOperand(kExtractCompositeIdInIdx)); - if (op_inst->opcode() != spv::Op::OpLoad) { + if (op_inst->opcode() != SpvOpLoad) { return false; } @@ -136,7 +139,7 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) { all_elements_used = !def_use_mgr->WhileEachUser(op_inst, [&elements_used](Instruction* use) { if (use->IsCommonDebugInstr()) return true; - if (use->opcode() != spv::Op::OpCompositeExtract || + if (use->opcode() != SpvOpCompositeExtract || use->NumInOperands() == 1) { return false; } diff --git a/source/opt/reflect.h b/source/opt/reflect.h index ec7c2dd0..c2ffb0be 100644 --- a/source/opt/reflect.h +++ b/source/opt/reflect.h @@ -16,7 +16,6 @@ #define SOURCE_OPT_REFLECT_H_ #include "source/latest_version_spirv_header.h" -#include "source/opcode.h" namespace spvtools { namespace opt { @@ -25,36 +24,41 @@ namespace opt { // following functions tend to be outdated and should be updated when SPIR-V // version bumps. -inline bool IsDebug1Inst(spv::Op opcode) { - return (opcode >= spv::Op::OpSourceContinued && - opcode <= spv::Op::OpSourceExtension) || - opcode == spv::Op::OpString; +inline bool IsDebug1Inst(SpvOp opcode) { + return (opcode >= SpvOpSourceContinued && opcode <= SpvOpSourceExtension) || + opcode == SpvOpString; } -inline bool IsDebug2Inst(spv::Op opcode) { - return opcode == spv::Op::OpName || opcode == spv::Op::OpMemberName; +inline bool IsDebug2Inst(SpvOp opcode) { + return opcode == SpvOpName || opcode == SpvOpMemberName; } -inline bool IsDebug3Inst(spv::Op opcode) { - return opcode == spv::Op::OpModuleProcessed; +inline bool IsDebug3Inst(SpvOp opcode) { + return opcode == SpvOpModuleProcessed; } -inline bool IsOpLineInst(spv::Op opcode) { - return opcode == spv::Op::OpLine || opcode == spv::Op::OpNoLine; +inline bool IsOpLineInst(SpvOp opcode) { + return opcode == SpvOpLine || opcode == SpvOpNoLine; } -inline bool IsAnnotationInst(spv::Op opcode) { - return (opcode >= spv::Op::OpDecorate && - opcode <= spv::Op::OpGroupMemberDecorate) || - opcode == spv::Op::OpDecorateId || - opcode == spv::Op::OpDecorateStringGOOGLE || - opcode == spv::Op::OpMemberDecorateStringGOOGLE; +inline bool IsAnnotationInst(SpvOp opcode) { + return (opcode >= SpvOpDecorate && opcode <= SpvOpGroupMemberDecorate) || + opcode == SpvOpDecorateId || opcode == SpvOpDecorateStringGOOGLE || + opcode == SpvOpMemberDecorateStringGOOGLE; } -inline bool IsTypeInst(spv::Op opcode) { - return spvOpcodeGeneratesType(opcode) || - opcode == spv::Op::OpTypeForwardPointer; +inline bool IsTypeInst(SpvOp opcode) { + return (opcode >= SpvOpTypeVoid && opcode <= SpvOpTypeForwardPointer) || + opcode == SpvOpTypePipeStorage || opcode == SpvOpTypeNamedBarrier || + opcode == SpvOpTypeAccelerationStructureNV || + opcode == SpvOpTypeAccelerationStructureKHR || + opcode == SpvOpTypeRayQueryKHR || + opcode == SpvOpTypeCooperativeMatrixNV; } -inline bool IsConstantInst(spv::Op opcode) { - return spvOpcodeIsConstant(opcode); +inline bool IsConstantInst(SpvOp opcode) { + return (opcode >= SpvOpConstantTrue && opcode <= SpvOpSpecConstantOp) || + opcode == SpvOpConstantFunctionPointerINTEL; } -inline bool IsSpecConstantInst(spv::Op opcode) { - return spvOpcodeIsSpecConstant(opcode); +inline bool IsCompileTimeConstantInst(SpvOp opcode) { + return opcode >= SpvOpConstantTrue && opcode <= SpvOpConstantNull; +} +inline bool IsSpecConstantInst(SpvOp opcode) { + return opcode >= SpvOpSpecConstantTrue && opcode <= SpvOpSpecConstantOp; } } // namespace opt diff --git a/source/opt/register_pressure.cpp b/source/opt/register_pressure.cpp index 34a8ba3e..1ad33738 100644 --- a/source/opt/register_pressure.cpp +++ b/source/opt/register_pressure.cpp @@ -26,6 +26,7 @@ namespace spvtools { namespace opt { + namespace { // Predicate for the FilterIterator to only consider instructions that are not // phi instructions defined in the basic block |bb|. @@ -35,7 +36,7 @@ class ExcludePhiDefinedInBlock { : context_(context), bb_(bb) {} bool operator()(Instruction* insn) const { - return !(insn->opcode() == spv::Op::OpPhi && + return !(insn->opcode() == SpvOpPhi && context_->get_instr_block(insn) == bb_); } @@ -48,9 +49,9 @@ class ExcludePhiDefinedInBlock { // physical register. bool CreatesRegisterUsage(Instruction* insn) { if (!insn->HasResultId()) return false; - if (insn->opcode() == spv::Op::OpUndef) return false; + if (insn->opcode() == SpvOpUndef) return false; if (IsConstantInst(insn->opcode())) return false; - if (insn->opcode() == spv::Op::OpLabel) return false; + if (insn->opcode() == SpvOpLabel) return false; return true; } @@ -146,7 +147,7 @@ class ComputeRegisterLiveness { live_inout->live_in_ = live_inout->live_out_; for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { - if (insn.opcode() == spv::Op::OpPhi) { + if (insn.opcode() == SpvOpPhi) { live_inout->live_in_.insert(&insn); break; } @@ -223,7 +224,7 @@ class ComputeRegisterLiveness { for (Instruction& insn : make_range(bb.rbegin(), bb.rend())) { // If it is a phi instruction, the register pressure will not change // anymore. - if (insn.opcode() == spv::Op::OpPhi) { + if (insn.opcode() == SpvOpPhi) { break; } @@ -270,7 +271,7 @@ void RegisterLiveness::RegionRegisterLiveness::AddRegisterClass( RegisterLiveness::RegisterClass reg_class{type, false}; insn->context()->get_decoration_mgr()->WhileEachDecoration( - insn->result_id(), uint32_t(spv::Decoration::Uniform), + insn->result_id(), SpvDecorationUniform, [®_class](const Instruction&) { reg_class.is_uniform_ = true; return false; @@ -324,7 +325,7 @@ void RegisterLiveness::ComputeLoopRegisterPressure( loop_reg_pressure->used_registers_, live_inout->used_registers_); for (Instruction& insn : *bb) { - if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -385,7 +386,7 @@ void RegisterLiveness::SimulateFusion( [&l1, &l2](Instruction* insn) { BasicBlock* bb = insn->context()->get_instr_block(insn); return insn->HasResultId() && - !(insn->opcode() == spv::Op::OpPhi && + !(insn->opcode() == SpvOpPhi && (bb == l1.GetHeaderBlock() || bb == l2.GetHeaderBlock())); }); @@ -402,7 +403,7 @@ void RegisterLiveness::SimulateFusion( live_inout_info->live_out_.size()); for (Instruction& insn : *bb) { - if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -433,7 +434,7 @@ void RegisterLiveness::SimulateFusion( live_inout_info->live_out_.size()); for (Instruction& insn : *bb) { - if (insn.opcode() == spv::Op::OpPhi || !CreatesRegisterUsage(&insn) || + if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) || seen_insn.count(insn.result_id())) { continue; } @@ -531,7 +532,7 @@ void RegisterLiveness::SimulateFission( std::unordered_set die_in_block; for (Instruction& insn : make_range(bb->rbegin(), bb->rend())) { - if (insn.opcode() == spv::Op::OpPhi) { + if (insn.opcode() == SpvOpPhi) { break; } diff --git a/source/opt/relax_float_ops_pass.cpp b/source/opt/relax_float_ops_pass.cpp index df925a25..3fcf8795 100644 --- a/source/opt/relax_float_ops_pass.cpp +++ b/source/opt/relax_float_ops_pass.cpp @@ -25,7 +25,7 @@ bool RelaxFloatOpsPass::IsRelaxable(Instruction* inst) { return target_ops_core_f_rslt_.count(inst->opcode()) != 0 || target_ops_core_f_opnd_.count(inst->opcode()) != 0 || sample_ops_.count(inst->opcode()) != 0 || - (inst->opcode() == spv::Op::OpExtInst && + (inst->opcode() == SpvOpExtInst && inst->GetSingleWordInOperand(0) == context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450() && target_ops_450_.count(inst->GetSingleWordInOperand(1)) != 0); @@ -46,9 +46,8 @@ bool RelaxFloatOpsPass::IsFloat32(Instruction* inst) { bool RelaxFloatOpsPass::IsRelaxed(uint32_t r_id) { for (auto r_inst : get_decoration_mgr()->GetDecorationsFor(r_id, false)) - if (r_inst->opcode() == spv::Op::OpDecorate && - spv::Decoration(r_inst->GetSingleWordInOperand(1)) == - spv::Decoration::RelaxedPrecision) + if (r_inst->opcode() == SpvOpDecorate && + r_inst->GetSingleWordInOperand(1) == SpvDecorationRelaxedPrecision) return true; return false; } @@ -59,8 +58,7 @@ bool RelaxFloatOpsPass::ProcessInst(Instruction* r_inst) { if (!IsFloat32(r_inst)) return false; if (IsRelaxed(r_id)) return false; if (!IsRelaxable(r_inst)) return false; - get_decoration_mgr()->AddDecoration( - r_id, uint32_t(spv::Decoration::RelaxedPrecision)); + get_decoration_mgr()->AddDecoration(r_id, SpvDecorationRelaxedPrecision); return true; } @@ -89,48 +87,48 @@ Pass::Status RelaxFloatOpsPass::Process() { void RelaxFloatOpsPass::Initialize() { target_ops_core_f_rslt_ = { - spv::Op::OpLoad, - spv::Op::OpPhi, - spv::Op::OpVectorExtractDynamic, - spv::Op::OpVectorInsertDynamic, - spv::Op::OpVectorShuffle, - spv::Op::OpCompositeExtract, - spv::Op::OpCompositeConstruct, - spv::Op::OpCompositeInsert, - spv::Op::OpCopyObject, - spv::Op::OpTranspose, - spv::Op::OpConvertSToF, - spv::Op::OpConvertUToF, - spv::Op::OpFConvert, - // spv::Op::OpQuantizeToF16, - spv::Op::OpFNegate, - spv::Op::OpFAdd, - spv::Op::OpFSub, - spv::Op::OpFMul, - spv::Op::OpFDiv, - spv::Op::OpFMod, - spv::Op::OpVectorTimesScalar, - spv::Op::OpMatrixTimesScalar, - spv::Op::OpVectorTimesMatrix, - spv::Op::OpMatrixTimesVector, - spv::Op::OpMatrixTimesMatrix, - spv::Op::OpOuterProduct, - spv::Op::OpDot, - spv::Op::OpSelect, + SpvOpLoad, + SpvOpPhi, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeExtract, + SpvOpCompositeConstruct, + SpvOpCompositeInsert, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpConvertSToF, + SpvOpConvertUToF, + SpvOpFConvert, + // SpvOpQuantizeToF16, + SpvOpFNegate, + SpvOpFAdd, + SpvOpFSub, + SpvOpFMul, + SpvOpFDiv, + SpvOpFMod, + SpvOpVectorTimesScalar, + SpvOpMatrixTimesScalar, + SpvOpVectorTimesMatrix, + SpvOpMatrixTimesVector, + SpvOpMatrixTimesMatrix, + SpvOpOuterProduct, + SpvOpDot, + SpvOpSelect, }; target_ops_core_f_opnd_ = { - spv::Op::OpFOrdEqual, - spv::Op::OpFUnordEqual, - spv::Op::OpFOrdNotEqual, - spv::Op::OpFUnordNotEqual, - spv::Op::OpFOrdLessThan, - spv::Op::OpFUnordLessThan, - spv::Op::OpFOrdGreaterThan, - spv::Op::OpFUnordGreaterThan, - spv::Op::OpFOrdLessThanEqual, - spv::Op::OpFUnordLessThanEqual, - spv::Op::OpFOrdGreaterThanEqual, - spv::Op::OpFUnordGreaterThanEqual, + SpvOpFOrdEqual, + SpvOpFUnordEqual, + SpvOpFOrdNotEqual, + SpvOpFUnordNotEqual, + SpvOpFOrdLessThan, + SpvOpFUnordLessThan, + SpvOpFOrdGreaterThan, + SpvOpFUnordGreaterThan, + SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpFUnordGreaterThanEqual, }; target_ops_450_ = { GLSLstd450Round, GLSLstd450RoundEven, GLSLstd450Trunc, GLSLstd450FAbs, @@ -149,31 +147,31 @@ void RelaxFloatOpsPass::Initialize() { GLSLstd450Ldexp, GLSLstd450Length, GLSLstd450Distance, GLSLstd450Cross, GLSLstd450Normalize, GLSLstd450FaceForward, GLSLstd450Reflect, GLSLstd450Refract, GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp}; - sample_ops_ = {spv::Op::OpImageSampleImplicitLod, - spv::Op::OpImageSampleExplicitLod, - spv::Op::OpImageSampleDrefImplicitLod, - spv::Op::OpImageSampleDrefExplicitLod, - spv::Op::OpImageSampleProjImplicitLod, - spv::Op::OpImageSampleProjExplicitLod, - spv::Op::OpImageSampleProjDrefImplicitLod, - spv::Op::OpImageSampleProjDrefExplicitLod, - spv::Op::OpImageFetch, - spv::Op::OpImageGather, - spv::Op::OpImageDrefGather, - spv::Op::OpImageRead, - spv::Op::OpImageSparseSampleImplicitLod, - spv::Op::OpImageSparseSampleExplicitLod, - spv::Op::OpImageSparseSampleDrefImplicitLod, - spv::Op::OpImageSparseSampleDrefExplicitLod, - spv::Op::OpImageSparseSampleProjImplicitLod, - spv::Op::OpImageSparseSampleProjExplicitLod, - spv::Op::OpImageSparseSampleProjDrefImplicitLod, - spv::Op::OpImageSparseSampleProjDrefExplicitLod, - spv::Op::OpImageSparseFetch, - spv::Op::OpImageSparseGather, - spv::Op::OpImageSparseDrefGather, - spv::Op::OpImageSparseTexelsResident, - spv::Op::OpImageSparseRead}; + sample_ops_ = {SpvOpImageSampleImplicitLod, + SpvOpImageSampleExplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageFetch, + SpvOpImageGather, + SpvOpImageDrefGather, + SpvOpImageRead, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleExplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseFetch, + SpvOpImageSparseGather, + SpvOpImageSparseDrefGather, + SpvOpImageSparseTexelsResident, + SpvOpImageSparseRead}; } } // namespace opt diff --git a/source/opt/relax_float_ops_pass.h b/source/opt/relax_float_ops_pass.h index 9e4606f8..5ee3d73c 100644 --- a/source/opt/relax_float_ops_pass.h +++ b/source/opt/relax_float_ops_pass.h @@ -61,23 +61,17 @@ class RelaxFloatOpsPass : public Pass { // Initialize state for converting to half void Initialize(); - struct hasher { - size_t operator()(const spv::Op& op) const noexcept { - return std::hash()(uint32_t(op)); - } - }; - // Set of float result core operations to be processed - std::unordered_set target_ops_core_f_rslt_; + std::unordered_set target_ops_core_f_rslt_; // Set of float operand core operations to be processed - std::unordered_set target_ops_core_f_opnd_; + std::unordered_set target_ops_core_f_opnd_; // Set of 450 extension operations to be processed std::unordered_set target_ops_450_; // Set of sample operations - std::unordered_set sample_ops_; + std::unordered_set sample_ops_; }; } // namespace opt diff --git a/source/opt/remove_dontinline_pass.cpp b/source/opt/remove_dontinline_pass.cpp index 3750bc1f..4dd1cd4f 100644 --- a/source/opt/remove_dontinline_pass.cpp +++ b/source/opt/remove_dontinline_pass.cpp @@ -37,11 +37,10 @@ bool RemoveDontInline::ClearDontInlineFunctionControl(Function* function) { uint32_t function_control = function_inst->GetSingleWordInOperand(kFunctionControlInOperandIdx); - if ((function_control & uint32_t(spv::FunctionControlMask::DontInline)) == - 0) { + if ((function_control & SpvFunctionControlDontInlineMask) == 0) { return false; } - function_control &= ~uint32_t(spv::FunctionControlMask::DontInline); + function_control &= ~SpvFunctionControlDontInlineMask; function_inst->SetInOperand(kFunctionControlInOperandIdx, {function_control}); return true; } diff --git a/source/opt/remove_duplicates_pass.cpp b/source/opt/remove_duplicates_pass.cpp index 0df559b3..1ed8e2a0 100644 --- a/source/opt/remove_duplicates_pass.cpp +++ b/source/opt/remove_duplicates_pass.cpp @@ -15,6 +15,8 @@ #include "source/opt/remove_duplicates_pass.h" #include +#include +#include #include #include #include @@ -23,6 +25,7 @@ #include "source/opcode.h" #include "source/opt/decoration_manager.h" #include "source/opt/ir_context.h" +#include "source/opt/reflect.h" namespace spvtools { namespace opt { @@ -67,7 +70,7 @@ bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports() const { return modified; } - std::unordered_map ext_inst_imports; + std::unordered_map ext_inst_imports; for (auto* i = &*context()->ext_inst_import_begin(); i;) { auto res = ext_inst_imports.emplace(i->GetInOperand(0u).AsString(), i->result_id()); @@ -98,8 +101,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { std::vector visited_forward_pointers; std::vector to_delete; for (auto* i = &*context()->types_values_begin(); i; i = i->NextNode()) { - const bool is_i_forward_pointer = - i->opcode() == spv::Op::OpTypeForwardPointer; + const bool is_i_forward_pointer = i->opcode() == SpvOpTypeForwardPointer; // We only care about types. if (!spvOpcodeGeneratesType(i->opcode()) && !is_i_forward_pointer) { @@ -108,7 +110,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { if (!is_i_forward_pointer) { // Is the current type equal to one of the types we have already visited? - spv::Id id_to_keep = 0u; + SpvId id_to_keep = 0u; analysis::Type* i_type = type_manager.GetType(i->result_id()); assert(i_type); // TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the @@ -135,7 +137,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes() const { } else { analysis::ForwardPointer i_type( i->GetSingleWordInOperand(0u), - (spv::StorageClass)i->GetSingleWordInOperand(1u)); + (SpvStorageClass)i->GetSingleWordInOperand(1u)); i_type.SetTargetPointer( type_manager.GetType(i_type.target_id())->AsPointer()); diff --git a/source/opt/remove_unused_interface_variables_pass.cpp b/source/opt/remove_unused_interface_variables_pass.cpp index d4df1b2e..31e87bd4 100644 --- a/source/opt/remove_unused_interface_variables_pass.cpp +++ b/source/opt/remove_unused_interface_variables_pass.cpp @@ -31,14 +31,13 @@ class RemoveUnusedInterfaceVariablesContext { instruction.ForEachInId([&](const uint32_t* id) { if (used_variables_.count(*id)) return; auto* var = parent_.get_def_use_mgr()->GetDef(*id); - if (!var || var->opcode() != spv::Op::OpVariable) return; - auto storage_class = - spv::StorageClass(var->GetSingleWordInOperand(0)); - if (storage_class != spv::StorageClass::Function && + if (!var || var->opcode() != SpvOpVariable) return; + auto storage_class = var->GetSingleWordInOperand(0); + if (storage_class != SpvStorageClassFunction && (parent_.get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4) || - storage_class == spv::StorageClass::Input || - storage_class == spv::StorageClass::Output)) + storage_class == SpvStorageClassInput || + storage_class == SpvStorageClassOutput)) used_variables_.insert(*id); }); return false; @@ -91,4 +90,4 @@ RemoveUnusedInterfaceVariablesPass::Process() { return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); } } // namespace opt -} // namespace spvtools +} // namespace spvtools \ No newline at end of file diff --git a/source/opt/remove_unused_interface_variables_pass.h b/source/opt/remove_unused_interface_variables_pass.h index a4cb1085..7f11187c 100644 --- a/source/opt/remove_unused_interface_variables_pass.h +++ b/source/opt/remove_unused_interface_variables_pass.h @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ -#define SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ - #include "source/opt/pass.h" namespace spvtools { namespace opt { @@ -26,6 +23,4 @@ class RemoveUnusedInterfaceVariablesPass : public Pass { Status Process() override; }; } // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_REMOVE_UNUSED_INTERFACE_VARIABLES_PASS_H_ \ No newline at end of file +} // namespace spvtools \ No newline at end of file diff --git a/source/opt/replace_desc_array_access_using_var_index.cpp b/source/opt/replace_desc_array_access_using_var_index.cpp index 59745e12..e97593ef 100644 --- a/source/opt/replace_desc_array_access_using_var_index.cpp +++ b/source/opt/replace_desc_array_access_using_var_index.cpp @@ -21,10 +21,11 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kOpAccessChainInOperandIndexes = 1; -constexpr uint32_t kOpTypePointerInOperandType = 1; -constexpr uint32_t kOpTypeArrayInOperandType = 0; -constexpr uint32_t kOpTypeStructInOperandMember = 0; + +const uint32_t kOpAccessChainInOperandIndexes = 1; +const uint32_t kOpTypePointerInOperandType = 1; +const uint32_t kOpTypeArrayInOperandType = 0; +const uint32_t kOpTypeStructInOperandMember = 0; IRContext::Analysis kAnalysisDefUseAndInstrToBlockMapping = IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping; @@ -53,8 +54,8 @@ bool ReplaceDescArrayAccessUsingVarIndex:: std::vector work_list; get_def_use_mgr()->ForEachUser(var, [&work_list](Instruction* use) { switch (use->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: work_list.push_back(use); break; default: @@ -131,8 +132,8 @@ ReplaceDescArrayAccessUsingVarIndex::CollectRequiredImageAndAccessInsts( Instruction* operand = get_def_use_mgr()->GetDef(*idp); if (context()->get_instr_block(operand) != nullptr && (HasImageOrImagePtrType(operand) || - operand->opcode() == spv::Op::OpAccessChain || - operand->opcode() == spv::Op::OpInBoundsAccessChain)) { + operand->opcode() == SpvOpAccessChain || + operand->opcode() == SpvOpInBoundsAccessChain)) { work_list.push(operand); } }; @@ -157,22 +158,22 @@ bool ReplaceDescArrayAccessUsingVarIndex::HasImageOrImagePtrType( bool ReplaceDescArrayAccessUsingVarIndex::IsImageOrImagePtrType( const Instruction* type_inst) const { - if (type_inst->opcode() == spv::Op::OpTypeImage || - type_inst->opcode() == spv::Op::OpTypeSampler || - type_inst->opcode() == spv::Op::OpTypeSampledImage) { + if (type_inst->opcode() == SpvOpTypeImage || + type_inst->opcode() == SpvOpTypeSampler || + type_inst->opcode() == SpvOpTypeSampledImage) { return true; } - if (type_inst->opcode() == spv::Op::OpTypePointer) { + if (type_inst->opcode() == SpvOpTypePointer) { Instruction* pointee_type_inst = get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(kOpTypePointerInOperandType)); return IsImageOrImagePtrType(pointee_type_inst); } - if (type_inst->opcode() == spv::Op::OpTypeArray) { + if (type_inst->opcode() == SpvOpTypeArray) { Instruction* element_type_inst = get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(kOpTypeArrayInOperandType)); return IsImageOrImagePtrType(element_type_inst); } - if (type_inst->opcode() != spv::Op::OpTypeStruct) return false; + if (type_inst->opcode() != SpvOpTypeStruct) return false; for (uint32_t in_operand_idx = kOpTypeStructInOperandMember; in_operand_idx < type_inst->NumInOperands(); ++in_operand_idx) { Instruction* member_type_inst = get_def_use_mgr()->GetDef( @@ -185,16 +186,16 @@ bool ReplaceDescArrayAccessUsingVarIndex::IsImageOrImagePtrType( bool ReplaceDescArrayAccessUsingVarIndex::IsConcreteType( uint32_t type_id) const { Instruction* type_inst = get_def_use_mgr()->GetDef(type_id); - if (type_inst->opcode() == spv::Op::OpTypeInt || - type_inst->opcode() == spv::Op::OpTypeFloat) { + if (type_inst->opcode() == SpvOpTypeInt || + type_inst->opcode() == SpvOpTypeFloat) { return true; } - if (type_inst->opcode() == spv::Op::OpTypeVector || - type_inst->opcode() == spv::Op::OpTypeMatrix || - type_inst->opcode() == spv::Op::OpTypeArray) { + if (type_inst->opcode() == SpvOpTypeVector || + type_inst->opcode() == SpvOpTypeMatrix || + type_inst->opcode() == SpvOpTypeArray) { return IsConcreteType(type_inst->GetSingleWordInOperand(0)); } - if (type_inst->opcode() == spv::Op::OpTypeStruct) { + if (type_inst->opcode() == SpvOpTypeStruct) { for (uint32_t i = 0; i < type_inst->NumInOperands(); ++i) { if (!IsConcreteType(type_inst->GetSingleWordInOperand(i))) return false; } @@ -321,8 +322,8 @@ ReplaceDescArrayAccessUsingVarIndex::SeparateInstructionsIntoNewBlock( } BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateNewBlock() const { - auto* new_block = new BasicBlock(std::unique_ptr(new Instruction( - context(), spv::Op::OpLabel, 0, context()->TakeNextId(), {}))); + auto* new_block = new BasicBlock(std::unique_ptr( + new Instruction(context(), SpvOpLabel, 0, context()->TakeNextId(), {}))); get_def_use_mgr()->AnalyzeInstDefUse(new_block->GetLabelInst()); context()->set_instr_block(new_block->GetLabelInst(), new_block); return new_block; @@ -331,7 +332,7 @@ BasicBlock* ReplaceDescArrayAccessUsingVarIndex::CreateNewBlock() const { void ReplaceDescArrayAccessUsingVarIndex::UseConstIndexForAccessChain( Instruction* access_chain, uint32_t const_element_idx) const { uint32_t const_element_idx_id = - context()->get_constant_mgr()->GetUIntConstId(const_element_idx); + context()->get_constant_mgr()->GetUIntConst(const_element_idx); access_chain->SetInOperand(kOpAccessChainInOperandIndexes, {const_element_idx_id}); } @@ -421,7 +422,7 @@ void ReplaceDescArrayAccessUsingVarIndex::ReplacePhiIncomingBlock( uint32_t old_incoming_block_id, uint32_t new_incoming_block_id) const { context()->ReplaceAllUsesWithPredicate( old_incoming_block_id, new_incoming_block_id, - [](Instruction* use) { return use->opcode() == spv::Op::OpPhi; }); + [](Instruction* use) { return use->opcode() == SpvOpPhi; }); } } // namespace opt diff --git a/source/opt/replace_invalid_opc.cpp b/source/opt/replace_invalid_opc.cpp index 1b97c0e8..1dcd06f5 100644 --- a/source/opt/replace_invalid_opc.cpp +++ b/source/opt/replace_invalid_opc.cpp @@ -23,16 +23,16 @@ namespace opt { Pass::Status ReplaceInvalidOpcodePass::Process() { bool modified = false; - if (context()->get_feature_mgr()->HasCapability(spv::Capability::Linkage)) { + if (context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage)) { return Status::SuccessWithoutChange; } - spv::ExecutionModel execution_model = GetExecutionModel(); - if (execution_model == spv::ExecutionModel::Kernel) { + SpvExecutionModel execution_model = GetExecutionModel(); + if (execution_model == SpvExecutionModelKernel) { // We do not handle kernels. return Status::SuccessWithoutChange; } - if (execution_model == spv::ExecutionModel::Max) { + if (execution_model == SpvExecutionModelMax) { // Mixed execution models for the entry points. This case is not currently // handled. return Status::SuccessWithoutChange; @@ -44,19 +44,19 @@ Pass::Status ReplaceInvalidOpcodePass::Process() { return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); } -spv::ExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { - spv::ExecutionModel result = spv::ExecutionModel::Max; +SpvExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { + SpvExecutionModel result = SpvExecutionModelMax; bool first = true; for (Instruction& entry_point : get_module()->entry_points()) { if (first) { - result = static_cast( - entry_point.GetSingleWordInOperand(0)); + result = + static_cast(entry_point.GetSingleWordInOperand(0)); first = false; } else { - spv::ExecutionModel current_model = static_cast( - entry_point.GetSingleWordInOperand(0)); + SpvExecutionModel current_model = + static_cast(entry_point.GetSingleWordInOperand(0)); if (current_model != result) { - result = spv::ExecutionModel::Max; + result = SpvExecutionModelMax; break; } } @@ -65,13 +65,13 @@ spv::ExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() { } bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, - spv::ExecutionModel model) { + SpvExecutionModel model) { bool modified = false; Instruction* last_line_dbg_inst = nullptr; function->ForEachInst( [model, &modified, &last_line_dbg_inst, this](Instruction* inst) { // Track the debug information so we can have a meaningful message. - if (inst->opcode() == spv::Op::OpLabel || inst->IsNoLine()) { + if (inst->opcode() == SpvOpLabel || inst->IsNoLine()) { last_line_dbg_inst = nullptr; return; } else if (inst->IsLine()) { @@ -80,16 +80,15 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, } bool replace = false; - if (model != spv::ExecutionModel::Fragment && + if (model != SpvExecutionModelFragment && IsFragmentShaderOnlyInstruction(inst)) { replace = true; } - if (model != spv::ExecutionModel::TessellationControl && - model != spv::ExecutionModel::GLCompute && - !context()->IsTargetEnvAtLeast(SPV_ENV_UNIVERSAL_1_3)) { - if (inst->opcode() == spv::Op::OpControlBarrier) { - assert(model != spv::ExecutionModel::Kernel && + if (model != SpvExecutionModelTessellationControl && + model != SpvExecutionModelGLCompute) { + if (inst->opcode() == SpvOpControlBarrier) { + assert(model != SpvExecutionModelKernel && "Expecting to be working on a shader module."); replace = true; } @@ -102,7 +101,7 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, } else { // Get the name of the source file. uint32_t file_name_id = 0; - if (last_line_dbg_inst->opcode() == spv::Op::OpLine) { + if (last_line_dbg_inst->opcode() == SpvOpLine) { file_name_id = last_line_dbg_inst->GetSingleWordInOperand(0); } else { // Shader100::DebugLine uint32_t debug_source_id = @@ -132,26 +131,26 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, bool ReplaceInvalidOpcodePass::IsFragmentShaderOnlyInstruction( Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpDPdx: - case spv::Op::OpDPdy: - case spv::Op::OpFwidth: - case spv::Op::OpDPdxFine: - case spv::Op::OpDPdyFine: - case spv::Op::OpFwidthFine: - case spv::Op::OpDPdxCoarse: - case spv::Op::OpDPdyCoarse: - case spv::Op::OpFwidthCoarse: - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageQueryLod: + case SpvOpDPdx: + case SpvOpDPdy: + case SpvOpFwidth: + case SpvOpDPdxFine: + case SpvOpDPdyFine: + case SpvOpFwidthFine: + case SpvOpDPdxCoarse: + case SpvOpDPdyCoarse: + case SpvOpFwidthCoarse: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageQueryLod: // TODO: Teach |ReplaceInstruction| to handle block terminators. Then // uncomment the OpKill case. - // case spv::Op::OpKill: - // case spv::Op::OpTerminateInstruction: + // case SpvOpKill: + // case SpvOpTerminateInstruction: return true; default: return false; @@ -184,7 +183,7 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { analysis::TypeManager* type_mgr = context()->get_type_mgr(); Instruction* type = context()->get_def_use_mgr()->GetDef(type_id); - if (type->opcode() == spv::Op::OpTypeVector) { + if (type->opcode() == SpvOpTypeVector) { uint32_t component_const = GetSpecialConstant(type->GetSingleWordInOperand(0)); std::vector ids; @@ -193,8 +192,7 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { } special_const = const_mgr->GetConstant(type_mgr->GetType(type_id), ids); } else { - assert(type->opcode() == spv::Op::OpTypeInt || - type->opcode() == spv::Op::OpTypeFloat); + assert(type->opcode() == SpvOpTypeInt || type->opcode() == SpvOpTypeFloat); std::vector literal_words; for (uint32_t i = 0; i < type->GetSingleWordInOperand(0); i += 32) { literal_words.push_back(0xDEADBEEF); @@ -206,7 +204,7 @@ uint32_t ReplaceInvalidOpcodePass::GetSpecialConstant(uint32_t type_id) { return const_mgr->GetDefiningInstruction(special_const)->result_id(); } -std::string ReplaceInvalidOpcodePass::BuildWarningMessage(spv::Op opcode) { +std::string ReplaceInvalidOpcodePass::BuildWarningMessage(SpvOp opcode) { spv_opcode_desc opcode_info; context()->grammar().lookupOpcode(opcode, &opcode_info); std::string message = "Removing "; diff --git a/source/opt/replace_invalid_opc.h b/source/opt/replace_invalid_opc.h index 3f0d16bb..426bcac5 100644 --- a/source/opt/replace_invalid_opc.h +++ b/source/opt/replace_invalid_opc.h @@ -34,13 +34,13 @@ class ReplaceInvalidOpcodePass : public Pass { private: // Returns the execution model that is used by every entry point in the // module. If more than one execution model is used in the module, then the - // return value is spv::ExecutionModel::Max. - spv::ExecutionModel GetExecutionModel(); + // return value is SpvExecutionModelMax. + SpvExecutionModel GetExecutionModel(); // Replaces all instructions in |function| that are invalid with execution // model |mode|, but valid for another shader model, with a special constant // value. See |GetSpecialConstant|. - bool RewriteFunction(Function* function, spv::ExecutionModel mode); + bool RewriteFunction(Function* function, SpvExecutionModel mode); // Returns true if |inst| is valid for fragment shaders only. bool IsFragmentShaderOnlyInstruction(Instruction* inst); @@ -58,7 +58,7 @@ class ReplaceInvalidOpcodePass : public Pass { // width of the type has been reached. For a vector, each element of the // constant will be constructed the same way. uint32_t GetSpecialConstant(uint32_t type_id); - std::string BuildWarningMessage(spv::Op opcode); + std::string BuildWarningMessage(SpvOp opcode); }; } // namespace opt diff --git a/source/opt/scalar_analysis.cpp b/source/opt/scalar_analysis.cpp index 26cc8b30..2b0a824c 100644 --- a/source/opt/scalar_analysis.cpp +++ b/source/opt/scalar_analysis.cpp @@ -14,6 +14,7 @@ #include "source/opt/scalar_analysis.h" +#include #include #include #include @@ -96,7 +97,7 @@ SENode* ScalarEvolutionAnalysis::CreateRecurrentExpression( SENode* ScalarEvolutionAnalysis::AnalyzeMultiplyOp( const Instruction* multiply) { - assert(multiply->opcode() == spv::Op::OpIMul && + assert(multiply->opcode() == SpvOp::SpvOpIMul && "Multiply node did not come from a multiply instruction"); analysis::DefUseManager* def_use = context_->get_def_use_mgr(); @@ -167,21 +168,21 @@ SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(const Instruction* inst) { SENode* output = nullptr; switch (inst->opcode()) { - case spv::Op::OpPhi: { + case SpvOp::SpvOpPhi: { output = AnalyzePhiInstruction(inst); break; } - case spv::Op::OpConstant: - case spv::Op::OpConstantNull: { + case SpvOp::SpvOpConstant: + case SpvOp::SpvOpConstantNull: { output = AnalyzeConstant(inst); break; } - case spv::Op::OpISub: - case spv::Op::OpIAdd: { + case SpvOp::SpvOpISub: + case SpvOp::SpvOpIAdd: { output = AnalyzeAddOp(inst); break; } - case spv::Op::OpIMul: { + case SpvOp::SpvOpIMul: { output = AnalyzeMultiplyOp(inst); break; } @@ -195,9 +196,9 @@ SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(const Instruction* inst) { } SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const Instruction* inst) { - if (inst->opcode() == spv::Op::OpConstantNull) return CreateConstant(0); + if (inst->opcode() == SpvOp::SpvOpConstantNull) return CreateConstant(0); - assert(inst->opcode() == spv::Op::OpConstant); + assert(inst->opcode() == SpvOp::SpvOpConstant); assert(inst->NumInOperands() == 1); int64_t value = 0; @@ -225,8 +226,8 @@ SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const Instruction* inst) { // Handles both addition and subtraction. If the |sub| flag is set then the // addition will be op1+(-op2) otherwise op1+op2. SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const Instruction* inst) { - assert((inst->opcode() == spv::Op::OpIAdd || - inst->opcode() == spv::Op::OpISub) && + assert((inst->opcode() == SpvOp::SpvOpIAdd || + inst->opcode() == SpvOp::SpvOpISub) && "Add node must be created from a OpIAdd or OpISub instruction"); analysis::DefUseManager* def_use = context_->get_def_use_mgr(); @@ -238,7 +239,7 @@ SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const Instruction* inst) { AnalyzeInstruction(def_use->GetDef(inst->GetSingleWordInOperand(1))); // To handle subtraction we wrap the second operand in a unary negation node. - if (inst->opcode() == spv::Op::OpISub) { + if (inst->opcode() == SpvOp::SpvOpISub) { op2 = CreateNegation(op2); } @@ -572,7 +573,7 @@ struct PushToStringImpl { }; template -void PushToString(T id, std::u32string* str) { +static void PushToString(T id, std::u32string* str) { PushToStringImpl{}(id, str); } @@ -927,8 +928,8 @@ namespace { // Remove |node| from the |mul| chain (of the form A * ... * |node| * ... * Z), // if |node| is not in the chain, returns the original chain. -SENode* RemoveOneNodeFromMultiplyChain(SEMultiplyNode* mul, - const SENode* node) { +static SENode* RemoveOneNodeFromMultiplyChain(SEMultiplyNode* mul, + const SENode* node) { SENode* lhs = mul->GetChildren()[0]; SENode* rhs = mul->GetChildren()[1]; if (lhs == node) { diff --git a/source/opt/scalar_analysis_simplification.cpp b/source/opt/scalar_analysis_simplification.cpp index 3c0947cd..3c1ecc08 100644 --- a/source/opt/scalar_analysis_simplification.cpp +++ b/source/opt/scalar_analysis_simplification.cpp @@ -12,15 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "source/opt/scalar_analysis.h" + #include #include #include #include +#include #include #include -#include "source/opt/scalar_analysis.h" - // Simplifies scalar analysis DAGs. // // 1. Given a node passed to SimplifyExpression we first simplify the graph by diff --git a/source/opt/scalar_replacement_pass.cpp b/source/opt/scalar_replacement_pass.cpp index 38c8aecc..e27c828b 100644 --- a/source/opt/scalar_replacement_pass.cpp +++ b/source/opt/scalar_replacement_pass.cpp @@ -19,18 +19,19 @@ #include #include +#include "source/enum_string_mapping.h" #include "source/extensions.h" #include "source/opt/reflect.h" #include "source/opt/types.h" #include "source/util/make_unique.h" +#include "types.h" + +static const uint32_t kDebugValueOperandValueIndex = 5; +static const uint32_t kDebugValueOperandExpressionIndex = 6; +static const uint32_t kDebugDeclareOperandVariableIndex = 5; namespace spvtools { namespace opt { -namespace { -constexpr uint32_t kDebugValueOperandValueIndex = 5; -constexpr uint32_t kDebugValueOperandExpressionIndex = 6; -constexpr uint32_t kDebugDeclareOperandVariableIndex = 5; -} // namespace Pass::Status ScalarReplacementPass::Process() { Status status = Status::SuccessWithoutChange; @@ -55,7 +56,7 @@ Pass::Status ScalarReplacementPass::ProcessFunction(Function* function) { for (auto iter = entry.begin(); iter != entry.end(); ++iter) { // Function storage class OpVariables must appear as the first instructions // of the entry block. - if (iter->opcode() != spv::Op::OpVariable) break; + if (iter->opcode() != SpvOpVariable) break; Instruction* varInst = &*iter; if (CanReplaceVariable(varInst)) { @@ -104,29 +105,29 @@ Pass::Status ScalarReplacementPass::ReplaceVariable( } if (!IsAnnotationInst(user->opcode())) { switch (user->opcode()) { - case spv::Op::OpLoad: + case SpvOpLoad: if (ReplaceWholeLoad(user, replacements)) { dead.push_back(user); } else { return false; } break; - case spv::Op::OpStore: + case SpvOpStore: if (ReplaceWholeStore(user, replacements)) { dead.push_back(user); } else { return false; } break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: if (ReplaceAccessChain(user, replacements)) dead.push_back(user); else return false; break; - case spv::Op::OpName: - case spv::Op::OpMemberName: + case SpvOpName: + case SpvOpMemberName: break; default: assert(false && "Unexpected opcode"); @@ -154,7 +155,7 @@ Pass::Status ScalarReplacementPass::ReplaceVariable( // Attempt to further scalarize. for (auto var : replacements) { - if (var->opcode() == spv::Op::OpVariable) { + if (var->opcode() == SpvOpVariable) { if (get_def_use_mgr()->NumUsers(var) == 0) { context()->KillInst(var); } else if (CanReplaceVariable(var)) { @@ -178,7 +179,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare( int32_t idx = 0; for (const auto* var : replacements) { Instruction* insert_before = var->NextNode(); - while (insert_before->opcode() == spv::Op::OpVariable) + while (insert_before->opcode() == SpvOpVariable) insert_before = insert_before->NextNode(); assert(insert_before != nullptr && "unexpected end of list"); Instruction* added_dbg_value = @@ -189,7 +190,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare( if (added_dbg_value == nullptr) return false; added_dbg_value->AddOperand( {SPV_OPERAND_TYPE_ID, - {context()->get_constant_mgr()->GetSIntConstId(idx)}}); + {context()->get_constant_mgr()->GetSIntConst(idx)}}); added_dbg_value->SetOperand(kDebugValueOperandExpressionIndex, {deref_expr->result_id()}); if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) { @@ -215,7 +216,7 @@ bool ScalarReplacementPass::ReplaceWholeDebugValue( // Append 'Indexes' operand. new_dbg_value->AddOperand( {SPV_OPERAND_TYPE_ID, - {context()->get_constant_mgr()->GetSIntConstId(idx)}}); + {context()->get_constant_mgr()->GetSIntConst(idx)}}); // Insert the new DebugValue to the basic block. auto* added_instr = dbg_value->InsertBefore(std::move(new_dbg_value)); get_def_use_mgr()->AnalyzeInstDefUse(added_instr); @@ -235,7 +236,7 @@ bool ScalarReplacementPass::ReplaceWholeLoad( BasicBlock::iterator where(load); for (auto var : replacements) { // Create a load of each replacement variable. - if (var->opcode() != spv::Op::OpVariable) { + if (var->opcode() != SpvOpVariable) { loads.push_back(var); continue; } @@ -246,7 +247,7 @@ bool ScalarReplacementPass::ReplaceWholeLoad( return false; } std::unique_ptr newLoad( - new Instruction(context(), spv::Op::OpLoad, type->result_id(), loadId, + new Instruction(context(), SpvOpLoad, type->result_id(), loadId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {var->result_id()}}})); // Copy memory access attributes which start at index 1. Index 0 is the @@ -268,9 +269,8 @@ bool ScalarReplacementPass::ReplaceWholeLoad( return false; } where = load; - std::unique_ptr compositeConstruct( - new Instruction(context(), spv::Op::OpCompositeConstruct, load->type_id(), - compositeId, {})); + std::unique_ptr compositeConstruct(new Instruction( + context(), SpvOpCompositeConstruct, load->type_id(), compositeId, {})); for (auto l : loads) { Operand op(SPV_OPERAND_TYPE_ID, std::initializer_list{l->result_id()}); @@ -294,7 +294,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( uint32_t elementIndex = 0; for (auto var : replacements) { // Create the extract. - if (var->opcode() != spv::Op::OpVariable) { + if (var->opcode() != SpvOpVariable) { elementIndex++; continue; } @@ -305,7 +305,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( return false; } std::unique_ptr extract(new Instruction( - context(), spv::Op::OpCompositeExtract, type->result_id(), extractId, + context(), SpvOpCompositeExtract, type->result_id(), extractId, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {storeInput}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {elementIndex++}}})); @@ -316,7 +316,7 @@ bool ScalarReplacementPass::ReplaceWholeStore( // Create the store. std::unique_ptr newStore( - new Instruction(context(), spv::Op::OpStore, 0, 0, + new Instruction(context(), SpvOpStore, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {var->result_id()}}, {SPV_OPERAND_TYPE_ID, {extractId}}})); @@ -390,7 +390,7 @@ bool ScalarReplacementPass::CreateReplacementVariables( uint32_t elem = 0; switch (type->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: type->ForEachInOperand( [this, inst, &elem, replacements, &components_used](uint32_t* id) { if (!components_used || components_used->count(elem)) { @@ -401,7 +401,7 @@ bool ScalarReplacementPass::CreateReplacementVariables( elem++; }); break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: for (uint32_t i = 0; i != GetArrayLength(type); ++i) { if (!components_used || components_used->count(i)) { CreateVariable(type->GetSingleWordInOperand(0u), inst, i, @@ -413,8 +413,8 @@ bool ScalarReplacementPass::CreateReplacementVariables( } break; - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: for (uint32_t i = 0; i != GetNumElements(type); ++i) { CreateVariable(type->GetSingleWordInOperand(0u), inst, i, replacements); } @@ -440,20 +440,20 @@ void ScalarReplacementPass::TransferAnnotations( // no type or member decorations that are necessary to transfer. for (auto inst : get_decoration_mgr()->GetDecorationsFor(source->result_id(), false)) { - assert(inst->opcode() == spv::Op::OpDecorate); - auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); - if (decoration == spv::Decoration::Invariant || - decoration == spv::Decoration::Restrict) { + assert(inst->opcode() == SpvOpDecorate); + uint32_t decoration = inst->GetSingleWordInOperand(1u); + if (decoration == SpvDecorationInvariant || + decoration == SpvDecorationRestrict) { for (auto var : *replacements) { if (var == nullptr) { continue; } - std::unique_ptr annotation(new Instruction( - context(), spv::Op::OpDecorate, 0, 0, - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {var->result_id()}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(decoration)}}})); + std::unique_ptr annotation( + new Instruction(context(), SpvOpDecorate, 0, 0, + std::initializer_list{ + {SPV_OPERAND_TYPE_ID, {var->result_id()}}, + {SPV_OPERAND_TYPE_DECORATION, {decoration}}})); for (uint32_t i = 2; i < inst->NumInOperands(); ++i) { Operand copy(inst->GetInOperand(i)); annotation->AddOperand(std::move(copy)); @@ -466,32 +466,60 @@ void ScalarReplacementPass::TransferAnnotations( } void ScalarReplacementPass::CreateVariable( - uint32_t type_id, Instruction* var_inst, uint32_t index, + uint32_t typeId, Instruction* varInst, uint32_t index, std::vector* replacements) { - uint32_t ptr_id = GetOrCreatePointerType(type_id); + uint32_t ptrId = GetOrCreatePointerType(typeId); uint32_t id = TakeNextId(); if (id == 0) { replacements->push_back(nullptr); } - std::unique_ptr variable( - new Instruction(context(), spv::Op::OpVariable, ptr_id, id, - std::initializer_list{ - {SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}})); + std::unique_ptr variable(new Instruction( + context(), SpvOpVariable, ptrId, id, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); - BasicBlock* block = context()->get_instr_block(var_inst); + BasicBlock* block = context()->get_instr_block(varInst); block->begin().InsertBefore(std::move(variable)); Instruction* inst = &*block->begin(); // If varInst was initialized, make sure to initialize its replacement. - GetOrCreateInitialValue(var_inst, index, inst); + GetOrCreateInitialValue(varInst, index, inst); get_def_use_mgr()->AnalyzeInstDefUse(inst); context()->set_instr_block(inst, block); - CopyDecorationsToVariable(var_inst, inst, index); - inst->UpdateDebugInfoFrom(var_inst); + // Copy decorations from the member to the new variable. + Instruction* typeInst = GetStorageType(varInst); + for (auto dec_inst : + get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { + uint32_t decoration; + if (dec_inst->opcode() != SpvOpMemberDecorate) { + continue; + } + + if (dec_inst->GetSingleWordInOperand(1) != index) { + continue; + } + + decoration = dec_inst->GetSingleWordInOperand(2u); + switch (decoration) { + case SpvDecorationRelaxedPrecision: { + std::unique_ptr new_dec_inst( + new Instruction(context(), SpvOpDecorate, 0, 0, {})); + new_dec_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {id})); + for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) { + new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i))); + } + context()->AddAnnotationInst(std::move(new_dec_inst)); + } break; + default: + break; + } + } + + // Update the DebugInfo debug information. + inst->UpdateDebugInfoFrom(varInst); replacements->push_back(inst); } @@ -500,17 +528,57 @@ uint32_t ScalarReplacementPass::GetOrCreatePointerType(uint32_t id) { auto iter = pointee_to_pointer_.find(id); if (iter != pointee_to_pointer_.end()) return iter->second; - analysis::TypeManager* type_mgr = context()->get_type_mgr(); - uint32_t ptr_type_id = - type_mgr->FindPointerToType(id, spv::StorageClass::Function); - pointee_to_pointer_[id] = ptr_type_id; - return ptr_type_id; + analysis::Type* pointeeTy; + std::unique_ptr pointerTy; + std::tie(pointeeTy, pointerTy) = + context()->get_type_mgr()->GetTypeAndPointerType(id, + SpvStorageClassFunction); + uint32_t ptrId = 0; + if (pointeeTy->IsUniqueType()) { + // Non-ambiguous type, just ask the type manager for an id. + ptrId = context()->get_type_mgr()->GetTypeInstruction(pointerTy.get()); + pointee_to_pointer_[id] = ptrId; + return ptrId; + } + + // Ambiguous type. We must perform a linear search to try and find the right + // type. + for (auto global : context()->types_values()) { + if (global.opcode() == SpvOpTypePointer && + global.GetSingleWordInOperand(0u) == SpvStorageClassFunction && + global.GetSingleWordInOperand(1u) == id) { + if (get_decoration_mgr()->GetDecorationsFor(id, false).empty()) { + // Only reuse a decoration-less pointer of the correct type. + ptrId = global.result_id(); + break; + } + } + } + + if (ptrId != 0) { + pointee_to_pointer_[id] = ptrId; + return ptrId; + } + + ptrId = TakeNextId(); + context()->AddType(MakeUnique( + context(), SpvOpTypePointer, 0, ptrId, + std::initializer_list{ + {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}, + {SPV_OPERAND_TYPE_ID, {id}}})); + Instruction* ptr = &*--context()->types_values_end(); + get_def_use_mgr()->AnalyzeInstDefUse(ptr); + pointee_to_pointer_[id] = ptrId; + // Register with the type manager if necessary. + context()->get_type_mgr()->RegisterType(ptrId, *pointerTy); + + return ptrId; } void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, uint32_t index, Instruction* newVar) { - assert(source->opcode() == spv::Op::OpVariable); + assert(source->opcode() == SpvOpVariable); if (source->NumInOperands() < 2) return; uint32_t initId = source->GetSingleWordInOperand(1u); @@ -518,14 +586,14 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, Instruction* init = get_def_use_mgr()->GetDef(initId); uint32_t newInitId = 0; // TODO(dnovillo): Refactor this with constant propagation. - if (init->opcode() == spv::Op::OpConstantNull) { + if (init->opcode() == SpvOpConstantNull) { // Initialize to appropriate NULL. auto iter = type_to_null_.find(storageId); if (iter == type_to_null_.end()) { newInitId = TakeNextId(); type_to_null_[storageId] = newInitId; context()->AddGlobalValue( - MakeUnique(context(), spv::Op::OpConstantNull, storageId, + MakeUnique(context(), SpvOpConstantNull, storageId, newInitId, std::initializer_list{})); Instruction* newNull = &*--context()->types_values_end(); get_def_use_mgr()->AnalyzeInstDefUse(newNull); @@ -536,19 +604,18 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, // Create a new constant extract. newInitId = TakeNextId(); context()->AddGlobalValue(MakeUnique( - context(), spv::Op::OpSpecConstantOp, storageId, newInitId, + context(), SpvOpSpecConstantOp, storageId, newInitId, std::initializer_list{ - {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, - {uint32_t(spv::Op::OpCompositeExtract)}}, + {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, {SpvOpCompositeExtract}}, {SPV_OPERAND_TYPE_ID, {init->result_id()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}})); Instruction* newSpecConst = &*--context()->types_values_end(); get_def_use_mgr()->AnalyzeInstDefUse(newSpecConst); - } else if (init->opcode() == spv::Op::OpConstantComposite) { + } else if (init->opcode() == SpvOpConstantComposite) { // Get the appropriate index constant. newInitId = init->GetSingleWordInOperand(index); Instruction* element = get_def_use_mgr()->GetDef(newInitId); - if (element->opcode() == spv::Op::OpUndef) { + if (element->opcode() == SpvOpUndef) { // Undef is not a valid initializer for a variable. newInitId = 0; } @@ -563,7 +630,7 @@ void ScalarReplacementPass::GetOrCreateInitialValue(Instruction* source, uint64_t ScalarReplacementPass::GetArrayLength( const Instruction* arrayType) const { - assert(arrayType->opcode() == spv::Op::OpTypeArray); + assert(arrayType->opcode() == SpvOpTypeArray); const Instruction* length = get_def_use_mgr()->GetDef(arrayType->GetSingleWordInOperand(1u)); return context() @@ -573,8 +640,8 @@ uint64_t ScalarReplacementPass::GetArrayLength( } uint64_t ScalarReplacementPass::GetNumElements(const Instruction* type) const { - assert(type->opcode() == spv::Op::OpTypeVector || - type->opcode() == spv::Op::OpTypeMatrix); + assert(type->opcode() == SpvOpTypeVector || + type->opcode() == SpvOpTypeMatrix); const Operand& op = type->GetInOperand(1u); assert(op.words.size() <= 2); uint64_t len = 0; @@ -592,7 +659,7 @@ bool ScalarReplacementPass::IsSpecConstant(uint32_t id) const { Instruction* ScalarReplacementPass::GetStorageType( const Instruction* inst) const { - assert(inst->opcode() == spv::Op::OpVariable); + assert(inst->opcode() == SpvOpVariable); uint32_t ptrTypeId = inst->type_id(); uint32_t typeId = @@ -602,11 +669,10 @@ Instruction* ScalarReplacementPass::GetStorageType( bool ScalarReplacementPass::CanReplaceVariable( const Instruction* varInst) const { - assert(varInst->opcode() == spv::Op::OpVariable); + assert(varInst->opcode() == SpvOpVariable); // Can only replace function scope variables. - if (spv::StorageClass(varInst->GetSingleWordInOperand(0u)) != - spv::StorageClass::Function) { + if (varInst->GetSingleWordInOperand(0u) != SpvStorageClassFunction) { return false; } @@ -636,14 +702,14 @@ bool ScalarReplacementPass::CheckType(const Instruction* typeInst) const { } switch (typeInst->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: // Don't bother with empty structs or very large structs. if (typeInst->NumInOperands() == 0 || IsLargerThanSizeLimit(typeInst->NumInOperands())) { return false; } return true; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: if (IsSpecConstant(typeInst->GetSingleWordInOperand(1u))) { return false; } @@ -655,12 +721,12 @@ bool ScalarReplacementPass::CheckType(const Instruction* typeInst) const { // re-enabled. //// Specifically including matrix and vector in an attempt to reduce the //// number of vector registers required. - // case spv::Op::OpTypeMatrix: - // case spv::Op::OpTypeVector: + // case SpvOpTypeMatrix: + // case SpvOpTypeVector: // if (IsLargerThanSizeLimit(GetNumElements(typeInst))) return false; // return true; - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: default: return false; } @@ -671,28 +737,26 @@ bool ScalarReplacementPass::CheckTypeAnnotations( for (auto inst : get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) { uint32_t decoration; - if (inst->opcode() == spv::Op::OpDecorate) { + if (inst->opcode() == SpvOpDecorate) { decoration = inst->GetSingleWordInOperand(1u); } else { - assert(inst->opcode() == spv::Op::OpMemberDecorate); + assert(inst->opcode() == SpvOpMemberDecorate); decoration = inst->GetSingleWordInOperand(2u); } - switch (spv::Decoration(decoration)) { - case spv::Decoration::RowMajor: - case spv::Decoration::ColMajor: - case spv::Decoration::ArrayStride: - case spv::Decoration::MatrixStride: - case spv::Decoration::CPacked: - case spv::Decoration::Invariant: - case spv::Decoration::Restrict: - case spv::Decoration::Offset: - case spv::Decoration::Alignment: - case spv::Decoration::AlignmentId: - case spv::Decoration::MaxByteOffset: - case spv::Decoration::RelaxedPrecision: - case spv::Decoration::AliasedPointer: - case spv::Decoration::RestrictPointer: + switch (decoration) { + case SpvDecorationRowMajor: + case SpvDecorationColMajor: + case SpvDecorationArrayStride: + case SpvDecorationMatrixStride: + case SpvDecorationCPacked: + case SpvDecorationInvariant: + case SpvDecorationRestrict: + case SpvDecorationOffset: + case SpvDecorationAlignment: + case SpvDecorationAlignmentId: + case SpvDecorationMaxByteOffset: + case SpvDecorationRelaxedPrecision: break; default: return false; @@ -705,16 +769,14 @@ bool ScalarReplacementPass::CheckTypeAnnotations( bool ScalarReplacementPass::CheckAnnotations(const Instruction* varInst) const { for (auto inst : get_decoration_mgr()->GetDecorationsFor(varInst->result_id(), false)) { - assert(inst->opcode() == spv::Op::OpDecorate); - auto decoration = spv::Decoration(inst->GetSingleWordInOperand(1u)); + assert(inst->opcode() == SpvOpDecorate); + uint32_t decoration = inst->GetSingleWordInOperand(1u); switch (decoration) { - case spv::Decoration::Invariant: - case spv::Decoration::Restrict: - case spv::Decoration::Alignment: - case spv::Decoration::AlignmentId: - case spv::Decoration::MaxByteOffset: - case spv::Decoration::AliasedPointer: - case spv::Decoration::RestrictPointer: + case SpvDecorationInvariant: + case SpvDecorationRestrict: + case SpvDecorationAlignment: + case SpvDecorationAlignmentId: + case SpvDecorationMaxByteOffset: break; default: return false; @@ -754,8 +816,8 @@ bool ScalarReplacementPass::CheckUses(const Instruction* inst, // Annotations are check as a group separately. if (!IsAnnotationInst(user->opcode())) { switch (user->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: if (index == 2u && user->NumInOperands() > 1) { uint32_t id = user->GetSingleWordInOperand(1u); const Instruction* opInst = get_def_use_mgr()->GetDef(id); @@ -773,16 +835,16 @@ bool ScalarReplacementPass::CheckUses(const Instruction* inst, ok = false; } break; - case spv::Op::OpLoad: + case SpvOpLoad: if (!CheckLoad(user, index)) ok = false; stats->num_full_accesses++; break; - case spv::Op::OpStore: + case SpvOpStore: if (!CheckStore(user, index)) ok = false; stats->num_full_accesses++; break; - case spv::Op::OpName: - case spv::Op::OpMemberName: + case SpvOpName: + case SpvOpMemberName: break; default: ok = false; @@ -799,24 +861,24 @@ bool ScalarReplacementPass::CheckUsesRelaxed(const Instruction* inst) const { get_def_use_mgr()->ForEachUse( inst, [this, &ok](const Instruction* user, uint32_t index) { switch (user->opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: if (index != 2u) { ok = false; } else { if (!CheckUsesRelaxed(user)) ok = false; } break; - case spv::Op::OpLoad: + case SpvOpLoad: if (!CheckLoad(user, index)) ok = false; break; - case spv::Op::OpStore: + case SpvOpStore: if (!CheckStore(user, index)) ok = false; break; - case spv::Op::OpImageTexelPointer: + case SpvOpImageTexelPointer: if (!CheckImageTexelPointer(index)) ok = false; break; - case spv::Op::OpExtInst: + case SpvOpExtInst: if (user->GetCommonDebugOpcode() != CommonDebugInfoDebugDeclare || !CheckDebugDeclare(index)) ok = false; @@ -838,8 +900,7 @@ bool ScalarReplacementPass::CheckLoad(const Instruction* inst, uint32_t index) const { if (index != 2u) return false; if (inst->NumInOperands() >= 2 && - inst->GetSingleWordInOperand(1u) & - uint32_t(spv::MemoryAccessMask::Volatile)) + inst->GetSingleWordInOperand(1u) & SpvMemoryAccessVolatileMask) return false; return true; } @@ -848,8 +909,7 @@ bool ScalarReplacementPass::CheckStore(const Instruction* inst, uint32_t index) const { if (index != 0u) return false; if (inst->NumInOperands() >= 3 && - inst->GetSingleWordInOperand(2u) & - uint32_t(spv::MemoryAccessMask::Volatile)) + inst->GetSingleWordInOperand(2u) & SpvMemoryAccessVolatileMask) return false; return true; } @@ -876,11 +936,11 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { def_use_mgr->WhileEachUser(inst, [&result, def_use_mgr, this](Instruction* use) { switch (use->opcode()) { - case spv::Op::OpLoad: { + case SpvOpLoad: { // Look for extract from the load. std::vector t; if (def_use_mgr->WhileEachUser(use, [&t](Instruction* use2) { - if (use2->opcode() != spv::Op::OpCompositeExtract || + if (use2->opcode() != SpvOpCompositeExtract || use2->NumInOperands() <= 1) { return false; } @@ -894,13 +954,13 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { return false; } } - case spv::Op::OpName: - case spv::Op::OpMemberName: - case spv::Op::OpStore: + case SpvOpName: + case SpvOpMemberName: + case SpvOpStore: // No components are used. return true; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: { + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: { // Add the first index it if is a constant. // TODO: Could be improved by checking if the address is used in a load. analysis::ConstantManager* const_mgr = context()->get_constant_mgr(); @@ -928,16 +988,16 @@ ScalarReplacementPass::GetUsedComponents(Instruction* inst) { uint64_t ScalarReplacementPass::GetMaxLegalIndex( const Instruction* var_inst) const { - assert(var_inst->opcode() == spv::Op::OpVariable && + assert(var_inst->opcode() == SpvOpVariable && "|var_inst| must be a variable instruction."); Instruction* type = GetStorageType(var_inst); switch (type->opcode()) { - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: return type->NumInOperands(); - case spv::Op::OpTypeArray: + case SpvOpTypeArray: return GetArrayLength(type); - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeVector: return GetNumElements(type); default: return 0; @@ -945,69 +1005,5 @@ uint64_t ScalarReplacementPass::GetMaxLegalIndex( return 0; } -void ScalarReplacementPass::CopyDecorationsToVariable(Instruction* from, - Instruction* to, - uint32_t member_index) { - CopyPointerDecorationsToVariable(from, to); - CopyNecessaryMemberDecorationsToVariable(from, to, member_index); -} - -void ScalarReplacementPass::CopyPointerDecorationsToVariable(Instruction* from, - Instruction* to) { - // The RestrictPointer and AliasedPointer decorations are copied to all - // members even if the new variable does not contain a pointer. It does - // not hurt to do so. - for (auto dec_inst : - get_decoration_mgr()->GetDecorationsFor(from->result_id(), false)) { - uint32_t decoration; - decoration = dec_inst->GetSingleWordInOperand(1u); - switch (spv::Decoration(decoration)) { - case spv::Decoration::AliasedPointer: - case spv::Decoration::RestrictPointer: { - std::unique_ptr new_dec_inst(dec_inst->Clone(context())); - new_dec_inst->SetInOperand(0, {to->result_id()}); - context()->AddAnnotationInst(std::move(new_dec_inst)); - } break; - default: - break; - } - } -} - -void ScalarReplacementPass::CopyNecessaryMemberDecorationsToVariable( - Instruction* from, Instruction* to, uint32_t member_index) { - Instruction* type_inst = GetStorageType(from); - for (auto dec_inst : - get_decoration_mgr()->GetDecorationsFor(type_inst->result_id(), false)) { - uint32_t decoration; - if (dec_inst->opcode() == spv::Op::OpMemberDecorate) { - if (dec_inst->GetSingleWordInOperand(1) != member_index) { - continue; - } - - decoration = dec_inst->GetSingleWordInOperand(2u); - switch (spv::Decoration(decoration)) { - case spv::Decoration::ArrayStride: - case spv::Decoration::Alignment: - case spv::Decoration::AlignmentId: - case spv::Decoration::MaxByteOffset: - case spv::Decoration::MaxByteOffsetId: - case spv::Decoration::RelaxedPrecision: { - std::unique_ptr new_dec_inst( - new Instruction(context(), spv::Op::OpDecorate, 0, 0, {})); - new_dec_inst->AddOperand( - Operand(SPV_OPERAND_TYPE_ID, {to->result_id()})); - for (uint32_t i = 2; i < dec_inst->NumInOperandWords(); ++i) { - new_dec_inst->AddOperand(Operand(dec_inst->GetInOperand(i))); - } - context()->AddAnnotationInst(std::move(new_dec_inst)); - } break; - default: - break; - } - } - } -} - } // namespace opt } // namespace spvtools diff --git a/source/opt/scalar_replacement_pass.h b/source/opt/scalar_replacement_pass.h index c73ecfd9..6a66dfb8 100644 --- a/source/opt/scalar_replacement_pass.h +++ b/source/opt/scalar_replacement_pass.h @@ -33,7 +33,7 @@ namespace opt { // Documented in optimizer.hpp class ScalarReplacementPass : public MemPass { private: - static constexpr uint32_t kDefaultLimit = 100; + static const uint32_t kDefaultLimit = 100; public: ScalarReplacementPass(uint32_t limit = kDefaultLimit) @@ -104,10 +104,10 @@ class ScalarReplacementPass : public MemPass { // Returns true if the uses of |inst| are acceptable for scalarization. // // Recursively checks all the uses of |inst|. For |inst| specifically, only - // allows spv::Op::OpAccessChain, spv::Op::OpInBoundsAccessChain, - // spv::Op::OpLoad and spv::Op::OpStore. Access chains must have the first - // index be a compile-time constant. Subsequent uses of access chains - // (including other access chains) are checked in a more relaxed manner. + // allows SpvOpAccessChain, SpvOpInBoundsAccessChain, SpvOpLoad and + // SpvOpStore. Access chains must have the first index be a compile-time + // constant. Subsequent uses of access chains (including other access chains) + // are checked in a more relaxed manner. bool CheckUses(const Instruction* inst) const; // Helper function for the above |CheckUses|. @@ -262,26 +262,9 @@ class ScalarReplacementPass : public MemPass { // that we will be willing to split. bool IsLargerThanSizeLimit(uint64_t length) const; - // Copies all relevant decorations from `from` to `to`. This includes - // decorations applied to the variable, and to the members of the type. - // It is assumed that `to` is a variable that is intended to replace the - // `member_index`th member of `from`. - void CopyDecorationsToVariable(Instruction* from, Instruction* to, - uint32_t member_index); - - // Copies pointer related decoration from `from` to `to` if they exist. - void CopyPointerDecorationsToVariable(Instruction* from, Instruction* to); - - // Copies decorations that are needed from the `member_index` of `from` to - // `to, if there was one. - void CopyNecessaryMemberDecorationsToVariable(Instruction* from, - Instruction* to, - uint32_t member_index); - // Limit on the number of members in an object that will be replaced. // 0 means there is no limit. uint32_t max_num_elements_; - // This has to be big enough to fit "scalar-replacement=" followed by a // uint32_t number written in decimal (so 10 digits), and then a // terminating nul. diff --git a/source/opt/set_spec_constant_default_value_pass.cpp b/source/opt/set_spec_constant_default_value_pass.cpp index d2aa9b1d..4def2b09 100644 --- a/source/opt/set_spec_constant_default_value_pass.cpp +++ b/source/opt/set_spec_constant_default_value_pass.cpp @@ -21,6 +21,8 @@ #include #include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" +#include "source/opt/type_manager.h" #include "source/opt/types.h" #include "source/util/make_unique.h" #include "source/util/parse_number.h" @@ -28,6 +30,7 @@ namespace spvtools { namespace opt { + namespace { using utils::EncodeNumberStatus; using utils::NumberType; @@ -136,9 +139,9 @@ std::vector ParseDefaultValueBitPattern( // decoration. bool CanHaveSpecIdDecoration(const Instruction& inst) { switch (inst.opcode()) { - case spv::Op::OpSpecConstant: - case spv::Op::OpSpecConstantFalse: - case spv::Op::OpSpecConstantTrue: + case SpvOp::SpvOpSpecConstant: + case SpvOp::SpvOpSpecConstantFalse: + case SpvOp::SpvOpSpecConstantTrue: return true; default: return false; @@ -162,7 +165,7 @@ Instruction* GetSpecIdTargetFromDecorationGroup( if (def_use_mgr->WhileEachUser(&decoration_group_defining_inst, [&group_decorate_inst](Instruction* user) { if (user->opcode() == - spv::Op::OpGroupDecorate) { + SpvOp::SpvOpGroupDecorate) { group_decorate_inst = user; return false; } @@ -214,16 +217,16 @@ Instruction* GetSpecIdTargetFromDecorationGroup( Pass::Status SetSpecConstantDefaultValuePass::Process() { // The operand index of decoration target in an OpDecorate instruction. - constexpr uint32_t kTargetIdOperandIndex = 0; + const uint32_t kTargetIdOperandIndex = 0; // The operand index of the decoration literal in an OpDecorate instruction. - constexpr uint32_t kDecorationOperandIndex = 1; + const uint32_t kDecorationOperandIndex = 1; // The operand index of Spec id literal value in an OpDecorate SpecId // instruction. - constexpr uint32_t kSpecIdLiteralOperandIndex = 2; + const uint32_t kSpecIdLiteralOperandIndex = 2; // The number of operands in an OpDecorate SpecId instruction. - constexpr uint32_t kOpDecorateSpecIdNumOperands = 3; + const uint32_t kOpDecorateSpecIdNumOperands = 3; // The in-operand index of the default value in a OpSpecConstant instruction. - constexpr uint32_t kOpSpecConstantLiteralInOperandIndex = 0; + const uint32_t kOpSpecConstantLiteralInOperandIndex = 0; bool modified = false; // Scan through all the annotation instructions to find 'OpDecorate SpecId' @@ -237,10 +240,10 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // default value of the target spec constant. for (Instruction& inst : context()->annotations()) { // Only process 'OpDecorate SpecId' instructions - if (inst.opcode() != spv::Op::OpDecorate) continue; + if (inst.opcode() != SpvOp::SpvOpDecorate) continue; if (inst.NumOperands() != kOpDecorateSpecIdNumOperands) continue; if (inst.GetSingleWordInOperand(kDecorationOperandIndex) != - uint32_t(spv::Decoration::SpecId)) { + uint32_t(SpvDecoration::SpvDecorationSpecId)) { continue; } @@ -252,7 +255,7 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // target_id might be a decoration group id. Instruction* spec_inst = nullptr; if (Instruction* target_inst = get_def_use_mgr()->GetDef(target_id)) { - if (target_inst->opcode() == spv::Op::OpDecorationGroup) { + if (target_inst->opcode() == SpvOp::SpvOpDecorationGroup) { spec_inst = GetSpecIdTargetFromDecorationGroup(*target_inst, get_def_use_mgr()); } else { @@ -298,7 +301,7 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { // Update the operand bit patterns of the spec constant defining // instruction. switch (spec_inst->opcode()) { - case spv::Op::OpSpecConstant: + case SpvOp::SpvOpSpecConstant: // If the new value is the same with the original value, no // need to do anything. Otherwise update the operand words. if (spec_inst->GetInOperand(kOpSpecConstantLiteralInOperandIndex) @@ -308,19 +311,19 @@ Pass::Status SetSpecConstantDefaultValuePass::Process() { modified = true; } break; - case spv::Op::OpSpecConstantTrue: + case SpvOp::SpvOpSpecConstantTrue: // If the new value is also 'true', no need to change anything. // Otherwise, set the opcode to OpSpecConstantFalse; if (!static_cast(bit_pattern.front())) { - spec_inst->SetOpcode(spv::Op::OpSpecConstantFalse); + spec_inst->SetOpcode(SpvOp::SpvOpSpecConstantFalse); modified = true; } break; - case spv::Op::OpSpecConstantFalse: + case SpvOp::SpvOpSpecConstantFalse: // If the new value is also 'false', no need to change anything. // Otherwise, set the opcode to OpSpecConstantTrue; if (static_cast(bit_pattern.front())) { - spec_inst->SetOpcode(spv::Op::OpSpecConstantTrue); + spec_inst->SetOpcode(SpvOp::SpvOpSpecConstantTrue); modified = true; } break; diff --git a/source/opt/simplification_pass.cpp b/source/opt/simplification_pass.cpp index f8ffc03c..43ec15f8 100644 --- a/source/opt/simplification_pass.cpp +++ b/source/opt/simplification_pass.cpp @@ -14,6 +14,7 @@ #include "source/opt/simplification_pass.h" +#include #include #include @@ -68,12 +69,12 @@ bool SimplificationPass::SimplifyFunction(Function* function) { &folder, &inst_seen, this](BasicBlock* bb) { for (Instruction* inst = &*bb->begin(); inst; inst = inst->NextNode()) { inst_seen.insert(inst); - if (inst->opcode() == spv::Op::OpPhi) { + if (inst->opcode() == SpvOpPhi) { process_phis.insert(inst); } bool is_foldable_copy = - inst->opcode() == spv::Op::OpCopyObject && + inst->opcode() == SpvOpCopyObject && context()->get_decoration_mgr()->HaveSubsetOfDecorations( inst->result_id(), inst->GetSingleWordInOperand(0)); @@ -90,7 +91,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { AddNewOperands(inst, &inst_seen, &work_list); - if (inst->opcode() == spv::Op::OpCopyObject) { + if (inst->opcode() == SpvOpCopyObject) { context()->ReplaceAllUsesWithPredicate( inst->result_id(), inst->GetSingleWordInOperand(0), [](Instruction* user) { @@ -103,7 +104,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { }); inst_to_kill.insert(inst); in_work_list.insert(inst); - } else if (inst->opcode() == spv::Op::OpNop) { + } else if (inst->opcode() == SpvOpNop) { inst_to_kill.insert(inst); in_work_list.insert(inst); } @@ -120,7 +121,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { inst_seen.insert(inst); bool is_foldable_copy = - inst->opcode() == spv::Op::OpCopyObject && + inst->opcode() == SpvOpCopyObject && context()->get_decoration_mgr()->HaveSubsetOfDecorations( inst->result_id(), inst->GetSingleWordInOperand(0)); @@ -129,7 +130,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { context()->AnalyzeUses(inst); get_def_use_mgr()->ForEachUser( inst, [&work_list, &in_work_list](Instruction* use) { - if (!use->IsDecoration() && use->opcode() != spv::Op::OpName && + if (!use->IsDecoration() && use->opcode() != SpvOpName && in_work_list.insert(use).second) { work_list.push_back(use); } @@ -137,7 +138,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { AddNewOperands(inst, &inst_seen, &work_list); - if (inst->opcode() == spv::Op::OpCopyObject) { + if (inst->opcode() == SpvOpCopyObject) { context()->ReplaceAllUsesWithPredicate( inst->result_id(), inst->GetSingleWordInOperand(0), [](Instruction* user) { @@ -149,7 +150,7 @@ bool SimplificationPass::SimplifyFunction(Function* function) { }); inst_to_kill.insert(inst); in_work_list.insert(inst); - } else if (inst->opcode() == spv::Op::OpNop) { + } else if (inst->opcode() == SpvOpNop) { inst_to_kill.insert(inst); in_work_list.insert(inst); } diff --git a/source/opt/spread_volatile_semantics.cpp b/source/opt/spread_volatile_semantics.cpp index e552ba5e..b61fd0f4 100644 --- a/source/opt/spread_volatile_semantics.cpp +++ b/source/opt/spread_volatile_semantics.cpp @@ -15,37 +15,38 @@ #include "source/opt/spread_volatile_semantics.h" #include "source/opt/decoration_manager.h" +#include "source/opt/ir_builder.h" #include "source/spirv_constant.h" namespace spvtools { namespace opt { namespace { -constexpr uint32_t kOpDecorateInOperandBuiltinDecoration = 2u; -constexpr uint32_t kOpLoadInOperandMemoryOperands = 1u; -constexpr uint32_t kOpEntryPointInOperandEntryPoint = 1u; -constexpr uint32_t kOpEntryPointInOperandInterface = 3u; + +const uint32_t kOpDecorateInOperandBuiltinDecoration = 2u; +const uint32_t kOpLoadInOperandMemoryOperands = 1u; +const uint32_t kOpEntryPointInOperandEntryPoint = 1u; +const uint32_t kOpEntryPointInOperandInterface = 3u; bool HasBuiltinDecoration(analysis::DecorationManager* decoration_manager, uint32_t var_id, uint32_t built_in) { return decoration_manager->FindDecoration( - var_id, uint32_t(spv::Decoration::BuiltIn), - [built_in](const Instruction& inst) { + var_id, SpvDecorationBuiltIn, [built_in](const Instruction& inst) { return built_in == inst.GetSingleWordInOperand( kOpDecorateInOperandBuiltinDecoration); }); } -bool IsBuiltInForRayTracingVolatileSemantics(spv::BuiltIn built_in) { +bool IsBuiltInForRayTracingVolatileSemantics(uint32_t built_in) { switch (built_in) { - case spv::BuiltIn::SMIDNV: - case spv::BuiltIn::WarpIDNV: - case spv::BuiltIn::SubgroupSize: - case spv::BuiltIn::SubgroupLocalInvocationId: - case spv::BuiltIn::SubgroupEqMask: - case spv::BuiltIn::SubgroupGeMask: - case spv::BuiltIn::SubgroupGtMask: - case spv::BuiltIn::SubgroupLeMask: - case spv::BuiltIn::SubgroupLtMask: + case SpvBuiltInSMIDNV: + case SpvBuiltInWarpIDNV: + case SpvBuiltInSubgroupSize: + case SpvBuiltInSubgroupLocalInvocationId: + case SpvBuiltInSubgroupEqMask: + case SpvBuiltInSubgroupGeMask: + case SpvBuiltInSubgroupGtMask: + case SpvBuiltInSubgroupLeMask: + case SpvBuiltInSubgroupLtMask: return true; default: return false; @@ -55,17 +56,16 @@ bool IsBuiltInForRayTracingVolatileSemantics(spv::BuiltIn built_in) { bool HasBuiltinForRayTracingVolatileSemantics( analysis::DecorationManager* decoration_manager, uint32_t var_id) { return decoration_manager->FindDecoration( - var_id, uint32_t(spv::Decoration::BuiltIn), [](const Instruction& inst) { - spv::BuiltIn built_in = spv::BuiltIn( - inst.GetSingleWordInOperand(kOpDecorateInOperandBuiltinDecoration)); + var_id, SpvDecorationBuiltIn, [](const Instruction& inst) { + uint32_t built_in = + inst.GetSingleWordInOperand(kOpDecorateInOperandBuiltinDecoration); return IsBuiltInForRayTracingVolatileSemantics(built_in); }); } bool HasVolatileDecoration(analysis::DecorationManager* decoration_manager, uint32_t var_id) { - return decoration_manager->HasDecoration(var_id, - uint32_t(spv::Decoration::Volatile)); + return decoration_manager->HasDecoration(var_id, SpvDecorationVolatile); } } // namespace @@ -76,7 +76,7 @@ Pass::Status SpreadVolatileSemantics::Process() { } const bool is_vk_memory_model_enabled = context()->get_feature_mgr()->HasCapability( - spv::Capability::VulkanMemoryModel); + SpvCapabilityVulkanMemoryModel); CollectTargetsForVolatileSemantics(is_vk_memory_model_enabled); // If VulkanMemoryModel capability is not enabled, we have to set Volatile @@ -128,16 +128,15 @@ bool SpreadVolatileSemantics::IsTargetUsedByNonVolatileLoadInEntryPoint( } uint32_t memory_operands = load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); - return (memory_operands & uint32_t(spv::MemoryAccessMask::Volatile)) != - 0; + return (memory_operands & SpvMemoryAccessVolatileMask) != 0; }, funcs); } bool SpreadVolatileSemantics::HasInterfaceInConflictOfVolatileSemantics() { for (Instruction& entry_point : get_module()->entry_points()) { - spv::ExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); + SpvExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); for (uint32_t operand_index = kOpEntryPointInOperandInterface; operand_index < entry_point.NumInOperands(); ++operand_index) { uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); @@ -171,8 +170,8 @@ void SpreadVolatileSemantics::MarkVolatileSemanticsForVariable( void SpreadVolatileSemantics::CollectTargetsForVolatileSemantics( const bool is_vk_memory_model_enabled) { for (Instruction& entry_point : get_module()->entry_points()) { - spv::ExecutionModel execution_model = - static_cast(entry_point.GetSingleWordInOperand(0)); + SpvExecutionModel execution_model = + static_cast(entry_point.GetSingleWordInOperand(0)); for (uint32_t operand_index = kOpEntryPointInOperandInterface; operand_index < entry_point.NumInOperands(); ++operand_index) { uint32_t var_id = entry_point.GetSingleWordInOperand(operand_index); @@ -195,10 +194,9 @@ void SpreadVolatileSemantics::DecorateVarWithVolatile(Instruction* var) { return; } get_decoration_mgr()->AddDecoration( - spv::Op::OpDecorate, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, - {uint32_t(spv::Decoration::Volatile)}}}); + SpvOpDecorate, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {var_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, + {SpvDecorationVolatile}}}); } bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( @@ -219,17 +217,17 @@ bool SpreadVolatileSemantics::VisitLoadsOfPointersToVariableInEntries( return true; } - if (user->opcode() == spv::Op::OpAccessChain || - user->opcode() == spv::Op::OpInBoundsAccessChain || - user->opcode() == spv::Op::OpPtrAccessChain || - user->opcode() == spv::Op::OpInBoundsPtrAccessChain || - user->opcode() == spv::Op::OpCopyObject) { + if (user->opcode() == SpvOpAccessChain || + user->opcode() == SpvOpInBoundsAccessChain || + user->opcode() == SpvOpPtrAccessChain || + user->opcode() == SpvOpInBoundsPtrAccessChain || + user->opcode() == SpvOpCopyObject) { if (ptr_id == user->GetSingleWordInOperand(0)) worklist.push_back(user->result_id()); return true; } - if (user->opcode() != spv::Op::OpLoad) { + if (user->opcode() != SpvOpLoad) { return true; } @@ -252,12 +250,12 @@ void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( [](Instruction* load) { if (load->NumInOperands() <= kOpLoadInOperandMemoryOperands) { load->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, - {uint32_t(spv::MemoryAccessMask::Volatile)}}); + {SpvMemoryAccessVolatileMask}}); return true; } uint32_t memory_operands = load->GetSingleWordInOperand(kOpLoadInOperandMemoryOperands); - memory_operands |= uint32_t(spv::MemoryAccessMask::Volatile); + memory_operands |= SpvMemoryAccessVolatileMask; load->SetInOperand(kOpLoadInOperandMemoryOperands, {memory_operands}); return true; }, @@ -266,29 +264,29 @@ void SpreadVolatileSemantics::SetVolatileForLoadsInEntries( } bool SpreadVolatileSemantics::IsTargetForVolatileSemantics( - uint32_t var_id, spv::ExecutionModel execution_model) { + uint32_t var_id, SpvExecutionModel execution_model) { analysis::DecorationManager* decoration_manager = context()->get_decoration_mgr(); - if (execution_model == spv::ExecutionModel::Fragment) { + if (execution_model == SpvExecutionModelFragment) { return get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 6) && HasBuiltinDecoration(decoration_manager, var_id, - uint32_t(spv::BuiltIn::HelperInvocation)); + SpvBuiltInHelperInvocation); } - if (execution_model == spv::ExecutionModel::IntersectionKHR || - execution_model == spv::ExecutionModel::IntersectionNV) { + if (execution_model == SpvExecutionModelIntersectionKHR || + execution_model == SpvExecutionModelIntersectionNV) { if (HasBuiltinDecoration(decoration_manager, var_id, - uint32_t(spv::BuiltIn::RayTmaxKHR))) { + SpvBuiltInRayTmaxKHR)) { return true; } } switch (execution_model) { - case spv::ExecutionModel::RayGenerationKHR: - case spv::ExecutionModel::ClosestHitKHR: - case spv::ExecutionModel::MissKHR: - case spv::ExecutionModel::CallableKHR: - case spv::ExecutionModel::IntersectionKHR: + case SpvExecutionModelRayGenerationKHR: + case SpvExecutionModelClosestHitKHR: + case SpvExecutionModelMissKHR: + case SpvExecutionModelCallableKHR: + case SpvExecutionModelIntersectionKHR: return HasBuiltinForRayTracingVolatileSemantics(decoration_manager, var_id); default: diff --git a/source/opt/spread_volatile_semantics.h b/source/opt/spread_volatile_semantics.h index 4cbb526f..014858d3 100644 --- a/source/opt/spread_volatile_semantics.h +++ b/source/opt/spread_volatile_semantics.h @@ -39,8 +39,7 @@ class SpreadVolatileSemantics : public Pass { // have an execution model. bool HasNoExecutionModel() { return get_module()->entry_points().empty() && - context()->get_feature_mgr()->HasCapability( - spv::Capability::Linkage); + context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage); } // Iterates interface variables and spreads the Volatile semantics if it has @@ -53,7 +52,7 @@ class SpreadVolatileSemantics : public Pass { // VUID-StandaloneSpirv-VulkanMemoryModel-04678 or // VUID-StandaloneSpirv-VulkanMemoryModel-04679. bool IsTargetForVolatileSemantics(uint32_t var_id, - spv::ExecutionModel execution_model); + SpvExecutionModel execution_model); // Collects interface variables that need the volatile semantics. // |is_vk_memory_model_enabled| is true if VulkanMemoryModel capability is diff --git a/source/opt/ssa_rewrite_pass.cpp b/source/opt/ssa_rewrite_pass.cpp index 3eb4ec3f..22d81104 100644 --- a/source/opt/ssa_rewrite_pass.cpp +++ b/source/opt/ssa_rewrite_pass.cpp @@ -48,6 +48,7 @@ #include "source/opt/cfg.h" #include "source/opt/mem_pass.h" #include "source/opt/types.h" +#include "source/util/make_unique.h" // Debug logging (0: Off, 1-N: Verbosity level). Replace this with the // implementation done for @@ -62,9 +63,10 @@ namespace spvtools { namespace opt { + namespace { -constexpr uint32_t kStoreValIdInIdx = 1; -constexpr uint32_t kVariableInitIdInIdx = 1; +const uint32_t kStoreValIdInIdx = 1; +const uint32_t kVariableInitIdInIdx = 1; } // namespace std::string SSARewriter::PhiCandidate::PrettyPrint(const CFG* cfg) const { @@ -298,12 +300,12 @@ void SSARewriter::SealBlock(BasicBlock* bb) { void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) { auto opcode = inst->opcode(); - assert((opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) && + assert((opcode == SpvOpStore || opcode == SpvOpVariable) && "Expecting a store or a variable definition instruction."); uint32_t var_id = 0; uint32_t val_id = 0; - if (opcode == spv::Op::OpStore) { + if (opcode == SpvOpStore) { (void)pass_->GetPtr(inst, &var_id); val_id = inst->GetSingleWordInOperand(kStoreValIdInIdx); } else if (inst->NumInOperands() >= 2) { @@ -441,9 +443,9 @@ bool SSARewriter::GenerateSSAReplacements(BasicBlock* bb) { for (auto& inst : *bb) { auto opcode = inst.opcode(); - if (opcode == spv::Op::OpStore || opcode == spv::Op::OpVariable) { + if (opcode == SpvOpStore || opcode == SpvOpVariable) { ProcessStore(&inst, bb); - } else if (inst.opcode() == spv::Op::OpLoad) { + } else if (inst.opcode() == SpvOpLoad) { if (!ProcessLoad(&inst, bb)) { return false; } @@ -543,7 +545,7 @@ bool SSARewriter::ApplyReplacements() { // Generate a new OpPhi instruction and insert it in its basic // block. std::unique_ptr phi_inst( - new Instruction(pass_->context(), spv::Op::OpPhi, type_id, + new Instruction(pass_->context(), SpvOpPhi, type_id, phi_candidate->result_id(), phi_operands)); generated_phis.push_back(phi_inst.get()); pass_->get_def_use_mgr()->AnalyzeInstDef(&*phi_inst); @@ -552,7 +554,7 @@ bool SSARewriter::ApplyReplacements() { insert_it = insert_it.InsertBefore(std::move(phi_inst)); pass_->context()->get_decoration_mgr()->CloneDecorations( phi_candidate->var_id(), phi_candidate->result_id(), - {spv::Decoration::RelaxedPrecision}); + {SpvDecorationRelaxedPrecision}); // Add DebugValue for the new OpPhi instruction. insert_it->SetDebugScope(local_var->GetDebugScope()); diff --git a/source/opt/strength_reduction_pass.cpp b/source/opt/strength_reduction_pass.cpp index 16a7869e..ab7c4eb8 100644 --- a/source/opt/strength_reduction_pass.cpp +++ b/source/opt/strength_reduction_pass.cpp @@ -14,8 +14,12 @@ #include "source/opt/strength_reduction_pass.h" +#include +#include #include #include +#include +#include #include #include @@ -24,8 +28,6 @@ #include "source/opt/log.h" #include "source/opt/reflect.h" -namespace spvtools { -namespace opt { namespace { // Count the number of trailing zeros in the binary representation of // |constVal|. @@ -51,6 +53,9 @@ bool IsPowerOf2(uint32_t val) { } // namespace +namespace spvtools { +namespace opt { + Pass::Status StrengthReductionPass::Process() { // Initialize the member variables on a per module basis. bool modified = false; @@ -65,7 +70,7 @@ Pass::Status StrengthReductionPass::Process() { bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( BasicBlock::iterator* inst) { - assert((*inst)->opcode() == spv::Op::OpIMul && + assert((*inst)->opcode() == SpvOp::SpvOpIMul && "Only works for multiplication of integers."); bool modified = false; @@ -79,7 +84,7 @@ bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( for (int i = 0; i < 2; i++) { uint32_t opId = (*inst)->GetSingleWordInOperand(i); Instruction* opInst = get_def_use_mgr()->GetDef(opId); - if (opInst->opcode() == spv::Op::OpConstant) { + if (opInst->opcode() == SpvOp::SpvOpConstant) { // We found a constant operand. uint32_t constVal = opInst->GetSingleWordOperand(2); @@ -96,7 +101,7 @@ bool StrengthReductionPass::ReplaceMultiplyByPowerOf2( {shiftConstResultId}); newOperands.push_back(shiftOperand); std::unique_ptr newInstruction( - new Instruction(context(), spv::Op::OpShiftLeftLogical, + new Instruction(context(), SpvOp::SpvOpShiftLeftLogical, (*inst)->type_id(), newResultId, newOperands)); // Insert the new instruction and update the data structures. @@ -128,7 +133,7 @@ void StrengthReductionPass::FindIntTypesAndConstants() { for (auto iter = get_module()->types_values_begin(); iter != get_module()->types_values_end(); ++iter) { switch (iter->opcode()) { - case spv::Op::OpConstant: + case SpvOp::SpvOpConstant: if (iter->type_id() == uint32_type_id_) { uint32_t value = iter->GetSingleWordOperand(2); if (value <= 32) constant_ids_[value] = iter->result_id(); @@ -154,8 +159,9 @@ uint32_t StrengthReductionPass::GetConstantId(uint32_t val) { uint32_t resultId = TakeNextId(); Operand constant(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}); - std::unique_ptr newConstant(new Instruction( - context(), spv::Op::OpConstant, uint32_type_id_, resultId, {constant})); + std::unique_ptr newConstant( + new Instruction(context(), SpvOp::SpvOpConstant, uint32_type_id_, + resultId, {constant})); get_module()->AddGlobalValue(std::move(newConstant)); // Notify the DefUseManager about this constant. @@ -178,7 +184,7 @@ bool StrengthReductionPass::ScanFunctions() { for (auto& bb : func) { for (auto inst = bb.begin(); inst != bb.end(); ++inst) { switch (inst->opcode()) { - case spv::Op::OpIMul: + case SpvOp::SpvOpIMul: if (ReplaceMultiplyByPowerOf2(&inst)) modified = true; break; default: diff --git a/source/opt/strip_debug_info_pass.cpp b/source/opt/strip_debug_info_pass.cpp index f81bced5..6a0ebf24 100644 --- a/source/opt/strip_debug_info_pass.cpp +++ b/source/opt/strip_debug_info_pass.cpp @@ -37,13 +37,13 @@ Pass::Status StripDebugInfoPass::Process() { if (uses_non_semantic_info) { for (auto& inst : context()->module()->debugs1()) { switch (inst.opcode()) { - case spv::Op::OpString: { + case SpvOpString: { analysis::DefUseManager* def_use = context()->get_def_use_mgr(); // see if this string is used anywhere by a non-semantic instruction bool no_nonsemantic_use = def_use->WhileEachUser(&inst, [def_use](Instruction* use) { - if (use->opcode() == spv::Op::OpExtInst) { + if (use->opcode() == SpvOpExtInst) { auto ext_inst_set = def_use->GetDef(use->GetSingleWordInOperand(0u)); const std::string extension_name = @@ -83,8 +83,7 @@ Pass::Status StripDebugInfoPass::Process() { // when that instruction is killed, which will lead to a double kill. std::sort(to_kill.begin(), to_kill.end(), [](Instruction* lhs, Instruction* rhs) -> bool { - if (lhs->opcode() == spv::Op::OpName && - rhs->opcode() != spv::Op::OpName) + if (lhs->opcode() == SpvOpName && rhs->opcode() != SpvOpName) return true; return false; }); diff --git a/source/opt/strip_nonsemantic_info_pass.cpp b/source/opt/strip_nonsemantic_info_pass.cpp index 3886835a..cd1fbb63 100644 --- a/source/opt/strip_nonsemantic_info_pass.cpp +++ b/source/opt/strip_nonsemantic_info_pass.cpp @@ -14,6 +14,7 @@ #include "source/opt/strip_nonsemantic_info_pass.h" +#include #include #include "source/opt/instruction.h" @@ -31,31 +32,27 @@ Pass::Status StripNonSemanticInfoPass::Process() { bool other_uses_for_decorate_string = false; for (auto& inst : context()->module()->annotations()) { switch (inst.opcode()) { - case spv::Op::OpDecorateStringGOOGLE: - if (spv::Decoration(inst.GetSingleWordInOperand(1)) == - spv::Decoration::HlslSemanticGOOGLE || - spv::Decoration(inst.GetSingleWordInOperand(1)) == - spv::Decoration::UserTypeGOOGLE) { + case SpvOpDecorateStringGOOGLE: + if (inst.GetSingleWordInOperand(1) == SpvDecorationHlslSemanticGOOGLE || + inst.GetSingleWordInOperand(1) == SpvDecorationUserTypeGOOGLE) { to_remove.push_back(&inst); } else { other_uses_for_decorate_string = true; } break; - case spv::Op::OpMemberDecorateStringGOOGLE: - if (spv::Decoration(inst.GetSingleWordInOperand(2)) == - spv::Decoration::HlslSemanticGOOGLE || - spv::Decoration(inst.GetSingleWordInOperand(2)) == - spv::Decoration::UserTypeGOOGLE) { + case SpvOpMemberDecorateStringGOOGLE: + if (inst.GetSingleWordInOperand(2) == SpvDecorationHlslSemanticGOOGLE || + inst.GetSingleWordInOperand(2) == SpvDecorationUserTypeGOOGLE) { to_remove.push_back(&inst); } else { other_uses_for_decorate_string = true; } break; - case spv::Op::OpDecorateId: - if (spv::Decoration(inst.GetSingleWordInOperand(1)) == - spv::Decoration::HlslCounterBufferGOOGLE) { + case SpvOpDecorateId: + if (inst.GetSingleWordInOperand(1) == + SpvDecorationHlslCounterBufferGOOGLE) { to_remove.push_back(&inst); } break; @@ -82,7 +79,7 @@ Pass::Status StripNonSemanticInfoPass::Process() { // remove any extended inst imports that are non semantic std::unordered_set non_semantic_sets; for (auto& inst : context()->module()->ext_inst_imports()) { - assert(inst.opcode() == spv::Op::OpExtInstImport && + assert(inst.opcode() == SpvOpExtInstImport && "Expecting an import of an extension's instruction set."); const std::string extension_name = inst.GetInOperand(0).AsString(); if (spvtools::utils::starts_with(extension_name, "NonSemantic.")) { @@ -96,7 +93,7 @@ Pass::Status StripNonSemanticInfoPass::Process() { if (!non_semantic_sets.empty()) { context()->module()->ForEachInst( [&non_semantic_sets, &to_remove](Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) != non_semantic_sets.end()) { to_remove.push_back(inst); diff --git a/source/opt/strip_reflect_info_pass.cpp b/source/opt/strip_reflect_info_pass.cpp new file mode 100644 index 00000000..8b0f2db7 --- /dev/null +++ b/source/opt/strip_reflect_info_pass.cpp @@ -0,0 +1,128 @@ +// Copyright (c) 2018 Google LLC +// +// 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 "source/opt/strip_reflect_info_pass.h" + +#include +#include + +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +Pass::Status StripReflectInfoPass::Process() { + bool modified = false; + + std::vector to_remove; + + bool other_uses_for_decorate_string = false; + for (auto& inst : context()->module()->annotations()) { + switch (inst.opcode()) { + case SpvOpDecorateStringGOOGLE: + if (inst.GetSingleWordInOperand(1) == SpvDecorationHlslSemanticGOOGLE) { + to_remove.push_back(&inst); + } else { + other_uses_for_decorate_string = true; + } + break; + + case SpvOpMemberDecorateStringGOOGLE: + if (inst.GetSingleWordInOperand(2) == SpvDecorationHlslSemanticGOOGLE) { + to_remove.push_back(&inst); + } else { + other_uses_for_decorate_string = true; + } + break; + + case SpvOpDecorateId: + if (inst.GetSingleWordInOperand(1) == + SpvDecorationHlslCounterBufferGOOGLE) { + to_remove.push_back(&inst); + } + break; + + default: + break; + } + } + + for (auto& inst : context()->module()->extensions()) { + const char* ext_name = + reinterpret_cast(&inst.GetInOperand(0).words[0]); + if (0 == std::strcmp(ext_name, "SPV_GOOGLE_hlsl_functionality1")) { + to_remove.push_back(&inst); + } else if (!other_uses_for_decorate_string && + 0 == std::strcmp(ext_name, "SPV_GOOGLE_decorate_string")) { + to_remove.push_back(&inst); + } else if (0 == std::strcmp(ext_name, "SPV_KHR_non_semantic_info")) { + to_remove.push_back(&inst); + } + } + + // clear all debug data now if it hasn't been cleared already, to remove any + // remaining OpString that may have been referenced by non-semantic extinsts + for (auto& dbg : context()->debugs1()) to_remove.push_back(&dbg); + for (auto& dbg : context()->debugs2()) to_remove.push_back(&dbg); + for (auto& dbg : context()->debugs3()) to_remove.push_back(&dbg); + for (auto& dbg : context()->ext_inst_debuginfo()) to_remove.push_back(&dbg); + + // remove any extended inst imports that are non semantic + std::unordered_set non_semantic_sets; + for (auto& inst : context()->module()->ext_inst_imports()) { + assert(inst.opcode() == SpvOpExtInstImport && + "Expecting an import of an extension's instruction set."); + const char* extension_name = + reinterpret_cast(&inst.GetInOperand(0).words[0]); + if (0 == std::strncmp(extension_name, "NonSemantic.", 12)) { + non_semantic_sets.insert(inst.result_id()); + to_remove.push_back(&inst); + } + } + + // if we removed some non-semantic sets, then iterate over the instructions in + // the module to remove any OpExtInst that referenced those sets + if (!non_semantic_sets.empty()) { + context()->module()->ForEachInst( + [&non_semantic_sets, &to_remove](Instruction* inst) { + if (inst->opcode() == SpvOpExtInst) { + if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) != + non_semantic_sets.end()) { + to_remove.push_back(inst); + } + } + }); + } + + // OpName must come first, since they may refer to other debug instructions. + // If they are after the instructions that refer to, then they will be killed + // when that instruction is killed, which will lead to a double kill. + std::sort(to_remove.begin(), to_remove.end(), + [](Instruction* lhs, Instruction* rhs) -> bool { + if (lhs->opcode() == SpvOpName && rhs->opcode() != SpvOpName) + return true; + return false; + }); + + for (auto* inst : to_remove) { + modified = true; + context()->KillInst(inst); + } + + return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/source/opt/analyze_live_input_pass.h b/source/opt/strip_reflect_info_pass.h old mode 100755 new mode 100644 similarity index 58% rename from source/opt/analyze_live_input_pass.h rename to source/opt/strip_reflect_info_pass.h index ab292eff..4e1999ed --- a/source/opt/analyze_live_input_pass.h +++ b/source/opt/strip_reflect_info_pass.h @@ -1,5 +1,4 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. +// Copyright (c) 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,45 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ -#define SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ - -#include +#ifndef SOURCE_OPT_STRIP_REFLECT_INFO_PASS_H_ +#define SOURCE_OPT_STRIP_REFLECT_INFO_PASS_H_ +#include "source/opt/ir_context.h" +#include "source/opt/module.h" #include "source/opt/pass.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. -class AnalyzeLiveInputPass : public Pass { +class StripReflectInfoPass : public Pass { public: - explicit AnalyzeLiveInputPass(std::unordered_set* live_locs, - std::unordered_set* live_builtins) - : live_locs_(live_locs), live_builtins_(live_builtins) {} - - const char* name() const override { return "analyze-live-input"; } + const char* name() const override { return "strip-reflect"; } Status Process() override; // Return the mask of preserved Analyses. IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisDefUse | - IRContext::kAnalysisInstrToBlockMapping | + return IRContext::kAnalysisInstrToBlockMapping | IRContext::kAnalysisCombinators | IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | IRContext::kAnalysisConstants | IRContext::kAnalysisTypes; } - - private: - // Do live input analysis - Status DoLiveInputAnalysis(); - - std::unordered_set* live_locs_; - std::unordered_set* live_builtins_; }; } // namespace opt } // namespace spvtools -#endif // SOURCE_OPT_ANALYZE_LIVE_INPUT_H_ +#endif // SOURCE_OPT_STRIP_REFLECT_INFO_PASS_H_ diff --git a/source/opt/struct_cfg_analysis.cpp b/source/opt/struct_cfg_analysis.cpp index 290b4bf4..203db87d 100644 --- a/source/opt/struct_cfg_analysis.cpp +++ b/source/opt/struct_cfg_analysis.cpp @@ -16,17 +16,18 @@ #include "source/opt/ir_context.h" +namespace { +const uint32_t kMergeNodeIndex = 0; +const uint32_t kContinueNodeIndex = 1; +} // namespace + namespace spvtools { namespace opt { -namespace { -constexpr uint32_t kMergeNodeIndex = 0; -constexpr uint32_t kContinueNodeIndex = 1; -} // namespace StructuredCFGAnalysis::StructuredCFGAnalysis(IRContext* ctx) : context_(ctx) { // If this is not a shader, there are no merge instructions, and not // structured CFG to analyze. - if (!context_->get_feature_mgr()->HasCapability(spv::Capability::Shader)) { + if (!context_->get_feature_mgr()->HasCapability(SpvCapabilityShader)) { return; } @@ -81,7 +82,7 @@ void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) { merge_inst->GetSingleWordInOperand(kMergeNodeIndex); new_state.cinfo.containing_construct = block->id(); - if (merge_inst->opcode() == spv::Op::OpLoopMerge) { + if (merge_inst->opcode() == SpvOpLoopMerge) { new_state.cinfo.containing_loop = block->id(); new_state.cinfo.containing_switch = 0; new_state.continue_node = @@ -97,7 +98,7 @@ void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) { new_state.cinfo.in_continue = state.back().cinfo.in_continue; new_state.continue_node = state.back().continue_node; - if (merge_inst->NextNode()->opcode() == spv::Op::OpSwitch) { + if (merge_inst->NextNode()->opcode() == SpvOpSwitch) { new_state.cinfo.containing_switch = block->id(); } else { new_state.cinfo.containing_switch = @@ -225,7 +226,7 @@ StructuredCFGAnalysis::FindFuncsCalledFromContinue() { for (auto& bb : func) { if (IsInContainingLoopsContinueConstruct(bb.id())) { for (const Instruction& inst : bb) { - if (inst.opcode() == spv::Op::OpFunctionCall) { + if (inst.opcode() == SpvOpFunctionCall) { funcs_to_process.push(inst.GetSingleWordInOperand(0)); } } diff --git a/source/opt/switch_descriptorset_pass.cpp b/source/opt/switch_descriptorset_pass.cpp deleted file mode 100755 index f07c9175..00000000 --- a/source/opt/switch_descriptorset_pass.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2023 LunarG Inc. -// -// 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 "source/opt/switch_descriptorset_pass.h" - -#include "source/opt/ir_builder.h" -#include "source/util/string_utils.h" - -namespace spvtools { -namespace opt { - -Pass::Status SwitchDescriptorSetPass::Process() { - Status status = Status::SuccessWithoutChange; - auto* deco_mgr = context()->get_decoration_mgr(); - - for (Instruction& var : context()->types_values()) { - if (var.opcode() != spv::Op::OpVariable) { - continue; - } - auto decos = deco_mgr->GetDecorationsFor(var.result_id(), false); - for (const auto& deco : decos) { - spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u)); - if (d == spv::Decoration::DescriptorSet && - deco->GetSingleWordInOperand(2u) == ds_from_) { - deco->SetInOperand(2u, {ds_to_}); - status = Status::SuccessWithChange; - break; - } - } - } - return status; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/switch_descriptorset_pass.h b/source/opt/switch_descriptorset_pass.h deleted file mode 100755 index 2084e9cd..00000000 --- a/source/opt/switch_descriptorset_pass.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2023 LunarG Inc. -// -// 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. - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// See optimizer.hpp for documentation. -class SwitchDescriptorSetPass : public Pass { - public: - SwitchDescriptorSetPass(uint32_t ds_from, uint32_t ds_to) - : ds_from_(ds_from), ds_to_(ds_to) {} - - const char* name() const override { return "switch-descriptorset"; } - - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - // this pass preserves everything except decorations - uint32_t mask = ((IRContext::kAnalysisEnd << 1) - 1); - mask &= ~static_cast(IRContext::kAnalysisDecorations); - return static_cast(mask); - } - - private: - uint32_t ds_from_; - uint32_t ds_to_; -}; - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/trim_capabilities_pass.cpp b/source/opt/trim_capabilities_pass.cpp deleted file mode 100755 index 05499471..00000000 --- a/source/opt/trim_capabilities_pass.cpp +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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 "source/opt/trim_capabilities_pass.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "source/enum_set.h" -#include "source/enum_string_mapping.h" -#include "source/opt/ir_context.h" -#include "source/opt/reflect.h" -#include "source/spirv_target_env.h" -#include "source/util/string_utils.h" - -namespace spvtools { -namespace opt { - -namespace { -constexpr uint32_t kOpTypeFloatSizeIndex = 0; -constexpr uint32_t kOpTypePointerStorageClassIndex = 0; -constexpr uint32_t kTypeArrayTypeIndex = 0; -constexpr uint32_t kOpTypeScalarBitWidthIndex = 0; -constexpr uint32_t kTypePointerTypeIdInIndex = 1; -constexpr uint32_t kOpTypeIntSizeIndex = 0; -constexpr uint32_t kOpTypeImageDimIndex = 1; -constexpr uint32_t kOpTypeImageArrayedIndex = kOpTypeImageDimIndex + 2; -constexpr uint32_t kOpTypeImageMSIndex = kOpTypeImageArrayedIndex + 1; -constexpr uint32_t kOpTypeImageSampledIndex = kOpTypeImageMSIndex + 1; -constexpr uint32_t kOpTypeImageFormatIndex = kOpTypeImageSampledIndex + 1; -constexpr uint32_t kOpImageReadImageIndex = 0; -constexpr uint32_t kOpImageSparseReadImageIndex = 0; - -// DFS visit of the type defined by `instruction`. -// If `condition` is true, children of the current node are visited. -// If `condition` is false, the children of the current node are ignored. -template -static void DFSWhile(const Instruction* instruction, UnaryPredicate condition) { - std::stack instructions_to_visit; - instructions_to_visit.push(instruction->result_id()); - const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); - - while (!instructions_to_visit.empty()) { - const Instruction* item = def_use_mgr->GetDef(instructions_to_visit.top()); - instructions_to_visit.pop(); - - if (!condition(item)) { - continue; - } - - if (item->opcode() == spv::Op::OpTypePointer) { - instructions_to_visit.push( - item->GetSingleWordInOperand(kTypePointerTypeIdInIndex)); - continue; - } - - if (item->opcode() == spv::Op::OpTypeMatrix || - item->opcode() == spv::Op::OpTypeVector || - item->opcode() == spv::Op::OpTypeArray || - item->opcode() == spv::Op::OpTypeRuntimeArray) { - instructions_to_visit.push( - item->GetSingleWordInOperand(kTypeArrayTypeIndex)); - continue; - } - - if (item->opcode() == spv::Op::OpTypeStruct) { - item->ForEachInOperand([&instructions_to_visit](const uint32_t* op_id) { - instructions_to_visit.push(*op_id); - }); - continue; - } - } -} - -// Walks the type defined by `instruction` (OpType* only). -// Returns `true` if any call to `predicate` with the type/subtype returns true. -template -static bool AnyTypeOf(const Instruction* instruction, - UnaryPredicate predicate) { - assert(IsTypeInst(instruction->opcode()) && - "AnyTypeOf called with a non-type instruction."); - - bool found_one = false; - DFSWhile(instruction, [&found_one, predicate](const Instruction* node) { - if (found_one || predicate(node)) { - found_one = true; - return false; - } - - return true; - }); - return found_one; -} - -static bool is16bitType(const Instruction* instruction) { - if (instruction->opcode() != spv::Op::OpTypeInt && - instruction->opcode() != spv::Op::OpTypeFloat) { - return false; - } - - return instruction->GetSingleWordInOperand(kOpTypeScalarBitWidthIndex) == 16; -} - -static bool Has16BitCapability(const FeatureManager* feature_manager) { - const CapabilitySet& capabilities = feature_manager->GetCapabilities(); - return capabilities.contains(spv::Capability::Float16) || - capabilities.contains(spv::Capability::Int16); -} - -} // namespace - -// ============== Begin opcode handler implementations. ======================= -// -// Adding support for a new capability should only require adding a new handler, -// and updating the -// kSupportedCapabilities/kUntouchableCapabilities/kFordiddenCapabilities lists. -// -// Handler names follow the following convention: -// Handler__() - -static std::optional Handler_OpTypeFloat_Float64( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypeFloat && - "This handler only support OpTypeFloat opcodes."); - - const uint32_t size = - instruction->GetSingleWordInOperand(kOpTypeFloatSizeIndex); - return size == 64 ? std::optional(spv::Capability::Float64) : std::nullopt; -} - -static std::optional -Handler_OpTypePointer_StorageInputOutput16(const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypePointer && - "This handler only support OpTypePointer opcodes."); - - // This capability is only required if the variable has an Input/Output - // storage class. - spv::StorageClass storage_class = spv::StorageClass( - instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { - return std::nullopt; - } - - if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { - return std::nullopt; - } - - return AnyTypeOf(instruction, is16bitType) - ? std::optional(spv::Capability::StorageInputOutput16) - : std::nullopt; -} - -static std::optional -Handler_OpTypePointer_StoragePushConstant16(const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypePointer && - "This handler only support OpTypePointer opcodes."); - - // This capability is only required if the variable has a PushConstant storage - // class. - spv::StorageClass storage_class = spv::StorageClass( - instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); - if (storage_class != spv::StorageClass::PushConstant) { - return std::nullopt; - } - - if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { - return std::nullopt; - } - - return AnyTypeOf(instruction, is16bitType) - ? std::optional(spv::Capability::StoragePushConstant16) - : std::nullopt; -} - -static std::optional -Handler_OpTypePointer_StorageUniformBufferBlock16( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypePointer && - "This handler only support OpTypePointer opcodes."); - - // This capability is only required if the variable has a Uniform storage - // class. - spv::StorageClass storage_class = spv::StorageClass( - instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); - if (storage_class != spv::StorageClass::Uniform) { - return std::nullopt; - } - - if (!Has16BitCapability(instruction->context()->get_feature_mgr())) { - return std::nullopt; - } - - const auto* decoration_mgr = instruction->context()->get_decoration_mgr(); - const bool matchesCondition = - AnyTypeOf(instruction, [decoration_mgr](const Instruction* item) { - if (!decoration_mgr->HasDecoration(item->result_id(), - spv::Decoration::BufferBlock)) { - return false; - } - - return AnyTypeOf(item, is16bitType); - }); - - return matchesCondition - ? std::optional(spv::Capability::StorageUniformBufferBlock16) - : std::nullopt; -} - -static std::optional Handler_OpTypePointer_StorageUniform16( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypePointer && - "This handler only support OpTypePointer opcodes."); - - // This capability is only required if the variable has a Uniform storage - // class. - spv::StorageClass storage_class = spv::StorageClass( - instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex)); - if (storage_class != spv::StorageClass::Uniform) { - return std::nullopt; - } - - const auto* feature_manager = instruction->context()->get_feature_mgr(); - if (!Has16BitCapability(feature_manager)) { - return std::nullopt; - } - - const bool hasBufferBlockCapability = - feature_manager->GetCapabilities().contains( - spv::Capability::StorageUniformBufferBlock16); - const auto* decoration_mgr = instruction->context()->get_decoration_mgr(); - bool found16bitType = false; - - DFSWhile(instruction, [decoration_mgr, hasBufferBlockCapability, - &found16bitType](const Instruction* item) { - if (found16bitType) { - return false; - } - - if (hasBufferBlockCapability && - decoration_mgr->HasDecoration(item->result_id(), - spv::Decoration::BufferBlock)) { - return false; - } - - if (is16bitType(item)) { - found16bitType = true; - return false; - } - - return true; - }); - - return found16bitType ? std::optional(spv::Capability::StorageUniform16) - : std::nullopt; -} - -static std::optional Handler_OpTypeInt_Int64( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypeInt && - "This handler only support OpTypeInt opcodes."); - - const uint32_t size = - instruction->GetSingleWordInOperand(kOpTypeIntSizeIndex); - return size == 64 ? std::optional(spv::Capability::Int64) : std::nullopt; -} - -static std::optional Handler_OpTypeImage_ImageMSArray( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpTypeImage && - "This handler only support OpTypeImage opcodes."); - - const uint32_t arrayed = - instruction->GetSingleWordInOperand(kOpTypeImageArrayedIndex); - const uint32_t ms = instruction->GetSingleWordInOperand(kOpTypeImageMSIndex); - const uint32_t sampled = - instruction->GetSingleWordInOperand(kOpTypeImageSampledIndex); - - return arrayed == 1 && sampled == 2 && ms == 1 - ? std::optional(spv::Capability::ImageMSArray) - : std::nullopt; -} - -static std::optional -Handler_OpImageRead_StorageImageReadWithoutFormat( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpImageRead && - "This handler only support OpImageRead opcodes."); - const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); - - const uint32_t image_index = - instruction->GetSingleWordInOperand(kOpImageReadImageIndex); - const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id(); - const Instruction* type = def_use_mgr->GetDef(type_index); - const uint32_t dim = type->GetSingleWordInOperand(kOpTypeImageDimIndex); - const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); - - const bool is_unknown = spv::ImageFormat(format) == spv::ImageFormat::Unknown; - const bool requires_capability_for_unknown = - spv::Dim(dim) != spv::Dim::SubpassData; - return is_unknown && requires_capability_for_unknown - ? std::optional(spv::Capability::StorageImageReadWithoutFormat) - : std::nullopt; -} - -static std::optional -Handler_OpImageSparseRead_StorageImageReadWithoutFormat( - const Instruction* instruction) { - assert(instruction->opcode() == spv::Op::OpImageSparseRead && - "This handler only support OpImageSparseRead opcodes."); - const auto* def_use_mgr = instruction->context()->get_def_use_mgr(); - - const uint32_t image_index = - instruction->GetSingleWordInOperand(kOpImageSparseReadImageIndex); - const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id(); - const Instruction* type = def_use_mgr->GetDef(type_index); - const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex); - - return spv::ImageFormat(format) == spv::ImageFormat::Unknown - ? std::optional(spv::Capability::StorageImageReadWithoutFormat) - : std::nullopt; -} - -// Opcode of interest to determine capabilities requirements. -constexpr std::array, 10> kOpcodeHandlers{{ - // clang-format off - {spv::Op::OpImageRead, Handler_OpImageRead_StorageImageReadWithoutFormat}, - {spv::Op::OpImageSparseRead, Handler_OpImageSparseRead_StorageImageReadWithoutFormat}, - {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float64 }, - {spv::Op::OpTypeImage, Handler_OpTypeImage_ImageMSArray}, - {spv::Op::OpTypeInt, Handler_OpTypeInt_Int64 }, - {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageInputOutput16}, - {spv::Op::OpTypePointer, Handler_OpTypePointer_StoragePushConstant16}, - {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16}, - {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16}, - {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniformBufferBlock16}, - // clang-format on -}}; - -// ============== End opcode handler implementations. ======================= - -namespace { -ExtensionSet getExtensionsRelatedTo(const CapabilitySet& capabilities, - const AssemblyGrammar& grammar) { - ExtensionSet output; - const spv_operand_desc_t* desc = nullptr; - for (auto capability : capabilities) { - if (SPV_SUCCESS != grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, - static_cast(capability), - &desc)) { - continue; - } - - for (uint32_t i = 0; i < desc->numExtensions; ++i) { - output.insert(desc->extensions[i]); - } - } - - return output; -} -} // namespace - -TrimCapabilitiesPass::TrimCapabilitiesPass() - : supportedCapabilities_( - TrimCapabilitiesPass::kSupportedCapabilities.cbegin(), - TrimCapabilitiesPass::kSupportedCapabilities.cend()), - forbiddenCapabilities_( - TrimCapabilitiesPass::kForbiddenCapabilities.cbegin(), - TrimCapabilitiesPass::kForbiddenCapabilities.cend()), - untouchableCapabilities_( - TrimCapabilitiesPass::kUntouchableCapabilities.cbegin(), - TrimCapabilitiesPass::kUntouchableCapabilities.cend()), - opcodeHandlers_(kOpcodeHandlers.cbegin(), kOpcodeHandlers.cend()) {} - -void TrimCapabilitiesPass::addInstructionRequirementsForOpcode( - spv::Op opcode, CapabilitySet* capabilities, - ExtensionSet* extensions) const { - // Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT - // because they have three possible capabilities, only one of which is needed - if (opcode == spv::Op::OpBeginInvocationInterlockEXT || - opcode == spv::Op::OpEndInvocationInterlockEXT) { - return; - } - - const spv_opcode_desc_t* desc = {}; - auto result = context()->grammar().lookupOpcode(opcode, &desc); - if (result != SPV_SUCCESS) { - return; - } - - addSupportedCapabilitiesToSet(desc, capabilities); - addSupportedExtensionsToSet(desc, extensions); -} - -void TrimCapabilitiesPass::addInstructionRequirementsForOperand( - const Operand& operand, CapabilitySet* capabilities, - ExtensionSet* extensions) const { - // No supported capability relies on a 2+-word operand. - if (operand.words.size() != 1) { - return; - } - - // No supported capability relies on a literal string operand or an ID. - if (operand.type == SPV_OPERAND_TYPE_LITERAL_STRING || - operand.type == SPV_OPERAND_TYPE_ID || - operand.type == SPV_OPERAND_TYPE_RESULT_ID) { - return; - } - - // case 1: Operand is a single value, can directly lookup. - if (!spvOperandIsConcreteMask(operand.type)) { - const spv_operand_desc_t* desc = {}; - auto result = context()->grammar().lookupOperand(operand.type, - operand.words[0], &desc); - if (result != SPV_SUCCESS) { - return; - } - addSupportedCapabilitiesToSet(desc, capabilities); - addSupportedExtensionsToSet(desc, extensions); - return; - } - - // case 2: operand can be a bitmask, we need to decompose the lookup. - for (uint32_t i = 0; i < 32; i++) { - const uint32_t mask = (1 << i) & operand.words[0]; - if (!mask) { - continue; - } - - const spv_operand_desc_t* desc = {}; - auto result = context()->grammar().lookupOperand(operand.type, mask, &desc); - if (result != SPV_SUCCESS) { - continue; - } - - addSupportedCapabilitiesToSet(desc, capabilities); - addSupportedExtensionsToSet(desc, extensions); - } -} - -void TrimCapabilitiesPass::addInstructionRequirements( - Instruction* instruction, CapabilitySet* capabilities, - ExtensionSet* extensions) const { - // Ignoring OpCapability and OpExtension instructions. - if (instruction->opcode() == spv::Op::OpCapability || - instruction->opcode() == spv::Op::OpExtension) { - return; - } - - addInstructionRequirementsForOpcode(instruction->opcode(), capabilities, - extensions); - - // Second case: one of the opcode operand is gated by a capability. - const uint32_t operandCount = instruction->NumOperands(); - for (uint32_t i = 0; i < operandCount; i++) { - addInstructionRequirementsForOperand(instruction->GetOperand(i), - capabilities, extensions); - } - - // Last case: some complex logic needs to be run to determine capabilities. - auto[begin, end] = opcodeHandlers_.equal_range(instruction->opcode()); - for (auto it = begin; it != end; it++) { - const OpcodeHandler handler = it->second; - auto result = handler(instruction); - if (!result.has_value()) { - continue; - } - - capabilities->insert(*result); - } -} - -void TrimCapabilitiesPass::AddExtensionsForOperand( - const spv_operand_type_t type, const uint32_t value, - ExtensionSet* extensions) const { - const spv_operand_desc_t* desc = nullptr; - spv_result_t result = context()->grammar().lookupOperand(type, value, &desc); - if (result != SPV_SUCCESS) { - return; - } - addSupportedExtensionsToSet(desc, extensions); -} - -std::pair -TrimCapabilitiesPass::DetermineRequiredCapabilitiesAndExtensions() const { - CapabilitySet required_capabilities; - ExtensionSet required_extensions; - - get_module()->ForEachInst([&](Instruction* instruction) { - addInstructionRequirements(instruction, &required_capabilities, - &required_extensions); - }); - - for (auto capability : required_capabilities) { - AddExtensionsForOperand(SPV_OPERAND_TYPE_CAPABILITY, - static_cast(capability), - &required_extensions); - } - -#if !defined(NDEBUG) - // Debug only. We check the outputted required capabilities against the - // supported capabilities list. The supported capabilities list is useful for - // API users to quickly determine if they can use the pass or not. But this - // list has to remain up-to-date with the pass code. If we can detect a - // capability as required, but it's not listed, it means the list is - // out-of-sync. This method is not ideal, but should cover most cases. - { - for (auto capability : required_capabilities) { - assert(supportedCapabilities_.contains(capability) && - "Module is using a capability that is not listed as supported."); - } - } -#endif - - return std::make_pair(std::move(required_capabilities), - std::move(required_extensions)); -} - -Pass::Status TrimCapabilitiesPass::TrimUnrequiredCapabilities( - const CapabilitySet& required_capabilities) const { - const FeatureManager* feature_manager = context()->get_feature_mgr(); - CapabilitySet capabilities_to_trim; - for (auto capability : feature_manager->GetCapabilities()) { - // Some capabilities cannot be safely removed. Leaving them untouched. - if (untouchableCapabilities_.contains(capability)) { - continue; - } - - // If the capability is unsupported, don't trim it. - if (!supportedCapabilities_.contains(capability)) { - continue; - } - - if (required_capabilities.contains(capability)) { - continue; - } - - capabilities_to_trim.insert(capability); - } - - for (auto capability : capabilities_to_trim) { - context()->RemoveCapability(capability); - } - - return capabilities_to_trim.size() == 0 ? Pass::Status::SuccessWithoutChange - : Pass::Status::SuccessWithChange; -} - -Pass::Status TrimCapabilitiesPass::TrimUnrequiredExtensions( - const ExtensionSet& required_extensions) const { - const auto supported_extensions = - getExtensionsRelatedTo(supportedCapabilities_, context()->grammar()); - - bool modified_module = false; - for (auto extension : supported_extensions) { - if (required_extensions.contains(extension)) { - continue; - } - - if (context()->RemoveExtension(extension)) { - modified_module = true; - } - } - - return modified_module ? Pass::Status::SuccessWithChange - : Pass::Status::SuccessWithoutChange; -} - -bool TrimCapabilitiesPass::HasForbiddenCapabilities() const { - // EnumSet.HasAnyOf returns `true` if the given set is empty. - if (forbiddenCapabilities_.size() == 0) { - return false; - } - - const auto& capabilities = context()->get_feature_mgr()->GetCapabilities(); - return capabilities.HasAnyOf(forbiddenCapabilities_); -} - -Pass::Status TrimCapabilitiesPass::Process() { - if (HasForbiddenCapabilities()) { - return Status::SuccessWithoutChange; - } - - auto[required_capabilities, required_extensions] = - DetermineRequiredCapabilitiesAndExtensions(); - - Pass::Status capStatus = TrimUnrequiredCapabilities(required_capabilities); - Pass::Status extStatus = TrimUnrequiredExtensions(required_extensions); - - return capStatus == Pass::Status::SuccessWithChange || - extStatus == Pass::Status::SuccessWithChange - ? Pass::Status::SuccessWithChange - : Pass::Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/trim_capabilities_pass.h b/source/opt/trim_capabilities_pass.h deleted file mode 100755 index 73d5dc80..00000000 --- a/source/opt/trim_capabilities_pass.h +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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. - -#ifndef SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_ -#define SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_ - -#include -#include -#include -#include -#include -#include - -#include "source/enum_set.h" -#include "source/extensions.h" -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" -#include "source/spirv_target_env.h" - -namespace spvtools { -namespace opt { - -// This is required for NDK build. The unordered_set/unordered_map -// implementation don't work with class enums. -struct ClassEnumHash { - std::size_t operator()(spv::Capability value) const { - using StoringType = typename std::underlying_type_t; - return std::hash{}(static_cast(value)); - } - - std::size_t operator()(spv::Op value) const { - using StoringType = typename std::underlying_type_t; - return std::hash{}(static_cast(value)); - } -}; - -// An opcode handler is a function which, given an instruction, returns either -// the required capability, or nothing. -// Each handler checks one case for a capability requirement. -// -// Example: -// - `OpTypeImage` can have operand `A` operand which requires capability 1 -// - `OpTypeImage` can also have operand `B` which requires capability 2. -// -> We have 2 handlers: `Handler_OpTypeImage_1` and -// `Handler_OpTypeImage_2`. -using OpcodeHandler = - std::optional (*)(const Instruction* instruction); - -// This pass tried to remove superfluous capabilities declared in the module. -// - If all the capabilities listed by an extension are removed, the extension -// is also trimmed. -// - If the module countains any capability listed in `kForbiddenCapabilities`, -// the module is left untouched. -// - No capabilities listed in `kUntouchableCapabilities` are trimmed, even when -// not used. -// - Only capabilitied listed in `kSupportedCapabilities` are supported. -// - If the module contains unsupported capabilities, results might be -// incorrect. -class TrimCapabilitiesPass : public Pass { - private: - // All the capabilities supported by this optimization pass. If your module - // contains unsupported instruction, the pass could yield bad results. - static constexpr std::array kSupportedCapabilities{ - // clang-format off - spv::Capability::ComputeDerivativeGroupLinearNV, - spv::Capability::ComputeDerivativeGroupQuadsNV, - spv::Capability::Float64, - spv::Capability::FragmentShaderPixelInterlockEXT, - spv::Capability::FragmentShaderSampleInterlockEXT, - spv::Capability::FragmentShaderShadingRateInterlockEXT, - spv::Capability::Groups, - spv::Capability::ImageMSArray, - spv::Capability::Int64, - spv::Capability::Linkage, - spv::Capability::MinLod, - spv::Capability::PhysicalStorageBufferAddresses, - spv::Capability::RayQueryKHR, - spv::Capability::RayTracingKHR, - spv::Capability::RayTraversalPrimitiveCullingKHR, - spv::Capability::Shader, - spv::Capability::ShaderClockKHR, - spv::Capability::StorageImageReadWithoutFormat, - spv::Capability::StorageInputOutput16, - spv::Capability::StoragePushConstant16, - spv::Capability::StorageUniform16, - spv::Capability::StorageUniformBufferBlock16 - // clang-format on - }; - - // Those capabilities disable all transformation of the module. - static constexpr std::array kForbiddenCapabilities{ - spv::Capability::Linkage, - }; - - // Those capabilities are never removed from a module because we cannot - // guess from the SPIR-V only if they are required or not. - static constexpr std::array kUntouchableCapabilities{ - spv::Capability::Shader, - }; - - public: - TrimCapabilitiesPass(); - TrimCapabilitiesPass(const TrimCapabilitiesPass&) = delete; - TrimCapabilitiesPass(TrimCapabilitiesPass&&) = delete; - - private: - // Inserts every capability listed by `descriptor` this pass supports into - // `output`. Expects a Descriptor like `spv_opcode_desc_t` or - // `spv_operand_desc_t`. - template - inline void addSupportedCapabilitiesToSet(const Descriptor* const descriptor, - CapabilitySet* output) const { - const uint32_t capabilityCount = descriptor->numCapabilities; - for (uint32_t i = 0; i < capabilityCount; ++i) { - const auto capability = descriptor->capabilities[i]; - if (supportedCapabilities_.contains(capability)) { - output->insert(capability); - } - } - } - - // Inserts every extension listed by `descriptor` required by the module into - // `output`. Expects a Descriptor like `spv_opcode_desc_t` or - // `spv_operand_desc_t`. - template - inline void addSupportedExtensionsToSet(const Descriptor* const descriptor, - ExtensionSet* output) const { - if (descriptor->minVersion <= - spvVersionForTargetEnv(context()->GetTargetEnv())) { - return; - } - output->insert(descriptor->extensions, - descriptor->extensions + descriptor->numExtensions); - } - - void addInstructionRequirementsForOpcode(spv::Op opcode, - CapabilitySet* capabilities, - ExtensionSet* extensions) const; - void addInstructionRequirementsForOperand(const Operand& operand, - CapabilitySet* capabilities, - ExtensionSet* extensions) const; - - // Given an `instruction`, determines the capabilities it requires, and output - // them in `capabilities`. The returned capabilities form a subset of - // kSupportedCapabilities. - void addInstructionRequirements(Instruction* instruction, - CapabilitySet* capabilities, - ExtensionSet* extensions) const; - - // Given an operand `type` and `value`, adds the extensions it would require - // to `extensions`. - void AddExtensionsForOperand(const spv_operand_type_t type, - const uint32_t value, - ExtensionSet* extensions) const; - - // Returns the list of required capabilities and extensions for the module. - // The returned capabilities form a subset of kSupportedCapabilities. - std::pair - DetermineRequiredCapabilitiesAndExtensions() const; - - // Trims capabilities not listed in `required_capabilities` if possible. - // Returns whether or not the module was modified. - Pass::Status TrimUnrequiredCapabilities( - const CapabilitySet& required_capabilities) const; - - // Trims extensions not listed in `required_extensions` if supported by this - // pass. An extensions is considered supported as soon as one capability this - // pass support requires it. - Pass::Status TrimUnrequiredExtensions( - const ExtensionSet& required_extensions) const; - - // Returns if the analyzed module contains any forbidden capability. - bool HasForbiddenCapabilities() const; - - public: - const char* name() const override { return "trim-capabilities"; } - Status Process() override; - - private: - const CapabilitySet supportedCapabilities_; - const CapabilitySet forbiddenCapabilities_; - const CapabilitySet untouchableCapabilities_; - const std::unordered_multimap - opcodeHandlers_; -}; - -} // namespace opt -} // namespace spvtools -#endif // SOURCE_OPT_TRIM_CAPABILITIES_H_ diff --git a/source/opt/type_manager.cpp b/source/opt/type_manager.cpp index ae320772..a0006f55 100644 --- a/source/opt/type_manager.cpp +++ b/source/opt/type_manager.cpp @@ -29,8 +29,10 @@ namespace spvtools { namespace opt { namespace analysis { namespace { -constexpr int kSpvTypePointerStorageClass = 1; -constexpr int kSpvTypePointerTypeIdInIdx = 2; + +const int kSpvTypePointerStorageClass = 1; +const int kSpvTypePointerTypeIdInIdx = 2; + } // namespace TypeManager::TypeManager(const MessageConsumer& consumer, IRContext* c) @@ -47,7 +49,7 @@ Type* TypeManager::GetType(uint32_t id) const { } std::pair> TypeManager::GetTypeAndPointerType( - uint32_t id, spv::StorageClass sc) const { + uint32_t id, SpvStorageClass sc) const { Type* type = GetType(id); if (type) { return std::make_pair(type, MakeUnique(type, sc)); @@ -178,7 +180,7 @@ void TypeManager::RemoveId(uint32_t id) { if (iter == id_to_type_.end()) return; auto& type = iter->second; - if (!type->IsUniqueType()) { + if (!type->IsUniqueType(true)) { auto tIter = type_to_id_.find(type); if (tIter != type_to_id_.end() && tIter->second == id) { // |type| currently maps to |id|. @@ -218,10 +220,10 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { RegisterType(id, *type); switch (type->kind()) { -#define DefineParameterlessCase(kind) \ - case Type::k##kind: \ - typeInst = MakeUnique(context(), spv::Op::OpType##kind, 0, \ - id, std::initializer_list{}); \ +#define DefineParameterlessCase(kind) \ + case Type::k##kind: \ + typeInst = MakeUnique(context(), SpvOpType##kind, 0, id, \ + std::initializer_list{}); \ break DefineParameterlessCase(Void); DefineParameterlessCase(Bool); @@ -234,11 +236,10 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { DefineParameterlessCase(NamedBarrier); DefineParameterlessCase(AccelerationStructureNV); DefineParameterlessCase(RayQueryKHR); - DefineParameterlessCase(HitObjectNV); #undef DefineParameterlessCase case Type::kInteger: typeInst = MakeUnique( - context(), spv::Op::OpTypeInt, 0, id, + context(), SpvOpTypeInt, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsInteger()->width()}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -246,7 +247,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { break; case Type::kFloat: typeInst = MakeUnique( - context(), spv::Op::OpTypeFloat, 0, id, + context(), SpvOpTypeFloat, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsFloat()->width()}}}); break; @@ -256,7 +257,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = - MakeUnique(context(), spv::Op::OpTypeVector, 0, id, + MakeUnique(context(), SpvOpTypeVector, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -269,7 +270,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = - MakeUnique(context(), spv::Op::OpTypeMatrix, 0, id, + MakeUnique(context(), SpvOpTypeMatrix, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, @@ -283,7 +284,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypeImage, 0, id, + context(), SpvOpTypeImage, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_DIMENSIONALITY, @@ -307,7 +308,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypeSampledImage, 0, id, + context(), SpvOpTypeSampledImage, 0, id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); break; } @@ -317,7 +318,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypeArray, 0, id, + context(), SpvOpTypeArray, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {subtype}}, {SPV_OPERAND_TYPE_ID, {type->AsArray()->LengthId()}}}); @@ -330,7 +331,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypeRuntimeArray, 0, id, + context(), SpvOpTypeRuntimeArray, 0, id, std::initializer_list{{SPV_OPERAND_TYPE_ID, {subtype}}}); break; } @@ -345,7 +346,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {member_type_id})); } typeInst = - MakeUnique(context(), spv::Op::OpTypeStruct, 0, id, ops); + MakeUnique(context(), SpvOpTypeStruct, 0, id, ops); break; } case Type::kOpaque: { @@ -353,7 +354,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { // Convert to null-terminated packed UTF-8 string. std::vector words = spvtools::utils::MakeVector(opaque->name()); typeInst = MakeUnique( - context(), spv::Op::OpTypeOpaque, 0, id, + context(), SpvOpTypeOpaque, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_STRING, words}}); break; @@ -365,7 +366,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypePointer, 0, id, + context(), SpvOpTypePointer, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(pointer->storage_class())}}, @@ -387,20 +388,20 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { } ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {paramater_type_id})); } - typeInst = MakeUnique(context(), spv::Op::OpTypeFunction, 0, - id, ops); + typeInst = + MakeUnique(context(), SpvOpTypeFunction, 0, id, ops); break; } case Type::kPipe: typeInst = MakeUnique( - context(), spv::Op::OpTypePipe, 0, id, + context(), SpvOpTypePipe, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ACCESS_QUALIFIER, {static_cast(type->AsPipe()->access_qualifier())}}}); break; case Type::kForwardPointer: typeInst = MakeUnique( - context(), spv::Op::OpTypeForwardPointer, 0, 0, + context(), SpvOpTypeForwardPointer, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {type->AsForwardPointer()->target_id()}}, {SPV_OPERAND_TYPE_STORAGE_CLASS, @@ -415,7 +416,7 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { return 0; } typeInst = MakeUnique( - context(), spv::Op::OpTypeCooperativeMatrixNV, 0, id, + context(), SpvOpTypeCooperativeMatrixNV, 0, id, std::initializer_list{ {SPV_OPERAND_TYPE_ID, {component_type}}, {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}}, @@ -423,23 +424,6 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { {SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}}}); break; } - case Type::kCooperativeMatrixKHR: { - auto coop_mat = type->AsCooperativeMatrixKHR(); - uint32_t const component_type = - GetTypeInstruction(coop_mat->component_type()); - if (component_type == 0) { - return 0; - } - typeInst = MakeUnique( - context(), spv::Op::OpTypeCooperativeMatrixKHR, 0, id, - std::initializer_list{ - {SPV_OPERAND_TYPE_ID, {component_type}}, - {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}}, - {SPV_OPERAND_TYPE_ID, {coop_mat->rows_id()}}, - {SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}}, - {SPV_OPERAND_TYPE_ID, {coop_mat->use_id()}}}); - break; - } default: assert(false && "Unexpected type"); break; @@ -451,10 +435,10 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) { } uint32_t TypeManager::FindPointerToType(uint32_t type_id, - spv::StorageClass storage_class) { + SpvStorageClass storage_class) { Type* pointeeTy = GetType(type_id); Pointer pointerTy(pointeeTy, storage_class); - if (pointeeTy->IsUniqueType()) { + if (pointeeTy->IsUniqueType(true)) { // Non-ambiguous type. Get the pointer type through the type manager. return GetTypeInstruction(&pointerTy); } @@ -463,11 +447,11 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, Module::inst_iterator type_itr = context()->module()->types_values_begin(); for (; type_itr != context()->module()->types_values_end(); ++type_itr) { const Instruction* type_inst = &*type_itr; - if (type_inst->opcode() == spv::Op::OpTypePointer && + if (type_inst->opcode() == SpvOpTypePointer && type_inst->GetSingleWordOperand(kSpvTypePointerTypeIdInIdx) == type_id && - spv::StorageClass(type_inst->GetSingleWordOperand( - kSpvTypePointerStorageClass)) == storage_class) + type_inst->GetSingleWordOperand(kSpvTypePointerStorageClass) == + storage_class) return type_inst->result_id(); } @@ -475,7 +459,7 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, // TODO(1841): Handle id overflow. uint32_t resultId = context()->TakeNextId(); std::unique_ptr type_inst( - new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, + new Instruction(context(), SpvOpTypePointer, 0, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, {uint32_t(storage_class)}}, {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {type_id}}})); @@ -492,7 +476,7 @@ void TypeManager::AttachDecorations(uint32_t id, const Type* type) { for (auto pair : structTy->element_decorations()) { uint32_t element = pair.first; for (auto vec : pair.second) { - CreateDecoration(id, vec, /* is_member */ true, element); + CreateDecoration(id, vec, element); } } } @@ -500,10 +484,10 @@ void TypeManager::AttachDecorations(uint32_t id, const Type* type) { void TypeManager::CreateDecoration(uint32_t target, const std::vector& decoration, - bool is_member, uint32_t element) { + uint32_t element) { std::vector ops; ops.push_back(Operand(SPV_OPERAND_TYPE_ID, {target})); - if (is_member) { + if (element != 0) { ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {element})); } ops.push_back(Operand(SPV_OPERAND_TYPE_DECORATION, {decoration[0]})); @@ -511,8 +495,8 @@ void TypeManager::CreateDecoration(uint32_t target, ops.push_back(Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration[i]})); } context()->AddAnnotationInst(MakeUnique( - context(), (is_member ? spv::Op::OpMemberDecorate : spv::Op::OpDecorate), - 0, 0, ops)); + context(), (element == 0 ? SpvOpDecorate : SpvOpMemberDecorate), 0, 0, + ops)); Instruction* inst = &*--context()->annotation_end(); context()->get_def_use_mgr()->AnalyzeInstUse(inst); } @@ -545,7 +529,6 @@ Type* TypeManager::RebuildType(const Type& type) { DefineNoSubtypeCase(NamedBarrier); DefineNoSubtypeCase(AccelerationStructureNV); DefineNoSubtypeCase(RayQueryKHR); - DefineNoSubtypeCase(HitObjectNV); #undef DefineNoSubtypeCase case Type::kVector: { const Vector* vec_ty = type.AsVector(); @@ -645,14 +628,6 @@ Type* TypeManager::RebuildType(const Type& type) { cm_type->columns_id()); break; } - case Type::kCooperativeMatrixKHR: { - const CooperativeMatrixKHR* cm_type = type.AsCooperativeMatrixKHR(); - const Type* component_type = cm_type->component_type(); - rebuilt_ty = MakeUnique( - RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(), - cm_type->columns_id(), cm_type->use_id()); - break; - } default: assert(false && "Unhandled type"); return nullptr; @@ -690,47 +665,46 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { Type* type = nullptr; switch (inst.opcode()) { - case spv::Op::OpTypeVoid: + case SpvOpTypeVoid: type = new Void(); break; - case spv::Op::OpTypeBool: + case SpvOpTypeBool: type = new Bool(); break; - case spv::Op::OpTypeInt: + case SpvOpTypeInt: type = new Integer(inst.GetSingleWordInOperand(0), inst.GetSingleWordInOperand(1)); break; - case spv::Op::OpTypeFloat: + case SpvOpTypeFloat: type = new Float(inst.GetSingleWordInOperand(0)); break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: type = new Vector(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1)); break; - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: type = new Matrix(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1)); break; - case spv::Op::OpTypeImage: { - const spv::AccessQualifier access = - inst.NumInOperands() < 8 ? spv::AccessQualifier::ReadOnly - : static_cast( - inst.GetSingleWordInOperand(7)); + case SpvOpTypeImage: { + const SpvAccessQualifier access = + inst.NumInOperands() < 8 + ? SpvAccessQualifierReadOnly + : static_cast(inst.GetSingleWordInOperand(7)); type = new Image( GetType(inst.GetSingleWordInOperand(0)), - static_cast(inst.GetSingleWordInOperand(1)), + static_cast(inst.GetSingleWordInOperand(1)), inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3) == 1, inst.GetSingleWordInOperand(4) == 1, inst.GetSingleWordInOperand(5), - static_cast(inst.GetSingleWordInOperand(6)), - access); + static_cast(inst.GetSingleWordInOperand(6)), access); } break; - case spv::Op::OpTypeSampler: + case SpvOpTypeSampler: type = new Sampler(); break; - case spv::Op::OpTypeSampledImage: + case SpvOpTypeSampledImage: type = new SampledImage(GetType(inst.GetSingleWordInOperand(0))); break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { const uint32_t length_id = inst.GetSingleWordInOperand(1); const Instruction* length_constant_inst = id_to_constant_inst_[length_id]; assert(length_constant_inst); @@ -743,11 +717,11 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { // Only OpSpecConstant has a SpecId. uint32_t spec_id = 0u; bool has_spec_id = false; - if (length_constant_inst->opcode() == spv::Op::OpSpecConstant) { + if (length_constant_inst->opcode() == SpvOpSpecConstant) { context()->get_decoration_mgr()->ForEachDecoration( - length_id, uint32_t(spv::Decoration::SpecId), + length_id, SpvDecorationSpecId, [&spec_id, &has_spec_id](const Instruction& decoration) { - assert(decoration.opcode() == spv::Op::OpDecorate); + assert(decoration.opcode() == SpvOpDecorate); spec_id = decoration.GetSingleWordOperand(2u); has_spec_id = true; }); @@ -756,8 +730,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { if (has_spec_id) { extra_words.push_back(spec_id); } - if ((opcode == spv::Op::OpConstant) || - (opcode == spv::Op::OpSpecConstant)) { + if ((opcode == SpvOpConstant) || (opcode == SpvOpSpecConstant)) { // Always include the literal constant words. In the spec constant // case, the constant might not be overridden, so it's still // significant. @@ -781,7 +754,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: type = new RuntimeArray(GetType(inst.GetSingleWordInOperand(0))); if (id_to_incomplete_type_.count(inst.GetSingleWordInOperand(0))) { incomplete_types_.emplace_back(inst.result_id(), type); @@ -789,7 +762,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { std::vector element_types; bool incomplete_type = false; for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { @@ -807,14 +780,14 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case spv::Op::OpTypeOpaque: { + case SpvOpTypeOpaque: { type = new Opaque(inst.GetInOperand(0).AsString()); } break; - case spv::Op::OpTypePointer: { + case SpvOpTypePointer: { uint32_t pointee_type_id = inst.GetSingleWordInOperand(1); type = new Pointer( GetType(pointee_type_id), - static_cast(inst.GetSingleWordInOperand(0))); + static_cast(inst.GetSingleWordInOperand(0))); if (id_to_incomplete_type_.count(pointee_type_id)) { incomplete_types_.emplace_back(inst.result_id(), type); @@ -824,7 +797,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { id_to_incomplete_type_.erase(inst.result_id()); } break; - case spv::Op::OpTypeFunction: { + case SpvOpTypeFunction: { bool incomplete_type = false; uint32_t return_type_id = inst.GetSingleWordInOperand(0); if (id_to_incomplete_type_.count(return_type_id)) { @@ -848,60 +821,51 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { return type; } } break; - case spv::Op::OpTypeEvent: + case SpvOpTypeEvent: type = new Event(); break; - case spv::Op::OpTypeDeviceEvent: + case SpvOpTypeDeviceEvent: type = new DeviceEvent(); break; - case spv::Op::OpTypeReserveId: + case SpvOpTypeReserveId: type = new ReserveId(); break; - case spv::Op::OpTypeQueue: + case SpvOpTypeQueue: type = new Queue(); break; - case spv::Op::OpTypePipe: + case SpvOpTypePipe: type = new Pipe( - static_cast(inst.GetSingleWordInOperand(0))); + static_cast(inst.GetSingleWordInOperand(0))); break; - case spv::Op::OpTypeForwardPointer: { + case SpvOpTypeForwardPointer: { // Handling of forward pointers is different from the other types. uint32_t target_id = inst.GetSingleWordInOperand(0); - type = new ForwardPointer(target_id, static_cast( + type = new ForwardPointer(target_id, static_cast( inst.GetSingleWordInOperand(1))); incomplete_types_.emplace_back(target_id, type); id_to_incomplete_type_[target_id] = type; return type; } - case spv::Op::OpTypePipeStorage: + case SpvOpTypePipeStorage: type = new PipeStorage(); break; - case spv::Op::OpTypeNamedBarrier: + case SpvOpTypeNamedBarrier: type = new NamedBarrier(); break; - case spv::Op::OpTypeAccelerationStructureNV: + case SpvOpTypeAccelerationStructureNV: type = new AccelerationStructureNV(); break; - case spv::Op::OpTypeCooperativeMatrixNV: + case SpvOpTypeCooperativeMatrixNV: type = new CooperativeMatrixNV(GetType(inst.GetSingleWordInOperand(0)), inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3)); break; - case spv::Op::OpTypeCooperativeMatrixKHR: - type = new CooperativeMatrixKHR( - GetType(inst.GetSingleWordInOperand(0)), - inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2), - inst.GetSingleWordInOperand(3), inst.GetSingleWordInOperand(4)); - break; - case spv::Op::OpTypeRayQueryKHR: + case SpvOpTypeRayQueryKHR: type = new RayQueryKHR(); break; - case spv::Op::OpTypeHitObjectNV: - type = new HitObjectNV(); - break; default: - assert(false && "Type not handled by the type manager."); + SPIRV_UNIMPLEMENTED(consumer_, "unhandled type"); break; } @@ -922,11 +886,11 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) { } void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { - const spv::Op opcode = inst.opcode(); + const SpvOp opcode = inst.opcode(); if (!IsAnnotationInst(opcode)) return; switch (opcode) { - case spv::Op::OpDecorate: { + case SpvOpDecorate: { const auto count = inst.NumOperands(); std::vector data; for (uint32_t i = 1; i < count; ++i) { @@ -934,7 +898,7 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { } type->AddDecoration(std::move(data)); } break; - case spv::Op::OpMemberDecorate: { + case SpvOpMemberDecorate: { const auto count = inst.NumOperands(); const uint32_t index = inst.GetSingleWordOperand(1); std::vector data; @@ -943,10 +907,12 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) { } if (Struct* st = type->AsStruct()) { st->AddMemberDecoration(index, std::move(data)); + } else { + SPIRV_UNIMPLEMENTED(consumer_, "OpMemberDecorate non-struct type"); } } break; default: - assert(false && "Unexpected opcode for a decoration instruction."); + SPIRV_UNREACHABLE(consumer_); break; } } diff --git a/source/opt/type_manager.h b/source/opt/type_manager.h index a70c371d..72e37f48 100644 --- a/source/opt/type_manager.h +++ b/source/opt/type_manager.h @@ -99,7 +99,7 @@ class TypeManager { // // |id| must be a registered type. std::pair> GetTypeAndPointerType( - uint32_t id, spv::StorageClass sc) const; + uint32_t id, SpvStorageClass sc) const; // Returns an id for a declaration representing |type|. Returns 0 if the type // does not exists, and could not be generated. @@ -112,7 +112,7 @@ class TypeManager { // Find pointer to type and storage in module, return its resultId. If it is // not found, a new type is created, and its id is returned. Returns 0 if the // type could not be created. - uint32_t FindPointerToType(uint32_t type_id, spv::StorageClass storage_class); + uint32_t FindPointerToType(uint32_t type_id, SpvStorageClass storage_class); // Registers |id| to |type|. // @@ -139,21 +139,17 @@ class TypeManager { const Type* GetMemberType(const Type* parent_type, const std::vector& access_chain); - // Attaches the decoration encoded in |inst| to |type|. Does nothing if the - // given instruction is not a decoration instruction. Assumes the target is - // |type| (e.g. should be called in loop of |type|'s decorations). - void AttachDecoration(const Instruction& inst, Type* type); - - Type* GetUIntType() { return GetIntType(32, false); } - - uint32_t GetUIntTypeId() { return GetTypeInstruction(GetUIntType()); } - - Type* GetIntType(int32_t bitWidth, bool isSigned) { - Integer int_type(bitWidth, isSigned); + Type* GetUIntType() { + Integer int_type(32, false); return GetRegisteredType(&int_type); } - Type* GetSIntType() { return GetIntType(32, true); } + uint32_t GetUIntTypeId() { return GetTypeInstruction(GetUIntType()); } + + Type* GetSIntType() { + Integer int_type(32, true); + return GetRegisteredType(&int_type); + } uint32_t GetSIntTypeId() { return GetTypeInstruction(GetSIntType()); } @@ -247,15 +243,19 @@ class TypeManager { // Create the annotation instruction. // - // If |is_member| is false, an OpDecorate of |decoration| on |id| is created, - // otherwise an OpMemberDecorate is created at |element|. The annotation is - // registered with the DefUseManager and the DecorationManager. + // If |element| is zero, an OpDecorate is created, other an OpMemberDecorate + // is created. The annotation is registered with the DefUseManager and the + // DecorationManager. void CreateDecoration(uint32_t id, const std::vector& decoration, - bool is_member = false, uint32_t element = 0); + uint32_t element = 0); // Creates and returns a type from the given SPIR-V |inst|. Returns nullptr if // the given instruction is not for defining a type. Type* RecordIfTypeDefinition(const Instruction& inst); + // Attaches the decoration encoded in |inst| to |type|. Does nothing if the + // given instruction is not a decoration instruction. Assumes the target is + // |type| (e.g. should be called in loop of |type|'s decorations). + void AttachDecoration(const Instruction& inst, Type* type); // Returns an equivalent pointer to |type| built in terms of pointers owned by // |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt diff --git a/source/opt/types.cpp b/source/opt/types.cpp index b18b8cb1..056acebb 100644 --- a/source/opt/types.cpp +++ b/source/opt/types.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include "source/util/hash_combine.h" #include "source/util/make_unique.h" +#include "spirv/unified1/spirv.h" namespace spvtools { namespace opt { @@ -63,7 +65,7 @@ bool CompareTwoVectors(const U32VecVec a, const U32VecVec b) { return true; } -} // namespace +} // anonymous namespace std::string Type::GetDecorationStr() const { std::ostringstream oss; @@ -84,9 +86,10 @@ bool Type::HasSameDecorations(const Type* that) const { return CompareTwoVectors(decorations_, that->decorations_); } -bool Type::IsUniqueType() const { +bool Type::IsUniqueType(bool allowVariablePointers) const { switch (kind_) { case kPointer: + return !allowVariablePointers; case kStruct: case kArray: case kRuntimeArray: @@ -128,9 +131,7 @@ std::unique_ptr Type::Clone() const { DeclareKindCase(NamedBarrier); DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); - DeclareKindCase(CooperativeMatrixKHR); DeclareKindCase(RayQueryKHR); - DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -176,9 +177,7 @@ bool Type::operator==(const Type& other) const { DeclareKindCase(NamedBarrier); DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); - DeclareKindCase(CooperativeMatrixKHR); DeclareKindCase(RayQueryKHR); - DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -232,9 +231,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const { DeclareKindCase(NamedBarrier); DeclareKindCase(AccelerationStructureNV); DeclareKindCase(CooperativeMatrixNV); - DeclareKindCase(CooperativeMatrixKHR); DeclareKindCase(RayQueryKHR); - DeclareKindCase(HitObjectNV); #undef DeclareKindCase default: assert(false && "Unhandled type"); @@ -360,9 +357,8 @@ size_t Matrix::ComputeExtraStateHash(size_t hash, SeenTypes* seen) const { return element_type_->ComputeHashValue(hash, seen); } -Image::Image(Type* type, spv::Dim dimen, uint32_t d, bool array, - bool multisample, uint32_t sampling, spv::ImageFormat f, - spv::AccessQualifier qualifier) +Image::Image(Type* type, SpvDim dimen, uint32_t d, bool array, bool multisample, + uint32_t sampling, SpvImageFormat f, SpvAccessQualifier qualifier) : Type(kImage), sampled_type_(type), dim_(dimen), @@ -387,9 +383,9 @@ bool Image::IsSameImpl(const Type* that, IsSameCache* seen) const { std::string Image::str() const { std::ostringstream oss; - oss << "image(" << sampled_type_->str() << ", " << uint32_t(dim_) << ", " - << depth_ << ", " << arrayed_ << ", " << ms_ << ", " << sampled_ << ", " - << uint32_t(format_) << ", " << uint32_t(access_qualifier_) << ")"; + oss << "image(" << sampled_type_->str() << ", " << dim_ << ", " << depth_ + << ", " << arrayed_ << ", " << ms_ << ", " << sampled_ << ", " << format_ + << ", " << access_qualifier_ << ")"; return oss.str(); } @@ -561,7 +557,7 @@ size_t Opaque::ComputeExtraStateHash(size_t hash, SeenTypes*) const { return hash_combine(hash, name_); } -Pointer::Pointer(const Type* type, spv::StorageClass sc) +Pointer::Pointer(const Type* type, SpvStorageClass sc) : Type(kPointer), pointee_type_(type), storage_class_(sc) {} bool Pointer::IsSameImpl(const Type* that, IsSameCache* seen) const { @@ -640,7 +636,7 @@ bool Pipe::IsSameImpl(const Type* that, IsSameCache*) const { std::string Pipe::str() const { std::ostringstream oss; - oss << "pipe(" << uint32_t(access_qualifier_) << ")"; + oss << "pipe(" << access_qualifier_ << ")"; return oss.str(); } @@ -711,45 +707,6 @@ bool CooperativeMatrixNV::IsSameImpl(const Type* that, columns_id_ == mt->columns_id_ && HasSameDecorations(that); } -CooperativeMatrixKHR::CooperativeMatrixKHR(const Type* type, - const uint32_t scope, - const uint32_t rows, - const uint32_t columns, - const uint32_t use) - : Type(kCooperativeMatrixKHR), - component_type_(type), - scope_id_(scope), - rows_id_(rows), - columns_id_(columns), - use_id_(use) { - assert(type != nullptr); - assert(scope != 0); - assert(rows != 0); - assert(columns != 0); -} - -std::string CooperativeMatrixKHR::str() const { - std::ostringstream oss; - oss << "<" << component_type_->str() << ", " << scope_id_ << ", " << rows_id_ - << ", " << columns_id_ << ", " << use_id_ << ">"; - return oss.str(); -} - -size_t CooperativeMatrixKHR::ComputeExtraStateHash(size_t hash, - SeenTypes* seen) const { - hash = hash_combine(hash, scope_id_, rows_id_, columns_id_, use_id_); - return component_type_->ComputeHashValue(hash, seen); -} - -bool CooperativeMatrixKHR::IsSameImpl(const Type* that, - IsSameCache* seen) const { - const CooperativeMatrixKHR* mt = that->AsCooperativeMatrixKHR(); - if (!mt) return false; - return component_type_->IsSameImpl(mt->component_type_, seen) && - scope_id_ == mt->scope_id_ && rows_id_ == mt->rows_id_ && - columns_id_ == mt->columns_id_ && HasSameDecorations(that); -} - } // namespace analysis } // namespace opt } // namespace spvtools diff --git a/source/opt/types.h b/source/opt/types.h index 16a948ce..a92669e9 100644 --- a/source/opt/types.h +++ b/source/opt/types.h @@ -60,9 +60,7 @@ class PipeStorage; class NamedBarrier; class AccelerationStructureNV; class CooperativeMatrixNV; -class CooperativeMatrixKHR; class RayQueryKHR; -class HitObjectNV; // Abstract class for a SPIR-V type. It has a bunch of As() methods, // which is used as a way to probe the actual . @@ -101,9 +99,7 @@ class Type { kNamedBarrier, kAccelerationStructureNV, kCooperativeMatrixNV, - kCooperativeMatrixKHR, kRayQueryKHR, - kHitObjectNV, kLast }; @@ -150,16 +146,12 @@ class Type { // Returns a clone of |this| minus any decorations. std::unique_ptr RemoveDecorations() const; - // Returns true if this cannot hash to the same value as another type in the - // module. For example, structs are not unique types because the module could - // have two types + // Returns true if this type must be unique. // - // %1 = OpTypeStruct %int - // %2 = OpTypeStruct %int - // - // The only way to distinguish these types is the result id. The type manager - // will hash them to the same value. - bool IsUniqueType() const; + // If variable pointers are allowed, then pointers are not required to be + // unique. + // TODO(alanbaker): Update this if variable pointers become a core feature. + bool IsUniqueType(bool allowVariablePointers = false) const; bool operator==(const Type& other) const; @@ -203,9 +195,7 @@ class Type { DeclareCastMethod(NamedBarrier) DeclareCastMethod(AccelerationStructureNV) DeclareCastMethod(CooperativeMatrixNV) - DeclareCastMethod(CooperativeMatrixKHR) DeclareCastMethod(RayQueryKHR) - DeclareCastMethod(HitObjectNV) #undef DeclareCastMethod protected: @@ -312,9 +302,9 @@ class Matrix : public Type { class Image : public Type { public: - Image(Type* type, spv::Dim dimen, uint32_t d, bool array, bool multisample, - uint32_t sampling, spv::ImageFormat f, - spv::AccessQualifier qualifier = spv::AccessQualifier::ReadOnly); + Image(Type* type, SpvDim dimen, uint32_t d, bool array, bool multisample, + uint32_t sampling, SpvImageFormat f, + SpvAccessQualifier qualifier = SpvAccessQualifierReadOnly); Image(const Image&) = default; std::string str() const override; @@ -323,13 +313,13 @@ class Image : public Type { const Image* AsImage() const override { return this; } const Type* sampled_type() const { return sampled_type_; } - spv::Dim dim() const { return dim_; } + SpvDim dim() const { return dim_; } uint32_t depth() const { return depth_; } bool is_arrayed() const { return arrayed_; } bool is_multisampled() const { return ms_; } uint32_t sampled() const { return sampled_; } - spv::ImageFormat format() const { return format_; } - spv::AccessQualifier access_qualifier() const { return access_qualifier_; } + SpvImageFormat format() const { return format_; } + SpvAccessQualifier access_qualifier() const { return access_qualifier_; } size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; @@ -337,13 +327,13 @@ class Image : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; Type* sampled_type_; - spv::Dim dim_; + SpvDim dim_; uint32_t depth_; bool arrayed_; bool ms_; uint32_t sampled_; - spv::ImageFormat format_; - spv::AccessQualifier access_qualifier_; + SpvImageFormat format_; + SpvAccessQualifier access_qualifier_; }; class SampledImage : public Type { @@ -501,12 +491,12 @@ class Opaque : public Type { class Pointer : public Type { public: - Pointer(const Type* pointee, spv::StorageClass sc); + Pointer(const Type* pointee, SpvStorageClass sc); Pointer(const Pointer&) = default; std::string str() const override; const Type* pointee_type() const { return pointee_type_; } - spv::StorageClass storage_class() const { return storage_class_; } + SpvStorageClass storage_class() const { return storage_class_; } Pointer* AsPointer() override { return this; } const Pointer* AsPointer() const override { return this; } @@ -519,7 +509,7 @@ class Pointer : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; const Type* pointee_type_; - spv::StorageClass storage_class_; + SpvStorageClass storage_class_; }; class Function : public Type { @@ -550,7 +540,7 @@ class Function : public Type { class Pipe : public Type { public: - Pipe(spv::AccessQualifier qualifier) + Pipe(SpvAccessQualifier qualifier) : Type(kPipe), access_qualifier_(qualifier) {} Pipe(const Pipe&) = default; @@ -559,19 +549,19 @@ class Pipe : public Type { Pipe* AsPipe() override { return this; } const Pipe* AsPipe() const override { return this; } - spv::AccessQualifier access_qualifier() const { return access_qualifier_; } + SpvAccessQualifier access_qualifier() const { return access_qualifier_; } size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; private: bool IsSameImpl(const Type* that, IsSameCache*) const override; - spv::AccessQualifier access_qualifier_; + SpvAccessQualifier access_qualifier_; }; class ForwardPointer : public Type { public: - ForwardPointer(uint32_t id, spv::StorageClass sc) + ForwardPointer(uint32_t id, SpvStorageClass sc) : Type(kForwardPointer), target_id_(id), storage_class_(sc), @@ -580,7 +570,7 @@ class ForwardPointer : public Type { uint32_t target_id() const { return target_id_; } void SetTargetPointer(const Pointer* pointer) { pointer_ = pointer; } - spv::StorageClass storage_class() const { return storage_class_; } + SpvStorageClass storage_class() const { return storage_class_; } const Pointer* target_pointer() const { return pointer_; } std::string str() const override; @@ -594,7 +584,7 @@ class ForwardPointer : public Type { bool IsSameImpl(const Type* that, IsSameCache*) const override; uint32_t target_id_; - spv::StorageClass storage_class_; + SpvStorageClass storage_class_; const Pointer* pointer_; }; @@ -627,38 +617,6 @@ class CooperativeMatrixNV : public Type { const uint32_t columns_id_; }; -class CooperativeMatrixKHR : public Type { - public: - CooperativeMatrixKHR(const Type* type, const uint32_t scope, - const uint32_t rows, const uint32_t columns, - const uint32_t use); - CooperativeMatrixKHR(const CooperativeMatrixKHR&) = default; - - std::string str() const override; - - CooperativeMatrixKHR* AsCooperativeMatrixKHR() override { return this; } - const CooperativeMatrixKHR* AsCooperativeMatrixKHR() const override { - return this; - } - - size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override; - - const Type* component_type() const { return component_type_; } - uint32_t scope_id() const { return scope_id_; } - uint32_t rows_id() const { return rows_id_; } - uint32_t columns_id() const { return columns_id_; } - uint32_t use_id() const { return use_id_; } - - private: - bool IsSameImpl(const Type* that, IsSameCache*) const override; - - const Type* component_type_; - const uint32_t scope_id_; - const uint32_t rows_id_; - const uint32_t columns_id_; - const uint32_t use_id_; -}; - #define DefineParameterlessType(type, name) \ class type : public Type { \ public: \ @@ -690,7 +648,6 @@ DefineParameterlessType(PipeStorage, pipe_storage); DefineParameterlessType(NamedBarrier, named_barrier); DefineParameterlessType(AccelerationStructureNV, accelerationStructureNV); DefineParameterlessType(RayQueryKHR, rayQueryKHR); -DefineParameterlessType(HitObjectNV, hitObjectNV); #undef DefineParameterlessType } // namespace analysis diff --git a/source/opt/unify_const_pass.cpp b/source/opt/unify_const_pass.cpp index 83dd438b..6bfa11a5 100644 --- a/source/opt/unify_const_pass.cpp +++ b/source/opt/unify_const_pass.cpp @@ -20,10 +20,12 @@ #include #include "source/opt/def_use_manager.h" +#include "source/opt/ir_context.h" #include "source/util/make_unique.h" namespace spvtools { namespace opt { + namespace { // The trie that stores a bunch of result ids and, for a given instruction, @@ -101,7 +103,7 @@ class ResultIdTrie { std::unique_ptr root_; // The root node of the trie. }; -} // namespace +} // anonymous namespace Pass::Status UnifyConstantPass::Process() { bool modified = false; @@ -137,12 +139,12 @@ Pass::Status UnifyConstantPass::Process() { // processing is up to a descendant. This makes comparing the key array // always valid for judging duplication. switch (inst->opcode()) { - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: - case spv::Op::OpConstant: - case spv::Op::OpConstantNull: - case spv::Op::OpConstantSampler: - case spv::Op::OpConstantComposite: + case SpvOp::SpvOpConstantTrue: + case SpvOp::SpvOpConstantFalse: + case SpvOp::SpvOpConstant: + case SpvOp::SpvOpConstantNull: + case SpvOp::SpvOpConstantSampler: + case SpvOp::SpvOpConstantComposite: // Only spec constants defined with OpSpecConstantOp and // OpSpecConstantComposite should be processed in this pass. Spec // constants defined with OpSpecConstant{|True|False} are decorated with @@ -152,8 +154,8 @@ Pass::Status UnifyConstantPass::Process() { // unique. When all the operands/components are the same between two // OpSpecConstant{Op|Composite} results, their result values must be the // same so are unifiable. - case spv::Op::OpSpecConstantOp: - case spv::Op::OpSpecConstantComposite: { + case SpvOp::SpvOpSpecConstantOp: + case SpvOp::SpvOpSpecConstantComposite: { uint32_t id = defined_constants.LookupEquivalentResultFor(*inst); if (id != inst->result_id()) { // The constant is a duplicated one, use the cached constant to diff --git a/source/opt/upgrade_memory_model.cpp b/source/opt/upgrade_memory_model.cpp index 1b439a6e..9d6a5bce 100644 --- a/source/opt/upgrade_memory_model.cpp +++ b/source/opt/upgrade_memory_model.cpp @@ -28,16 +28,14 @@ namespace opt { Pass::Status UpgradeMemoryModel::Process() { // TODO: This pass needs changes to support cooperative matrices. if (context()->get_feature_mgr()->HasCapability( - spv::Capability::CooperativeMatrixNV)) { + SpvCapabilityCooperativeMatrixNV)) { return Pass::Status::SuccessWithoutChange; } // Only update Logical GLSL450 to Logical VulkanKHR. Instruction* memory_model = get_module()->GetMemoryModel(); - if (memory_model->GetSingleWordInOperand(0u) != - uint32_t(spv::AddressingModel::Logical) || - memory_model->GetSingleWordInOperand(1u) != - uint32_t(spv::MemoryModel::GLSL450)) { + if (memory_model->GetSingleWordInOperand(0u) != SpvAddressingModelLogical || + memory_model->GetSingleWordInOperand(1u) != SpvMemoryModelGLSL450) { return Pass::Status::SuccessWithoutChange; } @@ -57,17 +55,16 @@ void UpgradeMemoryModel::UpgradeMemoryModelInstruction() { // 3. Modify the memory model. Instruction* memory_model = get_module()->GetMemoryModel(); context()->AddCapability(MakeUnique( - context(), spv::Op::OpCapability, 0, 0, + context(), SpvOpCapability, 0, 0, std::initializer_list{ - {SPV_OPERAND_TYPE_CAPABILITY, - {uint32_t(spv::Capability::VulkanMemoryModelKHR)}}})); + {SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityVulkanMemoryModelKHR}}})); const std::string extension = "SPV_KHR_vulkan_memory_model"; std::vector words = spvtools::utils::MakeVector(extension); context()->AddExtension( - MakeUnique(context(), spv::Op::OpExtension, 0, 0, + MakeUnique(context(), SpvOpExtension, 0, 0, std::initializer_list{ {SPV_OPERAND_TYPE_LITERAL_STRING, words}})); - memory_model->SetInOperand(1u, {uint32_t(spv::MemoryModel::VulkanKHR)}); + memory_model->SetInOperand(1u, {SpvMemoryModelVulkanKHR}); } void UpgradeMemoryModel::UpgradeInstructions() { @@ -82,7 +79,7 @@ void UpgradeMemoryModel::UpgradeInstructions() { // In SPIR-V 1.4 or later, normalize OpCopyMemory* access operands. for (auto& func : *get_module()) { func.ForEachInst([this](Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { auto ext_inst = inst->GetSingleWordInOperand(1u); if (ext_inst == GLSLstd450Modf || ext_inst == GLSLstd450Frexp) { auto import = @@ -92,10 +89,9 @@ void UpgradeMemoryModel::UpgradeInstructions() { } } } else if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { - if (inst->opcode() == spv::Op::OpCopyMemory || - inst->opcode() == spv::Op::OpCopyMemorySized) { - uint32_t start_operand = - inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + if (inst->opcode() == SpvOpCopyMemory || + inst->opcode() == SpvOpCopyMemorySized) { + uint32_t start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; if (inst->NumInOperands() > start_operand) { auto num_access_words = MemoryAccessNumWords( inst->GetSingleWordInOperand(start_operand)); @@ -109,10 +105,10 @@ void UpgradeMemoryModel::UpgradeInstructions() { } } else { // Add two memory access operands. - inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, - {uint32_t(spv::MemoryAccessMask::MaskNone)}}); - inst->AddOperand({SPV_OPERAND_TYPE_MEMORY_ACCESS, - {uint32_t(spv::MemoryAccessMask::MaskNone)}}); + inst->AddOperand( + {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessMaskNone}}); + inst->AddOperand( + {SPV_OPERAND_TYPE_MEMORY_ACCESS, {SpvMemoryAccessMaskNone}}); } } } @@ -133,23 +129,23 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { bool dst_coherent = false; bool dst_volatile = false; uint32_t start_operand = 0u; - spv::Scope scope = spv::Scope::QueueFamilyKHR; - spv::Scope src_scope = spv::Scope::QueueFamilyKHR; - spv::Scope dst_scope = spv::Scope::QueueFamilyKHR; + SpvScope scope = SpvScopeQueueFamilyKHR; + SpvScope src_scope = SpvScopeQueueFamilyKHR; + SpvScope dst_scope = SpvScopeQueueFamilyKHR; switch (inst->opcode()) { - case spv::Op::OpLoad: - case spv::Op::OpStore: + case SpvOpLoad: + case SpvOpStore: std::tie(is_coherent, is_volatile, scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); break; - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseRead: - case spv::Op::OpImageWrite: + case SpvOpImageRead: + case SpvOpImageSparseRead: + case SpvOpImageWrite: std::tie(is_coherent, is_volatile, scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: std::tie(dst_coherent, dst_volatile, dst_scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0u)); std::tie(src_coherent, src_volatile, src_scope) = @@ -160,17 +156,17 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { } switch (inst->opcode()) { - case spv::Op::OpLoad: + case SpvOpLoad: UpgradeFlags(inst, 1u, is_coherent, is_volatile, kVisibility, kMemory); break; - case spv::Op::OpStore: + case SpvOpStore: UpgradeFlags(inst, 2u, is_coherent, is_volatile, kAvailability, kMemory); break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: - start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: + start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { // There are guaranteed to be two memory access operands at this // point so treat source and target separately. @@ -187,11 +183,11 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { kVisibility, kMemory); } break; - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseRead: + case SpvOpImageRead: + case SpvOpImageSparseRead: UpgradeFlags(inst, 2u, is_coherent, is_volatile, kVisibility, kImage); break; - case spv::Op::OpImageWrite: + case SpvOpImageWrite: UpgradeFlags(inst, 3u, is_coherent, is_volatile, kAvailability, kImage); break; @@ -209,7 +205,7 @@ void UpgradeMemoryModel::UpgradeMemoryAndImages() { // There are two memory access operands. The first is for the target and // the second is for the source. if (dst_coherent || src_coherent) { - start_operand = inst->opcode() == spv::Op::OpCopyMemory ? 2u : 3u; + start_operand = inst->opcode() == SpvOpCopyMemory ? 2u : 3u; std::vector new_operands; uint32_t num_access_words = MemoryAccessNumWords(inst->GetSingleWordInOperand(start_operand)); @@ -259,13 +255,13 @@ void UpgradeMemoryModel::UpgradeAtomics() { if (spvOpcodeIsAtomicOp(inst->opcode())) { bool unused_coherent = false; bool is_volatile = false; - spv::Scope unused_scope = spv::Scope::QueueFamilyKHR; + SpvScope unused_scope = SpvScopeQueueFamilyKHR; std::tie(unused_coherent, is_volatile, unused_scope) = GetInstructionAttributes(inst->GetSingleWordInOperand(0)); UpgradeSemantics(inst, 2u, is_volatile); - if (inst->opcode() == spv::Op::OpAtomicCompareExchange || - inst->opcode() == spv::Op::OpAtomicCompareExchangeWeak) { + if (inst->opcode() == SpvOpAtomicCompareExchange || + inst->opcode() == SpvOpAtomicCompareExchangeWeak) { UpgradeSemantics(inst, 3u, is_volatile); } } @@ -290,14 +286,14 @@ void UpgradeMemoryModel::UpgradeSemantics(Instruction* inst, value = constant->GetU32(); } - value |= uint32_t(spv::MemorySemanticsMask::Volatile); + value |= SpvMemorySemanticsVolatileMask; auto new_constant = context()->get_constant_mgr()->GetConstant(type, {value}); auto new_semantics = context()->get_constant_mgr()->GetDefiningInstruction(new_constant); inst->SetInOperand(in_operand, {new_semantics->result_id()}); } -std::tuple UpgradeMemoryModel::GetInstructionAttributes( +std::tuple UpgradeMemoryModel::GetInstructionAttributes( uint32_t id) { // |id| is a pointer used in a memory/image instruction. Need to determine if // that pointer points to volatile or coherent memory. Workgroup storage @@ -306,8 +302,8 @@ std::tuple UpgradeMemoryModel::GetInstructionAttributes( Instruction* inst = context()->get_def_use_mgr()->GetDef(id); analysis::Type* type = context()->get_type_mgr()->GetType(inst->type_id()); if (type->AsPointer() && - type->AsPointer()->storage_class() == spv::StorageClass::Workgroup) { - return std::make_tuple(true, false, spv::Scope::Workgroup); + type->AsPointer()->storage_class() == SpvStorageClassWorkgroup) { + return std::make_tuple(true, false, SpvScopeWorkgroup); } bool is_coherent = false; @@ -317,7 +313,7 @@ std::tuple UpgradeMemoryModel::GetInstructionAttributes( TraceInstruction(context()->get_def_use_mgr()->GetDef(id), std::vector(), &visited); - return std::make_tuple(is_coherent, is_volatile, spv::Scope::QueueFamilyKHR); + return std::make_tuple(is_coherent, is_volatile, SpvScopeQueueFamilyKHR); } std::pair UpgradeMemoryModel::TraceInstruction( @@ -340,10 +336,10 @@ std::pair UpgradeMemoryModel::TraceInstruction( bool is_coherent = false; bool is_volatile = false; switch (inst->opcode()) { - case spv::Op::OpVariable: - case spv::Op::OpFunctionParameter: - is_coherent |= HasDecoration(inst, 0, spv::Decoration::Coherent); - is_volatile |= HasDecoration(inst, 0, spv::Decoration::Volatile); + case SpvOpVariable: + case SpvOpFunctionParameter: + is_coherent |= HasDecoration(inst, 0, SpvDecorationCoherent); + is_volatile |= HasDecoration(inst, 0, SpvDecorationVolatile); if (!is_coherent || !is_volatile) { bool type_coherent = false; bool type_volatile = false; @@ -353,14 +349,14 @@ std::pair UpgradeMemoryModel::TraceInstruction( is_volatile |= type_volatile; } break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: // Store indices in reverse order. for (uint32_t i = inst->NumInOperands() - 1; i > 0; --i) { indices.push_back(inst->GetSingleWordInOperand(i)); } break; - case spv::Op::OpPtrAccessChain: + case SpvOpPtrAccessChain: // Store indices in reverse order. Skip the |Element| operand. for (uint32_t i = inst->NumInOperands() - 1; i > 1; --i) { indices.push_back(inst->GetSingleWordInOperand(i)); @@ -379,8 +375,8 @@ std::pair UpgradeMemoryModel::TraceInstruction( // Variables and function parameters are sources. Continue searching until we // reach them. - if (inst->opcode() != spv::Op::OpVariable && - inst->opcode() != spv::Op::OpFunctionParameter) { + if (inst->opcode() != SpvOpVariable && + inst->opcode() != SpvOpFunctionParameter) { inst->ForEachInId([this, &is_coherent, &is_volatile, &indices, &visited](const uint32_t* id_ptr) { Instruction* op_inst = context()->get_def_use_mgr()->GetDef(*id_ptr); @@ -408,24 +404,24 @@ std::pair UpgradeMemoryModel::CheckType( bool is_coherent = false; bool is_volatile = false; Instruction* type_inst = context()->get_def_use_mgr()->GetDef(type_id); - assert(type_inst->opcode() == spv::Op::OpTypePointer); + assert(type_inst->opcode() == SpvOpTypePointer); Instruction* element_inst = context()->get_def_use_mgr()->GetDef( type_inst->GetSingleWordInOperand(1u)); for (int i = (int)indices.size() - 1; i >= 0; --i) { if (is_coherent && is_volatile) break; - if (element_inst->opcode() == spv::Op::OpTypePointer) { + if (element_inst->opcode() == SpvOpTypePointer) { element_inst = context()->get_def_use_mgr()->GetDef( element_inst->GetSingleWordInOperand(1u)); - } else if (element_inst->opcode() == spv::Op::OpTypeStruct) { + } else if (element_inst->opcode() == SpvOpTypeStruct) { uint32_t index = indices.at(i); Instruction* index_inst = context()->get_def_use_mgr()->GetDef(index); - assert(index_inst->opcode() == spv::Op::OpConstant); + assert(index_inst->opcode() == SpvOpConstant); uint64_t value = GetIndexValue(index_inst); is_coherent |= HasDecoration(element_inst, static_cast(value), - spv::Decoration::Coherent); + SpvDecorationCoherent); is_volatile |= HasDecoration(element_inst, static_cast(value), - spv::Decoration::Volatile); + SpvDecorationVolatile); element_inst = context()->get_def_use_mgr()->GetDef( element_inst->GetSingleWordInOperand(static_cast(value))); } else { @@ -461,13 +457,13 @@ std::pair UpgradeMemoryModel::CheckAllTypes( if (!visited.insert(def).second) continue; - if (def->opcode() == spv::Op::OpTypeStruct) { + if (def->opcode() == SpvOpTypeStruct) { // Any member decorated with coherent and/or volatile is enough to have // the related operation be flagged as coherent and/or volatile. is_coherent |= HasDecoration(def, std::numeric_limits::max(), - spv::Decoration::Coherent); + SpvDecorationCoherent); is_volatile |= HasDecoration(def, std::numeric_limits::max(), - spv::Decoration::Volatile); + SpvDecorationVolatile); if (is_coherent && is_volatile) return std::make_pair(is_coherent, is_volatile); @@ -479,7 +475,7 @@ std::pair UpgradeMemoryModel::CheckAllTypes( } else if (spvOpcodeIsComposite(def->opcode())) { stack.push_back(context()->get_def_use_mgr()->GetDef( def->GetSingleWordInOperand(0u))); - } else if (def->opcode() == spv::Op::OpTypePointer) { + } else if (def->opcode() == SpvOpTypePointer) { stack.push_back(context()->get_def_use_mgr()->GetDef( def->GetSingleWordInOperand(1u))); } @@ -508,15 +504,14 @@ uint64_t UpgradeMemoryModel::GetIndexValue(Instruction* index_inst) { } bool UpgradeMemoryModel::HasDecoration(const Instruction* inst, uint32_t value, - spv::Decoration decoration) { + SpvDecoration decoration) { // If the iteration was terminated early then an appropriate decoration was // found. return !context()->get_decoration_mgr()->WhileEachDecoration( - inst->result_id(), (uint32_t)decoration, [value](const Instruction& i) { - if (i.opcode() == spv::Op::OpDecorate || - i.opcode() == spv::Op::OpDecorateId) { + inst->result_id(), decoration, [value](const Instruction& i) { + if (i.opcode() == SpvOpDecorate || i.opcode() == SpvOpDecorateId) { return false; - } else if (i.opcode() == spv::Op::OpMemberDecorate) { + } else if (i.opcode() == SpvOpMemberDecorate) { if (value == i.GetSingleWordInOperand(1u) || value == std::numeric_limits::max()) return false; @@ -538,27 +533,27 @@ void UpgradeMemoryModel::UpgradeFlags(Instruction* inst, uint32_t in_operand, } if (is_coherent) { if (inst_type == kMemory) { - flags |= uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR); + flags |= SpvMemoryAccessNonPrivatePointerKHRMask; if (operation_type == kVisibility) { - flags |= uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); + flags |= SpvMemoryAccessMakePointerVisibleKHRMask; } else { - flags |= uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); + flags |= SpvMemoryAccessMakePointerAvailableKHRMask; } } else { - flags |= uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR); + flags |= SpvImageOperandsNonPrivateTexelKHRMask; if (operation_type == kVisibility) { - flags |= uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR); + flags |= SpvImageOperandsMakeTexelVisibleKHRMask; } else { - flags |= uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR); + flags |= SpvImageOperandsMakeTexelAvailableKHRMask; } } } if (is_volatile) { if (inst_type == kMemory) { - flags |= uint32_t(spv::MemoryAccessMask::Volatile); + flags |= SpvMemoryAccessVolatileMask; } else { - flags |= uint32_t(spv::ImageOperandsMask::VolatileTexelKHR); + flags |= SpvImageOperandsVolatileTexelKHRMask; } } @@ -571,7 +566,7 @@ void UpgradeMemoryModel::UpgradeFlags(Instruction* inst, uint32_t in_operand, } } -uint32_t UpgradeMemoryModel::GetScopeConstant(spv::Scope scope) { +uint32_t UpgradeMemoryModel::GetScopeConstant(SpvScope scope) { analysis::Integer int_ty(32, false); uint32_t int_id = context()->get_type_mgr()->GetTypeInstruction(&int_ty); const analysis::Constant* constant = @@ -592,19 +587,15 @@ void UpgradeMemoryModel::CleanupDecorations() { context()->get_decoration_mgr()->RemoveDecorationsFrom( inst->result_id(), [](const Instruction& dec) { switch (dec.opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - if (spv::Decoration(dec.GetSingleWordInOperand(1u)) == - spv::Decoration::Coherent || - spv::Decoration(dec.GetSingleWordInOperand(1u)) == - spv::Decoration::Volatile) + case SpvOpDecorate: + case SpvOpDecorateId: + if (dec.GetSingleWordInOperand(1u) == SpvDecorationCoherent || + dec.GetSingleWordInOperand(1u) == SpvDecorationVolatile) return true; break; - case spv::Op::OpMemberDecorate: - if (spv::Decoration(dec.GetSingleWordInOperand(2u)) == - spv::Decoration::Coherent || - spv::Decoration(dec.GetSingleWordInOperand(2u)) == - spv::Decoration::Volatile) + case SpvOpMemberDecorate: + if (dec.GetSingleWordInOperand(2u) == SpvDecorationCoherent || + dec.GetSingleWordInOperand(2u) == SpvDecorationVolatile) return true; break; default: @@ -625,7 +616,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { for (auto& block : *function) { block.ForEachInst([this, &barriers, &operates_on_output](Instruction* inst) { - if (inst->opcode() == spv::Op::OpControlBarrier) { + if (inst->opcode() == SpvOpControlBarrier) { barriers.push_back(inst); } else if (!operates_on_output) { // This instruction operates on output storage class if it is a @@ -634,7 +625,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { analysis::Type* type = context()->get_type_mgr()->GetType(inst->type_id()); if (type && type->AsPointer() && - type->AsPointer()->storage_class() == spv::StorageClass::Output) { + type->AsPointer()->storage_class() == SpvStorageClassOutput) { operates_on_output = true; return; } @@ -644,8 +635,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { analysis::Type* op_type = context()->get_type_mgr()->GetType(op_inst->type_id()); if (op_type && op_type->AsPointer() && - op_type->AsPointer()->storage_class() == - spv::StorageClass::Output) + op_type->AsPointer()->storage_class() == SpvStorageClassOutput) operates_on_output = true; }); } @@ -656,8 +646,7 @@ void UpgradeMemoryModel::UpgradeBarriers() { std::queue roots; for (auto& e : get_module()->entry_points()) - if (spv::ExecutionModel(e.GetSingleWordInOperand(0u)) == - spv::ExecutionModel::TessellationControl) { + if (e.GetSingleWordInOperand(0u) == SpvExecutionModelTessellationControl) { roots.push(e.GetSingleWordInOperand(1u)); if (context()->ProcessCallTreeFromRoots(CollectBarriers, &roots)) { for (auto barrier : barriers) { @@ -670,9 +659,8 @@ void UpgradeMemoryModel::UpgradeBarriers() { uint64_t semantics_value = GetIndexValue(semantics_inst); const analysis::Constant* constant = context()->get_constant_mgr()->GetConstant( - semantics_type, - {static_cast(semantics_value) | - uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR)}); + semantics_type, {static_cast(semantics_value) | + SpvMemorySemanticsOutputMemoryKHRMask}); barrier->SetInOperand(2u, {context() ->get_constant_mgr() ->GetDefiningInstruction(constant) @@ -692,15 +680,15 @@ void UpgradeMemoryModel::UpgradeMemoryScope() { // * Workgroup ops (e.g. async_copy) have at most workgroup scope. if (spvOpcodeIsAtomicOp(inst->opcode())) { if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { - inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + inst->SetInOperand(1, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); } - } else if (inst->opcode() == spv::Op::OpControlBarrier) { + } else if (inst->opcode() == SpvOpControlBarrier) { if (IsDeviceScope(inst->GetSingleWordInOperand(1))) { - inst->SetInOperand(1, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + inst->SetInOperand(1, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); } - } else if (inst->opcode() == spv::Op::OpMemoryBarrier) { + } else if (inst->opcode() == SpvOpMemoryBarrier) { if (IsDeviceScope(inst->GetSingleWordInOperand(0))) { - inst->SetInOperand(0, {GetScopeConstant(spv::Scope::QueueFamilyKHR)}); + inst->SetInOperand(0, {GetScopeConstant(SpvScopeQueueFamilyKHR)}); } } }); @@ -716,14 +704,14 @@ bool UpgradeMemoryModel::IsDeviceScope(uint32_t scope_id) { assert(type->width() == 32 || type->width() == 64); if (type->width() == 32) { if (type->IsSigned()) - return static_cast(constant->GetS32()) == spv::Scope::Device; + return static_cast(constant->GetS32()) == SpvScopeDevice; else - return static_cast(constant->GetU32()) == spv::Scope::Device; + return static_cast(constant->GetU32()) == SpvScopeDevice; } else { if (type->IsSigned()) - return static_cast(constant->GetS64()) == spv::Scope::Device; + return static_cast(constant->GetS64()) == SpvScopeDevice; else - return static_cast(constant->GetU64()) == spv::Scope::Device; + return static_cast(constant->GetU64()) == SpvScopeDevice; } assert(false); @@ -770,9 +758,9 @@ void UpgradeMemoryModel::UpgradeExtInst(Instruction* ext_inst) { uint32_t UpgradeMemoryModel::MemoryAccessNumWords(uint32_t mask) { uint32_t result = 1; - if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; + if (mask & SpvMemoryAccessAlignedMask) ++result; + if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) ++result; + if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) ++result; return result; } diff --git a/source/opt/upgrade_memory_model.h b/source/opt/upgrade_memory_model.h index 489436b6..f75304ed 100644 --- a/source/opt/upgrade_memory_model.h +++ b/source/opt/upgrade_memory_model.h @@ -71,7 +71,7 @@ class UpgradeMemoryModel : public Pass { void UpgradeAtomics(); // Returns whether |id| is coherent and/or volatile. - std::tuple GetInstructionAttributes(uint32_t id); + std::tuple GetInstructionAttributes(uint32_t id); // Traces |inst| to determine if it is coherent and/or volatile. // |indices| tracks the access chain indices seen so far. @@ -84,7 +84,7 @@ class UpgradeMemoryModel : public Pass { // match the index or |value| must be a maximum allowable value. The max // value allows any element to match. bool HasDecoration(const Instruction* inst, uint32_t value, - spv::Decoration decoration); + SpvDecoration decoration); // Returns whether |type_id| indexed via |indices| is coherent and/or // volatile. @@ -108,7 +108,7 @@ class UpgradeMemoryModel : public Pass { bool is_volatile); // Returns the result id for a constant for |scope|. - uint32_t GetScopeConstant(spv::Scope scope); + uint32_t GetScopeConstant(SpvScope scope); // Returns the value of |index_inst|. |index_inst| must be an OpConstant of // integer type.g @@ -127,7 +127,7 @@ class UpgradeMemoryModel : public Pass { // scope. void UpgradeMemoryScope(); - // Returns true if |scope_id| is spv::Scope::Device. + // Returns true if |scope_id| is SpvScopeDevice. bool IsDeviceScope(uint32_t scope_id); // Upgrades GLSL.std.450 modf and frexp. Both instructions are replaced with diff --git a/source/opt/value_number_table.cpp b/source/opt/value_number_table.cpp index 743dc52b..5271e3fe 100644 --- a/source/opt/value_number_table.cpp +++ b/source/opt/value_number_table.cpp @@ -57,9 +57,9 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { } switch (inst->opcode()) { - case spv::Op::OpSampledImage: - case spv::Op::OpImage: - case spv::Op::OpVariable: + case SpvOpSampledImage: + case SpvOpImage: + case SpvOpVariable: value = TakeNextValueNumber(); id_to_value_[inst->result_id()] = value; return value; @@ -82,7 +82,7 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { analysis::DecorationManager* dec_mgr = context()->get_decoration_mgr(); // When we copy an object, the value numbers should be the same. - if (inst->opcode() == spv::Op::OpCopyObject && + if (inst->opcode() == SpvOpCopyObject && dec_mgr->HaveTheSameDecorations(inst->result_id(), inst->GetSingleWordInOperand(0))) { value = GetValueNumber(inst->GetSingleWordInOperand(0)); @@ -94,7 +94,7 @@ uint32_t ValueNumberTable::AssignValueNumber(Instruction* inst) { // Phi nodes are a type of copy. If all of the inputs have the same value // number, then we can assign the result of the phi the same value number. - if (inst->opcode() == spv::Op::OpPhi && inst->NumInOperands() > 0 && + if (inst->opcode() == SpvOpPhi && inst->NumInOperands() > 0 && dec_mgr->HaveTheSameDecorations(inst->result_id(), inst->GetSingleWordInOperand(0))) { value = GetValueNumber(inst->GetSingleWordInOperand(0)); @@ -226,7 +226,7 @@ std::size_t ValueTableHash::operator()(const Instruction& inst) const { // instructions that are the same except for the result to hash to the // same value. std::u32string h; - h.push_back(uint32_t(inst.opcode())); + h.push_back(inst.opcode()); h.push_back(inst.type_id()); for (uint32_t i = 0; i < inst.NumInOperands(); ++i) { const auto& opnd = inst.GetInOperand(i); diff --git a/source/opt/vector_dce.cpp b/source/opt/vector_dce.cpp index 1e8d255d..28d94a07 100644 --- a/source/opt/vector_dce.cpp +++ b/source/opt/vector_dce.cpp @@ -19,9 +19,11 @@ namespace spvtools { namespace opt { namespace { -constexpr uint32_t kExtractCompositeIdInIdx = 0; -constexpr uint32_t kInsertObjectIdInIdx = 0; -constexpr uint32_t kInsertCompositeIdInIdx = 1; + +const uint32_t kExtractCompositeIdInIdx = 0; +const uint32_t kInsertObjectIdInIdx = 0; +const uint32_t kInsertCompositeIdInIdx = 1; + } // namespace Pass::Status VectorDCE::Process() { @@ -66,17 +68,17 @@ void VectorDCE::FindLiveComponents(Function* function, Instruction* current_inst = current_item.instruction; switch (current_inst->opcode()) { - case spv::Op::OpCompositeExtract: + case SpvOpCompositeExtract: MarkExtractUseAsLive(current_inst, current_item.components, live_components, &work_list); break; - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: MarkInsertUsesAsLive(current_item, live_components, &work_list); break; - case spv::Op::OpVectorShuffle: + case SpvOpVectorShuffle: MarkVectorShuffleUsesAsLive(current_item, live_components, &work_list); break; - case spv::Op::OpCompositeConstruct: + case SpvOpCompositeConstruct: MarkCompositeContructUsesAsLive(current_item, live_components, &work_list); break; @@ -345,11 +347,11 @@ bool VectorDCE::RewriteInstructions( } switch (current_inst->opcode()) { - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: modified |= RewriteInsertInstruction( current_inst, live_component->second, &dead_dbg_value); break; - case spv::Op::OpCompositeConstruct: + case SpvOpCompositeConstruct: // TODO: The members that are not live can be replaced by an undef // or constant. This will remove uses of those values, and possibly // create opportunities for ADCE. diff --git a/source/opt/workaround1209.cpp b/source/opt/workaround1209.cpp index 0cf954af..d6e9d2cf 100644 --- a/source/opt/workaround1209.cpp +++ b/source/opt/workaround1209.cpp @@ -43,13 +43,13 @@ bool Workaround1209::RemoveOpUnreachableInLoops() { loop_merges.pop(); } - if (bb->tail()->opcode() == spv::Op::OpUnreachable) { + if (bb->tail()->opcode() == SpvOpUnreachable) { if (!loop_merges.empty()) { // We found an OpUnreachable inside a loop. // Replace it with an unconditional branch to the loop merge. context()->KillInst(&*bb->tail()); std::unique_ptr new_branch( - new Instruction(context(), spv::Op::OpBranch, 0, 0, + new Instruction(context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {loop_merges.top()}}})); context()->AnalyzeDefUse(&*new_branch); diff --git a/source/opt/wrap_opkill.cpp b/source/opt/wrap_opkill.cpp index c0c6d622..51432a73 100644 --- a/source/opt/wrap_opkill.cpp +++ b/source/opt/wrap_opkill.cpp @@ -28,8 +28,7 @@ Pass::Status WrapOpKill::Process() { Function* func = context()->GetFunction(func_id); bool successful = func->WhileEachInst([this, &modified](Instruction* inst) { const auto opcode = inst->opcode(); - if ((opcode == spv::Op::OpKill) || - (opcode == spv::Op::OpTerminateInvocation)) { + if ((opcode == SpvOpKill) || (opcode == SpvOpTerminateInvocation)) { modified = true; if (!ReplaceWithFunctionCall(inst)) { return false; @@ -57,8 +56,8 @@ Pass::Status WrapOpKill::Process() { } bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { - assert((inst->opcode() == spv::Op::OpKill || - inst->opcode() == spv::Op::OpTerminateInvocation) && + assert((inst->opcode() == SpvOpKill || + inst->opcode() == SpvOpTerminateInvocation) && "|inst| must be an OpKill or OpTerminateInvocation instruction."); InstructionBuilder ir_builder( context(), inst, @@ -77,15 +76,14 @@ bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { Instruction* return_inst = nullptr; uint32_t return_type_id = GetOwningFunctionsReturnType(inst); if (return_type_id != GetVoidTypeId()) { - Instruction* undef = - ir_builder.AddNullaryOp(return_type_id, spv::Op::OpUndef); + Instruction* undef = ir_builder.AddNullaryOp(return_type_id, SpvOpUndef); if (undef == nullptr) { return false; } return_inst = - ir_builder.AddUnaryOp(0, spv::Op::OpReturnValue, undef->result_id()); + ir_builder.AddUnaryOp(0, SpvOpReturnValue, undef->result_id()); } else { - return_inst = ir_builder.AddNullaryOp(0, spv::Op::OpReturn); + return_inst = ir_builder.AddNullaryOp(0, SpvOpReturn); } if (return_inst == nullptr) { @@ -117,13 +115,13 @@ uint32_t WrapOpKill::GetVoidFunctionTypeId() { return type_mgr->GetTypeInstruction(&func_type); } -uint32_t WrapOpKill::GetKillingFuncId(spv::Op opcode) { +uint32_t WrapOpKill::GetKillingFuncId(SpvOp opcode) { // Parameterize by opcode - assert(opcode == spv::Op::OpKill || opcode == spv::Op::OpTerminateInvocation); + assert(opcode == SpvOpKill || opcode == SpvOpTerminateInvocation); std::unique_ptr* const killing_func = - (opcode == spv::Op::OpKill) ? &opkill_function_ - : &opterminateinvocation_function_; + (opcode == SpvOpKill) ? &opkill_function_ + : &opterminateinvocation_function_; if (*killing_func != nullptr) { return (*killing_func)->result_id(); @@ -141,14 +139,14 @@ uint32_t WrapOpKill::GetKillingFuncId(spv::Op opcode) { // Generate the function start instruction std::unique_ptr func_start(new Instruction( - context(), spv::Op::OpFunction, void_type_id, killing_func_id, {})); + context(), SpvOpFunction, void_type_id, killing_func_id, {})); func_start->AddOperand({SPV_OPERAND_TYPE_FUNCTION_CONTROL, {0}}); func_start->AddOperand({SPV_OPERAND_TYPE_ID, {GetVoidFunctionTypeId()}}); (*killing_func).reset(new Function(std::move(func_start))); // Generate the function end instruction std::unique_ptr func_end( - new Instruction(context(), spv::Op::OpFunctionEnd, 0, 0, {})); + new Instruction(context(), SpvOpFunctionEnd, 0, 0, {})); (*killing_func)->SetFunctionEnd(std::move(func_end)); // Create the one basic block for the function. @@ -157,7 +155,7 @@ uint32_t WrapOpKill::GetKillingFuncId(spv::Op opcode) { return 0; } std::unique_ptr label_inst( - new Instruction(context(), spv::Op::OpLabel, 0, lab_id, {})); + new Instruction(context(), SpvOpLabel, 0, lab_id, {})); std::unique_ptr bb(new BasicBlock(std::move(label_inst))); // Add the OpKill to the basic block diff --git a/source/opt/wrap_opkill.h b/source/opt/wrap_opkill.h index c9eb8887..7e43ca6c 100644 --- a/source/opt/wrap_opkill.h +++ b/source/opt/wrap_opkill.h @@ -53,7 +53,7 @@ class WrapOpKill : public Pass { // Return the id of a function that has return type void, has no parameters, // and contains a single instruction, which is |opcode|, either OpKill or // OpTerminateInvocation. Returns 0 if the function could not be generated. - uint32_t GetKillingFuncId(spv::Op opcode); + uint32_t GetKillingFuncId(SpvOp opcode); // Returns the id of the return type for the function that contains |inst|. // Returns 0 if |inst| is not in a function. diff --git a/source/parsed_operand.cpp b/source/parsed_operand.cpp index cc33f8ba..5f8e94db 100644 --- a/source/parsed_operand.cpp +++ b/source/parsed_operand.cpp @@ -24,7 +24,6 @@ namespace spvtools { void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst, const spv_parsed_operand_t& operand) { if (operand.type != SPV_OPERAND_TYPE_LITERAL_INTEGER && - operand.type != SPV_OPERAND_TYPE_LITERAL_FLOAT && operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER && operand.type != SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER && operand.type != SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER) diff --git a/source/print.cpp b/source/print.cpp index f36812ef..6c94e2b7 100644 --- a/source/print.cpp +++ b/source/print.cpp @@ -17,7 +17,7 @@ #if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \ defined(SPIRV_IOS) || defined(SPIRV_TVOS) || defined(SPIRV_FREEBSD) || \ defined(SPIRV_OPENBSD) || defined(SPIRV_EMSCRIPTEN) || \ - defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) || defined(SPIRV_QNX) + defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) namespace spvtools { clr::reset::operator const char*() { return "\x1b[0m"; } diff --git a/source/reduce/BUILD.gn b/source/reduce/BUILD.gn index c838868d..0b2ac9ac 100644 --- a/source/reduce/BUILD.gn +++ b/source/reduce/BUILD.gn @@ -26,115 +26,38 @@ config("deqp_spirvtool_reduce_config") { ] } -config("spv_headers_public_config") { - include_dirs = [ "include" ] -} - -config("spvtools_include_gen_dirs") { - include_dirs = [ "$target_gen_dir" ] -} - -config("spvtools_internal_config") { - include_dirs = [ - ".", - "//third_party/spirv-headers/include", - ] - - configs = [ - ":spv_headers_public_config", - ":spvtools_include_gen_dirs", - ] - - cflags = [] - if (is_clang) { - cflags += [ - "-Wno-implicit-fallthrough", - "-Wno-newline-eof", - "-Wno-unreachable-code-break", - "-Wno-unreachable-code-return", - ] - } else if (!is_win) { - # Work around a false-positive on a Skia GCC 10 builder. - cflags += [ "-Wno-format-truncation" ] - } else { - # Make MSVC report the correct value for __cplusplus - cflags += [ "/Zc:__cplusplus" ] - } - - if (!is_win) { - cflags += [ "-std=c++17" ] - } else { - cflags += [ "/std:c++17" ] - } -} - ohos_source_set("deqp_spirvtool_reduce_source") { sources = [ - "//third_party/spirv-tools/include/spirv-tools/instrument.hpp", - "//third_party/spirv-tools/include/spirv-tools/libspirv.h", - "//third_party/spirv-tools/include/spirv-tools/libspirv.hpp", - "//third_party/spirv-tools/include/spirv-tools/linker.hpp", - "//third_party/spirv-tools/include/spirv-tools/optimizer.hpp", "//third_party/spirv-tools/source/reduce/change_operand_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/change_operand_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/change_operand_to_undef_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/change_operand_to_undef_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/conditional_branch_to_simple_conditional_branch_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/merge_blocks_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/merge_blocks_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/merge_blocks_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/operand_to_const_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/operand_to_undef_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/reducer.cpp", - "//third_party/spirv-tools/source/reduce/reducer.h", "//third_party/spirv-tools/source/reduce/reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/reduction_pass.cpp", - "//third_party/spirv-tools/source/reduce/reduction_pass.h", "//third_party/spirv-tools/source/reduce/reduction_util.cpp", - "//third_party/spirv-tools/source/reduce/reduction_util.h", "//third_party/spirv-tools/source/reduce/remove_block_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/remove_block_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/remove_block_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/remove_block_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/remove_function_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/remove_function_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/remove_function_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/remove_function_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/remove_instruction_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/remove_selection_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/remove_selection_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/remove_selection_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/remove_struct_member_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/remove_unused_instruction_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/structured_construct_to_block_reduction_opportunity_finder.h", "//third_party/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp", - "//third_party/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity.h", "//third_party/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.cpp", - "//third_party/spirv-tools/source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h", ] include_dirs = deqp_common_include_dirs @@ -145,14 +68,7 @@ ohos_source_set("deqp_spirvtool_reduce_source") { "//third_party/spirv-tools/include", ] - if (build_with_chromium) { - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - } - configs = [ ":deqp_spirvtool_reduce_config" ] - configs += [ ":spv_headers_public_config" ] - configs += [ ":spvtools_internal_config" ] } ohos_static_library("libdeqp_spirvtools-reduce") { diff --git a/source/reduce/CMakeLists.txt b/source/reduce/CMakeLists.txt index 9ebe4183..6fd8409f 100644 --- a/source/reduce/CMakeLists.txt +++ b/source/reduce/CMakeLists.txt @@ -101,7 +101,10 @@ set_property(TARGET SPIRV-Tools-reduce PROPERTY FOLDER "SPIRV-Tools libraries") spvtools_check_symbol_exports(SPIRV-Tools-reduce) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS SPIRV-Tools-reduce EXPORT SPIRV-Tools-reduceTargets) + install(TARGETS SPIRV-Tools-reduce EXPORT SPIRV-Tools-reduceTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT SPIRV-Tools-reduceTargets FILE SPIRV-Tools-reduceTarget.cmake) spvtools_config_package_dir(SPIRV-Tools-reduce PACKAGE_DIR) diff --git a/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp b/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp index 93b51a11..2cd779a2 100644 --- a/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp +++ b/source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp @@ -36,9 +36,9 @@ ConditionalBranchToSimpleConditionalBranchOpportunityFinder:: for (auto* function : GetTargetFunctions(context, target_function)) { // Consider every block in the function. for (auto& block : *function) { - // The terminator must be spv::Op::OpBranchConditional. + // The terminator must be SpvOpBranchConditional. opt::Instruction* terminator = block.terminator(); - if (terminator->opcode() != spv::Op::OpBranchConditional) { + if (terminator->opcode() != SpvOpBranchConditional) { continue; } diff --git a/source/reduce/merge_blocks_reduction_opportunity.cpp b/source/reduce/merge_blocks_reduction_opportunity.cpp index e626d60b..a2c3b40a 100644 --- a/source/reduce/merge_blocks_reduction_opportunity.cpp +++ b/source/reduce/merge_blocks_reduction_opportunity.cpp @@ -23,7 +23,7 @@ namespace reduce { MergeBlocksReductionOpportunity::MergeBlocksReductionOpportunity( opt::IRContext* context, opt::Function* function, opt::BasicBlock* block) { // Precondition: the terminator has to be OpBranch. - assert(block->terminator()->opcode() == spv::Op::OpBranch); + assert(block->terminator()->opcode() == SpvOpBranch); context_ = context; function_ = function; // Get the successor block associated with the OpBranch. diff --git a/source/reduce/operand_to_const_reduction_opportunity_finder.cpp b/source/reduce/operand_to_const_reduction_opportunity_finder.cpp index c6196f36..eb7498ad 100644 --- a/source/reduce/operand_to_const_reduction_opportunity_finder.cpp +++ b/source/reduce/operand_to_const_reduction_opportunity_finder.cpp @@ -50,7 +50,7 @@ OperandToConstReductionOpportunityFinder::GetAvailableOpportunities( // The argument is already a constant. continue; } - if (def->opcode() == spv::Op::OpFunction) { + if (def->opcode() == SpvOpFunction) { // The argument refers to a function, e.g. the function called // by OpFunctionCall; avoid replacing this with a constant of // the function's return type. diff --git a/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp b/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp index c7bc1213..06bf9550 100644 --- a/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp +++ b/source/reduce/operand_to_undef_reduction_opportunity_finder.cpp @@ -32,7 +32,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( auto type_id = inst.type_id(); if (type_id) { auto type_id_def = context->get_def_use_mgr()->GetDef(type_id); - if (type_id_def->opcode() == spv::Op::OpTypePointer) { + if (type_id_def->opcode() == SpvOpTypePointer) { continue; } } @@ -57,7 +57,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( } // Don't replace function operands with undef. - if (operand_id_def->opcode() == spv::Op::OpFunction) { + if (operand_id_def->opcode() == SpvOpFunction) { continue; } @@ -68,7 +68,7 @@ OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities( context->get_def_use_mgr()->GetDef(operand_type_id); // Skip pointer operands. - if (operand_type_id_def->opcode() == spv::Op::OpTypePointer) { + if (operand_type_id_def->opcode() == SpvOpTypePointer) { continue; } diff --git a/source/reduce/reduction_util.cpp b/source/reduce/reduction_util.cpp index c9882d5e..511f4323 100644 --- a/source/reduce/reduction_util.cpp +++ b/source/reduce/reduction_util.cpp @@ -26,7 +26,7 @@ const uint32_t kFalseBranchOperandIndex = 2; uint32_t FindOrCreateGlobalVariable(opt::IRContext* context, uint32_t pointer_type_id) { for (auto& inst : context->module()->types_values()) { - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { continue; } if (inst.type_id() == pointer_type_id) { @@ -35,7 +35,7 @@ uint32_t FindOrCreateGlobalVariable(opt::IRContext* context, } const uint32_t variable_id = context->TakeNextId(); auto variable_inst = MakeUnique( - context, spv::Op::OpVariable, pointer_type_id, variable_id, + context, SpvOpVariable, pointer_type_id, variable_id, opt::Instruction::OperandList( {{SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(context->get_type_mgr() @@ -53,7 +53,7 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, assert(context->get_type_mgr() ->GetType(pointer_type_id) ->AsPointer() - ->storage_class() == spv::StorageClass::Function); + ->storage_class() == SpvStorageClassFunction); // Go through the instructions in the function's first block until we find a // suitable variable, or go past all the variables. @@ -62,7 +62,7 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, // We will either find a suitable variable, or find a non-variable // instruction; we won't exhaust all instructions. assert(iter != function->begin()->end()); - if (iter->opcode() != spv::Op::OpVariable) { + if (iter->opcode() != SpvOpVariable) { // If we see a non-variable, we have gone through all the variables. break; } @@ -74,17 +74,16 @@ uint32_t FindOrCreateFunctionVariable(opt::IRContext* context, // function's entry block. const uint32_t variable_id = context->TakeNextId(); auto variable_inst = MakeUnique( - context, spv::Op::OpVariable, pointer_type_id, variable_id, + context, SpvOpVariable, pointer_type_id, variable_id, opt::Instruction::OperandList( - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}})); + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); iter->InsertBefore(std::move(variable_inst)); return variable_id; } uint32_t FindOrCreateGlobalUndef(opt::IRContext* context, uint32_t type_id) { for (auto& inst : context->module()->types_values()) { - if (inst.opcode() != spv::Op::OpUndef) { + if (inst.opcode() != SpvOpUndef) { continue; } if (inst.type_id() == type_id) { @@ -92,9 +91,8 @@ uint32_t FindOrCreateGlobalUndef(opt::IRContext* context, uint32_t type_id) { } } const uint32_t undef_id = context->TakeNextId(); - auto undef_inst = - MakeUnique(context, spv::Op::OpUndef, type_id, undef_id, - opt::Instruction::OperandList()); + auto undef_inst = MakeUnique( + context, SpvOpUndef, type_id, undef_id, opt::Instruction::OperandList()); assert(undef_id == undef_inst->result_id()); context->module()->AddGlobalValue(std::move(undef_inst)); return undef_id; diff --git a/source/reduce/remove_selection_reduction_opportunity_finder.cpp b/source/reduce/remove_selection_reduction_opportunity_finder.cpp index 6abadf2a..74df1b8d 100644 --- a/source/reduce/remove_selection_reduction_opportunity_finder.cpp +++ b/source/reduce/remove_selection_reduction_opportunity_finder.cpp @@ -36,7 +36,7 @@ RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities( for (auto* function : GetTargetFunctions(context, target_function)) { for (auto& block : *function) { if (auto merge_instruction = block.GetMergeInst()) { - if (merge_instruction->opcode() == spv::Op::OpLoopMerge) { + if (merge_instruction->opcode() == SpvOpLoopMerge) { uint32_t merge_block_id = merge_instruction->GetSingleWordOperand(kMergeNodeIndex); uint32_t continue_block_id = @@ -54,7 +54,7 @@ RemoveSelectionReductionOpportunityFinder::GetAvailableOpportunities( for (auto& function : *context->module()) { for (auto& block : function) { if (auto merge_instruction = block.GetMergeInst()) { - if (merge_instruction->opcode() == spv::Op::OpSelectionMerge) { + if (merge_instruction->opcode() == SpvOpSelectionMerge) { if (CanOpSelectionMergeBeRemoved( context, block, merge_instruction, merge_and_continue_blocks_from_loops)) { diff --git a/source/reduce/remove_struct_member_reduction_opportunity.cpp b/source/reduce/remove_struct_member_reduction_opportunity.cpp index 3309fd09..e72ed351 100644 --- a/source/reduce/remove_struct_member_reduction_opportunity.cpp +++ b/source/reduce/remove_struct_member_reduction_opportunity.cpp @@ -36,14 +36,14 @@ void RemoveStructMemberReductionOpportunity::Apply() { struct_type_, [this, &decorations_to_kill](opt::Instruction* user, uint32_t /*operand_index*/) { switch (user->opcode()) { - case spv::Op::OpCompositeConstruct: - case spv::Op::OpConstantComposite: + case SpvOpCompositeConstruct: + case SpvOpConstantComposite: // This use is constructing a composite of the struct type, so we // must remove the id that was provided for the member we are // removing. user->RemoveInOperand(member_index_); break; - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: // This use is decorating a member of the struct. if (user->GetSingleWordInOperand(1) == member_index_) { // The member we are removing is being decorated, so we record @@ -78,8 +78,8 @@ void RemoveStructMemberReductionOpportunity::Apply() { for (auto& block : function) { for (auto& inst : block) { switch (inst.opcode()) { - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: { + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: { // These access chain instructions take sequences of ids for // indexing, starting from input operand 1. auto composite_type_id = @@ -90,8 +90,8 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->GetSingleWordInOperand(1); AdjustAccessedIndices(composite_type_id, 1, false, context, &inst); } break; - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: { + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: { // These access chain instructions take sequences of ids for // indexing, starting from input operand 2. auto composite_type_id = @@ -102,7 +102,7 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->GetSingleWordInOperand(1); AdjustAccessedIndices(composite_type_id, 2, false, context, &inst); } break; - case spv::Op::OpCompositeExtract: { + case SpvOpCompositeExtract: { // OpCompositeExtract uses literals for indexing, starting at input // operand 1. auto composite_type_id = @@ -111,7 +111,7 @@ void RemoveStructMemberReductionOpportunity::Apply() { ->type_id(); AdjustAccessedIndices(composite_type_id, 1, true, context, &inst); } break; - case spv::Op::OpCompositeInsert: { + case SpvOpCompositeInsert: { // OpCompositeInsert uses literals for indexing, starting at input // operand 2. auto composite_type_id = @@ -146,13 +146,13 @@ void RemoveStructMemberReductionOpportunity::AdjustAccessedIndices( i < composite_access_instruction->NumInOperands(); i++) { auto type_inst = context->get_def_use_mgr()->GetDef(next_type); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: next_type = type_inst->GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // Struct types are special because (a) we may need to adjust the index // being used, if the struct type is the one from which we are removing // a member, and (b) the type encountered by following the current index diff --git a/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp b/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp index fbbeb346..d7bb3a82 100644 --- a/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp +++ b/source/reduce/remove_unused_instruction_reduction_opportunity_finder.cpp @@ -103,8 +103,8 @@ RemoveUnusedInstructionReductionOpportunityFinder::GetAvailableOpportunities( continue; } if (spvOpcodeIsBlockTerminator(inst.opcode()) || - inst.opcode() == spv::Op::OpSelectionMerge || - inst.opcode() == spv::Op::OpLoopMerge) { + inst.opcode() == SpvOpSelectionMerge || + inst.opcode() == SpvOpLoopMerge) { // In this reduction pass we do not want to affect static // control flow. continue; @@ -133,7 +133,7 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: &inst, [this](opt::Instruction* user, uint32_t use_index) -> bool { return (user->IsDecoration() && !IsIndependentlyRemovableDecoration(*user)) || - (user->opcode() == spv::Op::OpEntryPoint && use_index > 2); + (user->opcode() == SpvOpEntryPoint && use_index > 2); }); } @@ -141,13 +141,13 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: IsIndependentlyRemovableDecoration(const opt::Instruction& inst) const { uint32_t decoration; switch (inst.opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateString: + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpDecorateString: decoration = inst.GetSingleWordInOperand(1u); break; - case spv::Op::OpMemberDecorate: - case spv::Op::OpMemberDecorateString: + case SpvOpMemberDecorate: + case SpvOpMemberDecorateString: decoration = inst.GetSingleWordInOperand(2u); break; default: @@ -160,12 +160,12 @@ bool RemoveUnusedInstructionReductionOpportunityFinder:: // not change the shader interface, will not make the shader invalid, will // actually be found in practice, etc. - switch (spv::Decoration(decoration)) { - case spv::Decoration::RelaxedPrecision: - case spv::Decoration::NoSignedWrap: - case spv::Decoration::NoContraction: - case spv::Decoration::NoUnsignedWrap: - case spv::Decoration::UserSemantic: + switch (decoration) { + case SpvDecorationRelaxedPrecision: + case SpvDecorationNoSignedWrap: + case SpvDecorationNoContraction: + case SpvDecorationNoUnsignedWrap: + case SpvDecorationUserSemantic: return true; default: return false; diff --git a/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp b/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp index db381e0f..cd0c4e4d 100644 --- a/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp +++ b/source/reduce/remove_unused_struct_member_reduction_opportunity_finder.cpp @@ -43,7 +43,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( // Consider every struct type in the module. for (auto& type_or_value : context->types_values()) { - if (type_or_value.opcode() != spv::Op::OpTypeStruct) { + if (type_or_value.opcode() != SpvOpTypeStruct) { continue; } @@ -60,7 +60,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( &type_or_value, [&unused_members](opt::Instruction* user, uint32_t /*operand_index*/) { switch (user->opcode()) { - case spv::Op::OpMemberName: + case SpvOpMemberName: unused_members.erase(user->GetSingleWordInOperand(1)); break; default: @@ -91,8 +91,8 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( // The way the helper is invoked depends on whether the instruction // uses literal or id indices, and the offset into the instruction's // input operands from which index operands are provided. - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: { + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(context->get_def_use_mgr() @@ -102,8 +102,8 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 1, false, inst, &unused_member_to_structs); } break; - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: { + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(context->get_def_use_mgr() @@ -113,7 +113,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 2, false, inst, &unused_member_to_structs); } break; - case spv::Op::OpCompositeExtract: { + case SpvOpCompositeExtract: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(inst.GetSingleWordInOperand(0)) @@ -121,7 +121,7 @@ RemoveUnusedStructMemberReductionOpportunityFinder::GetAvailableOpportunities( MarkAccessedMembersAsUsed(context, composite_type_id, 1, true, inst, &unused_member_to_structs); } break; - case spv::Op::OpCompositeInsert: { + case SpvOpCompositeInsert: { auto composite_type_id = context->get_def_use_mgr() ->GetDef(inst.GetSingleWordInOperand(1)) @@ -163,13 +163,13 @@ void RemoveUnusedStructMemberReductionOpportunityFinder:: i < composite_access_instruction.NumInOperands(); i++) { auto type_inst = context->get_def_use_mgr()->GetDef(next_type); switch (type_inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: next_type = type_inst->GetSingleWordInOperand(0); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { uint32_t index_operand = composite_access_instruction.GetSingleWordInOperand(i); uint32_t member = literal_indices ? index_operand diff --git a/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp b/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp index 9637f0f1..d867c3ad 100644 --- a/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp +++ b/source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp @@ -29,15 +29,15 @@ SimpleConditionalBranchToBranchOpportunityFinder::GetAvailableOpportunities( for (auto* function : GetTargetFunctions(context, target_function)) { // Consider every block in the function. for (auto& block : *function) { - // The terminator must be spv::Op::OpBranchConditional. + // The terminator must be SpvOpBranchConditional. opt::Instruction* terminator = block.terminator(); - if (terminator->opcode() != spv::Op::OpBranchConditional) { + if (terminator->opcode() != SpvOpBranchConditional) { continue; } // It must not be a selection header, as these cannot be followed by // OpBranch. if (block.GetMergeInst() && - block.GetMergeInst()->opcode() == spv::Op::OpSelectionMerge) { + block.GetMergeInst()->opcode() == SpvOpSelectionMerge) { continue; } // The conditional branch must be simplified. diff --git a/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp b/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp index 6d772b59..a2be0c4d 100644 --- a/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp +++ b/source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp @@ -31,8 +31,7 @@ bool SimpleConditionalBranchToBranchReductionOpportunity::PreconditionHolds() { } void SimpleConditionalBranchToBranchReductionOpportunity::Apply() { - assert(conditional_branch_instruction_->opcode() == - spv::Op::OpBranchConditional && + assert(conditional_branch_instruction_->opcode() == SpvOpBranchConditional && "SimpleConditionalBranchToBranchReductionOpportunity: branch was not " "a conditional branch"); @@ -47,7 +46,7 @@ void SimpleConditionalBranchToBranchReductionOpportunity::Apply() { // -> // OpBranch %block_id - conditional_branch_instruction_->SetOpcode(spv::Op::OpBranch); + conditional_branch_instruction_->SetOpcode(SpvOpBranch); conditional_branch_instruction_->ReplaceOperands( {{SPV_OPERAND_TYPE_ID, {conditional_branch_instruction_->GetSingleWordInOperand( diff --git a/source/reduce/structured_construct_to_block_reduction_opportunity.cpp b/source/reduce/structured_construct_to_block_reduction_opportunity.cpp index cc5ffe3c..ed738411 100644 --- a/source/reduce/structured_construct_to_block_reduction_opportunity.cpp +++ b/source/reduce/structured_construct_to_block_reduction_opportunity.cpp @@ -55,7 +55,7 @@ void StructuredConstructToBlockReductionOpportunity::Apply() { // The terminator for the header block is changed to be an unconditional // branch to the merge block. - header_block->terminator()->SetOpcode(spv::Op::OpBranch); + header_block->terminator()->SetOpcode(SpvOpBranch); header_block->terminator()->SetInOperands( {{SPV_OPERAND_TYPE_ID, {merge_block->id()}}}); diff --git a/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp b/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp index 45b95285..850af456 100644 --- a/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp +++ b/source/reduce/structured_loop_to_selection_reduction_opportunity.cpp @@ -129,12 +129,12 @@ void StructuredLoopToSelectionReductionOpportunity::RedirectEdge( // Figure out which operands of the terminator need to be considered for // redirection. std::vector operand_indices; - if (terminator->opcode() == spv::Op::OpBranch) { + if (terminator->opcode() == SpvOpBranch) { operand_indices = {0}; - } else if (terminator->opcode() == spv::Op::OpBranchConditional) { + } else if (terminator->opcode() == SpvOpBranchConditional) { operand_indices = {1, 2}; } else { - assert(terminator->opcode() == spv::Op::OpSwitch); + assert(terminator->opcode() == SpvOpSwitch); for (uint32_t label_index = 1; label_index < terminator->NumOperands(); label_index += 2) { operand_indices.push_back(label_index); @@ -179,19 +179,18 @@ void StructuredLoopToSelectionReductionOpportunity::ChangeLoopToSelection() { auto loop_merge_inst = loop_construct_header_->GetLoopMergeInst(); auto const loop_merge_block_id = loop_merge_inst->GetSingleWordOperand(kMergeNodeIndex); - loop_merge_inst->SetOpcode(spv::Op::OpSelectionMerge); + loop_merge_inst->SetOpcode(SpvOpSelectionMerge); loop_merge_inst->ReplaceOperands( {{loop_merge_inst->GetOperand(kMergeNodeIndex).type, {loop_merge_block_id}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}}); + {SPV_OPERAND_TYPE_SELECTION_CONTROL, {SpvSelectionControlMaskNone}}}); // The loop header either finishes with OpBranch or OpBranchConditional. // The latter is fine for a selection. In the former case we need to turn // it into OpBranchConditional. We use "true" as the condition, and make // the "else" branch be the merge block. auto terminator = loop_construct_header_->terminator(); - if (terminator->opcode() == spv::Op::OpBranch) { + if (terminator->opcode() == SpvOpBranch) { opt::analysis::Bool temp; const opt::analysis::Bool* bool_type = context_->get_type_mgr()->GetRegisteredType(&temp)->AsBool(); @@ -200,7 +199,7 @@ void StructuredLoopToSelectionReductionOpportunity::ChangeLoopToSelection() { auto true_const_result_id = const_mgr->GetDefiningInstruction(true_const)->result_id(); auto original_branch_id = terminator->GetSingleWordOperand(0); - terminator->SetOpcode(spv::Op::OpBranchConditional); + terminator->SetOpcode(SpvOpBranchConditional); terminator->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {true_const_result_id}}, {SPV_OPERAND_TYPE_ID, {original_branch_id}}, {SPV_OPERAND_TYPE_ID, {loop_merge_block_id}}}); @@ -216,7 +215,7 @@ void StructuredLoopToSelectionReductionOpportunity::FixNonDominatedIdUses() { // Consider each instruction in the function. for (auto& block : *loop_construct_header_->GetParent()) { for (auto& def : block) { - if (def.opcode() == spv::Op::OpVariable) { + if (def.opcode() == SpvOpVariable) { // Variables are defined at the start of the function, and can be // accessed by all blocks, even by unreachable blocks that have no // dominators, so we do not need to worry about them. @@ -234,11 +233,11 @@ void StructuredLoopToSelectionReductionOpportunity::FixNonDominatedIdUses() { // access chain, in which case replace it with some (possibly fresh) // variable (as we cannot load from / store to OpUndef). if (!DefinitionSufficientlyDominatesUse(&def, use, index, block)) { - if (def.opcode() == spv::Op::OpAccessChain) { + if (def.opcode() == SpvOpAccessChain) { auto pointer_type = context_->get_type_mgr()->GetType(def.type_id())->AsPointer(); switch (pointer_type->storage_class()) { - case spv::StorageClass::Function: + case SpvStorageClassFunction: use->SetOperand( index, {FindOrCreateFunctionVariable( context_, loop_construct_header_->GetParent(), @@ -271,7 +270,7 @@ bool StructuredLoopToSelectionReductionOpportunity:: opt::Instruction* use, uint32_t use_index, opt::BasicBlock& def_block) { - if (use->opcode() == spv::Op::OpPhi) { + if (use->opcode() == SpvOpPhi) { // A use in a phi doesn't need to be dominated by its definition, but the // associated parent block does need to be dominated by the definition. return context_->GetDominatorAnalysis(loop_construct_header_->GetParent()) diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index 585f8b65..9a038174 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "source/spirv_constant.h" #include "spirv-tools/libspirv.h" diff --git a/source/table.h b/source/table.h index 8097f13f..5adf04a4 100644 --- a/source/table.h +++ b/source/table.h @@ -21,9 +21,9 @@ typedef struct spv_opcode_desc_t { const char* name; - const spv::Op opcode; + const SpvOp opcode; const uint32_t numCapabilities; - const spv::Capability* capabilities; + const SpvCapability* capabilities; // operandTypes[0..numTypes-1] describe logical operands for the instruction. // The operand types include result id and result-type id, followed by // the types of arguments. @@ -48,7 +48,7 @@ typedef struct spv_operand_desc_t { const char* name; const uint32_t value; const uint32_t numCapabilities; - const spv::Capability* capabilities; + const SpvCapability* capabilities; // A set of extensions that enable this feature. If empty then this operand // value is in core and its availability is subject to minVersion. The // assembler, binary parser, and disassembler ignore this rule, so you can @@ -73,7 +73,7 @@ typedef struct spv_ext_inst_desc_t { const char* name; const uint32_t ext_inst; const uint32_t numCapabilities; - const spv::Capability* capabilities; + const SpvCapability* capabilities; const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? } spv_ext_inst_desc_t; diff --git a/source/text.cpp b/source/text.cpp index 737c223b..90f69c52 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -227,8 +227,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // Set the extended instruction type. // The import set id is the 3rd operand of OpExtInst. - if (spv::Op(pInst->opcode) == spv::Op::OpExtInst && - pInst->words.size() == 4) { + if (pInst->opcode == SpvOpExtInst && pInst->words.size() == 4) { auto ext_inst_type = context->getExtInstTypeForId(pInst->words[3]); if (ext_inst_type == SPV_EXT_INST_TYPE_NONE) { return context->diagnostic() @@ -280,7 +279,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // The assembler accepts the symbolic name for the opcode, but without // the "Op" prefix. For example, "IAdd" is accepted. The number // of the opcode is emitted. - spv::Op opcode; + SpvOp opcode; if (grammar.lookupSpecConstantOpcode(textValue, &opcode)) { return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) << " '" << textValue << "'."; @@ -312,17 +311,6 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, } } break; - case SPV_OPERAND_TYPE_LITERAL_FLOAT: { - // The current operand is a 32-bit float. - // That's just how the grammar works. - spvtools::IdType expected_type = { - 32, false, spvtools::IdTypeClass::kScalarFloatType}; - if (auto error = context->binaryEncodeNumericLiteral( - textValue, error_code_for_literals, expected_type, pInst)) { - return error; - } - } break; - case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER: // This is a context-independent literal number which can be a 32-bit // number of floating point value. @@ -339,8 +327,8 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // The encoding for OpConstant, OpSpecConstant and OpSwitch all // depend on either their own result-id or the result-id of // one of their parameters. - if (spv::Op::OpConstant == pInst->opcode || - spv::Op::OpSpecConstant == pInst->opcode) { + if (SpvOpConstant == pInst->opcode || + SpvOpSpecConstant == pInst->opcode) { // The type of the literal is determined by the type Id of the // instruction. expected_type = @@ -356,7 +344,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, << "Type for " << opcode_name << " must be a scalar floating point or integer type"; } - } else if (pInst->opcode == spv::Op::OpSwitch) { + } else if (pInst->opcode == SpvOpSwitch) { // The type of the literal is the same as the type of the selector. expected_type = context->getTypeOfValueInstruction(pInst->words[1]); if (!spvtools::isScalarIntegral(expected_type)) { @@ -387,7 +375,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, } // NOTE: Special case for extended instruction library import - if (spv::Op::OpExtInstImport == pInst->opcode) { + if (SpvOpExtInstImport == pInst->opcode) { const spv_ext_inst_type_t ext_inst_type = spvExtInstImportTypeGet(literal.str.c_str()); if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { @@ -413,8 +401,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: - case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: { + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: { uint32_t value; if (auto error = grammar.parseMaskOperand(type, textValue, &value)) { return context->diagnostic(error) @@ -556,8 +543,7 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar, std::string equal_sign; error = context->getWord(&equal_sign, &nextPosition); if ("=" != equal_sign) - return context->diagnostic() << "'=' expected after result id but found '" - << equal_sign << "'."; + return context->diagnostic() << "'=' expected after result id."; // The after the '=' sign. context->setPosition(nextPosition); @@ -702,7 +688,7 @@ spv_result_t SetHeader(spv_target_env env, const uint32_t bound, uint32_t* header) { if (!header) return SPV_ERROR_INVALID_BINARY; - header[SPV_INDEX_MAGIC_NUMBER] = spv::MagicNumber; + header[SPV_INDEX_MAGIC_NUMBER] = SpvMagicNumber; header[SPV_INDEX_VERSION_NUMBER] = spvVersionForTargetEnv(env); header[SPV_INDEX_GENERATOR_NUMBER] = SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, kAssemblerVersion); @@ -736,7 +722,7 @@ spv_result_t GetNumericIds(const spvtools::AssemblyGrammar& grammar, // being parsed. A malformed input might feature such an operand *before* // the opcode is known. To guard against accessing an uninitialized opcode, // the instruction's opcode is initialized to a default value. - inst.opcode = spv::Op::Max; + inst.opcode = SpvOpMax; if (spvTextEncodeOpcode(grammar, &context, &inst)) { return SPV_ERROR_INVALID_TEXT; diff --git a/source/text_handler.cpp b/source/text_handler.cpp index 35c4b83c..15c1741f 100644 --- a/source/text_handler.cpp +++ b/source/text_handler.cpp @@ -323,12 +323,12 @@ spv_result_t AssemblyContext::recordTypeDefinition( << " has already been used to generate a type"; } - if (pInst->opcode == spv::Op::OpTypeInt) { + if (pInst->opcode == SpvOpTypeInt) { if (pInst->words.size() != 4) return diagnostic() << "Invalid OpTypeInt instruction"; types_[value] = {pInst->words[2], pInst->words[3] != 0, IdTypeClass::kScalarIntegerType}; - } else if (pInst->opcode == spv::Op::OpTypeFloat) { + } else if (pInst->opcode == SpvOpTypeFloat) { if (pInst->words.size() != 3) return diagnostic() << "Invalid OpTypeFloat instruction"; types_[value] = {pInst->words[2], false, IdTypeClass::kScalarFloatType}; diff --git a/source/util/hex_float.h b/source/util/hex_float.h index 98353a4a..06e3c575 100644 --- a/source/util/hex_float.h +++ b/source/util/hex_float.h @@ -896,47 +896,6 @@ ParseNormalFloat, HexFloatTraits>>( return is; } -namespace detail { - -// Returns a new value formed from 'value' by setting 'bit' that is the -// 'n'th most significant bit (where 0 is the most significant bit). -// If 'bit' is zero or 'n' is more than the number of bits in the integer -// type, then return the original value. -template -UINT_TYPE set_nth_most_significant_bit(UINT_TYPE value, UINT_TYPE bit, - UINT_TYPE n) { - constexpr UINT_TYPE max_position = std::numeric_limits::digits - 1; - if ((bit != 0) && (n <= max_position)) { - return static_cast(value | (bit << (max_position - n))); - } - return value; -} - -// Attempts to increment the argument. -// If it does not overflow, then increments the argument and returns true. -// If it would overflow, returns false. -template -bool saturated_inc(INT_TYPE& value) { - if (value == std::numeric_limits::max()) { - return false; - } - value++; - return true; -} - -// Attempts to decrement the argument. -// If it does not underflow, then decrements the argument and returns true. -// If it would overflow, returns false. -template -bool saturated_dec(INT_TYPE& value) { - if (value == std::numeric_limits::min()) { - return false; - } - value--; - return true; -} -} // namespace detail - // Reads a HexFloat from the given stream. // If the float is not encoded as a hex-float then it will be parsed // as a regular float. @@ -1038,16 +997,13 @@ std::istream& operator>>(std::istream& is, HexFloat& value) { if (bits_written) { // If we are here the bits represented belong in the fractional // part of the float, and we have to adjust the exponent accordingly. - fraction = detail::set_nth_most_significant_bit(fraction, write_bit, - fraction_index); - // Increment the fraction index. If the input has bizarrely many - // significant digits, then silently drop them. - detail::saturated_inc(fraction_index); - if (!detail::saturated_inc(exponent)) { - // Overflow failure - is.setstate(std::ios::failbit); - return is; - } + fraction = static_cast( + fraction | + static_cast( + write_bit << (HF::top_bit_left_shift - fraction_index++))); + // TODO(dneto): Avoid overflow. Testing would require + // parameterization. + exponent = static_cast(exponent + 1); } // Since this updated after setting fraction bits, this effectively // drops the leading 1 bit. @@ -1078,17 +1034,14 @@ std::istream& operator>>(std::istream& is, HexFloat& value) { // Handle modifying the exponent here this way we can handle // an arbitrary number of hex values without overflowing our // integer. - if (!detail::saturated_dec(exponent)) { - // Overflow failure - is.setstate(std::ios::failbit); - return is; - } + // TODO(dneto): Handle underflow. Testing would require extra + // parameterization. + exponent = static_cast(exponent - 1); } else { - fraction = detail::set_nth_most_significant_bit(fraction, write_bit, - fraction_index); - // Increment the fraction index. If the input has bizarrely many - // significant digits, then silently drop them. - detail::saturated_inc(fraction_index); + fraction = static_cast( + fraction | + static_cast( + write_bit << (HF::top_bit_left_shift - fraction_index++))); } } } else { diff --git a/source/util/small_vector.h b/source/util/small_vector.h index 1351475b..648a3482 100644 --- a/source/util/small_vector.h +++ b/source/util/small_vector.h @@ -15,9 +15,7 @@ #ifndef SOURCE_UTIL_SMALL_VECTOR_H_ #define SOURCE_UTIL_SMALL_VECTOR_H_ -#include #include -#include #include #include #include @@ -463,19 +461,15 @@ class SmallVector { // The number of elements in |small_data_| that have been constructed. size_t size_; - // A type with the same alignment and size as T, but will is POD. - struct alignas(T) PodType { - std::array data; - }; - - // The actual data used to store the array elements. It must never be used - // directly, but must only be accessed through |small_data_|. - PodType buffer[small_size]; - // The pointed used to access the array of elements when the number of // elements is small. T* small_data_; + // The actual data used to store the array elements. It must never be used + // directly, but must only be accessed through |small_data_|. + typename std::aligned_storage::value>::type + buffer[small_size]; + // A pointer to a vector that is used to store the elements of the vector when // this size exceeds |small_size|. If |large_data_| is nullptr, then the data // is stored in |small_data_|. Otherwise, the data is stored in diff --git a/source/val/BUILD.gn b/source/val/BUILD.gn deleted file mode 100755 index 049c62cb..00000000 --- a/source/val/BUILD.gn +++ /dev/null @@ -1,157 +0,0 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. -# 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. - -import("//build/ohos.gni") -import("//third_party/vk-gl-cts/vk_gl_cts.gni") - -config("deqp_spirvtool_val_config") { - cflags_cc = deqp_common_cflags_cc - cflags_cc += [ "-ftemplate-depth=1024" ] - defines = deqp_common_defines - defines += [ - "SPIRV_CHECK_CONTEXT", - "SPIRV_COLOR_TERMINAL", - "SPIRV_LINUX", - "SPIRV_TIMER_ENABLED", - ] -} - -config("spv_headers_public_config") { - include_dirs = [ "include" ] -} - -config("spvtools_include_gen_dirs") { - include_dirs = [ "$target_gen_dir" ] -} - -config("spvtools_internal_config") { - include_dirs = [ - ".", - "//third_party/spirv-headers/include", - ] - - configs = [ - ":spv_headers_public_config", - ":spvtools_include_gen_dirs", - ] - - cflags = [] - if (is_clang) { - cflags += [ - "-Wno-implicit-fallthrough", - "-Wno-newline-eof", - "-Wno-unreachable-code-break", - "-Wno-unreachable-code-return", - ] - } else if (!is_win) { - # Work around a false-positive on a Skia GCC 10 builder. - cflags += [ "-Wno-format-truncation" ] - } else { - # Make MSVC report the correct value for __cplusplus - cflags += [ "/Zc:__cplusplus" ] - } - - if (!is_win) { - cflags += [ "-std=c++17" ] - } else { - cflags += [ "/std:c++17" ] - } -} - -ohos_source_set("deqp_spirvtool_val_source") { - sources = [ - "//third_party/spirv-tools/include/spirv-tools/instrument.hpp", - "//third_party/spirv-tools/include/spirv-tools/libspirv.h", - "//third_party/spirv-tools/include/spirv-tools/libspirv.hpp", - "//third_party/spirv-tools/include/spirv-tools/linker.hpp", - "//third_party/spirv-tools/include/spirv-tools/optimizer.hpp", - "//third_party/spirv-tools/source/val/basic_block.cpp", - "//third_party/spirv-tools/source/val/basic_block.h", - "//third_party/spirv-tools/source/val/construct.cpp", - "//third_party/spirv-tools/source/val/construct.h", - "//third_party/spirv-tools/source/val/decoration.h", - "//third_party/spirv-tools/source/val/function.cpp", - "//third_party/spirv-tools/source/val/function.h", - "//third_party/spirv-tools/source/val/instruction.cpp", - "//third_party/spirv-tools/source/val/validate.cpp", - "//third_party/spirv-tools/source/val/validate.h", - "//third_party/spirv-tools/source/val/validate_adjacency.cpp", - "//third_party/spirv-tools/source/val/validate_annotation.cpp", - "//third_party/spirv-tools/source/val/validate_arithmetics.cpp", - "//third_party/spirv-tools/source/val/validate_atomics.cpp", - "//third_party/spirv-tools/source/val/validate_barriers.cpp", - "//third_party/spirv-tools/source/val/validate_bitwise.cpp", - "//third_party/spirv-tools/source/val/validate_builtins.cpp", - "//third_party/spirv-tools/source/val/validate_capability.cpp", - "//third_party/spirv-tools/source/val/validate_cfg.cpp", - "//third_party/spirv-tools/source/val/validate_composites.cpp", - "//third_party/spirv-tools/source/val/validate_constants.cpp", - "//third_party/spirv-tools/source/val/validate_conversion.cpp", - "//third_party/spirv-tools/source/val/validate_debug.cpp", - "//third_party/spirv-tools/source/val/validate_decorations.cpp", - "//third_party/spirv-tools/source/val/validate_derivatives.cpp", - "//third_party/spirv-tools/source/val/validate_execution_limitations.cpp", - "//third_party/spirv-tools/source/val/validate_extensions.cpp", - "//third_party/spirv-tools/source/val/validate_function.cpp", - "//third_party/spirv-tools/source/val/validate_id.cpp", - "//third_party/spirv-tools/source/val/validate_image.cpp", - "//third_party/spirv-tools/source/val/validate_instruction.cpp", - "//third_party/spirv-tools/source/val/validate_interfaces.cpp", - "//third_party/spirv-tools/source/val/validate_layout.cpp", - "//third_party/spirv-tools/source/val/validate_literals.cpp", - "//third_party/spirv-tools/source/val/validate_logicals.cpp", - "//third_party/spirv-tools/source/val/validate_memory.cpp", - "//third_party/spirv-tools/source/val/validate_memory_semantics.cpp", - "//third_party/spirv-tools/source/val/validate_memory_semantics.h", - "//third_party/spirv-tools/source/val/validate_mesh_shading.cpp", - "//third_party/spirv-tools/source/val/validate_misc.cpp", - "//third_party/spirv-tools/source/val/validate_mode_setting.cpp", - "//third_party/spirv-tools/source/val/validate_non_uniform.cpp", - "//third_party/spirv-tools/source/val/validate_primitives.cpp", - "//third_party/spirv-tools/source/val/validate_ray_query.cpp", - "//third_party/spirv-tools/source/val/validate_ray_tracing.cpp", - "//third_party/spirv-tools/source/val/validate_ray_tracing_reorder.cpp", - "//third_party/spirv-tools/source/val/validate_scopes.cpp", - "//third_party/spirv-tools/source/val/validate_scopes.h", - "//third_party/spirv-tools/source/val/validate_small_type_uses.cpp", - "//third_party/spirv-tools/source/val/validate_type.cpp", - "//third_party/spirv-tools/source/val/validation_state.cpp", - "//third_party/spirv-tools/source/val/validation_state.h", - ] - - include_dirs = deqp_common_include_dirs - include_dirs += [ - "//third_party/spirv-tools", - "//third_party/vk-gl-cts/build/external/spirv-tools/spirv-tools", - "//third_party/spirv-headers/include", - "//third_party/spirv-tools/include", - ] - - if (build_with_chromium) { - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - } - - configs = [ ":deqp_spirvtool_val_config" ] - configs += [ ":spv_headers_public_config" ] - configs += [ ":spvtools_internal_config" ] -} - -ohos_static_library("libdeqp_spirvtools-val") { - deps = [ - ":deqp_spirvtool_val_source", - "//third_party/spirv-tools:libdeqp_spirvtools", - ] - part_name = "acts" - subsystem_name = "xts" -} diff --git a/source/val/basic_block.cpp b/source/val/basic_block.cpp index 9a358fcb..da05db3a 100644 --- a/source/val/basic_block.cpp +++ b/source/val/basic_block.cpp @@ -15,6 +15,7 @@ #include "source/val/basic_block.h" #include +#include #include namespace spvtools { diff --git a/source/val/construct.cpp b/source/val/construct.cpp index 10af155d..52e61d55 100644 --- a/source/val/construct.cpp +++ b/source/val/construct.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "source/val/function.h" #include "source/val/validation_state.h" @@ -163,12 +164,10 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { // ii. The immediate dominator of |block|. auto NextBlock = [](const BasicBlock* block) -> const BasicBlock* { for (auto& use : block->label()->uses()) { - if ((use.first->opcode() == spv::Op::OpLoopMerge || - use.first->opcode() == spv::Op::OpSelectionMerge) && + if ((use.first->opcode() == SpvOpLoopMerge || + use.first->opcode() == SpvOpSelectionMerge) && use.second == 1 && - use.first->block()->structurally_dominates(*block) && - // A header likely declared itself as its merge. - use.first->block() != block) { + use.first->block()->structurally_dominates(*block)) { return use.first->block(); } } @@ -182,10 +181,10 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { auto terminator = block->terminator(); auto index = terminator - &_.ordered_instructions()[0]; auto merge_inst = &_.ordered_instructions()[index - 1]; - if (merge_inst->opcode() == spv::Op::OpLoopMerge || - (header->terminator()->opcode() != spv::Op::OpSwitch && - merge_inst->opcode() == spv::Op::OpSelectionMerge && - terminator->opcode() == spv::Op::OpSwitch)) { + if (merge_inst->opcode() == SpvOpLoopMerge || + (header->terminator()->opcode() != SpvOpSwitch && + merge_inst->opcode() == SpvOpSelectionMerge && + terminator->opcode() == SpvOpSwitch)) { auto merge_target = merge_inst->GetOperandAs(0u); auto merge_block = merge_inst->function()->GetBlock(merge_target).first; if (merge_block->structurally_dominates(*header)) { @@ -193,22 +192,22 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const { continue; } - if ((!seen_switch || merge_inst->opcode() == spv::Op::OpLoopMerge) && + if ((!seen_switch || merge_inst->opcode() == SpvOpLoopMerge) && dest->id() == merge_target) { return true; - } else if (merge_inst->opcode() == spv::Op::OpLoopMerge) { + } else if (merge_inst->opcode() == SpvOpLoopMerge) { auto continue_target = merge_inst->GetOperandAs(1u); if (dest->id() == continue_target) { return true; } } - if (terminator->opcode() == spv::Op::OpSwitch) { + if (terminator->opcode() == SpvOpSwitch) { seen_switch = true; } // Hit an enclosing loop and didn't break or continue. - if (merge_inst->opcode() == spv::Op::OpLoopMerge) return false; + if (merge_inst->opcode() == SpvOpLoopMerge) return false; } block = NextBlock(block); diff --git a/source/val/decoration.h b/source/val/decoration.h index 384cc575..4f53f207 100644 --- a/source/val/decoration.h +++ b/source/val/decoration.h @@ -39,33 +39,33 @@ namespace val { // // Example 1: Decoration for an object with no parameters: // OpDecorate %obj Flat -// dec_type_ = spv::Decoration::Flat +// dec_type_ = SpvDecorationFlat // params_ = empty vector // struct_member_index_ = kInvalidMember // // Example 2: Decoration for an object with two parameters: // OpDecorate %obj LinkageAttributes "link" Import -// dec_type_ = spv::Decoration::LinkageAttributes +// dec_type_ = SpvDecorationLinkageAttributes // params_ = vector { link, Import } // struct_member_index_ = kInvalidMember // // Example 3: Decoration for a member of a structure with one parameter: // OpMemberDecorate %struct 2 Offset 2 -// dec_type_ = spv::Decoration::Offset +// dec_type_ = SpvDecorationOffset // params_ = vector { 2 } // struct_member_index_ = 2 // class Decoration { public: enum { kInvalidMember = -1 }; - Decoration(spv::Decoration t, + Decoration(SpvDecoration t, const std::vector& parameters = std::vector(), uint32_t member_index = kInvalidMember) : dec_type_(t), params_(parameters), struct_member_index_(member_index) {} void set_struct_member_index(uint32_t index) { struct_member_index_ = index; } int struct_member_index() const { return struct_member_index_; } - spv::Decoration dec_type() const { return dec_type_; } + SpvDecoration dec_type() const { return dec_type_; } std::vector& params() { return params_; } const std::vector& params() const { return params_; } @@ -84,7 +84,7 @@ class Decoration { } private: - spv::Decoration dec_type_; + SpvDecoration dec_type_; std::vector params_; // If the decoration applies to a member of a structure type, then the index diff --git a/source/val/function.cpp b/source/val/function.cpp index 290574b8..fc7ccd06 100644 --- a/source/val/function.cpp +++ b/source/val/function.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "source/cfa.h" @@ -32,7 +33,7 @@ namespace val { static const uint32_t kInvalidId = 0x400000; Function::Function(uint32_t function_id, uint32_t result_type_id, - spv::FunctionControlMask function_control, + SpvFunctionControlMask function_control, uint32_t function_type_id) : id_(function_id), function_type_id_(function_type_id), @@ -370,10 +371,10 @@ int Function::GetBlockDepth(BasicBlock* bb) { return block_depth_[bb]; } -void Function::RegisterExecutionModelLimitation(spv::ExecutionModel model, +void Function::RegisterExecutionModelLimitation(SpvExecutionModel model, const std::string& message) { execution_model_limitations_.push_back( - [model, message](spv::ExecutionModel in_model, std::string* out_message) { + [model, message](SpvExecutionModel in_model, std::string* out_message) { if (model != in_model) { if (out_message) { *out_message = message; @@ -384,7 +385,7 @@ void Function::RegisterExecutionModelLimitation(spv::ExecutionModel model, }); } -bool Function::IsCompatibleWithExecutionModel(spv::ExecutionModel model, +bool Function::IsCompatibleWithExecutionModel(SpvExecutionModel model, std::string* reason) const { bool return_value = true; std::stringstream ss_reason; diff --git a/source/val/function.h b/source/val/function.h index 48117944..126b1dc7 100644 --- a/source/val/function.h +++ b/source/val/function.h @@ -55,8 +55,7 @@ enum class FunctionDecl { class Function { public: Function(uint32_t id, uint32_t result_type_id, - spv::FunctionControlMask function_control, - uint32_t function_type_id); + SpvFunctionControlMask function_control, uint32_t function_type_id); /// Registers a function parameter in the current function /// @return Returns SPV_SUCCESS if the call was successful @@ -81,8 +80,7 @@ class Function { /// /// @return Returns SPV_SUCCESS if the call was successful spv_result_t RegisterBlockVariable(uint32_t type_id, uint32_t id, - spv::StorageClass storage, - uint32_t init_id); + SpvStorageClass storage, uint32_t init_id); /// Registers a loop merge construct in the function /// @@ -207,12 +205,12 @@ class Function { /// Registers execution model limitation such as "Feature X is only available /// with Execution Model Y". - void RegisterExecutionModelLimitation(spv::ExecutionModel model, + void RegisterExecutionModelLimitation(SpvExecutionModel model, const std::string& message); /// Registers execution model limitation with an |is_compatible| functor. void RegisterExecutionModelLimitation( - std::function is_compatible) { + std::function is_compatible) { execution_model_limitations_.push_back(is_compatible); } @@ -229,7 +227,7 @@ class Function { /// Returns true if the given execution model passes the limitations stored in /// execution_model_limitations_. Returns false otherwise and fills optional /// |reason| parameter. - bool IsCompatibleWithExecutionModel(spv::ExecutionModel model, + bool IsCompatibleWithExecutionModel(SpvExecutionModel model, std::string* reason = nullptr) const; // Inserts id to the set of functions called from this function. @@ -288,7 +286,7 @@ class Function { uint32_t result_type_id_; /// The control fo the function - spv::FunctionControlMask function_control_; + SpvFunctionControlMask function_control_; /// The type of declaration of each function FunctionDecl declaration_type_; @@ -383,7 +381,7 @@ class Function { /// function. The functor stored in the list return true if execution model /// is compatible, false otherwise. If the functor returns false, it can also /// optionally fill the string parameter with the reason for incompatibility. - std::list> + std::list> execution_model_limitations_; /// Stores limitations imposed by instructions used within the function. diff --git a/source/val/instruction.h b/source/val/instruction.h index c524bd37..6d1f9f4f 100644 --- a/source/val/instruction.h +++ b/source/val/instruction.h @@ -42,7 +42,7 @@ class Instruction { uint32_t id() const { return inst_.result_id; } uint32_t type_id() const { return inst_.type_id; } - spv::Op opcode() const { return static_cast(inst_.opcode); } + SpvOp opcode() const { return static_cast(inst_.opcode); } /// Returns the Function where the instruction was defined. nullptr if it was /// defined outside of a Function @@ -87,13 +87,13 @@ class Instruction { } bool IsNonSemantic() const { - return opcode() == spv::Op::OpExtInst && + return opcode() == SpvOp::SpvOpExtInst && spvExtInstIsNonSemantic(inst_.ext_inst_type); } /// True if this is an OpExtInst for debug info extension. bool IsDebugInfo() const { - return opcode() == spv::Op::OpExtInst && + return opcode() == SpvOp::SpvOpExtInst && spvExtInstIsDebugInfo(inst_.ext_inst_type); } diff --git a/source/val/validate.cpp b/source/val/validate.cpp index a5f320b9..efb9225e 100644 --- a/source/val/validate.cpp +++ b/source/val/validate.cpp @@ -14,9 +14,13 @@ #include "source/val/validate.h" +#include +#include +#include #include #include #include +#include #include #include @@ -24,11 +28,15 @@ #include "source/diagnostic.h" #include "source/enum_string_mapping.h" #include "source/extensions.h" +#include "source/instruction.h" #include "source/opcode.h" +#include "source/operand.h" #include "source/spirv_constant.h" #include "source/spirv_endian.h" #include "source/spirv_target_env.h" +#include "source/spirv_validator_options.h" #include "source/val/construct.h" +#include "source/val/function.h" #include "source/val/instruction.h" #include "source/val/validation_state.h" #include "spirv-tools/libspirv.h" @@ -58,15 +66,15 @@ void RegisterExtension(ValidationState_t& _, // Parses the beginning of the module searching for OpExtension instructions. // Registers extensions if recognized. Returns SPV_REQUESTED_TERMINATION -// once an instruction which is not spv::Op::OpCapability and -// spv::Op::OpExtension is encountered. According to the SPIR-V spec extensions -// are declared after capabilities and before everything else. +// once an instruction which is not SpvOpCapability and SpvOpExtension is +// encountered. According to the SPIR-V spec extensions are declared after +// capabilities and before everything else. spv_result_t ProcessExtensions(void* user_data, const spv_parsed_instruction_t* inst) { - const spv::Op opcode = static_cast(inst->opcode); - if (opcode == spv::Op::OpCapability) return SPV_SUCCESS; + const SpvOp opcode = static_cast(inst->opcode); + if (opcode == SpvOpCapability) return SPV_SUCCESS; - if (opcode == spv::Op::OpExtension) { + if (opcode == SpvOpExtension) { ValidationState_t& _ = *(reinterpret_cast(user_data)); RegisterExtension(_, inst); return SPV_SUCCESS; @@ -115,7 +123,7 @@ spv_result_t ValidateEntryPoints(ValidationState_t& _) { _.ComputeFunctionToEntryPointMapping(); _.ComputeRecursiveEntryPoints(); - if (_.entry_points().empty() && !_.HasCapability(spv::Capability::Linkage)) { + if (_.entry_points().empty() && !_.HasCapability(SpvCapabilityLinkage)) { return _.diag(SPV_ERROR_INVALID_BINARY, nullptr) << "No OpEntryPoint instruction was found. This is only allowed if " "the Linkage capability is being used."; @@ -210,9 +218,9 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( // able to, briefly, de-const the instruction. Instruction* inst = const_cast(&instruction); - if (inst->opcode() == spv::Op::OpEntryPoint) { + if (inst->opcode() == SpvOpEntryPoint) { const auto entry_point = inst->GetOperandAs(1); - const auto execution_model = inst->GetOperandAs(0); + const auto execution_model = inst->GetOperandAs(0); const std::string desc_name = inst->GetOperandAs(2); ValidationState_t::EntryPointDescription desc; @@ -228,7 +236,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (visited_entry_points.size() > 0) { for (const Instruction* check_inst : visited_entry_points) { const auto check_execution_model = - check_inst->GetOperandAs(0); + check_inst->GetOperandAs(0); const std::string check_name = check_inst->GetOperandAs(2); @@ -242,12 +250,12 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( } visited_entry_points.push_back(inst); - has_mask_task_nv |= (execution_model == spv::ExecutionModel::TaskNV || - execution_model == spv::ExecutionModel::MeshNV); - has_mask_task_ext |= (execution_model == spv::ExecutionModel::TaskEXT || - execution_model == spv::ExecutionModel::MeshEXT); + has_mask_task_nv |= (execution_model == SpvExecutionModelTaskNV || + execution_model == SpvExecutionModelMeshNV); + has_mask_task_ext |= (execution_model == SpvExecutionModelTaskEXT || + execution_model == SpvExecutionModelMeshEXT); } - if (inst->opcode() == spv::Op::OpFunctionCall) { + if (inst->opcode() == SpvOpFunctionCall) { if (!vstate->in_function_body()) { return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction) << "A FunctionCall must happen within a function body."; @@ -278,7 +286,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( { Instruction* inst = const_cast(&instruction); vstate->RegisterInstruction(inst); - if (inst->opcode() == spv::Op::OpTypeForwardPointer) { + if (inst->opcode() == SpvOpTypeForwardPointer) { vstate->RegisterForwardPointer(inst->GetOperandAs(0)); } } @@ -292,7 +300,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) << "Missing OpFunctionEnd at end of module."; - if (vstate->HasCapability(spv::Capability::BindlessTextureNV) && + if (vstate->HasCapability(SpvCapabilityBindlessTextureNV) && !vstate->has_samplerimage_variable_address_mode_specified()) return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr) << "Missing required OpSamplerImageAddressingModeNV instruction."; @@ -357,13 +365,11 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = LiteralsPass(*vstate, &instruction)) return error; if (auto error = RayQueryPass(*vstate, &instruction)) return error; if (auto error = RayTracingPass(*vstate, &instruction)) return error; - if (auto error = RayReorderNVPass(*vstate, &instruction)) return error; if (auto error = MeshShadingPass(*vstate, &instruction)) return error; } - // Validate the preconditions involving adjacent instructions. e.g. - // spv::Op::OpPhi must only be preceded by spv::Op::OpLabel, spv::Op::OpPhi, - // or spv::Op::OpLine. + // Validate the preconditions involving adjacent instructions. e.g. SpvOpPhi + // must only be preceded by SpvOpLabel, SpvOpPhi, or SpvOpLine. if (auto error = ValidateAdjacency(*vstate)) return error; if (auto error = ValidateEntryPoints(*vstate)) return error; @@ -381,8 +387,6 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( for (const auto& inst : vstate->ordered_instructions()) { if (auto error = ValidateExecutionLimitations(*vstate, &inst)) return error; if (auto error = ValidateSmallTypeUses(*vstate, &inst)) return error; - if (auto error = ValidateQCOMImageProcessingTextureUsages(*vstate, &inst)) - return error; } return SPV_SUCCESS; diff --git a/source/val/validate.h b/source/val/validate.h index 6b7d7cda..4b953ba3 100644 --- a/source/val/validate.h +++ b/source/val/validate.h @@ -31,6 +31,11 @@ class ValidationState_t; class BasicBlock; class Instruction; +/// A function that returns a vector of BasicBlocks given a BasicBlock. Used to +/// get the successor and predecessor nodes of a CFG block +using get_blocks_func = + std::function*(const BasicBlock*)>; + /// @brief Performs the Control Flow Graph checks /// /// @param[in] _ the validation state of the module @@ -64,8 +69,8 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _); /// instructions. /// /// This function will iterate over all instructions and check for any required -/// predecessor and/or successor instructions. e.g. spv::Op::OpPhi must only be -/// preceded by spv::Op::OpLabel, spv::Op::OpPhi, or spv::Op::OpLine. +/// predecessor and/or successor instructions. e.g. SpvOpPhi must only be +/// preceded by SpvOpLabel, SpvOpPhi, or SpvOpLine. /// /// @param[in] _ the validation state of the module /// @@ -198,9 +203,6 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst); /// Validates correctness of ray tracing instructions. spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst); -/// Validates correctness of shader execution reorder instructions. -spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst); - /// Validates correctness of mesh shading instructions. spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst); @@ -220,14 +222,6 @@ spv_result_t ValidateExecutionLimitations(ValidationState_t& _, spv_result_t ValidateSmallTypeUses(ValidationState_t& _, const Instruction* inst); -/// Validates restricted uses of QCOM decorated textures -/// -/// The textures that are decorated with some of QCOM image processing -/// decorations must be used in the specified QCOM image processing built-in -/// functions and not used in any other image functions. -spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _, - const Instruction* inst); - /// @brief Validate the ID's within a SPIR-V binary /// /// @param[in] pInstructions array of instructions diff --git a/source/val/validate_adjacency.cpp b/source/val/validate_adjacency.cpp index 7e371c2f..8e6c373e 100644 --- a/source/val/validate_adjacency.cpp +++ b/source/val/validate_adjacency.cpp @@ -15,10 +15,13 @@ // Validates correctness of the intra-block preconditions of SPIR-V // instructions. +#include "source/val/validate.h" + #include +#include "source/diagnostic.h" +#include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -43,15 +46,15 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { for (size_t i = 0; i < instructions.size(); ++i) { const auto& inst = instructions[i]; switch (inst.opcode()) { - case spv::Op::OpFunction: - case spv::Op::OpFunctionParameter: + case SpvOpFunction: + case SpvOpFunctionParameter: adjacency_status = IN_NEW_FUNCTION; break; - case spv::Op::OpLabel: + case SpvOpLabel: adjacency_status = adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID; break; - case spv::Op::OpExtInst: + case SpvOpExtInst: // If it is a debug info instruction, we do not change the status to // allow debug info instructions before OpVariable in a function. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need @@ -64,7 +67,7 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { adjacency_status = PHI_AND_VAR_INVALID; } break; - case spv::Op::OpPhi: + case SpvOpPhi: if (adjacency_status != PHI_VALID) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "OpPhi must appear within a non-entry block before all " @@ -72,15 +75,15 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { << "(except for OpLine, which can be mixed with OpPhi)."; } break; - case spv::Op::OpLine: - case spv::Op::OpNoLine: + case SpvOpLine: + case SpvOpNoLine: break; - case spv::Op::OpLoopMerge: + case SpvOpLoopMerge: adjacency_status = PHI_AND_VAR_INVALID; if (i != (instructions.size() - 1)) { switch (instructions[i + 1].opcode()) { - case spv::Op::OpBranch: - case spv::Op::OpBranchConditional: + case SpvOpBranch: + case SpvOpBranchConditional: break; default: return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -91,12 +94,12 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { } } break; - case spv::Op::OpSelectionMerge: + case SpvOpSelectionMerge: adjacency_status = PHI_AND_VAR_INVALID; if (i != (instructions.size() - 1)) { switch (instructions[i + 1].opcode()) { - case spv::Op::OpBranchConditional: - case spv::Op::OpSwitch: + case SpvOpBranchConditional: + case SpvOpSwitch: break; default: return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -107,9 +110,8 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { } } break; - case spv::Op::OpVariable: - if (inst.GetOperandAs(2) == - spv::StorageClass::Function && + case SpvOpVariable: + if (inst.GetOperandAs(2) == SpvStorageClassFunction && adjacency_status != IN_ENTRY_BLOCK) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "All OpVariable instructions in a function must be the " diff --git a/source/val/validate_annotation.cpp b/source/val/validate_annotation.cpp index 73d0285a..21f999b0 100644 --- a/source/val/validate_annotation.cpp +++ b/source/val/validate_annotation.cpp @@ -24,12 +24,12 @@ namespace { // Returns true if the decoration takes ID parameters. // TODO(dneto): This can be generated from the grammar. -bool DecorationTakesIdParameters(spv::Decoration type) { +bool DecorationTakesIdParameters(SpvDecoration type) { switch (type) { - case spv::Decoration::UniformId: - case spv::Decoration::AlignmentId: - case spv::Decoration::MaxByteOffsetId: - case spv::Decoration::HlslCounterBufferGOOGLE: + case SpvDecorationUniformId: + case SpvDecorationAlignmentId: + case SpvDecorationMaxByteOffsetId: + case SpvDecorationHlslCounterBufferGOOGLE: return true; default: break; @@ -37,14 +37,14 @@ bool DecorationTakesIdParameters(spv::Decoration type) { return false; } -bool IsMemberDecorationOnly(spv::Decoration dec) { +bool IsMemberDecorationOnly(SpvDecoration dec) { switch (dec) { - case spv::Decoration::RowMajor: - case spv::Decoration::ColMajor: - case spv::Decoration::MatrixStride: + case SpvDecorationRowMajor: + case SpvDecorationColMajor: + case SpvDecorationMatrixStride: // SPIR-V spec bug? Offset is generated on variables when dealing with // transform feedback. - // case spv::Decoration::Offset: + // case SpvDecorationOffset: return true; default: break; @@ -52,42 +52,42 @@ bool IsMemberDecorationOnly(spv::Decoration dec) { return false; } -bool IsNotMemberDecoration(spv::Decoration dec) { +bool IsNotMemberDecoration(SpvDecoration dec) { switch (dec) { - case spv::Decoration::SpecId: - case spv::Decoration::Block: - case spv::Decoration::BufferBlock: - case spv::Decoration::ArrayStride: - case spv::Decoration::GLSLShared: - case spv::Decoration::GLSLPacked: - case spv::Decoration::CPacked: + case SpvDecorationSpecId: + case SpvDecorationBlock: + case SpvDecorationBufferBlock: + case SpvDecorationArrayStride: + case SpvDecorationGLSLShared: + case SpvDecorationGLSLPacked: + case SpvDecorationCPacked: // TODO: https://github.com/KhronosGroup/glslang/issues/703: // glslang applies Restrict to structure members. - // case spv::Decoration::Restrict: - case spv::Decoration::Aliased: - case spv::Decoration::Constant: - case spv::Decoration::Uniform: - case spv::Decoration::UniformId: - case spv::Decoration::SaturatedConversion: - case spv::Decoration::Index: - case spv::Decoration::Binding: - case spv::Decoration::DescriptorSet: - case spv::Decoration::FuncParamAttr: - case spv::Decoration::FPRoundingMode: - case spv::Decoration::FPFastMathMode: - case spv::Decoration::LinkageAttributes: - case spv::Decoration::NoContraction: - case spv::Decoration::InputAttachmentIndex: - case spv::Decoration::Alignment: - case spv::Decoration::MaxByteOffset: - case spv::Decoration::AlignmentId: - case spv::Decoration::MaxByteOffsetId: - case spv::Decoration::NoSignedWrap: - case spv::Decoration::NoUnsignedWrap: - case spv::Decoration::NonUniform: - case spv::Decoration::RestrictPointer: - case spv::Decoration::AliasedPointer: - case spv::Decoration::CounterBuffer: + // case SpvDecorationRestrict: + case SpvDecorationAliased: + case SpvDecorationConstant: + case SpvDecorationUniform: + case SpvDecorationUniformId: + case SpvDecorationSaturatedConversion: + case SpvDecorationIndex: + case SpvDecorationBinding: + case SpvDecorationDescriptorSet: + case SpvDecorationFuncParamAttr: + case SpvDecorationFPRoundingMode: + case SpvDecorationFPFastMathMode: + case SpvDecorationLinkageAttributes: + case SpvDecorationNoContraction: + case SpvDecorationInputAttachmentIndex: + case SpvDecorationAlignment: + case SpvDecorationMaxByteOffset: + case SpvDecorationAlignmentId: + case SpvDecorationMaxByteOffsetId: + case SpvDecorationNoSignedWrap: + case SpvDecorationNoUnsignedWrap: + case SpvDecorationNonUniform: + case SpvDecorationRestrictPointer: + case SpvDecorationAliasedPointer: + case SpvDecorationCounterBuffer: return true; default: break; @@ -95,7 +95,7 @@ bool IsNotMemberDecoration(spv::Decoration dec) { return false; } -spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, +spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec, const Instruction* inst, const Instruction* target) { auto fail = [&_, dec, inst, target](uint32_t vuid) -> DiagnosticStream { @@ -106,76 +106,76 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, return ds; }; switch (dec) { - case spv::Decoration::SpecId: + case SpvDecorationSpecId: if (!spvOpcodeIsScalarSpecConstant(target->opcode())) { return fail(0) << "must be a scalar specialization constant"; } break; - case spv::Decoration::Block: - case spv::Decoration::BufferBlock: - case spv::Decoration::GLSLShared: - case spv::Decoration::GLSLPacked: - case spv::Decoration::CPacked: - if (target->opcode() != spv::Op::OpTypeStruct) { + case SpvDecorationBlock: + case SpvDecorationBufferBlock: + case SpvDecorationGLSLShared: + case SpvDecorationGLSLPacked: + case SpvDecorationCPacked: + if (target->opcode() != SpvOpTypeStruct) { return fail(0) << "must be a structure type"; } break; - case spv::Decoration::ArrayStride: - if (target->opcode() != spv::Op::OpTypeArray && - target->opcode() != spv::Op::OpTypeRuntimeArray && - target->opcode() != spv::Op::OpTypePointer) { + case SpvDecorationArrayStride: + if (target->opcode() != SpvOpTypeArray && + target->opcode() != SpvOpTypeRuntimeArray && + target->opcode() != SpvOpTypePointer) { return fail(0) << "must be an array or pointer type"; } break; - case spv::Decoration::BuiltIn: - if (target->opcode() != spv::Op::OpVariable && + case SpvDecorationBuiltIn: + if (target->opcode() != SpvOpVariable && !spvOpcodeIsConstant(target->opcode())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "BuiltIns can only target variables, structure members or " "constants"; } - if (_.HasCapability(spv::Capability::Shader) && - inst->GetOperandAs(2) == spv::BuiltIn::WorkgroupSize) { + if (_.HasCapability(SpvCapabilityShader) && + inst->GetOperandAs(2) == SpvBuiltInWorkgroupSize) { if (!spvOpcodeIsConstant(target->opcode())) { return fail(0) << "must be a constant for WorkgroupSize"; } - } else if (target->opcode() != spv::Op::OpVariable) { + } else if (target->opcode() != SpvOpVariable) { return fail(0) << "must be a variable"; } break; - case spv::Decoration::NoPerspective: - case spv::Decoration::Flat: - case spv::Decoration::Patch: - case spv::Decoration::Centroid: - case spv::Decoration::Sample: - case spv::Decoration::Restrict: - case spv::Decoration::Aliased: - case spv::Decoration::Volatile: - case spv::Decoration::Coherent: - case spv::Decoration::NonWritable: - case spv::Decoration::NonReadable: - case spv::Decoration::XfbBuffer: - case spv::Decoration::XfbStride: - case spv::Decoration::Component: - case spv::Decoration::Stream: - case spv::Decoration::RestrictPointer: - case spv::Decoration::AliasedPointer: - if (target->opcode() != spv::Op::OpVariable && - target->opcode() != spv::Op::OpFunctionParameter) { + case SpvDecorationNoPerspective: + case SpvDecorationFlat: + case SpvDecorationPatch: + case SpvDecorationCentroid: + case SpvDecorationSample: + case SpvDecorationRestrict: + case SpvDecorationAliased: + case SpvDecorationVolatile: + case SpvDecorationCoherent: + case SpvDecorationNonWritable: + case SpvDecorationNonReadable: + case SpvDecorationXfbBuffer: + case SpvDecorationXfbStride: + case SpvDecorationComponent: + case SpvDecorationStream: + case SpvDecorationRestrictPointer: + case SpvDecorationAliasedPointer: + if (target->opcode() != SpvOpVariable && + target->opcode() != SpvOpFunctionParameter) { return fail(0) << "must be a memory object declaration"; } - if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) { + if (_.GetIdOpcode(target->type_id()) != SpvOpTypePointer) { return fail(0) << "must be a pointer type"; } break; - case spv::Decoration::Invariant: - case spv::Decoration::Constant: - case spv::Decoration::Location: - case spv::Decoration::Index: - case spv::Decoration::Binding: - case spv::Decoration::DescriptorSet: - case spv::Decoration::InputAttachmentIndex: - if (target->opcode() != spv::Op::OpVariable) { + case SpvDecorationInvariant: + case SpvDecorationConstant: + case SpvDecorationLocation: + case SpvDecorationIndex: + case SpvDecorationBinding: + case SpvDecorationDescriptorSet: + case SpvDecorationInputAttachmentIndex: + if (target->opcode() != SpvOpVariable) { return fail(0) << "must be a variable"; } break; @@ -185,60 +185,57 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, if (spvIsVulkanEnv(_.context()->target_env)) { // The following were all checked as pointer types above. - spv::StorageClass sc = spv::StorageClass::Uniform; + SpvStorageClass sc = SpvStorageClassUniform; const auto type = _.FindDef(target->type_id()); if (type && type->operands().size() > 2) { - sc = type->GetOperandAs(1); + sc = type->GetOperandAs(1); } switch (dec) { - case spv::Decoration::Location: - case spv::Decoration::Component: - // Location is used for input, output, tile image, and ray tracing - // stages. - if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output && - sc != spv::StorageClass::RayPayloadKHR && - sc != spv::StorageClass::IncomingRayPayloadKHR && - sc != spv::StorageClass::HitAttributeKHR && - sc != spv::StorageClass::CallableDataKHR && - sc != spv::StorageClass::IncomingCallableDataKHR && - sc != spv::StorageClass::ShaderRecordBufferKHR && - sc != spv::StorageClass::HitObjectAttributeNV && - sc != spv::StorageClass::TileImageEXT) { + case SpvDecorationLocation: + case SpvDecorationComponent: + // Location is used for input, output and ray tracing stages. + if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput && + sc != SpvStorageClassRayPayloadKHR && + sc != SpvStorageClassIncomingRayPayloadKHR && + sc != SpvStorageClassHitAttributeKHR && + sc != SpvStorageClassCallableDataKHR && + sc != SpvStorageClassIncomingCallableDataKHR && + sc != SpvStorageClassShaderRecordBufferKHR) { return _.diag(SPV_ERROR_INVALID_ID, target) << _.VkErrorID(6672) << _.SpvDecorationString(dec) << " decoration must not be applied to this storage class"; } break; - case spv::Decoration::Index: + case SpvDecorationIndex: // Langauge from SPIR-V definition of Index - if (sc != spv::StorageClass::Output) { + if (sc != SpvStorageClassOutput) { return fail(0) << "must be in the Output storage class"; } break; - case spv::Decoration::Binding: - case spv::Decoration::DescriptorSet: - if (sc != spv::StorageClass::StorageBuffer && - sc != spv::StorageClass::Uniform && - sc != spv::StorageClass::UniformConstant) { + case SpvDecorationBinding: + case SpvDecorationDescriptorSet: + if (sc != SpvStorageClassStorageBuffer && + sc != SpvStorageClassUniform && + sc != SpvStorageClassUniformConstant) { return fail(6491) << "must be in the StorageBuffer, Uniform, or " "UniformConstant storage class"; } break; - case spv::Decoration::InputAttachmentIndex: - if (sc != spv::StorageClass::UniformConstant) { + case SpvDecorationInputAttachmentIndex: + if (sc != SpvStorageClassUniformConstant) { return fail(6678) << "must be in the UniformConstant storage class"; } break; - case spv::Decoration::Flat: - case spv::Decoration::NoPerspective: - case spv::Decoration::Centroid: - case spv::Decoration::Sample: - if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output) { + case SpvDecorationFlat: + case SpvDecorationNoPerspective: + case SpvDecorationCentroid: + case SpvDecorationSample: + if (sc != SpvStorageClassInput && sc != SpvStorageClassOutput) { return fail(4670) << "storage class must be Input or Output"; } break; - case spv::Decoration::PerVertexKHR: - if (sc != spv::StorageClass::Input) { + case SpvDecorationPerVertexKHR: + if (sc != SpvStorageClassInput) { return fail(6777) << "storage class must be Input"; } break; @@ -250,7 +247,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, } spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { - const auto decoration = inst->GetOperandAs(1); + const auto decoration = inst->GetOperandAs(1); const auto target_id = inst->GetOperandAs(0); const auto target = _.FindDef(target_id); if (!target) { @@ -258,8 +255,8 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((decoration == spv::Decoration::GLSLShared) || - (decoration == spv::Decoration::GLSLPacked)) { + if ((decoration == SpvDecorationGLSLShared) || + (decoration == SpvDecorationGLSLPacked)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4669) << "OpDecorate decoration '" << _.SpvDecorationString(decoration) @@ -273,7 +270,7 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { "OpDecorateId"; } - if (target->opcode() != spv::Op::OpDecorationGroup) { + if (target->opcode() != SpvOpDecorationGroup) { if (IsMemberDecorationOnly(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.SpvDecorationString(decoration) @@ -290,7 +287,7 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { } spv_result_t ValidateDecorateId(ValidationState_t& _, const Instruction* inst) { - const auto decoration = inst->GetOperandAs(1); + const auto decoration = inst->GetOperandAs(1); if (!DecorationTakesIdParameters(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Decorations that don't take ID parameters may not be used with " @@ -309,7 +306,7 @@ spv_result_t ValidateMemberDecorate(ValidationState_t& _, const Instruction* inst) { const auto struct_type_id = inst->GetOperandAs(0); const auto struct_type = _.FindDef(struct_type_id); - if (!struct_type || spv::Op::OpTypeStruct != struct_type->opcode()) { + if (!struct_type || SpvOpTypeStruct != struct_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpMemberDecorate Structure type " << _.getIdName(struct_type_id) << " is not a struct type."; @@ -326,7 +323,7 @@ spv_result_t ValidateMemberDecorate(ValidationState_t& _, << " members. Largest valid index is " << member_count - 1 << "."; } - const auto decoration = inst->GetOperandAs(2); + const auto decoration = inst->GetOperandAs(2); if (IsNotMemberDecoration(decoration)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.SpvDecorationString(decoration) @@ -342,11 +339,10 @@ spv_result_t ValidateDecorationGroup(ValidationState_t& _, const auto decoration_group = _.FindDef(decoration_group_id); for (auto pair : decoration_group->uses()) { auto use = pair.first; - if (use->opcode() != spv::Op::OpDecorate && - use->opcode() != spv::Op::OpGroupDecorate && - use->opcode() != spv::Op::OpGroupMemberDecorate && - use->opcode() != spv::Op::OpName && - use->opcode() != spv::Op::OpDecorateId && !use->IsNonSemantic()) { + if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate && + use->opcode() != SpvOpGroupMemberDecorate && + use->opcode() != SpvOpName && use->opcode() != SpvOpDecorateId && + !use->IsNonSemantic()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result id of OpDecorationGroup can only " << "be targeted by OpName, OpGroupDecorate, " @@ -360,8 +356,7 @@ spv_result_t ValidateGroupDecorate(ValidationState_t& _, const Instruction* inst) { const auto decoration_group_id = inst->GetOperandAs(0); auto decoration_group = _.FindDef(decoration_group_id); - if (!decoration_group || - spv::Op::OpDecorationGroup != decoration_group->opcode()) { + if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupDecorate Decoration group " << _.getIdName(decoration_group_id) << " is not a decoration group."; @@ -369,7 +364,7 @@ spv_result_t ValidateGroupDecorate(ValidationState_t& _, for (unsigned i = 1; i < inst->operands().size(); ++i) { auto target_id = inst->GetOperandAs(i); auto target = _.FindDef(target_id); - if (!target || target->opcode() == spv::Op::OpDecorationGroup) { + if (!target || target->opcode() == SpvOpDecorationGroup) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupDecorate may not target OpDecorationGroup " << _.getIdName(target_id); @@ -382,8 +377,7 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, const Instruction* inst) { const auto decoration_group_id = inst->GetOperandAs(0); const auto decoration_group = _.FindDef(decoration_group_id); - if (!decoration_group || - spv::Op::OpDecorationGroup != decoration_group->opcode()) { + if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupMemberDecorate Decoration group " << _.getIdName(decoration_group_id) << " is not a decoration group."; @@ -394,7 +388,7 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, const uint32_t struct_id = inst->GetOperandAs(i); const uint32_t index = inst->GetOperandAs(i + 1); auto struct_instr = _.FindDef(struct_id); - if (!struct_instr || spv::Op::OpTypeStruct != struct_instr->opcode()) { + if (!struct_instr || SpvOpTypeStruct != struct_instr->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpGroupMemberDecorate Structure type " << _.getIdName(struct_id) << " is not a struct type."; @@ -419,11 +413,10 @@ spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, spv_result_t RegisterDecorations(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: { + case SpvOpDecorate: + case SpvOpDecorateId: { const uint32_t target_id = inst->word(1); - const spv::Decoration dec_type = - static_cast(inst->word(2)); + const SpvDecoration dec_type = static_cast(inst->word(2)); std::vector dec_params; if (inst->words().size() > 3) { dec_params.insert(dec_params.end(), inst->words().begin() + 3, @@ -432,11 +425,10 @@ spv_result_t RegisterDecorations(ValidationState_t& _, _.RegisterDecorationForId(target_id, Decoration(dec_type, dec_params)); break; } - case spv::Op::OpMemberDecorate: { + case SpvOpMemberDecorate: { const uint32_t struct_id = inst->word(1); const uint32_t index = inst->word(2); - const spv::Decoration dec_type = - static_cast(inst->word(3)); + const SpvDecoration dec_type = static_cast(inst->word(3)); std::vector dec_params; if (inst->words().size() > 4) { dec_params.insert(dec_params.end(), inst->words().begin() + 4, @@ -446,12 +438,12 @@ spv_result_t RegisterDecorations(ValidationState_t& _, Decoration(dec_type, dec_params, index)); break; } - case spv::Op::OpDecorationGroup: { + case SpvOpDecorationGroup: { // We don't need to do anything right now. Assigning decorations to groups // will be taken care of via OpGroupDecorate. break; } - case spv::Op::OpGroupDecorate: { + case SpvOpGroupDecorate: { // Word 1 is the group . All subsequent words are target s that // are going to be decorated with the decorations. const uint32_t decoration_group_id = inst->word(1); @@ -464,7 +456,7 @@ spv_result_t RegisterDecorations(ValidationState_t& _, } break; } - case spv::Op::OpGroupMemberDecorate: { + case SpvOpGroupMemberDecorate: { // Word 1 is the Decoration Group followed by (struct,literal) // pairs. All decorations of the group should be applied to all the struct // members that are specified in the instructions. @@ -494,24 +486,24 @@ spv_result_t RegisterDecorations(ValidationState_t& _, spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpDecorate: + case SpvOpDecorate: if (auto error = ValidateDecorate(_, inst)) return error; break; - case spv::Op::OpDecorateId: + case SpvOpDecorateId: if (auto error = ValidateDecorateId(_, inst)) return error; break; - // TODO(dneto): spv::Op::OpDecorateStringGOOGLE + // TODO(dneto): SpvOpDecorateStringGOOGLE // See https://github.com/KhronosGroup/SPIRV-Tools/issues/2253 - case spv::Op::OpMemberDecorate: + case SpvOpMemberDecorate: if (auto error = ValidateMemberDecorate(_, inst)) return error; break; - case spv::Op::OpDecorationGroup: + case SpvOpDecorationGroup: if (auto error = ValidateDecorationGroup(_, inst)) return error; break; - case spv::Op::OpGroupDecorate: + case SpvOpGroupDecorate: if (auto error = ValidateGroupDecorate(_, inst)) return error; break; - case spv::Op::OpGroupMemberDecorate: + case SpvOpGroupMemberDecorate: if (auto error = ValidateGroupMemberDecorate(_, inst)) return error; break; default: diff --git a/source/val/validate_arithmetics.cpp b/source/val/validate_arithmetics.cpp index b608a859..bae9b5dc 100644 --- a/source/val/validate_arithmetics.cpp +++ b/source/val/validate_arithmetics.cpp @@ -14,11 +14,13 @@ // Performs validation of arithmetic instructions. +#include "source/val/validate.h" + #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -26,45 +28,29 @@ namespace val { // Validates correctness of arithmetic instructions. spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpFAdd: - case spv::Op::OpFSub: - case spv::Op::OpFMul: - case spv::Op::OpFDiv: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpFNegate: { + case SpvOpFAdd: + case SpvOpFSub: + case SpvOpFMul: + case SpvOpFDiv: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpFNegate: { bool supportsCoopMat = - (opcode != spv::Op::OpFMul && opcode != spv::Op::OpFRem && - opcode != spv::Op::OpFMod); + (opcode != SpvOpFMul && opcode != SpvOpFRem && opcode != SpvOpFMod); if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && - !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)) && - !(opcode == spv::Op::OpFMul && - _.IsCooperativeMatrixKHRType(result_type) && - _.IsFloatCooperativeMatrixType(result_type))) + !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type))) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected floating scalar or vector type as Result Type: " << spvOpcodeString(opcode); for (size_t operand_index = 2; operand_index < inst->operands().size(); ++operand_index) { - if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { - const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); - if (!_.IsCooperativeMatrixKHRType(type_id) || - !_.IsFloatCooperativeMatrixType(type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected arithmetic operands to be of Result Type: " - << spvOpcodeString(opcode) << " operand index " - << operand_index; - } - spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); - if (ret != SPV_SUCCESS) return ret; - } else if (_.GetOperandTypeId(inst, operand_index) != result_type) + if (_.GetOperandTypeId(inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected arithmetic operands to be of Result Type: " << spvOpcodeString(opcode) << " operand index " @@ -73,9 +59,9 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpUDiv: - case spv::Op::OpUMod: { - bool supportsCoopMat = (opcode == spv::Op::OpUDiv); + case SpvOpUDiv: + case SpvOpUMod: { + bool supportsCoopMat = (opcode == SpvOpUDiv); if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !(supportsCoopMat && @@ -86,19 +72,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { for (size_t operand_index = 2; operand_index < inst->operands().size(); ++operand_index) { - if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { - const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); - if (!_.IsCooperativeMatrixKHRType(type_id) || - !_.IsUnsignedIntCooperativeMatrixType(type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected arithmetic operands to be of Result Type: " - << spvOpcodeString(opcode) << " operand index " - << operand_index; - } - spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); - if (ret != SPV_SUCCESS) return ret; - } else if (_.GetOperandTypeId(inst, operand_index) != result_type) + if (_.GetOperandTypeId(inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected arithmetic operands to be of Result Type: " << spvOpcodeString(opcode) << " operand index " @@ -107,21 +81,17 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpISub: - case spv::Op::OpIAdd: - case spv::Op::OpIMul: - case spv::Op::OpSDiv: - case spv::Op::OpSMod: - case spv::Op::OpSRem: - case spv::Op::OpSNegate: { + case SpvOpISub: + case SpvOpIAdd: + case SpvOpIMul: + case SpvOpSDiv: + case SpvOpSMod: + case SpvOpSRem: + case SpvOpSNegate: { bool supportsCoopMat = - (opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem && - opcode != spv::Op::OpSMod); + (opcode != SpvOpIMul && opcode != SpvOpSRem && opcode != SpvOpSMod); if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && - !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) && - !(opcode == spv::Op::OpIMul && - _.IsCooperativeMatrixKHRType(result_type) && - _.IsIntCooperativeMatrixType(result_type))) + !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type))) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " << spvOpcodeString(opcode); @@ -132,26 +102,9 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { for (size_t operand_index = 2; operand_index < inst->operands().size(); ++operand_index) { const uint32_t type_id = _.GetOperandTypeId(inst, operand_index); - - if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) { - if (!_.IsCooperativeMatrixKHRType(type_id) || - !_.IsIntCooperativeMatrixType(type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected arithmetic operands to be of Result Type: " - << spvOpcodeString(opcode) << " operand index " - << operand_index; - } - spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, type_id, result_type); - if (ret != SPV_SUCCESS) return ret; - } - if (!type_id || (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) && - !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) && - !(opcode == spv::Op::OpIMul && - _.IsCooperativeMatrixKHRType(result_type) && - _.IsIntCooperativeMatrixType(result_type)))) + !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)))) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as operand: " << spvOpcodeString(opcode) << " operand index " @@ -172,7 +125,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpDot: { + case SpvOpDot: { if (!_.IsFloatScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected float scalar type as Result Type: " @@ -209,7 +162,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpVectorTimesScalar: { + case SpvOpVectorTimesScalar: { if (!_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected float vector type as Result Type: " @@ -232,9 +185,9 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpMatrixTimesScalar: { + case SpvOpMatrixTimesScalar: { if (!_.IsFloatMatrixType(result_type) && - !(_.IsCooperativeMatrixType(result_type))) + !_.IsCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected float matrix type as Result Type: " << spvOpcodeString(opcode); @@ -256,7 +209,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpVectorTimesMatrix: { + case SpvOpVectorTimesMatrix: { const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2); const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 3); @@ -306,7 +259,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpMatrixTimesVector: { + case SpvOpMatrixTimesVector: { const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2); const uint32_t vector_type_id = _.GetOperandTypeId(inst, 3); @@ -350,7 +303,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpMatrixTimesMatrix: { + case SpvOpMatrixTimesMatrix: { const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); @@ -416,7 +369,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpOuterProduct: { + case SpvOpOuterProduct: { const uint32_t left_type_id = _.GetOperandTypeId(inst, 2); const uint32_t right_type_id = _.GetOperandTypeId(inst, 3); @@ -454,10 +407,10 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpIAddCarry: - case spv::Op::OpISubBorrow: - case spv::Op::OpUMulExtended: - case spv::Op::OpSMulExtended: { + case SpvOpIAddCarry: + case SpvOpISubBorrow: + case SpvOpUMulExtended: + case SpvOpSMulExtended: { std::vector result_types; if (!_.GetStructMemberTypes(result_type, &result_types)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -469,7 +422,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type struct to have two members: " << spvOpcodeString(opcode); - if (opcode == spv::Op::OpSMulExtended) { + if (opcode == SpvOpSMulExtended) { if (!_.IsIntScalarType(result_types[0]) && !_.IsIntVectorType(result_types[0])) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -500,114 +453,28 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpCooperativeMatrixMulAddNV: { + case SpvOpCooperativeMatrixMulAddNV: { const uint32_t D_type_id = _.GetOperandTypeId(inst, 1); const uint32_t A_type_id = _.GetOperandTypeId(inst, 2); const uint32_t B_type_id = _.GetOperandTypeId(inst, 3); const uint32_t C_type_id = _.GetOperandTypeId(inst, 4); - if (!_.IsCooperativeMatrixNVType(A_type_id)) { + if (!_.IsCooperativeMatrixType(A_type_id)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix type as A Type: " << spvOpcodeString(opcode); } - if (!_.IsCooperativeMatrixNVType(B_type_id)) { + if (!_.IsCooperativeMatrixType(B_type_id)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix type as B Type: " << spvOpcodeString(opcode); } - if (!_.IsCooperativeMatrixNVType(C_type_id)) { + if (!_.IsCooperativeMatrixType(C_type_id)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix type as C Type: " << spvOpcodeString(opcode); } - if (!_.IsCooperativeMatrixNVType(D_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected cooperative matrix type as Result Type: " - << spvOpcodeString(opcode); - } - - const auto A = _.FindDef(A_type_id); - const auto B = _.FindDef(B_type_id); - const auto C = _.FindDef(C_type_id); - const auto D = _.FindDef(D_type_id); - - std::tuple A_scope, B_scope, C_scope, D_scope, - A_rows, B_rows, C_rows, D_rows, A_cols, B_cols, C_cols, D_cols; - - A_scope = _.EvalInt32IfConst(A->GetOperandAs(2)); - B_scope = _.EvalInt32IfConst(B->GetOperandAs(2)); - C_scope = _.EvalInt32IfConst(C->GetOperandAs(2)); - D_scope = _.EvalInt32IfConst(D->GetOperandAs(2)); - - A_rows = _.EvalInt32IfConst(A->GetOperandAs(3)); - B_rows = _.EvalInt32IfConst(B->GetOperandAs(3)); - C_rows = _.EvalInt32IfConst(C->GetOperandAs(3)); - D_rows = _.EvalInt32IfConst(D->GetOperandAs(3)); - - A_cols = _.EvalInt32IfConst(A->GetOperandAs(4)); - B_cols = _.EvalInt32IfConst(B->GetOperandAs(4)); - C_cols = _.EvalInt32IfConst(C->GetOperandAs(4)); - D_cols = _.EvalInt32IfConst(D->GetOperandAs(4)); - - const auto notEqual = [](std::tuple X, - std::tuple Y) { - return (std::get<1>(X) && std::get<1>(Y) && - std::get<2>(X) != std::get<2>(Y)); - }; - - if (notEqual(A_scope, B_scope) || notEqual(A_scope, C_scope) || - notEqual(A_scope, D_scope) || notEqual(B_scope, C_scope) || - notEqual(B_scope, D_scope) || notEqual(C_scope, D_scope)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix scopes must match: " - << spvOpcodeString(opcode); - } - - if (notEqual(A_rows, C_rows) || notEqual(A_rows, D_rows) || - notEqual(C_rows, D_rows)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix 'M' mismatch: " - << spvOpcodeString(opcode); - } - - if (notEqual(B_cols, C_cols) || notEqual(B_cols, D_cols) || - notEqual(C_cols, D_cols)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix 'N' mismatch: " - << spvOpcodeString(opcode); - } - - if (notEqual(A_cols, B_rows)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix 'K' mismatch: " - << spvOpcodeString(opcode); - } - break; - } - - case spv::Op::OpCooperativeMatrixMulAddKHR: { - const uint32_t D_type_id = _.GetOperandTypeId(inst, 1); - const uint32_t A_type_id = _.GetOperandTypeId(inst, 2); - const uint32_t B_type_id = _.GetOperandTypeId(inst, 3); - const uint32_t C_type_id = _.GetOperandTypeId(inst, 4); - - if (!_.IsCooperativeMatrixAType(A_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix type must be A Type: " - << spvOpcodeString(opcode); - } - if (!_.IsCooperativeMatrixBType(B_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix type must be B Type: " - << spvOpcodeString(opcode); - } - if (!_.IsCooperativeMatrixAccType(C_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix type must be Accumulator Type: " - << spvOpcodeString(opcode); - } - if (!_.IsCooperativeMatrixKHRType(D_type_id)) { + if (!_.IsCooperativeMatrixType(D_type_id)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix type as Result Type: " << spvOpcodeString(opcode); diff --git a/source/val/validate_atomics.cpp b/source/val/validate_atomics.cpp index b745a9ec..bf565c31 100644 --- a/source/val/validate_atomics.cpp +++ b/source/val/validate_atomics.cpp @@ -16,29 +16,31 @@ // Validates correctness of atomic SPIR-V instructions. +#include "source/val/validate.h" + +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/util/bitutils.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validate_memory_semantics.h" #include "source/val/validate_scopes.h" #include "source/val/validation_state.h" namespace { -bool IsStorageClassAllowedByUniversalRules(spv::StorageClass storage_class) { +bool IsStorageClassAllowedByUniversalRules(uint32_t storage_class) { switch (storage_class) { - case spv::StorageClass::Uniform: - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::Workgroup: - case spv::StorageClass::CrossWorkgroup: - case spv::StorageClass::Generic: - case spv::StorageClass::AtomicCounter: - case spv::StorageClass::Image: - case spv::StorageClass::Function: - case spv::StorageClass::PhysicalStorageBuffer: - case spv::StorageClass::TaskPayloadWorkgroupEXT: + case SpvStorageClassUniform: + case SpvStorageClassStorageBuffer: + case SpvStorageClassWorkgroup: + case SpvStorageClassCrossWorkgroup: + case SpvStorageClassGeneric: + case SpvStorageClassAtomicCounter: + case SpvStorageClassImage: + case SpvStorageClassFunction: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassTaskPayloadWorkgroupEXT: return true; break; default: @@ -46,10 +48,10 @@ bool IsStorageClassAllowedByUniversalRules(spv::StorageClass storage_class) { } } -bool HasReturnType(spv::Op opcode) { +bool HasReturnType(uint32_t opcode) { switch (opcode) { - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicFlagClear: + case SpvOpAtomicStore: + case SpvOpAtomicFlagClear: return false; break; default: @@ -57,11 +59,11 @@ bool HasReturnType(spv::Op opcode) { } } -bool HasOnlyFloatReturnType(spv::Op opcode) { +bool HasOnlyFloatReturnType(uint32_t opcode) { switch (opcode) { - case spv::Op::OpAtomicFAddEXT: - case spv::Op::OpAtomicFMinEXT: - case spv::Op::OpAtomicFMaxEXT: + case SpvOpAtomicFAddEXT: + case SpvOpAtomicFMinEXT: + case SpvOpAtomicFMaxEXT: return true; break; default: @@ -69,21 +71,21 @@ bool HasOnlyFloatReturnType(spv::Op opcode) { } } -bool HasOnlyIntReturnType(spv::Op opcode) { +bool HasOnlyIntReturnType(uint32_t opcode) { switch (opcode) { - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: return true; break; default: @@ -91,10 +93,10 @@ bool HasOnlyIntReturnType(spv::Op opcode) { } } -bool HasIntOrFloatReturnType(spv::Op opcode) { +bool HasIntOrFloatReturnType(uint32_t opcode) { switch (opcode) { - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicExchange: + case SpvOpAtomicLoad: + case SpvOpAtomicExchange: return true; break; default: @@ -102,9 +104,9 @@ bool HasIntOrFloatReturnType(spv::Op opcode) { } } -bool HasOnlyBoolReturnType(spv::Op opcode) { +bool HasOnlyBoolReturnType(uint32_t opcode) { switch (opcode) { - case spv::Op::OpAtomicFlagTestAndSet: + case SpvOpAtomicFlagTestAndSet: return true; break; default: @@ -119,29 +121,29 @@ namespace val { // Validates correctness of atomic instructions. spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); switch (opcode) { - case spv::Op::OpAtomicLoad: - case spv::Op::OpAtomicStore: - case spv::Op::OpAtomicExchange: - case spv::Op::OpAtomicFAddEXT: - case spv::Op::OpAtomicCompareExchange: - case spv::Op::OpAtomicCompareExchangeWeak: - case spv::Op::OpAtomicIIncrement: - case spv::Op::OpAtomicIDecrement: - case spv::Op::OpAtomicIAdd: - case spv::Op::OpAtomicISub: - case spv::Op::OpAtomicSMin: - case spv::Op::OpAtomicUMin: - case spv::Op::OpAtomicFMinEXT: - case spv::Op::OpAtomicSMax: - case spv::Op::OpAtomicUMax: - case spv::Op::OpAtomicFMaxEXT: - case spv::Op::OpAtomicAnd: - case spv::Op::OpAtomicOr: - case spv::Op::OpAtomicXor: - case spv::Op::OpAtomicFlagTestAndSet: - case spv::Op::OpAtomicFlagClear: { + case SpvOpAtomicLoad: + case SpvOpAtomicStore: + case SpvOpAtomicExchange: + case SpvOpAtomicFAddEXT: + case SpvOpAtomicCompareExchange: + case SpvOpAtomicCompareExchangeWeak: + case SpvOpAtomicIIncrement: + case SpvOpAtomicIDecrement: + case SpvOpAtomicIAdd: + case SpvOpAtomicISub: + case SpvOpAtomicSMin: + case SpvOpAtomicUMin: + case SpvOpAtomicFMinEXT: + case SpvOpAtomicSMax: + case SpvOpAtomicUMax: + case SpvOpAtomicFMaxEXT: + case SpvOpAtomicAnd: + case SpvOpAtomicOr: + case SpvOpAtomicXor: + case SpvOpAtomicFlagTestAndSet: + case SpvOpAtomicFlagClear: { const uint32_t result_type = inst->type_id(); // All current atomics only are scalar result @@ -175,7 +177,7 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { uint32_t operand_index = HasReturnType(opcode) ? 2 : 0; const uint32_t pointer_type = _.GetOperandTypeId(inst, operand_index++); uint32_t data_type = 0; - spv::StorageClass storage_class; + uint32_t storage_class = 0; if (!_.GetPointerTypeInfo(pointer_type, &data_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) @@ -183,8 +185,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // Can't use result_type because OpAtomicStore doesn't have a result - if (_.IsIntScalarType(data_type) && _.GetBitWidth(data_type) == 64 && - !_.HasCapability(spv::Capability::Int64Atomics)) { + if ( _.IsIntScalarType(data_type) &&_.GetBitWidth(data_type) == 64 && + !_.HasCapability(SpvCapabilityInt64Atomics)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": 64-bit atomics require the Int64Atomics capability"; @@ -198,69 +200,69 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // Then Shader rules - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { // Vulkan environment rule if (spvIsVulkanEnv(_.context()->target_env)) { - if ((storage_class != spv::StorageClass::Uniform) && - (storage_class != spv::StorageClass::StorageBuffer) && - (storage_class != spv::StorageClass::Workgroup) && - (storage_class != spv::StorageClass::Image) && - (storage_class != spv::StorageClass::PhysicalStorageBuffer) && - (storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT)) { + if ((storage_class != SpvStorageClassUniform) && + (storage_class != SpvStorageClassStorageBuffer) && + (storage_class != SpvStorageClassWorkgroup) && + (storage_class != SpvStorageClassImage) && + (storage_class != SpvStorageClassPhysicalStorageBuffer) && + (storage_class != SpvStorageClassTaskPayloadWorkgroupEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4686) << spvOpcodeString(opcode) << ": Vulkan spec only allows storage classes for atomic to " "be: Uniform, Workgroup, Image, StorageBuffer, " "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT."; } - } else if (storage_class == spv::StorageClass::Function) { + } else if (storage_class == SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Function storage class forbidden when the Shader " "capability is declared."; } - if (opcode == spv::Op::OpAtomicFAddEXT) { + if (opcode == SpvOpAtomicFAddEXT) { // result type being float checked already if ((_.GetBitWidth(result_type) == 16) && - (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat16AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat32AddEXT " "capability"; } if ((_.GetBitWidth(result_type) == 32) && - (!_.HasCapability(spv::Capability::AtomicFloat32AddEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat32AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat32AddEXT " "capability"; } if ((_.GetBitWidth(result_type) == 64) && - (!_.HasCapability(spv::Capability::AtomicFloat64AddEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat64AddEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float add atomics require the AtomicFloat64AddEXT " "capability"; } - } else if (opcode == spv::Op::OpAtomicFMinEXT || - opcode == spv::Op::OpAtomicFMaxEXT) { + } else if (opcode == SpvOpAtomicFMinEXT || + opcode == SpvOpAtomicFMaxEXT) { if ((_.GetBitWidth(result_type) == 16) && - (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat16MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " "AtomicFloat16MinMaxEXT capability"; } if ((_.GetBitWidth(result_type) == 32) && - (!_.HasCapability(spv::Capability::AtomicFloat32MinMaxEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat32MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " "AtomicFloat32MinMaxEXT capability"; } if ((_.GetBitWidth(result_type) == 64) && - (!_.HasCapability(spv::Capability::AtomicFloat64MinMaxEXT))) { + (!_.HasCapability(SpvCapabilityAtomicFloat64MinMaxEXT))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": float min/max atomics require the " @@ -271,10 +273,10 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { // And finally OpenCL environment rules if (spvIsOpenCLEnv(_.context()->target_env)) { - if ((storage_class != spv::StorageClass::Function) && - (storage_class != spv::StorageClass::Workgroup) && - (storage_class != spv::StorageClass::CrossWorkgroup) && - (storage_class != spv::StorageClass::Generic)) { + if ((storage_class != SpvStorageClassFunction) && + (storage_class != SpvStorageClassWorkgroup) && + (storage_class != SpvStorageClassCrossWorkgroup) && + (storage_class != SpvStorageClassGeneric)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": storage class must be Function, Workgroup, " @@ -282,7 +284,7 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } if (_.context()->target_env == SPV_ENV_OPENCL_1_2) { - if (storage_class == spv::StorageClass::Generic) { + if (storage_class == SpvStorageClassGeneric) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Storage class cannot be Generic in OpenCL 1.2 " "environment"; @@ -291,15 +293,15 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } // If result and pointer type are different, need to do special check here - if (opcode == spv::Op::OpAtomicFlagTestAndSet || - opcode == spv::Op::OpAtomicFlagClear) { + if (opcode == SpvOpAtomicFlagTestAndSet || + opcode == SpvOpAtomicFlagClear) { if (!_.IsIntScalarType(data_type) || _.GetBitWidth(data_type) != 32) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Pointer to point to a value of 32-bit integer " "type"; } - } else if (opcode == spv::Op::OpAtomicStore) { + } else if (opcode == SpvOpAtomicStore) { if (!_.IsFloatScalarType(data_type) && !_.IsIntScalarType(data_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) @@ -323,8 +325,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { memory_scope)) return error; - if (opcode == spv::Op::OpAtomicCompareExchange || - opcode == spv::Op::OpAtomicCompareExchangeWeak) { + if (opcode == SpvOpAtomicCompareExchange || + opcode == SpvOpAtomicCompareExchangeWeak) { const auto unequal_semantics_index = operand_index++; if (auto error = ValidateMemorySemantics( _, inst, unequal_semantics_index, memory_scope)) @@ -344,15 +346,15 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { _.EvalInt32IfConst( inst->GetOperandAs(unequal_semantics_index)); if (is_equal_const && is_unequal_const && - ((equal_value & uint32_t(spv::MemorySemanticsMask::Volatile)) ^ - (unequal_value & uint32_t(spv::MemorySemanticsMask::Volatile)))) { + ((equal_value & SpvMemorySemanticsVolatileMask) ^ + (unequal_value & SpvMemorySemanticsVolatileMask))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Volatile mask setting must match for Equal and Unequal " "memory semantics"; } } - if (opcode == spv::Op::OpAtomicStore) { + if (opcode == SpvOpAtomicStore) { const uint32_t value_type = _.GetOperandTypeId(inst, 3); if (value_type != data_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -360,11 +362,10 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { << ": expected Value type and the type pointed to by " "Pointer to be the same"; } - } else if (opcode != spv::Op::OpAtomicLoad && - opcode != spv::Op::OpAtomicIIncrement && - opcode != spv::Op::OpAtomicIDecrement && - opcode != spv::Op::OpAtomicFlagTestAndSet && - opcode != spv::Op::OpAtomicFlagClear) { + } else if (opcode != SpvOpAtomicLoad && opcode != SpvOpAtomicIIncrement && + opcode != SpvOpAtomicIDecrement && + opcode != SpvOpAtomicFlagTestAndSet && + opcode != SpvOpAtomicFlagClear) { const uint32_t value_type = _.GetOperandTypeId(inst, operand_index++); if (value_type != result_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -373,8 +374,8 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) { } } - if (opcode == spv::Op::OpAtomicCompareExchange || - opcode == spv::Op::OpAtomicCompareExchangeWeak) { + if (opcode == SpvOpAtomicCompareExchange || + opcode == SpvOpAtomicCompareExchangeWeak) { const uint32_t comparator_type = _.GetOperandTypeId(inst, operand_index++); if (comparator_type != result_type) { diff --git a/source/val/validate_barriers.cpp b/source/val/validate_barriers.cpp index 0abd5c85..03225d86 100644 --- a/source/val/validate_barriers.cpp +++ b/source/val/validate_barriers.cpp @@ -16,8 +16,11 @@ #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_constant.h" +#include "source/spirv_target_env.h" +#include "source/util/bitutils.h" #include "source/val/instruction.h" #include "source/val/validate.h" #include "source/val/validate_memory_semantics.h" @@ -29,20 +32,20 @@ namespace val { // Validates correctness of barrier instructions. spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpControlBarrier: { + case SpvOpControlBarrier: { if (_.version() < SPV_SPIRV_VERSION_WORD(1, 3)) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::TessellationControl && - model != spv::ExecutionModel::GLCompute && - model != spv::ExecutionModel::Kernel && - model != spv::ExecutionModel::TaskNV && - model != spv::ExecutionModel::MeshNV) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelTessellationControl && + model != SpvExecutionModelGLCompute && + model != SpvExecutionModelKernel && + model != SpvExecutionModelTaskNV && + model != SpvExecutionModelMeshNV) { if (message) { *message = "OpControlBarrier requires one of the following " @@ -73,7 +76,7 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpMemoryBarrier: { + case SpvOpMemoryBarrier: { const uint32_t memory_scope = inst->word(1); if (auto error = ValidateMemoryScope(_, inst, memory_scope)) { @@ -86,8 +89,8 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpNamedBarrierInitialize: { - if (_.GetIdOpcode(result_type) != spv::Op::OpTypeNamedBarrier) { + case SpvOpNamedBarrierInitialize: { + if (_.GetIdOpcode(result_type) != SpvOpTypeNamedBarrier) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Result Type to be OpTypeNamedBarrier"; @@ -103,9 +106,9 @@ spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpMemoryNamedBarrier: { + case SpvOpMemoryNamedBarrier: { const uint32_t named_barrier_type = _.GetOperandTypeId(inst, 0); - if (_.GetIdOpcode(named_barrier_type) != spv::Op::OpTypeNamedBarrier) { + if (_.GetIdOpcode(named_barrier_type) != SpvOpTypeNamedBarrier) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Named Barrier to be of type OpTypeNamedBarrier"; diff --git a/source/val/validate_bitwise.cpp b/source/val/validate_bitwise.cpp index d8d99581..e6e97c4a 100644 --- a/source/val/validate_bitwise.cpp +++ b/source/val/validate_bitwise.cpp @@ -14,6 +14,7 @@ // Validates correctness of bitwise instructions. +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" @@ -26,7 +27,7 @@ namespace val { // Validates when base and result need to be the same type spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, const uint32_t base_type) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -46,7 +47,7 @@ spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, } // OpBitCount just needs same number of components - if (base_type != inst->type_id() && opcode != spv::Op::OpBitCount) { + if (base_type != inst->type_id() && opcode != SpvOpBitCount) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Base Type to be equal to Result Type: " << spvOpcodeString(opcode); @@ -57,13 +58,13 @@ spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst, // Validates correctness of bitwise instructions. spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpShiftRightLogical: - case spv::Op::OpShiftRightArithmetic: - case spv::Op::OpShiftLeftLogical: { + case SpvOpShiftRightLogical: + case SpvOpShiftRightArithmetic: + case SpvOpShiftLeftLogical: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -102,10 +103,10 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpBitwiseOr: - case spv::Op::OpBitwiseXor: - case spv::Op::OpBitwiseAnd: - case spv::Op::OpNot: { + case SpvOpBitwiseOr: + case SpvOpBitwiseXor: + case SpvOpBitwiseAnd: + case SpvOpNot: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -139,7 +140,7 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpBitFieldInsert: { + case SpvOpBitFieldInsert: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); const uint32_t insert_type = _.GetOperandTypeId(inst, 3); const uint32_t offset_type = _.GetOperandTypeId(inst, 4); @@ -166,8 +167,8 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpBitFieldSExtract: - case spv::Op::OpBitFieldUExtract: { + case SpvOpBitFieldSExtract: + case SpvOpBitFieldUExtract: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); const uint32_t offset_type = _.GetOperandTypeId(inst, 3); const uint32_t count_type = _.GetOperandTypeId(inst, 4); @@ -188,7 +189,7 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpBitReverse: { + case SpvOpBitReverse: { const uint32_t base_type = _.GetOperandTypeId(inst, 2); if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { @@ -198,21 +199,20 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpBitCount: { + case SpvOpBitCount: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " << spvOpcodeString(opcode); const uint32_t base_type = _.GetOperandTypeId(inst, 2); + const uint32_t base_dimension = _.GetDimension(base_type); + const uint32_t result_dimension = _.GetDimension(result_type); if (spv_result_t error = ValidateBaseType(_, inst, base_type)) { return error; } - const uint32_t base_dimension = _.GetDimension(base_type); - const uint32_t result_dimension = _.GetDimension(result_type); - if (base_dimension != result_dimension) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Base dimension to be equal to Result Type " diff --git a/source/val/validate_builtins.cpp b/source/val/validate_builtins.cpp index 3e817125..6f4b0f9c 100644 --- a/source/val/validate_builtins.cpp +++ b/source/val/validate_builtins.cpp @@ -24,8 +24,10 @@ #include #include #include +#include #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/util/bitutils.h" @@ -60,7 +62,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, const Instruction& inst, uint32_t* underlying_type) { if (decoration.struct_member_index() != Decoration::kInvalidMember) { - if (inst.opcode() != spv::Op::OpTypeStruct) { + if (inst.opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) << "Attempted to get underlying data type via member index for " @@ -70,7 +72,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, return SPV_SUCCESS; } - if (inst.opcode() == spv::Op::OpTypeStruct) { + if (inst.opcode() == SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) << " did not find an member index to get underlying data type for " @@ -82,7 +84,7 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, return SPV_SUCCESS; } - spv::StorageClass storage_class; + uint32_t storage_class = 0; if (!_.GetPointerTypeInfo(inst.type_id(), underlying_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << GetIdDesc(inst) @@ -93,22 +95,22 @@ spv_result_t GetUnderlyingType(ValidationState_t& _, } // Returns Storage Class used by the instruction if applicable. -// Returns spv::StorageClass::Max if not. -spv::StorageClass GetStorageClass(const Instruction& inst) { +// Returns SpvStorageClassMax if not. +SpvStorageClass GetStorageClass(const Instruction& inst) { switch (inst.opcode()) { - case spv::Op::OpTypePointer: - case spv::Op::OpTypeForwardPointer: { - return spv::StorageClass(inst.word(2)); + case SpvOpTypePointer: + case SpvOpTypeForwardPointer: { + return SpvStorageClass(inst.word(2)); } - case spv::Op::OpVariable: { - return spv::StorageClass(inst.word(3)); + case SpvOpVariable: { + return SpvStorageClass(inst.word(3)); } - case spv::Op::OpGenericCastToPtrExplicit: { - return spv::StorageClass(inst.word(4)); + case SpvOpGenericCastToPtrExplicit: { + return SpvStorageClass(inst.word(4)); } default: { break; } } - return spv::StorageClass::Max; + return SpvStorageClassMax; } typedef enum VUIDError_ { @@ -121,52 +123,52 @@ typedef enum VUIDError_ { const static uint32_t NumVUIDBuiltins = 36; typedef struct { - spv::BuiltIn builtIn; + SpvBuiltIn builtIn; uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs } BuiltinVUIDMapping; std::array builtinVUIDInfo = {{ // clang-format off - {spv::BuiltIn::SubgroupEqMask, {0, 4370, 4371}}, - {spv::BuiltIn::SubgroupGeMask, {0, 4372, 4373}}, - {spv::BuiltIn::SubgroupGtMask, {0, 4374, 4375}}, - {spv::BuiltIn::SubgroupLeMask, {0, 4376, 4377}}, - {spv::BuiltIn::SubgroupLtMask, {0, 4378, 4379}}, - {spv::BuiltIn::SubgroupLocalInvocationId, {0, 4380, 4381}}, - {spv::BuiltIn::SubgroupSize, {0, 4382, 4383}}, - {spv::BuiltIn::GlobalInvocationId, {4236, 4237, 4238}}, - {spv::BuiltIn::LocalInvocationId, {4281, 4282, 4283}}, - {spv::BuiltIn::NumWorkgroups, {4296, 4297, 4298}}, - {spv::BuiltIn::NumSubgroups, {4293, 4294, 4295}}, - {spv::BuiltIn::SubgroupId, {4367, 4368, 4369}}, - {spv::BuiltIn::WorkgroupId, {4422, 4423, 4424}}, - {spv::BuiltIn::HitKindKHR, {4242, 4243, 4244}}, - {spv::BuiltIn::HitTNV, {4245, 4246, 4247}}, - {spv::BuiltIn::InstanceCustomIndexKHR, {4251, 4252, 4253}}, - {spv::BuiltIn::InstanceId, {4254, 4255, 4256}}, - {spv::BuiltIn::RayGeometryIndexKHR, {4345, 4346, 4347}}, - {spv::BuiltIn::ObjectRayDirectionKHR, {4299, 4300, 4301}}, - {spv::BuiltIn::ObjectRayOriginKHR, {4302, 4303, 4304}}, - {spv::BuiltIn::ObjectToWorldKHR, {4305, 4306, 4307}}, - {spv::BuiltIn::WorldToObjectKHR, {4434, 4435, 4436}}, - {spv::BuiltIn::IncomingRayFlagsKHR, {4248, 4249, 4250}}, - {spv::BuiltIn::RayTminKHR, {4351, 4352, 4353}}, - {spv::BuiltIn::RayTmaxKHR, {4348, 4349, 4350}}, - {spv::BuiltIn::WorldRayDirectionKHR, {4428, 4429, 4430}}, - {spv::BuiltIn::WorldRayOriginKHR, {4431, 4432, 4433}}, - {spv::BuiltIn::LaunchIdKHR, {4266, 4267, 4268}}, - {spv::BuiltIn::LaunchSizeKHR, {4269, 4270, 4271}}, - {spv::BuiltIn::FragInvocationCountEXT, {4217, 4218, 4219}}, - {spv::BuiltIn::FragSizeEXT, {4220, 4221, 4222}}, - {spv::BuiltIn::FragStencilRefEXT, {4223, 4224, 4225}}, - {spv::BuiltIn::FullyCoveredEXT, {4232, 4233, 4234}}, - {spv::BuiltIn::CullMaskKHR, {6735, 6736, 6737}}, - {spv::BuiltIn::BaryCoordKHR, {4154, 4155, 4156}}, - {spv::BuiltIn::BaryCoordNoPerspKHR, {4160, 4161, 4162}}, + {SpvBuiltInSubgroupEqMask, {0, 4370, 4371}}, + {SpvBuiltInSubgroupGeMask, {0, 4372, 4373}}, + {SpvBuiltInSubgroupGtMask, {0, 4374, 4375}}, + {SpvBuiltInSubgroupLeMask, {0, 4376, 4377}}, + {SpvBuiltInSubgroupLtMask, {0, 4378, 4379}}, + {SpvBuiltInSubgroupLocalInvocationId, {0, 4380, 4381}}, + {SpvBuiltInSubgroupSize, {0, 4382, 4383}}, + {SpvBuiltInGlobalInvocationId, {4236, 4237, 4238}}, + {SpvBuiltInLocalInvocationId, {4281, 4282, 4283}}, + {SpvBuiltInNumWorkgroups, {4296, 4297, 4298}}, + {SpvBuiltInNumSubgroups, {4293, 4294, 4295}}, + {SpvBuiltInSubgroupId, {4367, 4368, 4369}}, + {SpvBuiltInWorkgroupId, {4422, 4423, 4424}}, + {SpvBuiltInHitKindKHR, {4242, 4243, 4244}}, + {SpvBuiltInHitTNV, {4245, 4246, 4247}}, + {SpvBuiltInInstanceCustomIndexKHR, {4251, 4252, 4253}}, + {SpvBuiltInInstanceId, {4254, 4255, 4256}}, + {SpvBuiltInRayGeometryIndexKHR, {4345, 4346, 4347}}, + {SpvBuiltInObjectRayDirectionKHR, {4299, 4300, 4301}}, + {SpvBuiltInObjectRayOriginKHR, {4302, 4303, 4304}}, + {SpvBuiltInObjectToWorldKHR, {4305, 4306, 4307}}, + {SpvBuiltInWorldToObjectKHR, {4434, 4435, 4436}}, + {SpvBuiltInIncomingRayFlagsKHR, {4248, 4249, 4250}}, + {SpvBuiltInRayTminKHR, {4351, 4352, 4353}}, + {SpvBuiltInRayTmaxKHR, {4348, 4349, 4350}}, + {SpvBuiltInWorldRayDirectionKHR, {4428, 4429, 4430}}, + {SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}}, + {SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}}, + {SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}}, + {SpvBuiltInFragInvocationCountEXT, {4217, 4218, 4219}}, + {SpvBuiltInFragSizeEXT, {4220, 4221, 4222}}, + {SpvBuiltInFragStencilRefEXT, {4223, 4224, 4225}}, + {SpvBuiltInFullyCoveredEXT, {4232, 4233, 4234}}, + {SpvBuiltInCullMaskKHR, {6735, 6736, 6737}}, + {SpvBuiltInBaryCoordKHR, {4154, 4155, 4156}}, + {SpvBuiltInBaryCoordNoPerspKHR, {4160, 4161, 4162}}, // clang-format off } }; -uint32_t GetVUIDForBuiltin(spv::BuiltIn builtIn, VUIDError type) { +uint32_t GetVUIDForBuiltin(SpvBuiltIn builtIn, VUIDError type) { uint32_t vuid = 0; for (const auto& iter: builtinVUIDInfo) { if (iter.builtIn == builtIn) { @@ -178,57 +180,57 @@ uint32_t GetVUIDForBuiltin(spv::BuiltIn builtIn, VUIDError type) { return vuid; } -bool IsExecutionModelValidForRtBuiltIn(spv::BuiltIn builtin, - spv::ExecutionModel stage) { +bool IsExecutionModelValidForRtBuiltIn(SpvBuiltIn builtin, + SpvExecutionModel stage) { switch (builtin) { - case spv::BuiltIn::HitKindKHR: - case spv::BuiltIn::HitTNV: - if (stage == spv::ExecutionModel::AnyHitKHR || - stage == spv::ExecutionModel::ClosestHitKHR) { + case SpvBuiltInHitKindKHR: + case SpvBuiltInHitTNV: + if (stage == SpvExecutionModelAnyHitKHR || + stage == SpvExecutionModelClosestHitKHR) { return true; } break; - case spv::BuiltIn::InstanceCustomIndexKHR: - case spv::BuiltIn::InstanceId: - case spv::BuiltIn::RayGeometryIndexKHR: - case spv::BuiltIn::ObjectRayDirectionKHR: - case spv::BuiltIn::ObjectRayOriginKHR: - case spv::BuiltIn::ObjectToWorldKHR: - case spv::BuiltIn::WorldToObjectKHR: + case SpvBuiltInInstanceCustomIndexKHR: + case SpvBuiltInInstanceId: + case SpvBuiltInRayGeometryIndexKHR: + case SpvBuiltInObjectRayDirectionKHR: + case SpvBuiltInObjectRayOriginKHR: + case SpvBuiltInObjectToWorldKHR: + case SpvBuiltInWorldToObjectKHR: switch (stage) { - case spv::ExecutionModel::IntersectionKHR: - case spv::ExecutionModel::AnyHitKHR: - case spv::ExecutionModel::ClosestHitKHR: + case SpvExecutionModelIntersectionKHR: + case SpvExecutionModelAnyHitKHR: + case SpvExecutionModelClosestHitKHR: return true; default: return false; } break; - case spv::BuiltIn::IncomingRayFlagsKHR: - case spv::BuiltIn::RayTminKHR: - case spv::BuiltIn::RayTmaxKHR: - case spv::BuiltIn::WorldRayDirectionKHR: - case spv::BuiltIn::WorldRayOriginKHR: - case spv::BuiltIn::CullMaskKHR: + case SpvBuiltInIncomingRayFlagsKHR: + case SpvBuiltInRayTminKHR: + case SpvBuiltInRayTmaxKHR: + case SpvBuiltInWorldRayDirectionKHR: + case SpvBuiltInWorldRayOriginKHR: + case SpvBuiltInCullMaskKHR: switch (stage) { - case spv::ExecutionModel::IntersectionKHR: - case spv::ExecutionModel::AnyHitKHR: - case spv::ExecutionModel::ClosestHitKHR: - case spv::ExecutionModel::MissKHR: + case SpvExecutionModelIntersectionKHR: + case SpvExecutionModelAnyHitKHR: + case SpvExecutionModelClosestHitKHR: + case SpvExecutionModelMissKHR: return true; default: return false; } break; - case spv::BuiltIn::LaunchIdKHR: - case spv::BuiltIn::LaunchSizeKHR: + case SpvBuiltInLaunchIdKHR: + case SpvBuiltInLaunchSizeKHR: switch (stage) { - case spv::ExecutionModel::RayGenerationKHR: - case spv::ExecutionModel::IntersectionKHR: - case spv::ExecutionModel::AnyHitKHR: - case spv::ExecutionModel::ClosestHitKHR: - case spv::ExecutionModel::MissKHR: - case spv::ExecutionModel::CallableKHR: + case SpvExecutionModelRayGenerationKHR: + case SpvExecutionModelIntersectionKHR: + case SpvExecutionModelAnyHitKHR: + case SpvExecutionModelClosestHitKHR: + case SpvExecutionModelMissKHR: + case SpvExecutionModelCallableKHR: return true; default: return false; @@ -557,7 +559,7 @@ class BuiltInsValidator { // |referenced_from_inst| - instruction which references id defined by // |referenced_inst| from within a function. spv_result_t ValidateNotCalledWithExecutionModel( - int vuid, const char* comment, spv::ExecutionModel execution_model, + int vuid, const char* comment, SpvExecutionModel execution_model, const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst); @@ -640,7 +642,7 @@ class BuiltInsValidator { const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst, - spv::ExecutionModel execution_model = spv::ExecutionModel::Max) const; + SpvExecutionModel execution_model = SpvExecutionModelMax) const; // Generates strings like "ID <51> (OpTypePointer) uses storage class // UniformConstant". @@ -669,12 +671,12 @@ class BuiltInsValidator { const std::vector* entry_points_ = &no_entry_points; // Execution models with which the current function can be called. - std::set execution_models_; + std::set execution_models_; }; void BuiltInsValidator::Update(const Instruction& inst) { - const spv::Op opcode = inst.opcode(); - if (opcode == spv::Op::OpFunction) { + const SpvOp opcode = inst.opcode(); + if (opcode == SpvOpFunction) { // Entering a function. assert(function_id_ == 0); function_id_ = inst.id(); @@ -689,7 +691,7 @@ void BuiltInsValidator::Update(const Instruction& inst) { } } - if (opcode == spv::Op::OpFunctionEnd) { + if (opcode == SpvOpFunctionEnd) { // Exiting a function. assert(function_id_ != 0); function_id_ = 0; @@ -702,7 +704,7 @@ std::string BuiltInsValidator::GetDefinitionDesc( const Decoration& decoration, const Instruction& inst) const { std::ostringstream ss; if (decoration.struct_member_index() != Decoration::kInvalidMember) { - assert(inst.opcode() == spv::Op::OpTypeStruct); + assert(inst.opcode() == SpvOpTypeStruct); ss << "Member #" << decoration.struct_member_index(); ss << " of struct ID <" << inst.id() << ">"; } else { @@ -714,7 +716,7 @@ std::string BuiltInsValidator::GetDefinitionDesc( std::string BuiltInsValidator::GetReferenceDesc( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst, - spv::ExecutionModel execution_model) const { + SpvExecutionModel execution_model) const { std::ostringstream ss; ss << GetIdDesc(referenced_from_inst) << " is referencing " << GetIdDesc(referenced_inst); @@ -727,10 +729,10 @@ std::string BuiltInsValidator::GetReferenceDesc( decoration.params()[0]); if (function_id_) { ss << " in function <" << function_id_ << ">"; - if (execution_model != spv::ExecutionModel::Max) { + if (execution_model != SpvExecutionModelMax) { ss << " called with execution model "; ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_EXECUTION_MODEL, - uint32_t(execution_model)); + execution_model); } } ss << "."; @@ -742,7 +744,7 @@ std::string BuiltInsValidator::GetStorageClassDesc( std::ostringstream ss; ss << GetIdDesc(inst) << " uses storage class "; ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_STORAGE_CLASS, - uint32_t(GetStorageClass(inst))); + GetStorageClass(inst)); ss << "."; return ss.str(); } @@ -801,7 +803,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedI32( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -837,7 +839,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -920,7 +922,7 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Vec( } // Strip the array, if present. - if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { underlying_type = _.FindDef(underlying_type)->word(2u); } @@ -981,7 +983,7 @@ spv_result_t BuiltInsValidator::ValidateI32Arr( } const Instruction* const type_inst = _.FindDef(underlying_type); - if (type_inst->opcode() != spv::Op::OpTypeArray) { + if (type_inst->opcode() != SpvOpTypeArray) { return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); } @@ -1027,9 +1029,9 @@ spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Arr( } // Strip an extra layer of arraying if present. - if (_.GetIdOpcode(underlying_type) == spv::Op::OpTypeArray) { + if (_.GetIdOpcode(underlying_type) == SpvOpTypeArray) { uint32_t subtype = _.FindDef(underlying_type)->word(2u); - if (_.GetIdOpcode(subtype) == spv::Op::OpTypeArray) { + if (_.GetIdOpcode(subtype) == SpvOpTypeArray) { underlying_type = subtype; } } @@ -1044,7 +1046,7 @@ spv_result_t BuiltInsValidator::ValidateF32ArrHelper( const std::function& diag, uint32_t underlying_type) { const Instruction* const type_inst = _.FindDef(underlying_type); - if (type_inst->opcode() != spv::Op::OpTypeArray) { + if (type_inst->opcode() != SpvOpTypeArray) { return diag(GetDefinitionDesc(decoration, inst) + " is not an array."); } @@ -1105,14 +1107,14 @@ spv_result_t BuiltInsValidator::ValidateF32Mat( } spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel( - int vuid, const char* comment, spv::ExecutionModel execution_model, + int vuid, const char* comment, SpvExecutionModel execution_model, const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (function_id_) { if (execution_models_.count(execution_model)) { const char* execution_model_str = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)); + SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model); const char* built_in_str = _.grammar().lookupOperandName( SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -1147,11 +1149,11 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4190 : 4199; + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { + uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4190 : 4199; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -1163,54 +1165,54 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4188 : 4197; + uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4188 : 4197; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "Vertex.", - spv::ExecutionModel::Vertex, decoration, built_in_inst, + SpvExecutionModelVertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "MeshNV.", - spv::ExecutionModel::MeshNV, decoration, built_in_inst, + SpvExecutionModelMeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Input storage class if execution model is " "MeshEXT.", - spv::ExecutionModel::MeshEXT, decoration, built_in_inst, + SpvExecutionModelMeshEXT, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - if (storage_class == spv::StorageClass::Output) { + if (storage_class == SpvStorageClassOutput) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4189 : 4198; + uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4189 : 4198; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " "used for variables with Output storage class if execution model is " "Fragment.", - spv::ExecutionModel::Fragment, decoration, built_in_inst, + SpvExecutionModelFragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Fragment: - case spv::ExecutionModel::Vertex: { + case SpvExecutionModelFragment: + case SpvExecutionModelVertex: { if (spv_result_t error = ValidateF32Arr( decoration, built_in_inst, /* Any number of components */ 0, [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.params()[0] == SpvBuiltInClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -1226,11 +1228,11 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( } break; } - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: { + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { if (decoration.struct_member_index() != Decoration::kInvalidMember) { // The outer level of array is applied on the variable. if (spv_result_t error = ValidateF32Arr( @@ -1238,7 +1240,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.params()[0] == SpvBuiltInClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1259,7 +1261,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.params()[0] == SpvBuiltInClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1280,7 +1282,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( default: { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4187 : 4196; + (decoration.params()[0] == SpvBuiltInClipDistance) ? 4187 : 4196; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -1333,9 +1335,9 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4211) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FragCoord to be only used for " @@ -1345,8 +1347,8 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4210) << spvLogStringForEnv(_.context()->target_env) @@ -1394,9 +1396,9 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4214) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FragDepth to be only used for " @@ -1406,8 +1408,8 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4213) << spvLogStringForEnv(_.context()->target_env) @@ -1422,7 +1424,7 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( // Every entry point from which this function is called needs to have // Execution Mode DepthReplacing. const auto* modes = _.GetExecutionModes(entry_point); - if (!modes || !modes->count(spv::ExecutionMode::DepthReplacing)) { + if (!modes || !modes->count(SpvExecutionModeDepthReplacing)) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4216) << spvLogStringForEnv(_.context()->target_env) @@ -1470,9 +1472,9 @@ spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4230) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn FrontFacing to be only used for " @@ -1482,8 +1484,8 @@ spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4229) << spvLogStringForEnv(_.context()->target_env) @@ -1530,9 +1532,9 @@ spv_result_t BuiltInsValidator::ValidateHelperInvocationAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4240) << "Vulkan spec allows BuiltIn HelperInvocation to be only used " @@ -1542,8 +1544,8 @@ spv_result_t BuiltInsValidator::ValidateHelperInvocationAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4239) << "Vulkan spec allows BuiltIn HelperInvocation to be used only " @@ -1590,9 +1592,9 @@ spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4258) << "Vulkan spec allows BuiltIn InvocationId to be only used for " @@ -1602,9 +1604,9 @@ spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::TessellationControl && - execution_model != spv::ExecutionModel::Geometry) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelTessellationControl && + execution_model != SpvExecutionModelGeometry) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4257) << "Vulkan spec allows BuiltIn InvocationId to be used only " @@ -1651,9 +1653,9 @@ spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4264) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn InstanceIndex to be only used for " @@ -1663,8 +1665,8 @@ spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Vertex) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelVertex) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4263) << spvLogStringForEnv(_.context()->target_env) @@ -1711,9 +1713,9 @@ spv_result_t BuiltInsValidator::ValidatePatchVerticesAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4309) << "Vulkan spec allows BuiltIn PatchVertices to be only used for " @@ -1723,9 +1725,9 @@ spv_result_t BuiltInsValidator::ValidatePatchVerticesAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::TessellationControl && - execution_model != spv::ExecutionModel::TessellationEvaluation) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelTessellationControl && + execution_model != SpvExecutionModelTessellationEvaluation) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4308) << "Vulkan spec allows BuiltIn PatchVertices to be used only " @@ -1773,9 +1775,9 @@ spv_result_t BuiltInsValidator::ValidatePointCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4312) << "Vulkan spec allows BuiltIn PointCoord to be only used for " @@ -1785,8 +1787,8 @@ spv_result_t BuiltInsValidator::ValidatePointCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4311) << "Vulkan spec allows BuiltIn PointCoord to be used only with " @@ -1818,10 +1820,10 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4316) << "Vulkan spec allows BuiltIn PointSize to be only used for " @@ -1831,20 +1833,20 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4315, "Vulkan spec doesn't allow BuiltIn PointSize to be used for " "variables with Input storage class if execution model is " "Vertex.", - spv::ExecutionModel::Vertex, decoration, built_in_inst, + SpvExecutionModelVertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Vertex: { + case SpvExecutionModelVertex: { if (spv_result_t error = ValidateF32( decoration, built_in_inst, [this, &referenced_from_inst]( @@ -1859,11 +1861,11 @@ spv_result_t BuiltInsValidator::ValidatePointSizeAtReference( } break; } - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: { + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { // PointSize can be a per-vertex variable for tessellation control, // tessellation evaluation and geometry shader stages. In such cases // variables will have an array of 32-bit floats. @@ -1936,10 +1938,10 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4320) << "Vulkan spec allows BuiltIn Position to be only used for " "variables with Input or Output storage class. " @@ -1948,34 +1950,34 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is Vertex.", - spv::ExecutionModel::Vertex, decoration, built_in_inst, + SpvExecutionModelVertex, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is MeshNV.", - spv::ExecutionModel::MeshNV, decoration, built_in_inst, + SpvExecutionModelMeshNV, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319, "Vulkan spec doesn't allow BuiltIn Position to be used " "for variables " "with Input storage class if execution model is MeshEXT.", - spv::ExecutionModel::MeshEXT, decoration, built_in_inst, + SpvExecutionModelMeshEXT, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Vertex: { + case SpvExecutionModelVertex: { if (spv_result_t error = ValidateF32Vec( decoration, built_in_inst, 4, [this, &referenced_from_inst]( @@ -1991,11 +1993,11 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( } break; } - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: { + case SpvExecutionModelGeometry: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: { // Position can be a per-vertex variable for tessellation control, // tessellation evaluation, geometry and mesh shader stages. In such // cases variables will have an array of 4-component 32-bit float @@ -2101,10 +2103,10 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn PrimitiveId to be only used for " "variables with Input or Output storage class. " @@ -2113,63 +2115,63 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Output) { + if (storage_class == SpvStorageClassOutput) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "TessellationControl.", - spv::ExecutionModel::TessellationControl, decoration, built_in_inst, + SpvExecutionModelTessellationControl, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "TessellationEvaluation.", - spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, + SpvExecutionModelTessellationEvaluation, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "Fragment.", - spv::ExecutionModel::Fragment, decoration, built_in_inst, + SpvExecutionModelFragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "IntersectionKHR.", - spv::ExecutionModel::IntersectionKHR, decoration, built_in_inst, + SpvExecutionModelIntersectionKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "AnyHitKHR.", - spv::ExecutionModel::AnyHitKHR, decoration, built_in_inst, + SpvExecutionModelAnyHitKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334, "Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for " "variables with Output storage class if execution model is " "ClosestHitKHR.", - spv::ExecutionModel::ClosestHitKHR, decoration, built_in_inst, + SpvExecutionModelClosestHitKHR, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Fragment: - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: - case spv::ExecutionModel::IntersectionKHR: - case spv::ExecutionModel::AnyHitKHR: - case spv::ExecutionModel::ClosestHitKHR: { + case SpvExecutionModelFragment: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: + case SpvExecutionModelIntersectionKHR: + case SpvExecutionModelAnyHitKHR: + case SpvExecutionModelClosestHitKHR: { // Ok. break; } @@ -2223,9 +2225,9 @@ spv_result_t BuiltInsValidator::ValidateSampleIdAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4355) << "Vulkan spec allows BuiltIn SampleId to be only used for " @@ -2235,8 +2237,8 @@ spv_result_t BuiltInsValidator::ValidateSampleIdAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4354) << "Vulkan spec allows BuiltIn SampleId to be used only with " @@ -2282,10 +2284,10 @@ spv_result_t BuiltInsValidator::ValidateSampleMaskAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4358) << "Vulkan spec allows BuiltIn SampleMask to be only used for " @@ -2295,8 +2297,8 @@ spv_result_t BuiltInsValidator::ValidateSampleMaskAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4357) << "Vulkan spec allows BuiltIn SampleMask to be used only " @@ -2344,9 +2346,9 @@ spv_result_t BuiltInsValidator::ValidateSamplePositionAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4361) << "Vulkan spec allows BuiltIn SamplePosition to be only used " @@ -2357,8 +2359,8 @@ spv_result_t BuiltInsValidator::ValidateSamplePositionAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4360) << "Vulkan spec allows BuiltIn SamplePosition to be used only " @@ -2406,9 +2408,9 @@ spv_result_t BuiltInsValidator::ValidateTessCoordAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4388) << "Vulkan spec allows BuiltIn TessCoord to be only used for " @@ -2418,8 +2420,8 @@ spv_result_t BuiltInsValidator::ValidateTessCoordAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::TessellationEvaluation) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelTessellationEvaluation) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4387) << "Vulkan spec allows BuiltIn TessCoord to be used only with " @@ -2488,10 +2490,10 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2503,42 +2505,42 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395; + uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4391 : 4395; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " "used " "for variables with Input storage class if execution model is " "TessellationControl.", - spv::ExecutionModel::TessellationControl, decoration, built_in_inst, + SpvExecutionModelTessellationControl, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - if (storage_class == spv::StorageClass::Output) { + if (storage_class == SpvStorageClassOutput) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396; + uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4392 : 4396; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " "used " "for variables with Output storage class if execution model is " "TessellationEvaluation.", - spv::ExecutionModel::TessellationEvaluation, decoration, built_in_inst, + SpvExecutionModelTessellationEvaluation, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: { + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: { // Ok. break; } default: { - uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::TessLevelOuter) ? 4390 : 4394; + uint32_t vuid = (operand == SpvBuiltInTessLevelOuter) ? 4390 : 4394; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2621,9 +2623,9 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4399) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn VertexIndex to be only used for " @@ -2633,8 +2635,8 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Vertex) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelVertex) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4398) << spvLogStringForEnv(_.context()->target_env) @@ -2668,7 +2670,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + (decoration.params()[0] == SpvBuiltInLayer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " @@ -2685,7 +2687,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + (decoration.params()[0] == SpvBuiltInLayer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " @@ -2709,10 +2711,10 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2724,15 +2726,15 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); for (const auto em : - {spv::ExecutionModel::Vertex, spv::ExecutionModel::TessellationEvaluation, - spv::ExecutionModel::Geometry, spv::ExecutionModel::MeshNV, - spv::ExecutionModel::MeshEXT}) { + {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation, + SpvExecutionModelGeometry, SpvExecutionModelMeshNV, + SpvExecutionModelMeshEXT}) { id_to_at_reference_checks_[referenced_from_inst.id()].push_back( std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, - this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4274 : 4406), + this, ((operand == SpvBuiltInLayer) ? 4274 : 4406), "Vulkan spec doesn't allow BuiltIn Layer and " "ViewportIndex to be " "used for variables with Input storage class if " @@ -2743,46 +2745,46 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( } } - if (storage_class == spv::StorageClass::Output) { + if (storage_class == SpvStorageClassOutput) { assert(function_id_ == 0); id_to_at_reference_checks_[referenced_from_inst.id()].push_back( std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, - this, ((spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4275 : 4407), + this, ((operand == SpvBuiltInLayer) ? 4275 : 4407), "Vulkan spec doesn't allow BuiltIn Layer and " "ViewportIndex to be " "used for variables with Output storage class if " "execution model is " "Fragment.", - spv::ExecutionModel::Fragment, decoration, built_in_inst, + SpvExecutionModelFragment, decoration, built_in_inst, referenced_from_inst, std::placeholders::_1)); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::Fragment: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: + case SpvExecutionModelGeometry: + case SpvExecutionModelFragment: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: // Ok. break; - case spv::ExecutionModel::Vertex: - case spv::ExecutionModel::TessellationEvaluation: { - if (!_.HasCapability(spv::Capability::ShaderViewportIndexLayerEXT)) { - if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex && - _.HasCapability(spv::Capability::ShaderViewportIndex)) + case SpvExecutionModelVertex: + case SpvExecutionModelTessellationEvaluation: { + if (!_.HasCapability(SpvCapabilityShaderViewportIndexLayerEXT)) { + if (operand == SpvBuiltInViewportIndex && + _.HasCapability(SpvCapabilityShaderViewportIndex)) break; // Ok - if (spv::BuiltIn(operand) == spv::BuiltIn::Layer && - _.HasCapability(spv::Capability::ShaderLayer)) + if (operand == SpvBuiltInLayer && + _.HasCapability(SpvCapabilityShaderLayer)) break; // Ok const char* capability = "ShaderViewportIndexLayerEXT"; - if (spv::BuiltIn(operand) == spv::BuiltIn::ViewportIndex) + if (operand == SpvBuiltInViewportIndex) capability = "ShaderViewportIndexLayerEXT or ShaderViewportIndex"; - if (spv::BuiltIn(operand) == spv::BuiltIn::Layer) + if (operand == SpvBuiltInLayer) capability = "ShaderViewportIndexLayerEXT or ShaderLayer"; - uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4273 : 4405; + uint32_t vuid = (operand == SpvBuiltInLayer) ? 4273 : 4405; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Using BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2793,7 +2795,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( break; } default: { - uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::Layer) ? 4272 : 4404; + uint32_t vuid = (operand == SpvBuiltInLayer) ? 4272 : 4404; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2821,7 +2823,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateF32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2831,7 +2833,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a 3-component 32-bit float " "vector. " << message; @@ -2851,29 +2853,29 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -2895,7 +2897,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2905,7 +2907,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a 3-component 32-bit int " "vector. " << message; @@ -2924,27 +2926,27 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || - execution_model == spv::ExecutionModel::TaskNV || - execution_model == spv::ExecutionModel::MeshNV || - execution_model == spv::ExecutionModel::TaskEXT || - execution_model == spv::ExecutionModel::MeshEXT; + for (const SpvExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || + execution_model == SpvExecutionModelTaskNV || + execution_model == SpvExecutionModelMeshNV || + execution_model == SpvExecutionModelTaskEXT || + execution_model == SpvExecutionModelMeshEXT; if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); @@ -2952,7 +2954,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or" << " TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -2975,11 +2977,11 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32( @@ -2991,7 +2993,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 32-bit int " "vector. " << message; @@ -3009,35 +3011,35 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - bool has_vulkan_model = execution_model == spv::ExecutionModel::GLCompute || - execution_model == spv::ExecutionModel::TaskNV || - execution_model == spv::ExecutionModel::MeshNV || - execution_model == spv::ExecutionModel::TaskEXT || - execution_model == spv::ExecutionModel::MeshEXT; + for (const SpvExecutionModel execution_model : execution_models_) { + bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || + execution_model == SpvExecutionModelTaskNV || + execution_model == SpvExecutionModelMeshNV || + execution_model == SpvExecutionModelTaskEXT || + execution_model == SpvExecutionModelMeshEXT; if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " << "TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -3060,11 +3062,11 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32( @@ -3076,21 +3078,21 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 32-bit int. " << message; })) { return error; } - const spv::StorageClass storage_class = GetStorageClass(inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, inst, inst, inst) << " " << GetStorageClassDesc(inst); @@ -3103,11 +3105,11 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " cannot be used as a member decoration "; } if (spv_result_t error = ValidateI32Vec( @@ -3119,7 +3121,7 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 4-component 32-bit int " "vector. " << message; @@ -3127,15 +3129,15 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( return error; } - const spv::StorageClass storage_class = GetStorageClass(inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, inst, inst, inst) << " " << GetStorageClassDesc(inst); @@ -3180,12 +3182,12 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::GLCompute && - execution_model != spv::ExecutionModel::TaskNV && - execution_model != spv::ExecutionModel::MeshNV && - execution_model != spv::ExecutionModel::TaskEXT && - execution_model != spv::ExecutionModel::MeshEXT) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelGLCompute && + execution_model != SpvExecutionModelTaskNV && + execution_model != SpvExecutionModelMeshNV && + execution_model != SpvExecutionModelTaskEXT && + execution_model != SpvExecutionModelMeshEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4425) << spvLogStringForEnv(_.context()->target_env) @@ -3217,7 +3219,7 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtDefinition( decoration, inst, [this, &inst, &decoration](const std::string& message) -> spv_result_t { - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::BaseInstance) + uint32_t vuid = (decoration.params()[0] == SpvBuiltInBaseInstance) ? 4183 : 4186; return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -3241,10 +3243,10 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { - uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4182 : 4185; + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { + uint32_t vuid = (operand == SpvBuiltInBaseInstance) ? 4182 : 4185; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3255,9 +3257,9 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Vertex) { - uint32_t vuid = (spv::BuiltIn(operand) == spv::BuiltIn::BaseInstance) ? 4181 : 4184; + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelVertex) { + uint32_t vuid = (operand == SpvBuiltInBaseInstance) ? 4181 : 4184; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3308,9 +3310,9 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4208) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3321,12 +3323,12 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Vertex && - execution_model != spv::ExecutionModel::MeshNV && - execution_model != spv::ExecutionModel::TaskNV && - execution_model != spv::ExecutionModel::MeshEXT && - execution_model != spv::ExecutionModel::TaskEXT) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelVertex && + execution_model != SpvExecutionModelMeshNV && + execution_model != SpvExecutionModelTaskNV && + execution_model != SpvExecutionModelMeshEXT && + execution_model != SpvExecutionModelTaskEXT) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4207) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3378,9 +3380,9 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4402) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3391,8 +3393,8 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model == spv::ExecutionModel::GLCompute) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model == SpvExecutionModelGLCompute) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4401) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3442,9 +3444,9 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference( const Instruction& referenced_from_inst) { uint32_t operand = decoration.params()[0]; if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4205) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3470,7 +3472,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3480,7 +3482,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3497,29 +3499,29 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3540,7 +3542,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32Vec( decoration, inst, 2, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3550,7 +3552,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& d << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a 2-component 32-bit int vector. " << message; })) { @@ -3567,29 +3569,29 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3610,7 +3612,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3620,7 +3622,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decorat << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a int scalar. " << message; })) { @@ -3637,29 +3639,29 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Output) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassOutput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Output storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3680,7 +3682,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateBool( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3690,7 +3692,7 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoratio << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - uint32_t(builtin)) + builtin) << " variable needs to be a bool scalar. " << message; })) { @@ -3707,29 +3709,29 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin) << " to be used only with Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3776,9 +3778,9 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " @@ -3830,9 +3832,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Output) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassOutput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4485) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3843,12 +3845,12 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { switch (execution_model) { - case spv::ExecutionModel::Vertex: - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::MeshNV: - case spv::ExecutionModel::MeshEXT: + case SpvExecutionModelVertex: + case SpvExecutionModelGeometry: + case SpvExecutionModelMeshNV: + case SpvExecutionModelMeshEXT: break; default: { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -3903,9 +3905,9 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4491) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3916,8 +3918,8 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { - if (execution_model != spv::ExecutionModel::Fragment) { + for (const SpvExecutionModel execution_model : execution_models_) { + if (execution_model != SpvExecutionModelFragment) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4490) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -3942,11 +3944,11 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); switch (builtin) { - case spv::BuiltIn::HitTNV: - case spv::BuiltIn::RayTminKHR: - case spv::BuiltIn::RayTmaxKHR: + case SpvBuiltInHitTNV: + case SpvBuiltInRayTminKHR: + case SpvBuiltInRayTmaxKHR: // f32 scalar if (spv_result_t error = ValidateF32( decoration, inst, @@ -3957,19 +3959,19 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 32-bit float scalar. " << message; })) { return error; } break; - case spv::BuiltIn::HitKindKHR: - case spv::BuiltIn::InstanceCustomIndexKHR: - case spv::BuiltIn::InstanceId: - case spv::BuiltIn::RayGeometryIndexKHR: - case spv::BuiltIn::IncomingRayFlagsKHR: - case spv::BuiltIn::CullMaskKHR: + case SpvBuiltInHitKindKHR: + case SpvBuiltInInstanceCustomIndexKHR: + case SpvBuiltInInstanceId: + case SpvBuiltInRayGeometryIndexKHR: + case SpvBuiltInIncomingRayFlagsKHR: + case SpvBuiltInCullMaskKHR: // i32 scalar if (spv_result_t error = ValidateI32( decoration, inst, @@ -3980,17 +3982,17 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 32-bit int scalar. " << message; })) { return error; } break; - case spv::BuiltIn::ObjectRayDirectionKHR: - case spv::BuiltIn::ObjectRayOriginKHR: - case spv::BuiltIn::WorldRayDirectionKHR: - case spv::BuiltIn::WorldRayOriginKHR: + case SpvBuiltInObjectRayDirectionKHR: + case SpvBuiltInObjectRayOriginKHR: + case SpvBuiltInWorldRayDirectionKHR: + case SpvBuiltInWorldRayOriginKHR: // f32 vec3 if (spv_result_t error = ValidateF32Vec( decoration, inst, 3, @@ -4001,7 +4003,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 3-component 32-bit float " "vector. " << message; @@ -4009,8 +4011,8 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( return error; } break; - case spv::BuiltIn::LaunchIdKHR: - case spv::BuiltIn::LaunchSizeKHR: + case SpvBuiltInLaunchIdKHR: + case SpvBuiltInLaunchSizeKHR: // i32 vec3 if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, @@ -4021,7 +4023,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a 3-component 32-bit int " "vector. " << message; @@ -4029,8 +4031,8 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( return error; } break; - case spv::BuiltIn::ObjectToWorldKHR: - case spv::BuiltIn::WorldToObjectKHR: + case SpvBuiltInObjectToWorldKHR: + case SpvBuiltInWorldToObjectKHR: // f32 mat4x3 if (spv_result_t error = ValidateF32Mat( decoration, inst, 3, 4, @@ -4041,7 +4043,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, uint32_t(builtin)) + SPV_OPERAND_TYPE_BUILT_IN, builtin) << " variable needs to be a matrix with" << " 4 columns of 3-component vectors of 32-bit " "floats. " @@ -4065,10 +4067,10 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); - const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != spv::StorageClass::Max && - storage_class != spv::StorageClass::Input) { + const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); + const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); + if (storage_class != SpvStorageClassMax && + storage_class != SpvStorageClassInput) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " @@ -4080,7 +4082,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( << " " << GetStorageClassDesc(referenced_from_inst); } - for (const spv::ExecutionModel execution_model : execution_models_) { + for (const SpvExecutionModel execution_model : execution_models_) { if (!IsExecutionModelValidForRtBuiltIn(builtin, execution_model)) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -4089,7 +4091,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( decoration.params()[0]) << " to be used with the execution model " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)) + SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model) << ".\n" << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -4110,7 +4112,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( const Decoration& decoration, const Instruction& inst) { - const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]); + const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]); if (!spvIsVulkanEnv(_.context()->target_env)) { // Early return. All currently implemented rules are based on Vulkan spec. @@ -4127,166 +4129,166 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( // If the newly added enum has validation rules associated with it // consider leaving a TODO and/or creating an issue. switch (label) { - case spv::BuiltIn::ClipDistance: - case spv::BuiltIn::CullDistance: { + case SpvBuiltInClipDistance: + case SpvBuiltInCullDistance: { return ValidateClipOrCullDistanceAtDefinition(decoration, inst); } - case spv::BuiltIn::FragCoord: { + case SpvBuiltInFragCoord: { return ValidateFragCoordAtDefinition(decoration, inst); } - case spv::BuiltIn::FragDepth: { + case SpvBuiltInFragDepth: { return ValidateFragDepthAtDefinition(decoration, inst); } - case spv::BuiltIn::FrontFacing: { + case SpvBuiltInFrontFacing: { return ValidateFrontFacingAtDefinition(decoration, inst); } - case spv::BuiltIn::GlobalInvocationId: - case spv::BuiltIn::LocalInvocationId: - case spv::BuiltIn::NumWorkgroups: - case spv::BuiltIn::WorkgroupId: { + case SpvBuiltInGlobalInvocationId: + case SpvBuiltInLocalInvocationId: + case SpvBuiltInNumWorkgroups: + case SpvBuiltInWorkgroupId: { return ValidateComputeShaderI32Vec3InputAtDefinition(decoration, inst); } - case spv::BuiltIn::BaryCoordKHR: - case spv::BuiltIn::BaryCoordNoPerspKHR: { + case SpvBuiltInBaryCoordKHR: + case SpvBuiltInBaryCoordNoPerspKHR: { return ValidateFragmentShaderF32Vec3InputAtDefinition(decoration, inst); } - case spv::BuiltIn::HelperInvocation: { + case SpvBuiltInHelperInvocation: { return ValidateHelperInvocationAtDefinition(decoration, inst); } - case spv::BuiltIn::InvocationId: { + case SpvBuiltInInvocationId: { return ValidateInvocationIdAtDefinition(decoration, inst); } - case spv::BuiltIn::InstanceIndex: { + case SpvBuiltInInstanceIndex: { return ValidateInstanceIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::Layer: - case spv::BuiltIn::ViewportIndex: { + case SpvBuiltInLayer: + case SpvBuiltInViewportIndex: { return ValidateLayerOrViewportIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::PatchVertices: { + case SpvBuiltInPatchVertices: { return ValidatePatchVerticesAtDefinition(decoration, inst); } - case spv::BuiltIn::PointCoord: { + case SpvBuiltInPointCoord: { return ValidatePointCoordAtDefinition(decoration, inst); } - case spv::BuiltIn::PointSize: { + case SpvBuiltInPointSize: { return ValidatePointSizeAtDefinition(decoration, inst); } - case spv::BuiltIn::Position: { + case SpvBuiltInPosition: { return ValidatePositionAtDefinition(decoration, inst); } - case spv::BuiltIn::PrimitiveId: { + case SpvBuiltInPrimitiveId: { return ValidatePrimitiveIdAtDefinition(decoration, inst); } - case spv::BuiltIn::SampleId: { + case SpvBuiltInSampleId: { return ValidateSampleIdAtDefinition(decoration, inst); } - case spv::BuiltIn::SampleMask: { + case SpvBuiltInSampleMask: { return ValidateSampleMaskAtDefinition(decoration, inst); } - case spv::BuiltIn::SamplePosition: { + case SpvBuiltInSamplePosition: { return ValidateSamplePositionAtDefinition(decoration, inst); } - case spv::BuiltIn::SubgroupId: - case spv::BuiltIn::NumSubgroups: { + case SpvBuiltInSubgroupId: + case SpvBuiltInNumSubgroups: { return ValidateComputeI32InputAtDefinition(decoration, inst); } - case spv::BuiltIn::SubgroupLocalInvocationId: - case spv::BuiltIn::SubgroupSize: { + case SpvBuiltInSubgroupLocalInvocationId: + case SpvBuiltInSubgroupSize: { return ValidateI32InputAtDefinition(decoration, inst); } - case spv::BuiltIn::SubgroupEqMask: - case spv::BuiltIn::SubgroupGeMask: - case spv::BuiltIn::SubgroupGtMask: - case spv::BuiltIn::SubgroupLeMask: - case spv::BuiltIn::SubgroupLtMask: { + case SpvBuiltInSubgroupEqMask: + case SpvBuiltInSubgroupGeMask: + case SpvBuiltInSubgroupGtMask: + case SpvBuiltInSubgroupLeMask: + case SpvBuiltInSubgroupLtMask: { return ValidateI32Vec4InputAtDefinition(decoration, inst); } - case spv::BuiltIn::TessCoord: { + case SpvBuiltInTessCoord: { return ValidateTessCoordAtDefinition(decoration, inst); } - case spv::BuiltIn::TessLevelOuter: { + case SpvBuiltInTessLevelOuter: { return ValidateTessLevelOuterAtDefinition(decoration, inst); } - case spv::BuiltIn::TessLevelInner: { + case SpvBuiltInTessLevelInner: { return ValidateTessLevelInnerAtDefinition(decoration, inst); } - case spv::BuiltIn::VertexIndex: { + case SpvBuiltInVertexIndex: { return ValidateVertexIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::WorkgroupSize: { + case SpvBuiltInWorkgroupSize: { return ValidateWorkgroupSizeAtDefinition(decoration, inst); } - case spv::BuiltIn::VertexId: { + case SpvBuiltInVertexId: { return ValidateVertexIdAtDefinition(decoration, inst); } - case spv::BuiltIn::LocalInvocationIndex: { + case SpvBuiltInLocalInvocationIndex: { return ValidateLocalInvocationIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::CoreIDARM: - case spv::BuiltIn::CoreCountARM: - case spv::BuiltIn::CoreMaxIDARM: - case spv::BuiltIn::WarpIDARM: - case spv::BuiltIn::WarpMaxIDARM: - case spv::BuiltIn::WarpsPerSMNV: - case spv::BuiltIn::SMCountNV: - case spv::BuiltIn::WarpIDNV: - case spv::BuiltIn::SMIDNV: { + case SpvBuiltInCoreIDARM: + case SpvBuiltInCoreCountARM: + case SpvBuiltInCoreMaxIDARM: + case SpvBuiltInWarpIDARM: + case SpvBuiltInWarpMaxIDARM: + case SpvBuiltInWarpsPerSMNV: + case SpvBuiltInSMCountNV: + case SpvBuiltInWarpIDNV: + case SpvBuiltInSMIDNV: { return ValidateNVSMOrARMCoreBuiltinsAtDefinition(decoration, inst); } - case spv::BuiltIn::BaseInstance: - case spv::BuiltIn::BaseVertex: { + case SpvBuiltInBaseInstance: + case SpvBuiltInBaseVertex: { return ValidateBaseInstanceOrVertexAtDefinition(decoration, inst); } - case spv::BuiltIn::DrawIndex: { + case SpvBuiltInDrawIndex: { return ValidateDrawIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::ViewIndex: { + case SpvBuiltInViewIndex: { return ValidateViewIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::DeviceIndex: { + case SpvBuiltInDeviceIndex: { return ValidateDeviceIndexAtDefinition(decoration, inst); } - case spv::BuiltIn::FragInvocationCountEXT: { - // alias spv::BuiltIn::InvocationsPerPixelNV + case SpvBuiltInFragInvocationCountEXT: { + // alias SpvBuiltInInvocationsPerPixelNV return ValidateFragInvocationCountAtDefinition(decoration, inst); } - case spv::BuiltIn::FragSizeEXT: { - // alias spv::BuiltIn::FragmentSizeNV + case SpvBuiltInFragSizeEXT: { + // alias SpvBuiltInFragmentSizeNV return ValidateFragSizeAtDefinition(decoration, inst); } - case spv::BuiltIn::FragStencilRefEXT: { + case SpvBuiltInFragStencilRefEXT: { return ValidateFragStencilRefAtDefinition(decoration, inst); } - case spv::BuiltIn::FullyCoveredEXT:{ + case SpvBuiltInFullyCoveredEXT:{ return ValidateFullyCoveredAtDefinition(decoration, inst); } // Ray tracing builtins - case spv::BuiltIn::HitKindKHR: // alias spv::BuiltIn::HitKindNV - case spv::BuiltIn::HitTNV: // NOT present in KHR - case spv::BuiltIn::InstanceId: - case spv::BuiltIn::LaunchIdKHR: // alias spv::BuiltIn::LaunchIdNV - case spv::BuiltIn::LaunchSizeKHR: // alias spv::BuiltIn::LaunchSizeNV - case spv::BuiltIn::WorldRayOriginKHR: // alias spv::BuiltIn::WorldRayOriginNV - case spv::BuiltIn::WorldRayDirectionKHR: // alias spv::BuiltIn::WorldRayDirectionNV - case spv::BuiltIn::ObjectRayOriginKHR: // alias spv::BuiltIn::ObjectRayOriginNV - case spv::BuiltIn::ObjectRayDirectionKHR: // alias - // spv::BuiltIn::ObjectRayDirectionNV - case spv::BuiltIn::RayTminKHR: // alias spv::BuiltIn::RayTminNV - case spv::BuiltIn::RayTmaxKHR: // alias spv::BuiltIn::RayTmaxNV - case spv::BuiltIn::InstanceCustomIndexKHR: // alias - // spv::BuiltIn::InstanceCustomIndexNV - case spv::BuiltIn::ObjectToWorldKHR: // alias spv::BuiltIn::ObjectToWorldNV - case spv::BuiltIn::WorldToObjectKHR: // alias spv::BuiltIn::WorldToObjectNV - case spv::BuiltIn::IncomingRayFlagsKHR: // alias spv::BuiltIn::IncomingRayFlagsNV - case spv::BuiltIn::RayGeometryIndexKHR: // NOT present in NV - case spv::BuiltIn::CullMaskKHR: { + case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV + case SpvBuiltInHitTNV: // NOT present in KHR + case SpvBuiltInInstanceId: + case SpvBuiltInLaunchIdKHR: // alias SpvBuiltInLaunchIdNV + case SpvBuiltInLaunchSizeKHR: // alias SpvBuiltInLaunchSizeNV + case SpvBuiltInWorldRayOriginKHR: // alias SpvBuiltInWorldRayOriginNV + case SpvBuiltInWorldRayDirectionKHR: // alias SpvBuiltInWorldRayDirectionNV + case SpvBuiltInObjectRayOriginKHR: // alias SpvBuiltInObjectRayOriginNV + case SpvBuiltInObjectRayDirectionKHR: // alias + // SpvBuiltInObjectRayDirectionNV + case SpvBuiltInRayTminKHR: // alias SpvBuiltInRayTminNV + case SpvBuiltInRayTmaxKHR: // alias SpvBuiltInRayTmaxNV + case SpvBuiltInInstanceCustomIndexKHR: // alias + // SpvBuiltInInstanceCustomIndexNV + case SpvBuiltInObjectToWorldKHR: // alias SpvBuiltInObjectToWorldNV + case SpvBuiltInWorldToObjectKHR: // alias SpvBuiltInWorldToObjectNV + case SpvBuiltInIncomingRayFlagsKHR: // alias SpvBuiltInIncomingRayFlagsNV + case SpvBuiltInRayGeometryIndexKHR: // NOT present in NV + case SpvBuiltInCullMaskKHR: { return ValidateRayTracingBuiltinsAtDefinition(decoration, inst); } - case spv::BuiltIn::PrimitiveShadingRateKHR: { + case SpvBuiltInPrimitiveShadingRateKHR: { return ValidatePrimitiveShadingRateAtDefinition(decoration, inst); } - case spv::BuiltIn::ShadingRateKHR: { + case SpvBuiltInShadingRateKHR: { return ValidateShadingRateAtDefinition(decoration, inst); } default: @@ -4308,7 +4310,7 @@ spv_result_t BuiltInsValidator::ValidateBuiltInsAtDefinition() { assert(inst); for (const auto& decoration : kv.second) { - if (decoration.dec_type() != spv::Decoration::BuiltIn) { + if (decoration.dec_type() != SpvDecorationBuiltIn) { continue; } diff --git a/source/val/validate_capability.cpp b/source/val/validate_capability.cpp index 81d2ad52..8efd5542 100644 --- a/source/val/validate_capability.cpp +++ b/source/val/validate_capability.cpp @@ -16,7 +16,9 @@ #include #include +#include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/val/instruction.h" #include "source/val/validate.h" @@ -27,82 +29,74 @@ namespace val { namespace { bool IsSupportGuaranteedVulkan_1_0(uint32_t capability) { - switch (spv::Capability(capability)) { - case spv::Capability::Matrix: - case spv::Capability::Shader: - case spv::Capability::InputAttachment: - case spv::Capability::Sampled1D: - case spv::Capability::Image1D: - case spv::Capability::SampledBuffer: - case spv::Capability::ImageBuffer: - case spv::Capability::ImageQuery: - case spv::Capability::DerivativeControl: + switch (capability) { + case SpvCapabilityMatrix: + case SpvCapabilityShader: + case SpvCapabilityInputAttachment: + case SpvCapabilitySampled1D: + case SpvCapabilityImage1D: + case SpvCapabilitySampledBuffer: + case SpvCapabilityImageBuffer: + case SpvCapabilityImageQuery: + case SpvCapabilityDerivativeControl: return true; - default: - break; } return false; } bool IsSupportGuaranteedVulkan_1_1(uint32_t capability) { if (IsSupportGuaranteedVulkan_1_0(capability)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::DeviceGroup: - case spv::Capability::MultiView: + switch (capability) { + case SpvCapabilityDeviceGroup: + case SpvCapabilityMultiView: return true; - default: - break; } return false; } bool IsSupportGuaranteedVulkan_1_2(uint32_t capability) { if (IsSupportGuaranteedVulkan_1_1(capability)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::ShaderNonUniform: + switch (capability) { + case SpvCapabilityShaderNonUniform: return true; - default: - break; } return false; } bool IsSupportOptionalVulkan_1_0(uint32_t capability) { - switch (spv::Capability(capability)) { - case spv::Capability::Geometry: - case spv::Capability::Tessellation: - case spv::Capability::Float64: - case spv::Capability::Int64: - case spv::Capability::Int16: - case spv::Capability::TessellationPointSize: - case spv::Capability::GeometryPointSize: - case spv::Capability::ImageGatherExtended: - case spv::Capability::StorageImageMultisample: - case spv::Capability::UniformBufferArrayDynamicIndexing: - case spv::Capability::SampledImageArrayDynamicIndexing: - case spv::Capability::StorageBufferArrayDynamicIndexing: - case spv::Capability::StorageImageArrayDynamicIndexing: - case spv::Capability::ClipDistance: - case spv::Capability::CullDistance: - case spv::Capability::ImageCubeArray: - case spv::Capability::SampleRateShading: - case spv::Capability::SparseResidency: - case spv::Capability::MinLod: - case spv::Capability::SampledCubeArray: - case spv::Capability::ImageMSArray: - case spv::Capability::StorageImageExtendedFormats: - case spv::Capability::InterpolationFunction: - case spv::Capability::StorageImageReadWithoutFormat: - case spv::Capability::StorageImageWriteWithoutFormat: - case spv::Capability::MultiViewport: - case spv::Capability::Int64Atomics: - case spv::Capability::TransformFeedback: - case spv::Capability::GeometryStreams: - case spv::Capability::Float16: - case spv::Capability::Int8: + switch (capability) { + case SpvCapabilityGeometry: + case SpvCapabilityTessellation: + case SpvCapabilityFloat64: + case SpvCapabilityInt64: + case SpvCapabilityInt16: + case SpvCapabilityTessellationPointSize: + case SpvCapabilityGeometryPointSize: + case SpvCapabilityImageGatherExtended: + case SpvCapabilityStorageImageMultisample: + case SpvCapabilityUniformBufferArrayDynamicIndexing: + case SpvCapabilitySampledImageArrayDynamicIndexing: + case SpvCapabilityStorageBufferArrayDynamicIndexing: + case SpvCapabilityStorageImageArrayDynamicIndexing: + case SpvCapabilityClipDistance: + case SpvCapabilityCullDistance: + case SpvCapabilityImageCubeArray: + case SpvCapabilitySampleRateShading: + case SpvCapabilitySparseResidency: + case SpvCapabilityMinLod: + case SpvCapabilitySampledCubeArray: + case SpvCapabilityImageMSArray: + case SpvCapabilityStorageImageExtendedFormats: + case SpvCapabilityInterpolationFunction: + case SpvCapabilityStorageImageReadWithoutFormat: + case SpvCapabilityStorageImageWriteWithoutFormat: + case SpvCapabilityMultiViewport: + case SpvCapabilityInt64Atomics: + case SpvCapabilityTransformFeedback: + case SpvCapabilityGeometryStreams: + case SpvCapabilityFloat16: + case SpvCapabilityInt8: return true; - default: - break; } return false; } @@ -110,29 +104,27 @@ bool IsSupportOptionalVulkan_1_0(uint32_t capability) { bool IsSupportOptionalVulkan_1_1(uint32_t capability) { if (IsSupportOptionalVulkan_1_0(capability)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::GroupNonUniform: - case spv::Capability::GroupNonUniformVote: - case spv::Capability::GroupNonUniformArithmetic: - case spv::Capability::GroupNonUniformBallot: - case spv::Capability::GroupNonUniformShuffle: - case spv::Capability::GroupNonUniformShuffleRelative: - case spv::Capability::GroupNonUniformClustered: - case spv::Capability::GroupNonUniformQuad: - case spv::Capability::DrawParameters: - // Alias spv::Capability::StorageBuffer16BitAccess. - case spv::Capability::StorageUniformBufferBlock16: - // Alias spv::Capability::UniformAndStorageBuffer16BitAccess. - case spv::Capability::StorageUniform16: - case spv::Capability::StoragePushConstant16: - case spv::Capability::StorageInputOutput16: - case spv::Capability::DeviceGroup: - case spv::Capability::MultiView: - case spv::Capability::VariablePointersStorageBuffer: - case spv::Capability::VariablePointers: + switch (capability) { + case SpvCapabilityGroupNonUniform: + case SpvCapabilityGroupNonUniformVote: + case SpvCapabilityGroupNonUniformArithmetic: + case SpvCapabilityGroupNonUniformBallot: + case SpvCapabilityGroupNonUniformShuffle: + case SpvCapabilityGroupNonUniformShuffleRelative: + case SpvCapabilityGroupNonUniformClustered: + case SpvCapabilityGroupNonUniformQuad: + case SpvCapabilityDrawParameters: + // Alias SpvCapabilityStorageBuffer16BitAccess. + case SpvCapabilityStorageUniformBufferBlock16: + // Alias SpvCapabilityUniformAndStorageBuffer16BitAccess. + case SpvCapabilityStorageUniform16: + case SpvCapabilityStoragePushConstant16: + case SpvCapabilityStorageInputOutput16: + case SpvCapabilityDeviceGroup: + case SpvCapabilityMultiView: + case SpvCapabilityVariablePointersStorageBuffer: + case SpvCapabilityVariablePointers: return true; - default: - break; } return false; } @@ -140,51 +132,47 @@ bool IsSupportOptionalVulkan_1_1(uint32_t capability) { bool IsSupportOptionalVulkan_1_2(uint32_t capability) { if (IsSupportOptionalVulkan_1_1(capability)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::DenormPreserve: - case spv::Capability::DenormFlushToZero: - case spv::Capability::SignedZeroInfNanPreserve: - case spv::Capability::RoundingModeRTE: - case spv::Capability::RoundingModeRTZ: - case spv::Capability::VulkanMemoryModel: - case spv::Capability::VulkanMemoryModelDeviceScope: - case spv::Capability::StorageBuffer8BitAccess: - case spv::Capability::UniformAndStorageBuffer8BitAccess: - case spv::Capability::StoragePushConstant8: - case spv::Capability::ShaderViewportIndex: - case spv::Capability::ShaderLayer: - case spv::Capability::PhysicalStorageBufferAddresses: - case spv::Capability::RuntimeDescriptorArray: - case spv::Capability::UniformTexelBufferArrayDynamicIndexing: - case spv::Capability::StorageTexelBufferArrayDynamicIndexing: - case spv::Capability::UniformBufferArrayNonUniformIndexing: - case spv::Capability::SampledImageArrayNonUniformIndexing: - case spv::Capability::StorageBufferArrayNonUniformIndexing: - case spv::Capability::StorageImageArrayNonUniformIndexing: - case spv::Capability::InputAttachmentArrayNonUniformIndexing: - case spv::Capability::UniformTexelBufferArrayNonUniformIndexing: - case spv::Capability::StorageTexelBufferArrayNonUniformIndexing: + switch (capability) { + case SpvCapabilityDenormPreserve: + case SpvCapabilityDenormFlushToZero: + case SpvCapabilitySignedZeroInfNanPreserve: + case SpvCapabilityRoundingModeRTE: + case SpvCapabilityRoundingModeRTZ: + case SpvCapabilityVulkanMemoryModel: + case SpvCapabilityVulkanMemoryModelDeviceScope: + case SpvCapabilityStorageBuffer8BitAccess: + case SpvCapabilityUniformAndStorageBuffer8BitAccess: + case SpvCapabilityStoragePushConstant8: + case SpvCapabilityShaderViewportIndex: + case SpvCapabilityShaderLayer: + case SpvCapabilityPhysicalStorageBufferAddresses: + case SpvCapabilityRuntimeDescriptorArray: + case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: + case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: + case SpvCapabilityUniformBufferArrayNonUniformIndexing: + case SpvCapabilitySampledImageArrayNonUniformIndexing: + case SpvCapabilityStorageBufferArrayNonUniformIndexing: + case SpvCapabilityStorageImageArrayNonUniformIndexing: + case SpvCapabilityInputAttachmentArrayNonUniformIndexing: + case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: + case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: return true; - default: - break; } return false; } bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) { - switch (spv::Capability(capability)) { - case spv::Capability::Addresses: - case spv::Capability::Float16Buffer: - case spv::Capability::Int16: - case spv::Capability::Int8: - case spv::Capability::Kernel: - case spv::Capability::Linkage: - case spv::Capability::Vector16: + switch (capability) { + case SpvCapabilityAddresses: + case SpvCapabilityFloat16Buffer: + case SpvCapabilityInt16: + case SpvCapabilityInt8: + case SpvCapabilityKernel: + case SpvCapabilityLinkage: + case SpvCapabilityVector16: return true; - case spv::Capability::Int64: + case SpvCapabilityInt64: return !embedded_profile; - default: - break; } return false; } @@ -192,14 +180,12 @@ bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) { bool IsSupportGuaranteedOpenCL_2_0(uint32_t capability, bool embedded_profile) { if (IsSupportGuaranteedOpenCL_1_2(capability, embedded_profile)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::DeviceEnqueue: - case spv::Capability::GenericPointer: - case spv::Capability::Groups: - case spv::Capability::Pipes: + switch (capability) { + case SpvCapabilityDeviceEnqueue: + case SpvCapabilityGenericPointer: + case SpvCapabilityGroups: + case SpvCapabilityPipes: return true; - default: - break; } return false; } @@ -207,23 +193,19 @@ bool IsSupportGuaranteedOpenCL_2_0(uint32_t capability, bool embedded_profile) { bool IsSupportGuaranteedOpenCL_2_2(uint32_t capability, bool embedded_profile) { if (IsSupportGuaranteedOpenCL_2_0(capability, embedded_profile)) return true; - switch (spv::Capability(capability)) { - case spv::Capability::SubgroupDispatch: - case spv::Capability::PipeStorage: + switch (capability) { + case SpvCapabilitySubgroupDispatch: + case SpvCapabilityPipeStorage: return true; - default: - break; } return false; } bool IsSupportOptionalOpenCL_1_2(uint32_t capability) { - switch (spv::Capability(capability)) { - case spv::Capability::ImageBasic: - case spv::Capability::Float64: + switch (capability) { + case SpvCapabilityImageBasic: + case SpvCapabilityFloat64: return true; - default: - break; } return false; } @@ -240,23 +222,21 @@ bool IsEnabledByExtension(ValidationState_t& _, uint32_t capability) { ExtensionSet operand_exts(operand_desc->numExtensions, operand_desc->extensions); - if (operand_exts.empty()) return false; + if (operand_exts.IsEmpty()) return false; return _.HasAnyOfExtensions(operand_exts); } bool IsEnabledByCapabilityOpenCL_1_2(ValidationState_t& _, uint32_t capability) { - if (_.HasCapability(spv::Capability::ImageBasic)) { - switch (spv::Capability(capability)) { - case spv::Capability::LiteralSampler: - case spv::Capability::Sampled1D: - case spv::Capability::Image1D: - case spv::Capability::SampledBuffer: - case spv::Capability::ImageBuffer: + if (_.HasCapability(SpvCapabilityImageBasic)) { + switch (capability) { + case SpvCapabilityLiteralSampler: + case SpvCapabilitySampled1D: + case SpvCapabilityImage1D: + case SpvCapabilitySampledBuffer: + case SpvCapabilityImageBuffer: return true; - default: - break; } return false; } @@ -265,17 +245,15 @@ bool IsEnabledByCapabilityOpenCL_1_2(ValidationState_t& _, bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, uint32_t capability) { - if (_.HasCapability(spv::Capability::ImageBasic)) { - switch (spv::Capability(capability)) { - case spv::Capability::ImageReadWrite: - case spv::Capability::LiteralSampler: - case spv::Capability::Sampled1D: - case spv::Capability::Image1D: - case spv::Capability::SampledBuffer: - case spv::Capability::ImageBuffer: + if (_.HasCapability(SpvCapabilityImageBasic)) { + switch (capability) { + case SpvCapabilityImageReadWrite: + case SpvCapabilityLiteralSampler: + case SpvCapabilitySampled1D: + case SpvCapabilityImage1D: + case SpvCapabilitySampledBuffer: + case SpvCapabilityImageBuffer: return true; - default: - break; } return false; } @@ -287,7 +265,7 @@ bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, // Validates that capability declarations use operands allowed in the current // context. spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { - if (inst->opcode() != spv::Op::OpCapability) return SPV_SUCCESS; + if (inst->opcode() != SpvOpCapability) return SPV_SUCCESS; assert(inst->operands().size() == 1); diff --git a/source/val/validate_cfg.cpp b/source/val/validate_cfg.cpp index 7b3f7480..cc0b999f 100644 --- a/source/val/validate_cfg.cpp +++ b/source/val/validate_cfg.cpp @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include +#include #include #include #include @@ -26,6 +28,7 @@ #include "source/cfa.h" #include "source/opcode.h" #include "source/spirv_constant.h" +#include "source/spirv_target_env.h" #include "source/spirv_validator_options.h" #include "source/val/basic_block.h" #include "source/val/construct.h" @@ -51,7 +54,7 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { << "OpPhi must not have void result type"; } if (_.IsPointerType(inst->type_id()) && - _.addressing_model() == spv::AddressingModel::Logical) { + _.addressing_model() == SpvAddressingModelLogical) { if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using pointers with OpPhi requires capability " @@ -61,14 +64,13 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { const Instruction* type_inst = _.FindDef(inst->type_id()); assert(type_inst); - const spv::Op type_opcode = type_inst->opcode(); + const SpvOp type_opcode = type_inst->opcode(); if (!_.options()->before_hlsl_legalization && - !_.HasCapability(spv::Capability::BindlessTextureNV)) { - if (type_opcode == spv::Op::OpTypeSampledImage || - (_.HasCapability(spv::Capability::Shader) && - (type_opcode == spv::Op::OpTypeImage || - type_opcode == spv::Op::OpTypeSampler))) { + !_.HasCapability(SpvCapabilityBindlessTextureNV)) { + if (type_opcode == SpvOpTypeSampledImage || + (_.HasCapability(SpvCapabilityShader) && + (type_opcode == SpvOpTypeImage || type_opcode == SpvOpTypeSampler))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result type cannot be Op" << spvOpcodeString(type_opcode); } @@ -106,7 +108,7 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) { << " type " << _.getIdName(inc_type_id) << "."; } } else { - if (_.GetIdOpcode(inc_id) != spv::Op::OpLabel) { + if (_.GetIdOpcode(inc_id) != SpvOpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpPhi's incoming basic block " << _.getIdName(inc_id) << " is not an OpLabel."; @@ -141,7 +143,7 @@ spv_result_t ValidateBranch(ValidationState_t& _, const Instruction* inst) { // target operands must be OpLabel const auto id = inst->GetOperandAs(0); const auto target = _.FindDef(id); - if (!target || spv::Op::OpLabel != target->opcode()) { + if (!target || SpvOpLabel != target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "'Target Label' operands for OpBranch must be the ID " "of an OpLabel instruction"; @@ -176,7 +178,7 @@ spv_result_t ValidateBranchConditional(ValidationState_t& _, // PerformCfgChecks already checks for that const auto true_id = inst->GetOperandAs(1); const auto true_target = _.FindDef(true_id); - if (!true_target || spv::Op::OpLabel != true_target->opcode()) { + if (!true_target || SpvOpLabel != true_target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The 'True Label' operand for OpBranchConditional must be the " "ID of an OpLabel instruction"; @@ -184,7 +186,7 @@ spv_result_t ValidateBranchConditional(ValidationState_t& _, const auto false_id = inst->GetOperandAs(2); const auto false_target = _.FindDef(false_id); - if (!false_target || spv::Op::OpLabel != false_target->opcode()) { + if (!false_target || SpvOpLabel != false_target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The 'False Label' operand for OpBranchConditional must be the " "ID of an OpLabel instruction"; @@ -211,7 +213,7 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) { } const auto default_label = _.FindDef(inst->GetOperandAs(1)); - if (default_label->opcode() != spv::Op::OpLabel) { + if (default_label->opcode() != SpvOpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Default must be an OpLabel instruction"; } @@ -221,7 +223,7 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) { // literal, id const auto id = inst->GetOperandAs(i + 1); const auto target = _.FindDef(id); - if (!target || spv::Op::OpLabel != target->opcode()) { + if (!target || SpvOpLabel != target->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "'Target Label' operands for OpSwitch must be IDs of an " "OpLabel instruction"; @@ -241,14 +243,14 @@ spv_result_t ValidateReturnValue(ValidationState_t& _, << " does not represent a value."; } auto value_type = _.FindDef(value->type_id()); - if (!value_type || spv::Op::OpTypeVoid == value_type->opcode()) { + if (!value_type || SpvOpTypeVoid == value_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpReturnValue value's type " << _.getIdName(value->type_id()) << " is missing or void."; } - if (_.addressing_model() == spv::AddressingModel::Logical && - spv::Op::OpTypePointer == value_type->opcode() && + if (_.addressing_model() == SpvAddressingModelLogical && + SpvOpTypePointer == value_type->opcode() && !_.features().variable_pointers && !_.options()->relax_logical_pointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpReturnValue value's type " @@ -268,15 +270,10 @@ spv_result_t ValidateReturnValue(ValidationState_t& _, return SPV_SUCCESS; } -uint32_t operator>>(const spv::LoopControlShift& lhs, - const spv::LoopControlShift& rhs) { - return uint32_t(lhs) >> uint32_t(rhs); -} - spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { const auto merge_id = inst->GetOperandAs(0); const auto merge = _.FindDef(merge_id); - if (!merge || merge->opcode() != spv::Op::OpLabel) { + if (!merge || merge->opcode() != SpvOpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel"; } @@ -287,7 +284,7 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { const auto continue_id = inst->GetOperandAs(1); const auto continue_target = _.FindDef(continue_id); - if (!continue_target || continue_target->opcode() != spv::Op::OpLabel) { + if (!continue_target || continue_target->opcode() != SpvOpLabel) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Continue Target " << _.getIdName(continue_id) << " must be an OpLabel"; @@ -298,36 +295,36 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { << "Merge Block and Continue Target must be different ids"; } - const auto loop_control = inst->GetOperandAs(2); - if ((loop_control >> spv::LoopControlShift::Unroll) & 0x1 && - (loop_control >> spv::LoopControlShift::DontUnroll) & 0x1) { + const auto loop_control = inst->GetOperandAs(2); + if ((loop_control >> SpvLoopControlUnrollShift) & 0x1 && + (loop_control >> SpvLoopControlDontUnrollShift) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Unroll and DontUnroll loop controls must not both be specified"; } - if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && - (loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { + if ((loop_control >> SpvLoopControlDontUnrollShift) & 0x1 && + (loop_control >> SpvLoopControlPeelCountShift) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PeelCount and DontUnroll " "loop controls must not " "both be specified"; } - if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 && - (loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { + if ((loop_control >> SpvLoopControlDontUnrollShift) & 0x1 && + (loop_control >> SpvLoopControlPartialCountShift) & 0x1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PartialCount and " "DontUnroll loop controls " "must not both be specified"; } uint32_t operand = 3; - if ((loop_control >> spv::LoopControlShift::DependencyLength) & 0x1) { + if ((loop_control >> SpvLoopControlDependencyLengthShift) & 0x1) { ++operand; } - if ((loop_control >> spv::LoopControlShift::MinIterations) & 0x1) { + if ((loop_control >> SpvLoopControlMinIterationsShift) & 0x1) { ++operand; } - if ((loop_control >> spv::LoopControlShift::MaxIterations) & 0x1) { + if ((loop_control >> SpvLoopControlMaxIterationsShift) & 0x1) { ++operand; } - if ((loop_control >> spv::LoopControlShift::IterationMultiple) & 0x1) { + if ((loop_control >> SpvLoopControlIterationMultipleShift) & 0x1) { if (inst->operands().size() < operand || inst->GetOperandAs(operand) == 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "IterationMultiple loop " @@ -336,10 +333,10 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) { } ++operand; } - if ((loop_control >> spv::LoopControlShift::PeelCount) & 0x1) { + if ((loop_control >> SpvLoopControlPeelCountShift) & 0x1) { ++operand; } - if ((loop_control >> spv::LoopControlShift::PartialCount) & 0x1) { + if ((loop_control >> SpvLoopControlPartialCountShift) & 0x1) { ++operand; } @@ -557,7 +554,7 @@ spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function, target_block->structurally_reachable() && !header->structurally_dominates(*target_block)) { return _.diag(SPV_ERROR_INVALID_CFG, header->label()) - << "Switch header " << _.getIdName(header->id()) + << "Selection header " << _.getIdName(header->id()) << " does not structurally dominate its case construct " << _.getIdName(target); } @@ -647,9 +644,9 @@ spv_result_t ValidateStructuredSelections( const auto index = terminator - &_.ordered_instructions()[0]; auto* merge = &_.ordered_instructions()[index - 1]; // Marks merges and continues as seen. - if (merge->opcode() == spv::Op::OpSelectionMerge) { + if (merge->opcode() == SpvOpSelectionMerge) { seen.insert(merge->GetOperandAs(0)); - } else if (merge->opcode() == spv::Op::OpLoopMerge) { + } else if (merge->opcode() == SpvOpLoopMerge) { seen.insert(merge->GetOperandAs(0)); seen.insert(merge->GetOperandAs(1)); } else { @@ -660,7 +657,7 @@ spv_result_t ValidateStructuredSelections( // Skip unreachable blocks. if (!block->structurally_reachable()) continue; - if (terminator->opcode() == spv::Op::OpBranchConditional) { + if (terminator->opcode() == SpvOpBranchConditional) { const auto true_label = terminator->GetOperandAs(1); const auto false_label = terminator->GetOperandAs(2); // Mark the upcoming blocks as seen now, but only error out if this block @@ -668,12 +665,11 @@ spv_result_t ValidateStructuredSelections( // previously. const bool true_label_unseen = seen.insert(true_label).second; const bool false_label_unseen = seen.insert(false_label).second; - if ((!merge || merge->opcode() == spv::Op::OpLoopMerge) && - true_label_unseen && false_label_unseen) { + if (!merge && true_label_unseen && false_label_unseen) { return _.diag(SPV_ERROR_INVALID_CFG, terminator) << "Selection must be structured"; } - } else if (terminator->opcode() == spv::Op::OpSwitch) { + } else if (terminator->opcode() == SpvOpSwitch) { if (!merge) { return _.diag(SPV_ERROR_INVALID_CFG, terminator) << "OpSwitch must be preceded by an OpSelectionMerge " @@ -750,7 +746,6 @@ spv_result_t StructuredControlFlowChecks( _.getIdName(merge->id()), "does not structurally dominate"); } - // If it's really a merge block for a selection or loop, then it must be // *strictly* structrually dominated by the header. if (construct.ExitBlockIsMergeBlock() && (header == merge)) { @@ -803,8 +798,8 @@ spv_result_t StructuredControlFlowChecks( block->is_type(BlockType::kBlockTypeLoop)) { size_t index = (block->terminator() - &_.ordered_instructions()[0]) - 1; const auto& merge_inst = _.ordered_instructions()[index]; - if (merge_inst.opcode() == spv::Op::OpSelectionMerge || - merge_inst.opcode() == spv::Op::OpLoopMerge) { + if (merge_inst.opcode() == SpvOpSelectionMerge || + merge_inst.opcode() == SpvOpLoopMerge) { uint32_t merge_id = merge_inst.GetOperandAs(0); auto merge_block = function->GetBlock(merge_id).first; if (merge_block->structurally_reachable() && @@ -859,7 +854,7 @@ spv_result_t StructuredControlFlowChecks( // Checks rules for case constructs. if (construct.type() == ConstructType::kSelection && - header->terminator()->opcode() == spv::Op::OpSwitch) { + header->terminator()->opcode() == SpvOpSwitch) { const auto terminator = header->terminator(); if (auto error = StructuredSwitchChecks(_, function, terminator, header, merge)) { @@ -933,7 +928,7 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } // If we have structured control flow, check that no block has a control // flow nesting depth larger than the limit. - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { const int control_flow_nesting_depth_limit = _.options()->universal_limits_.max_control_flow_nesting_depth; for (auto block = begin(blocks); block != end(blocks); ++block) { @@ -947,7 +942,7 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } /// Structured control flow checks are only required for shader capabilities - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { // Calculate structural dominance. postorder.clear(); std::vector postdom_postorder; @@ -1003,9 +998,9 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { } spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); switch (opcode) { - case spv::Op::OpLabel: + case SpvOpLabel: if (auto error = _.current_function().RegisterBlock(inst->id())) return error; @@ -1014,7 +1009,7 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { // passes the OpLabel ends up not being part of the basic block it starts. _.current_function().current_block()->set_label(inst); break; - case spv::Op::OpLoopMerge: { + case SpvOpLoopMerge: { uint32_t merge_block = inst->GetOperandAs(0); uint32_t continue_block = inst->GetOperandAs(1); CFG_ASSERT(MergeBlockAssert, merge_block); @@ -1023,20 +1018,20 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { continue_block)) return error; } break; - case spv::Op::OpSelectionMerge: { + case SpvOpSelectionMerge: { uint32_t merge_block = inst->GetOperandAs(0); CFG_ASSERT(MergeBlockAssert, merge_block); if (auto error = _.current_function().RegisterSelectionMerge(merge_block)) return error; } break; - case spv::Op::OpBranch: { + case SpvOpBranch: { uint32_t target = inst->GetOperandAs(0); CFG_ASSERT(FirstBlockAssert, target); _.current_function().RegisterBlockEnd({target}); } break; - case spv::Op::OpBranchConditional: { + case SpvOpBranchConditional: { uint32_t tlabel = inst->GetOperandAs(1); uint32_t flabel = inst->GetOperandAs(2); CFG_ASSERT(FirstBlockAssert, tlabel); @@ -1045,7 +1040,7 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { _.current_function().RegisterBlockEnd({tlabel, flabel}); } break; - case spv::Op::OpSwitch: { + case SpvOpSwitch: { std::vector cases; for (size_t i = 1; i < inst->operands().size(); i += 2) { uint32_t target = inst->GetOperandAs(i); @@ -1054,44 +1049,44 @@ spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) { } _.current_function().RegisterBlockEnd({cases}); } break; - case spv::Op::OpReturn: { + case SpvOpReturn: { const uint32_t return_type = _.current_function().GetResultTypeId(); const Instruction* return_type_inst = _.FindDef(return_type); assert(return_type_inst); - if (return_type_inst->opcode() != spv::Op::OpTypeVoid) + if (return_type_inst->opcode() != SpvOpTypeVoid) return _.diag(SPV_ERROR_INVALID_CFG, inst) << "OpReturn can only be called from a function with void " << "return type."; _.current_function().RegisterBlockEnd(std::vector()); break; } - case spv::Op::OpKill: - case spv::Op::OpReturnValue: - case spv::Op::OpUnreachable: - case spv::Op::OpTerminateInvocation: - case spv::Op::OpIgnoreIntersectionKHR: - case spv::Op::OpTerminateRayKHR: - case spv::Op::OpEmitMeshTasksEXT: + case SpvOpKill: + case SpvOpReturnValue: + case SpvOpUnreachable: + case SpvOpTerminateInvocation: + case SpvOpIgnoreIntersectionKHR: + case SpvOpTerminateRayKHR: + case SpvOpEmitMeshTasksEXT: _.current_function().RegisterBlockEnd(std::vector()); // Ops with dedicated passes check for the Execution Model there - if (opcode == spv::Op::OpKill) { + if (opcode == SpvOpKill) { _.current_function().RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, "OpKill requires Fragment execution model"); } - if (opcode == spv::Op::OpTerminateInvocation) { + if (opcode == SpvOpTerminateInvocation) { _.current_function().RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, "OpTerminateInvocation requires Fragment execution model"); } - if (opcode == spv::Op::OpIgnoreIntersectionKHR) { + if (opcode == SpvOpIgnoreIntersectionKHR) { _.current_function().RegisterExecutionModelLimitation( - spv::ExecutionModel::AnyHitKHR, + SpvExecutionModelAnyHitKHR, "OpIgnoreIntersectionKHR requires AnyHitKHR execution model"); } - if (opcode == spv::Op::OpTerminateRayKHR) { + if (opcode == SpvOpTerminateRayKHR) { _.current_function().RegisterExecutionModelLimitation( - spv::ExecutionModel::AnyHitKHR, + SpvExecutionModelAnyHitKHR, "OpTerminateRayKHR requires AnyHitKHR execution model"); } @@ -1145,22 +1140,22 @@ void ReachabilityPass(ValidationState_t& _) { spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpPhi: + case SpvOpPhi: if (auto error = ValidatePhi(_, inst)) return error; break; - case spv::Op::OpBranch: + case SpvOpBranch: if (auto error = ValidateBranch(_, inst)) return error; break; - case spv::Op::OpBranchConditional: + case SpvOpBranchConditional: if (auto error = ValidateBranchConditional(_, inst)) return error; break; - case spv::Op::OpReturnValue: + case SpvOpReturnValue: if (auto error = ValidateReturnValue(_, inst)) return error; break; - case spv::Op::OpSwitch: + case SpvOpSwitch: if (auto error = ValidateSwitch(_, inst)) return error; break; - case spv::Op::OpLoopMerge: + case SpvOpLoopMerge: if (auto error = ValidateLoopMerge(_, inst)) return error; break; default: diff --git a/source/val/validate_composites.cpp b/source/val/validate_composites.cpp index ed043b68..c3d948dc 100644 --- a/source/val/validate_composites.cpp +++ b/source/val/validate_composites.cpp @@ -14,10 +14,12 @@ // Validates correctness of composite SPIR-V instructions. +#include "source/val/validate.h" + +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -33,10 +35,9 @@ namespace { spv_result_t GetExtractInsertValueType(ValidationState_t& _, const Instruction* inst, uint32_t* member_type) { - const spv::Op opcode = inst->opcode(); - assert(opcode == spv::Op::OpCompositeExtract || - opcode == spv::Op::OpCompositeInsert); - uint32_t word_index = opcode == spv::Op::OpCompositeExtract ? 4 : 5; + const SpvOp opcode = inst->opcode(); + assert(opcode == SpvOpCompositeExtract || opcode == SpvOpCompositeInsert); + uint32_t word_index = opcode == SpvOpCompositeExtract ? 4 : 5; const uint32_t num_words = static_cast(inst->words().size()); const uint32_t composite_id_index = word_index - 1; const uint32_t num_indices = num_words - word_index; @@ -65,7 +66,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, const Instruction* const type_inst = _.FindDef(*member_type); assert(type_inst); switch (type_inst->opcode()) { - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { *member_type = type_inst->word(2); const uint32_t vector_size = type_inst->word(3); if (component_index >= vector_size) { @@ -75,7 +76,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { *member_type = type_inst->word(2); const uint32_t num_cols = type_inst->word(3); if (component_index >= num_cols) { @@ -85,7 +86,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { uint64_t array_size = 0; auto size = _.FindDef(type_inst->word(3)); *member_type = type_inst->word(2); @@ -104,12 +105,12 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, } break; } - case spv::Op::OpTypeRuntimeArray: { + case SpvOpTypeRuntimeArray: { *member_type = type_inst->word(2); // Array size is unknown. break; } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const size_t num_struct_members = type_inst->words().size() - 2; if (component_index >= num_struct_members) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -122,8 +123,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, *member_type = type_inst->word(component_index + 2); break; } - case spv::Op::OpTypeCooperativeMatrixKHR: - case spv::Op::OpTypeCooperativeMatrixNV: { + case SpvOpTypeCooperativeMatrixNV: { *member_type = type_inst->word(2); break; } @@ -140,15 +140,15 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _, spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - const spv::Op result_opcode = _.GetIdOpcode(result_type); + const SpvOp result_opcode = _.GetIdOpcode(result_type); if (!spvOpcodeIsScalarType(result_opcode)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a scalar type"; } const uint32_t vector_type = _.GetOperandTypeId(inst, 2); - const spv::Op vector_opcode = _.GetIdOpcode(vector_type); - if (vector_opcode != spv::Op::OpTypeVector) { + const SpvOp vector_opcode = _.GetIdOpcode(vector_type); + if (vector_opcode != SpvOpTypeVector) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Vector type to be OpTypeVector"; } @@ -164,7 +164,7 @@ spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, << "Expected Index to be int scalar"; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot extract from a vector of 8- or 16-bit types"; @@ -175,8 +175,8 @@ spv_result_t ValidateVectorExtractDynamic(ValidationState_t& _, spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - const spv::Op result_opcode = _.GetIdOpcode(result_type); - if (result_opcode != spv::Op::OpTypeVector) { + const SpvOp result_opcode = _.GetIdOpcode(result_type); + if (result_opcode != SpvOpTypeVector) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeVector"; } @@ -200,7 +200,7 @@ spv_result_t ValidateVectorInsertDyanmic(ValidationState_t& _, << "Expected Index to be int scalar"; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot insert into a vector of 8- or 16-bit types"; @@ -212,9 +212,9 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, const Instruction* inst) { const uint32_t num_operands = static_cast(inst->operands().size()); const uint32_t result_type = inst->type_id(); - const spv::Op result_opcode = _.GetIdOpcode(result_type); + const SpvOp result_opcode = _.GetIdOpcode(result_type); switch (result_opcode) { - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { const uint32_t num_result_components = _.GetDimension(result_type); const uint32_t result_component_type = _.GetComponentType(result_type); uint32_t given_component_count = 0; @@ -230,7 +230,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, if (operand_type == result_component_type) { ++given_component_count; } else { - if (_.GetIdOpcode(operand_type) != spv::Op::OpTypeVector || + if (_.GetIdOpcode(operand_type) != SpvOpTypeVector || _.GetComponentType(operand_type) != result_component_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Constituents to be scalars or vectors of" @@ -249,7 +249,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { uint32_t result_num_rows = 0; uint32_t result_num_cols = 0; uint32_t result_col_type = 0; @@ -277,10 +277,10 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { const Instruction* const array_inst = _.FindDef(result_type); assert(array_inst); - assert(array_inst->opcode() == spv::Op::OpTypeArray); + assert(array_inst->opcode() == SpvOpTypeArray); auto size = _.FindDef(array_inst->word(3)); if (spvOpcodeIsSpecConstant(size->opcode())) { @@ -312,10 +312,10 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const Instruction* const struct_inst = _.FindDef(result_type); assert(struct_inst); - assert(struct_inst->opcode() == spv::Op::OpTypeStruct); + assert(struct_inst->opcode() == SpvOpTypeStruct); if (struct_inst->operands().size() + 1 != num_operands) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -336,26 +336,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, break; } - case spv::Op::OpTypeCooperativeMatrixKHR: { - const auto result_type_inst = _.FindDef(result_type); - assert(result_type_inst); - const auto component_type_id = - result_type_inst->GetOperandAs(1); - - if (3 != num_operands) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Must be only one constituent"; - } - - const uint32_t operand_type_id = _.GetOperandTypeId(inst, 2); - - if (operand_type_id != component_type_id) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Constituent type to be equal to the component type"; - } - break; - } - case spv::Op::OpTypeCooperativeMatrixNV: { + case SpvOpTypeCooperativeMatrixNV: { const auto result_type_inst = _.FindDef(result_type); assert(result_type_inst); const auto component_type_id = @@ -381,7 +362,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _, } } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot create a composite containing 8- or 16-bit types"; @@ -405,7 +386,7 @@ spv_result_t ValidateCompositeExtract(ValidationState_t& _, << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot extract from a composite of 8- or 16-bit types"; @@ -440,7 +421,7 @@ spv_result_t ValidateCompositeInsert(ValidationState_t& _, << spvOpcodeString(_.GetIdOpcode(member_type)) << ")."; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot insert into a composite of 8- or 16-bit types"; @@ -499,7 +480,7 @@ spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { << "to be the reverse of those of Result Type"; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot transpose matrices of 16-bit floats"; @@ -510,12 +491,11 @@ spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateVectorShuffle(ValidationState_t& _, const Instruction* inst) { auto resultType = _.FindDef(inst->type_id()); - if (!resultType || resultType->opcode() != spv::Op::OpTypeVector) { + if (!resultType || resultType->opcode() != SpvOpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Result Type of OpVectorShuffle must be" << " OpTypeVector. Found Op" - << spvOpcodeString(static_cast(resultType->opcode())) - << "."; + << spvOpcodeString(static_cast(resultType->opcode())) << "."; } // The number of components in Result Type must be the same as the number of @@ -535,11 +515,11 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, auto vector1Type = _.FindDef(vector1Object->type_id()); auto vector2Object = _.FindDef(inst->GetOperandAs(3)); auto vector2Type = _.FindDef(vector2Object->type_id()); - if (!vector1Type || vector1Type->opcode() != spv::Op::OpTypeVector) { + if (!vector1Type || vector1Type->opcode() != SpvOpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The type of Vector 1 must be OpTypeVector."; } - if (!vector2Type || vector2Type->opcode() != spv::Op::OpTypeVector) { + if (!vector2Type || vector2Type->opcode() != SpvOpTypeVector) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The type of Vector 2 must be OpTypeVector."; } @@ -568,7 +548,7 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, } } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot shuffle a vector of 8- or 16-bit types"; @@ -592,7 +572,7 @@ spv_result_t ValidateCopyLogical(ValidationState_t& _, << "Result Type does not logically match the Operand type"; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Cannot copy composites of 8- or 16-bit types"; @@ -606,23 +586,23 @@ spv_result_t ValidateCopyLogical(ValidationState_t& _, // Validates correctness of composite instructions. spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpVectorExtractDynamic: + case SpvOpVectorExtractDynamic: return ValidateVectorExtractDynamic(_, inst); - case spv::Op::OpVectorInsertDynamic: + case SpvOpVectorInsertDynamic: return ValidateVectorInsertDyanmic(_, inst); - case spv::Op::OpVectorShuffle: + case SpvOpVectorShuffle: return ValidateVectorShuffle(_, inst); - case spv::Op::OpCompositeConstruct: + case SpvOpCompositeConstruct: return ValidateCompositeConstruct(_, inst); - case spv::Op::OpCompositeExtract: + case SpvOpCompositeExtract: return ValidateCompositeExtract(_, inst); - case spv::Op::OpCompositeInsert: + case SpvOpCompositeInsert: return ValidateCompositeInsert(_, inst); - case spv::Op::OpCopyObject: + case SpvOpCopyObject: return ValidateCopyObject(_, inst); - case spv::Op::OpTranspose: + case SpvOpTranspose: return ValidateTranspose(_, inst); - case spv::Op::OpCopyLogical: + case SpvOpCopyLogical: return ValidateCopyLogical(_, inst); default: break; diff --git a/source/val/validate_constants.cpp b/source/val/validate_constants.cpp index 4deaa496..fdfaea5f 100644 --- a/source/val/validate_constants.cpp +++ b/source/val/validate_constants.cpp @@ -24,7 +24,7 @@ namespace { spv_result_t ValidateConstantBool(ValidationState_t& _, const Instruction* inst) { auto type = _.FindDef(inst->type_id()); - if (!type || type->opcode() != spv::Op::OpTypeBool) { + if (!type || type->opcode() != SpvOpTypeBool) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Op" << spvOpcodeString(inst->opcode()) << " Result Type " << _.getIdName(inst->type_id()) << " is not a boolean type."; @@ -46,7 +46,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, const auto constituent_count = inst->words().size() - 3; switch (result_type->opcode()) { - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { const auto component_count = result_type->GetOperandAs(2); if (component_count != constituent_count) { // TODO: Output ID's on diagnostic @@ -76,7 +76,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } const auto constituent_result_type = _.FindDef(constituent->type_id()); if (!constituent_result_type || - component_type->id() != constituent_result_type->id()) { + component_type->opcode() != constituent_result_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opcode_name << " Constituent " << _.getIdName(constituent_id) @@ -85,7 +85,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { const auto column_count = result_type->GetOperandAs(2); if (column_count != constituent_count) { // TODO: Output ID's on diagnostic @@ -155,7 +155,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { auto element_type = _.FindDef(result_type->GetOperandAs(1)); if (!element_type) { return _.diag(SPV_ERROR_INVALID_ID, result_type) @@ -203,7 +203,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const auto member_count = result_type->words().size() - 2; if (member_count != constituent_count) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -243,8 +243,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, } } } break; - case spv::Op::OpTypeCooperativeMatrixKHR: - case spv::Op::OpTypeCooperativeMatrixNV: { + case SpvOpTypeCooperativeMatrixNV: { if (1 != constituent_count) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opcode_name << " Constituent " @@ -282,7 +281,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _, spv_result_t ValidateConstantSampler(ValidationState_t& _, const Instruction* inst) { const auto result_type = _.FindDef(inst->type_id()); - if (!result_type || result_type->opcode() != spv::Op::OpTypeSampler) { + if (!result_type || result_type->opcode() != SpvOpTypeSampler) { return _.diag(SPV_ERROR_INVALID_ID, result_type) << "OpConstantSampler Result Type " << _.getIdName(inst->type_id()) << " is not a sampler type."; @@ -299,24 +298,23 @@ bool IsTypeNullable(const std::vector& instruction, uint16_t opcode; uint16_t word_count; spvOpcodeSplit(instruction[0], &word_count, &opcode); - switch (static_cast(opcode)) { - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeEvent: - case spv::Op::OpTypeDeviceEvent: - case spv::Op::OpTypeReserveId: - case spv::Op::OpTypeQueue: + switch (static_cast(opcode)) { + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: + case SpvOpTypeEvent: + case SpvOpTypeDeviceEvent: + case SpvOpTypeReserveId: + case SpvOpTypeQueue: return true; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: - case spv::Op::OpTypeVector: { + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeCooperativeMatrixNV: + case SpvOpTypeVector: { auto base_type = _.FindDef(instruction[2]); return base_type && IsTypeNullable(base_type->words(), _); } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { for (size_t elementIndex = 2; elementIndex < instruction.size(); ++elementIndex) { auto element = _.FindDef(instruction[elementIndex]); @@ -324,9 +322,8 @@ bool IsTypeNullable(const std::vector& instruction, } return true; } - case spv::Op::OpTypePointer: - if (spv::StorageClass(instruction[2]) == - spv::StorageClass::PhysicalStorageBuffer) { + case SpvOpTypePointer: + if (instruction[2] == SpvStorageClassPhysicalStorageBuffer) { return false; } return true; @@ -354,8 +351,7 @@ spv_result_t ValidateSpecConstant(ValidationState_t& _, auto type_id = inst->GetOperandAs(0); auto type_instruction = _.FindDef(type_id); auto type_opcode = type_instruction->opcode(); - if (type_opcode != spv::Op::OpTypeInt && - type_opcode != spv::Op::OpTypeFloat) { + if (type_opcode != SpvOpTypeInt && type_opcode != SpvOpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Specialization constant " "must be an integer or " "floating-point number."; @@ -365,22 +361,22 @@ spv_result_t ValidateSpecConstant(ValidationState_t& _, spv_result_t ValidateSpecConstantOp(ValidationState_t& _, const Instruction* inst) { - const auto op = inst->GetOperandAs(2); + const auto op = inst->GetOperandAs(2); // The binary parser already ensures that the op is valid for *some* // environment. Here we check restrictions. switch (op) { - case spv::Op::OpQuantizeToF16: - if (!_.HasCapability(spv::Capability::Shader)) { + case SpvOpQuantizeToF16: + if (!_.HasCapability(SpvCapabilityShader)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Specialization constant operation " << spvOpcodeString(op) << " requires Shader capability"; } break; - case spv::Op::OpUConvert: + case SpvOpUConvert: if (!_.features().uconvert_spec_constant_op && - !_.HasCapability(spv::Capability::Kernel)) { + !_.HasCapability(SpvCapabilityKernel)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Prior to SPIR-V 1.4, specialization constant operation " "UConvert requires Kernel capability or extension " @@ -388,27 +384,27 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _, } break; - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertUToF: - case spv::Op::OpConvertPtrToU: - case spv::Op::OpConvertUToPtr: - case spv::Op::OpGenericCastToPtr: - case spv::Op::OpPtrCastToGeneric: - case spv::Op::OpBitcast: - case spv::Op::OpFNegate: - case spv::Op::OpFAdd: - case spv::Op::OpFSub: - case spv::Op::OpFMul: - case spv::Op::OpFDiv: - case spv::Op::OpFRem: - case spv::Op::OpFMod: - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpPtrAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: - if (!_.HasCapability(spv::Capability::Kernel)) { + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertFToU: + case SpvOpConvertUToF: + case SpvOpConvertPtrToU: + case SpvOpConvertUToPtr: + case SpvOpGenericCastToPtr: + case SpvOpPtrCastToGeneric: + case SpvOpBitcast: + case SpvOpFNegate: + case SpvOpFAdd: + case SpvOpFSub: + case SpvOpFMul: + case SpvOpFDiv: + case SpvOpFRem: + case SpvOpFMod: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpPtrAccessChain: + case SpvOpInBoundsPtrAccessChain: + if (!_.HasCapability(SpvCapabilityKernel)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Specialization constant operation " << spvOpcodeString(op) << " requires Kernel capability"; @@ -427,26 +423,26 @@ spv_result_t ValidateSpecConstantOp(ValidationState_t& _, spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpConstantTrue: - case spv::Op::OpConstantFalse: - case spv::Op::OpSpecConstantTrue: - case spv::Op::OpSpecConstantFalse: + case SpvOpConstantTrue: + case SpvOpConstantFalse: + case SpvOpSpecConstantTrue: + case SpvOpSpecConstantFalse: if (auto error = ValidateConstantBool(_, inst)) return error; break; - case spv::Op::OpConstantComposite: - case spv::Op::OpSpecConstantComposite: + case SpvOpConstantComposite: + case SpvOpSpecConstantComposite: if (auto error = ValidateConstantComposite(_, inst)) return error; break; - case spv::Op::OpConstantSampler: + case SpvOpConstantSampler: if (auto error = ValidateConstantSampler(_, inst)) return error; break; - case spv::Op::OpConstantNull: + case SpvOpConstantNull: if (auto error = ValidateConstantNull(_, inst)) return error; break; - case spv::Op::OpSpecConstant: + case SpvOpSpecConstant: if (auto error = ValidateSpecConstant(_, inst)) return error; break; - case spv::Op::OpSpecConstantOp: + case SpvOpSpecConstantOp: if (auto error = ValidateSpecConstantOp(_, inst)) return error; break; default: @@ -456,7 +452,7 @@ spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) { // Generally disallow creating 8- or 16-bit constants unless the full // capabilities are present. if (spvOpcodeIsConstant(inst->opcode()) && - _.HasCapability(spv::Capability::Shader) && + _.HasCapability(SpvCapabilityShader) && !_.IsPointerType(inst->type_id()) && _.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) diff --git a/source/val/validate_conversion.cpp b/source/val/validate_conversion.cpp index b2892a86..dc6b1517 100644 --- a/source/val/validate_conversion.cpp +++ b/source/val/validate_conversion.cpp @@ -14,6 +14,7 @@ // Validates correctness of conversion instructions. +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" @@ -26,11 +27,11 @@ namespace val { // Validates correctness of conversion instructions. spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpConvertFToU: { + case SpvOpConvertFToU: { if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !_.IsUnsignedIntCooperativeMatrixType(result_type)) @@ -61,7 +62,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpConvertFToS: { + case SpvOpConvertFToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && !_.IsIntCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -91,8 +92,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: { + case SpvOpConvertSToF: + case SpvOpConvertUToF: { if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && !_.IsFloatCooperativeMatrixType(result_type)) @@ -123,7 +124,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpUConvert: { + case SpvOpUConvert: { if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type) && !_.IsUnsignedIntCooperativeMatrixType(result_type)) @@ -159,7 +160,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpSConvert: { + case SpvOpSConvert: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) && !_.IsIntCooperativeMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -194,7 +195,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpFConvert: { + case SpvOpFConvert: { if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type) && !_.IsFloatCooperativeMatrixType(result_type)) @@ -230,7 +231,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpQuantizeToF16: { + case SpvOpQuantizeToF16: { if ((!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) || _.GetBitWidth(result_type) != 32) @@ -246,7 +247,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpConvertPtrToU: { + case SpvOpConvertPtrToU: { if (!_.IsUnsignedIntScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected unsigned int scalar type as Result Type: " @@ -257,18 +258,17 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (_.addressing_model() == spv::AddressingModel::Logical) + if (_.addressing_model() == SpvAddressingModelLogical) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Logical addressing not supported: " << spvOpcodeString(opcode); - if (_.addressing_model() == - spv::AddressingModel::PhysicalStorageBuffer64) { - spv::StorageClass input_storage_class; + if (_.addressing_model() == SpvAddressingModelPhysicalStorageBuffer64) { + uint32_t input_storage_class = 0; uint32_t input_data_type = 0; _.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class); - if (input_storage_class != spv::StorageClass::PhysicalStorageBuffer) + if (input_storage_class != SpvStorageClassPhysicalStorageBuffer) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Pointer storage class must be PhysicalStorageBuffer: " << spvOpcodeString(opcode); @@ -286,8 +286,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpSatConvertSToU: - case spv::Op::OpSatConvertUToS: { + case SpvOpSatConvertSToU: + case SpvOpSatConvertUToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar or vector type as Result Type: " @@ -307,7 +307,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpConvertUToPtr: { + case SpvOpConvertUToPtr: { if (!_.IsPointerType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a pointer: " @@ -318,18 +318,17 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected int scalar as input: " << spvOpcodeString(opcode); - if (_.addressing_model() == spv::AddressingModel::Logical) + if (_.addressing_model() == SpvAddressingModelLogical) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Logical addressing not supported: " << spvOpcodeString(opcode); - if (_.addressing_model() == - spv::AddressingModel::PhysicalStorageBuffer64) { - spv::StorageClass result_storage_class; + if (_.addressing_model() == SpvAddressingModelPhysicalStorageBuffer64) { + uint32_t result_storage_class = 0; uint32_t result_data_type = 0; _.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class); - if (result_storage_class != spv::StorageClass::PhysicalStorageBuffer) + if (result_storage_class != SpvStorageClassPhysicalStorageBuffer) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Pointer storage class must be PhysicalStorageBuffer: " << spvOpcodeString(opcode); @@ -347,8 +346,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpPtrCastToGeneric: { - spv::StorageClass result_storage_class; + case SpvOpPtrCastToGeneric: { + uint32_t result_storage_class = 0; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -356,22 +355,22 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - if (result_storage_class != spv::StorageClass::Generic) + if (result_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to have storage class Generic: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - spv::StorageClass input_storage_class; + uint32_t input_storage_class = 0; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != spv::StorageClass::Workgroup && - input_storage_class != spv::StorageClass::CrossWorkgroup && - input_storage_class != spv::StorageClass::Function) + if (input_storage_class != SpvStorageClassWorkgroup && + input_storage_class != SpvStorageClassCrossWorkgroup && + input_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); @@ -383,8 +382,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpGenericCastToPtr: { - spv::StorageClass result_storage_class; + case SpvOpGenericCastToPtr: { + uint32_t result_storage_class = 0; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -392,22 +391,22 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - if (result_storage_class != spv::StorageClass::Workgroup && - result_storage_class != spv::StorageClass::CrossWorkgroup && - result_storage_class != spv::StorageClass::Function) + if (result_storage_class != SpvStorageClassWorkgroup && + result_storage_class != SpvStorageClassCrossWorkgroup && + result_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to have storage class Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - spv::StorageClass input_storage_class; + uint32_t input_storage_class = 0; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != spv::StorageClass::Generic) + if (input_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Generic: " << spvOpcodeString(opcode); @@ -419,8 +418,8 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpGenericCastToPtrExplicit: { - spv::StorageClass result_storage_class; + case SpvOpGenericCastToPtrExplicit: { + uint32_t result_storage_class = 0; uint32_t result_data_type = 0; if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) @@ -428,22 +427,21 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer: " << spvOpcodeString(opcode); - const auto target_storage_class = - inst->GetOperandAs(3); + const uint32_t target_storage_class = inst->word(4); if (result_storage_class != target_storage_class) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be of target storage class: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - spv::StorageClass input_storage_class; + uint32_t input_storage_class = 0; uint32_t input_data_type = 0; if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer: " << spvOpcodeString(opcode); - if (input_storage_class != spv::StorageClass::Generic) + if (input_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to have storage class Generic: " << spvOpcodeString(opcode); @@ -453,16 +451,16 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected input and Result Type to point to the same type: " << spvOpcodeString(opcode); - if (target_storage_class != spv::StorageClass::Workgroup && - target_storage_class != spv::StorageClass::CrossWorkgroup && - target_storage_class != spv::StorageClass::Function) + if (target_storage_class != SpvStorageClassWorkgroup && + target_storage_class != SpvStorageClassCrossWorkgroup && + target_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected target storage class to be Workgroup, " << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); break; } - case spv::Op::OpBitcast: { + case SpvOpBitcast: { const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -473,10 +471,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { const bool input_is_pointer = _.IsPointerType(input_type); const bool input_is_int_scalar = _.IsIntScalarType(input_type); - const bool result_is_coopmat = _.IsCooperativeMatrixType(result_type); - const bool input_is_coopmat = _.IsCooperativeMatrixType(input_type); - - if (!result_is_pointer && !result_is_int_scalar && !result_is_coopmat && + if (!result_is_pointer && !result_is_int_scalar && !_.IsIntVectorType(result_type) && !_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) @@ -484,32 +479,21 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { << "Expected Result Type to be a pointer or int or float vector " << "or scalar type: " << spvOpcodeString(opcode); - if (!input_is_pointer && !input_is_int_scalar && !input_is_coopmat && + if (!input_is_pointer && !input_is_int_scalar && !_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected input to be a pointer or int or float vector " << "or scalar: " << spvOpcodeString(opcode); - if (result_is_coopmat != input_is_coopmat) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cooperative matrix can only be cast to another cooperative " - << "matrix: " << spvOpcodeString(opcode); - - if (result_is_coopmat) { - spv_result_t ret = - _.CooperativeMatrixShapesMatch(inst, result_type, input_type); - if (ret != SPV_SUCCESS) return ret; - } - if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 5) || _.HasExtension(kSPV_KHR_physical_storage_buffer)) { const bool result_is_int_vector = _.IsIntVectorType(result_type); const bool result_has_int32 = - _.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeInt, 32); + _.ContainsSizedIntOrFloatType(result_type, SpvOpTypeInt, 32); const bool input_is_int_vector = _.IsIntVectorType(input_type); const bool input_has_int32 = - _.ContainsSizedIntOrFloatType(input_type, spv::Op::OpTypeInt, 32); + _.ContainsSizedIntOrFloatType(input_type, SpvOpTypeInt, 32); if (result_is_pointer && !input_is_pointer && !input_is_int_scalar && !(input_is_int_vector && input_has_int32)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -550,7 +534,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpConvertUToAccelerationStructureKHR: { + case SpvOpConvertUToAccelerationStructureKHR: { if (!_.IsAccelerationStructureType(result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be a Acceleration Structure: " @@ -572,13 +556,13 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) { break; } - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { switch (inst->opcode()) { - case spv::Op::OpConvertFToU: - case spv::Op::OpConvertFToS: - case spv::Op::OpConvertSToF: - case spv::Op::OpConvertUToF: - case spv::Op::OpBitcast: + case SpvOpConvertFToU: + case SpvOpConvertFToS: + case SpvOpConvertSToF: + case SpvOpConvertUToF: + case SpvOpBitcast: if (_.ContainsLimitedUseIntOrFloatType(inst->type_id()) || _.ContainsLimitedUseIntOrFloatType(_.GetOperandTypeId(inst, 2u))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) diff --git a/source/val/validate_debug.cpp b/source/val/validate_debug.cpp index ef537ea0..7ab597a1 100644 --- a/source/val/validate_debug.cpp +++ b/source/val/validate_debug.cpp @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "source/val/validate.h" + +#include "source/opcode.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -24,7 +26,7 @@ namespace { spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { const auto type_id = inst->GetOperandAs(0); const auto type = _.FindDef(type_id); - if (!type || spv::Op::OpTypeStruct != type->opcode()) { + if (!type || SpvOpTypeStruct != type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpMemberName Type " << _.getIdName(type_id) << " is not a struct type."; @@ -43,7 +45,7 @@ spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { const auto file_id = inst->GetOperandAs(0); const auto file = _.FindDef(file_id); - if (!file || spv::Op::OpString != file->opcode()) { + if (!file || SpvOpString != file->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpLine Target " << _.getIdName(file_id) << " is not an OpString."; @@ -55,10 +57,10 @@ spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpMemberName: + case SpvOpMemberName: if (auto error = ValidateMemberName(_, inst)) return error; break; - case spv::Op::OpLine: + case SpvOpLine: if (auto error = ValidateLine(_, inst)) return error; break; default: diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp index caa4a6f1..75058501 100644 --- a/source/val/validate_decorations.cpp +++ b/source/val/validate_decorations.cpp @@ -21,6 +21,7 @@ #include #include +#include "source/binary.h" #include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_constant.h" @@ -47,6 +48,13 @@ struct PairHash { } }; +// A functor for hashing decoration types. +struct SpvDecorationHash { + std::size_t operator()(SpvDecoration dec) const { + return static_cast(dec); + } +}; + // Struct member layout attributes that are inherited through arrays. struct LayoutConstraints { explicit LayoutConstraints( @@ -64,7 +72,7 @@ using MemberConstraints = std::unordered_map, // Returns the array stride of the given array type. uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { for (auto& decoration : vstate.id_decorations(array_id)) { - if (spv::Decoration::ArrayStride == decoration.dec_type()) { + if (SpvDecorationArrayStride == decoration.dec_type()) { return decoration.params()[0]; } } @@ -74,10 +82,9 @@ uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { // Returns true if the given variable has a BuiltIn decoration. bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(var_id); - return std::any_of(decorations.begin(), decorations.end(), - [](const Decoration& d) { - return spv::Decoration::BuiltIn == d.dec_type(); - }); + return std::any_of( + decorations.begin(), decorations.end(), + [](const Decoration& d) { return SpvDecorationBuiltIn == d.dec_type(); }); } // Returns true if the given structure type has any members with BuiltIn @@ -86,7 +93,7 @@ bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(struct_id); return std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::BuiltIn == d.dec_type() && + return SpvDecorationBuiltIn == d.dec_type() && Decoration::kInvalidMember != d.struct_member_index(); }); } @@ -94,21 +101,20 @@ bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { // Returns true if the given structure type has a Block decoration. bool isBlock(uint32_t struct_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(struct_id); - return std::any_of(decorations.begin(), decorations.end(), - [](const Decoration& d) { - return spv::Decoration::Block == d.dec_type(); - }); + return std::any_of( + decorations.begin(), decorations.end(), + [](const Decoration& d) { return SpvDecorationBlock == d.dec_type(); }); } // Returns true if the given ID has the Import LinkageAttributes decoration. bool hasImportLinkageAttribute(uint32_t id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(id); - return std::any_of( - decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::LinkageAttributes == d.dec_type() && - d.params().size() >= 2u && - spv::LinkageType(d.params().back()) == spv::LinkageType::Import; - }); + return std::any_of(decorations.begin(), decorations.end(), + [](const Decoration& d) { + return SpvDecorationLinkageAttributes == d.dec_type() && + d.params().size() >= 2u && + d.params().back() == SpvLinkageTypeImport; + }); } // Returns a vector of all members of a structure. @@ -119,7 +125,7 @@ std::vector getStructMembers(uint32_t struct_id, } // Returns a vector of all members of a structure that have specific type. -std::vector getStructMembers(uint32_t struct_id, spv::Op type, +std::vector getStructMembers(uint32_t struct_id, SpvOp type, ValidationState_t& vstate) { std::vector members; for (auto id : getStructMembers(struct_id, vstate)) { @@ -136,21 +142,21 @@ bool isMissingOffsetInStruct(uint32_t struct_id, ValidationState_t& vstate) { const auto* inst = vstate.FindDef(struct_id); std::vector hasOffset; std::vector struct_members; - if (inst->opcode() == spv::Op::OpTypeStruct) { + if (inst->opcode() == SpvOpTypeStruct) { // Check offsets of member decorations. struct_members = getStructMembers(struct_id, vstate); hasOffset.resize(struct_members.size(), false); for (auto& decoration : vstate.id_decorations(struct_id)) { - if (spv::Decoration::Offset == decoration.dec_type() && + if (SpvDecorationOffset == decoration.dec_type() && Decoration::kInvalidMember != decoration.struct_member_index()) { // Offset 0xffffffff is not valid so ignore it for simplicity's sake. if (decoration.params()[0] == 0xffffffff) return true; hasOffset[decoration.struct_member_index()] = true; } } - } else if (inst->opcode() == spv::Op::OpTypeArray || - inst->opcode() == spv::Op::OpTypeRuntimeArray) { + } else if (inst->opcode() == SpvOpTypeArray || + inst->opcode() == SpvOpTypeRuntimeArray) { hasOffset.resize(1, true); struct_members.push_back(inst->GetOperandAs(1u)); } @@ -185,18 +191,18 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, // Minimal alignment is byte-aligned. uint32_t baseAlignment = 1; switch (inst->opcode()) { - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeImage: - if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + case SpvOpTypeSampledImage: + case SpvOpTypeSampler: + case SpvOpTypeImage: + if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) return baseAlignment = vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeFloat: baseAlignment = words[2] / 8; break; - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { const auto componentId = words[2]; const auto numComponents = words[3]; const auto componentAlignment = getBaseAlignment( @@ -205,7 +211,7 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, componentAlignment * (numComponents == 3 ? 4 : numComponents); break; } - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { const auto column_type = words[2]; if (inherited.majorness == kColumnMajor) { baseAlignment = getBaseAlignment(column_type, roundUp, inherited, @@ -223,13 +229,13 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, } if (roundUp) baseAlignment = align(baseAlignment, 16u); } break; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: baseAlignment = getBaseAlignment(words[2], roundUp, inherited, constraints, vstate); if (roundUp) baseAlignment = align(baseAlignment, 16u); break; - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const auto members = getStructMembers(member_id, vstate); for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); memberIdx < numMembers; ++memberIdx) { @@ -243,7 +249,7 @@ uint32_t getBaseAlignment(uint32_t member_id, bool roundUp, if (roundUp) baseAlignment = align(baseAlignment, 16u); break; } - case spv::Op::OpTypePointer: + case SpvOpTypePointer: baseAlignment = vstate.pointer_size_and_alignment(); break; default: @@ -259,24 +265,24 @@ uint32_t getScalarAlignment(uint32_t type_id, ValidationState_t& vstate) { const auto inst = vstate.FindDef(type_id); const auto& words = inst->words(); switch (inst->opcode()) { - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeImage: - if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + case SpvOpTypeSampledImage: + case SpvOpTypeSampler: + case SpvOpTypeImage: + if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) return vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeFloat: return words[2] / 8; - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: { + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: { const auto compositeMemberTypeId = words[2]; return getScalarAlignment(compositeMemberTypeId, vstate); } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const auto members = getStructMembers(type_id, vstate); uint32_t max_member_alignment = 1; for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); @@ -289,7 +295,7 @@ uint32_t getScalarAlignment(uint32_t type_id, ValidationState_t& vstate) { } return max_member_alignment; } break; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: return vstate.pointer_size_and_alignment(); default: assert(0); @@ -306,17 +312,17 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto inst = vstate.FindDef(member_id); const auto& words = inst->words(); switch (inst->opcode()) { - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeSampler: - case spv::Op::OpTypeImage: - if (vstate.HasCapability(spv::Capability::BindlessTextureNV)) + case SpvOpTypeSampledImage: + case SpvOpTypeSampler: + case SpvOpTypeImage: + if (vstate.HasCapability(SpvCapabilityBindlessTextureNV)) return vstate.samplerimage_variable_address_mode() / 8; assert(0); return 0; - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeFloat: return words[2] / 8; - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { const auto componentId = words[2]; const auto numComponents = words[3]; const auto componentSize = @@ -324,10 +330,10 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto size = componentSize * numComponents; return size; } - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { const auto sizeInst = vstate.FindDef(words[3]); if (spvOpcodeIsSpecConstant(sizeInst->opcode())) return 0; - assert(spv::Op::OpConstant == sizeInst->opcode()); + assert(SpvOpConstant == sizeInst->opcode()); const uint32_t num_elem = sizeInst->words()[3]; const uint32_t elem_type = words[2]; const uint32_t elem_size = @@ -338,9 +344,9 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, (num_elem - 1) * GetArrayStride(member_id, vstate) + elem_size; return size; } - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: return 0; - case spv::Op::OpTypeMatrix: { + case SpvOpTypeMatrix: { const auto num_columns = words[3]; if (inherited.majorness == kColumnMajor) { return num_columns * inherited.matrix_stride; @@ -356,7 +362,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, num_columns * scalar_elem_size; } } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { const auto& members = getStructMembers(member_id, vstate); if (members.empty()) return 0; const auto lastIdx = uint32_t(members.size() - 1); @@ -368,7 +374,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, for (auto decoration = member_decorations.begin; decoration != member_decorations.end; ++decoration) { assert(decoration->struct_member_index() == (int)lastIdx); - if (spv::Decoration::Offset == decoration->dec_type()) { + if (SpvDecorationOffset == decoration->dec_type()) { offset = decoration->params()[0]; } } @@ -378,7 +384,7 @@ uint32_t getSize(uint32_t member_id, const LayoutConstraints& inherited, const auto& constraint = constraints[std::make_pair(lastMember, lastIdx)]; return offset + getSize(lastMember, constraint, constraints, vstate); } - case spv::Op::OpTypePointer: + case SpvOpTypePointer: return vstate.pointer_size_and_alignment(); default: assert(0); @@ -452,16 +458,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, return ds; }; - // If we are checking physical storage buffer pointers, we may not actually - // have a struct here. Instead, pretend we have a struct with a single member - // at offset 0. - const auto& struct_type = vstate.FindDef(struct_id); - std::vector members; - if (struct_type->opcode() == spv::Op::OpTypeStruct) { - members = getStructMembers(struct_id, vstate); - } else { - members.push_back(struct_id); - } + const auto& members = getStructMembers(struct_id, vstate); // To check for member overlaps, we want to traverse the members in // offset order. @@ -470,38 +467,31 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, uint32_t offset; }; std::vector member_offsets; - - // With physical storage buffers, we might be checking layouts that do not - // originate from a structure. - if (struct_type->opcode() == spv::Op::OpTypeStruct) { - member_offsets.reserve(members.size()); - for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); - memberIdx < numMembers; memberIdx++) { - uint32_t offset = 0xffffffff; - auto member_decorations = - vstate.id_member_decorations(struct_id, memberIdx); - for (auto decoration = member_decorations.begin; - decoration != member_decorations.end; ++decoration) { - assert(decoration->struct_member_index() == (int)memberIdx); - switch (decoration->dec_type()) { - case spv::Decoration::Offset: - offset = decoration->params()[0]; - break; - default: - break; - } + member_offsets.reserve(members.size()); + for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size()); + memberIdx < numMembers; memberIdx++) { + uint32_t offset = 0xffffffff; + auto member_decorations = + vstate.id_member_decorations(struct_id, memberIdx); + for (auto decoration = member_decorations.begin; + decoration != member_decorations.end; ++decoration) { + assert(decoration->struct_member_index() == (int)memberIdx); + switch (decoration->dec_type()) { + case SpvDecorationOffset: + offset = decoration->params()[0]; + break; + default: + break; } - member_offsets.push_back( - MemberOffsetPair{memberIdx, incoming_offset + offset}); } - std::stable_sort( - member_offsets.begin(), member_offsets.end(), - [](const MemberOffsetPair& lhs, const MemberOffsetPair& rhs) { - return lhs.offset < rhs.offset; - }); - } else { - member_offsets.push_back({0, 0}); + member_offsets.push_back( + MemberOffsetPair{memberIdx, incoming_offset + offset}); } + std::stable_sort( + member_offsets.begin(), member_offsets.end(), + [](const MemberOffsetPair& lhs, const MemberOffsetPair& rhs) { + return lhs.offset < rhs.offset; + }); // Now scan from lowest offset to highest offset. uint32_t nextValidOffset = 0; @@ -527,7 +517,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, if (offset == 0xffffffff) return fail(memberIdx) << "is missing an Offset decoration"; if (!scalar_block_layout && relaxed_block_layout && - opcode == spv::Op::OpTypeVector) { + opcode == SpvOpTypeVector) { // In relaxed block layout, the vector offset must be aligned to the // vector's scalar element type. const auto componentId = inst->words()[2]; @@ -551,20 +541,21 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, << nextValidOffset - 1; if (!scalar_block_layout && relaxed_block_layout) { // Check improper straddle of vectors. - if (spv::Op::OpTypeVector == opcode && + if (SpvOpTypeVector == opcode && hasImproperStraddle(id, offset, constraint, constraints, vstate)) return fail(memberIdx) << "is an improperly straddling vector at offset " << offset; } // Check struct members recursively. spv_result_t recursive_status = SPV_SUCCESS; - if (spv::Op::OpTypeStruct == opcode && + if (SpvOpTypeStruct == opcode && SPV_SUCCESS != (recursive_status = checkLayout( id, storage_class_str, decoration_str, blockRules, - scalar_block_layout, offset, constraints, vstate))) + scalar_block_layout, + offset, constraints, vstate))) return recursive_status; // Check matrix stride. - if (spv::Op::OpTypeMatrix == opcode) { + if (SpvOpTypeMatrix == opcode) { const auto stride = constraint.matrix_stride; if (!IsAlignedTo(stride, alignment)) { return fail(memberIdx) << "is a matrix with stride " << stride @@ -575,14 +566,14 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // Check arrays and runtime arrays recursively. auto array_inst = inst; auto array_alignment = alignment; - while (array_inst->opcode() == spv::Op::OpTypeArray || - array_inst->opcode() == spv::Op::OpTypeRuntimeArray) { + while (array_inst->opcode() == SpvOpTypeArray || + array_inst->opcode() == SpvOpTypeRuntimeArray) { const auto typeId = array_inst->word(2); const auto element_inst = vstate.FindDef(typeId); // Check array stride. uint32_t array_stride = 0; for (auto& decoration : vstate.id_decorations(array_inst->id())) { - if (spv::Decoration::ArrayStride == decoration.dec_type()) { + if (SpvDecorationArrayStride == decoration.dec_type()) { array_stride = decoration.params()[0]; if (array_stride == 0) { return fail(memberIdx) << "contains an array with stride 0"; @@ -597,7 +588,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, bool is_int32 = false; bool is_const = false; uint32_t num_elements = 0; - if (array_inst->opcode() == spv::Op::OpTypeArray) { + if (array_inst->opcode() == SpvOpTypeArray) { std::tie(is_int32, is_const, num_elements) = vstate.EvalInt32IfConst(array_inst->word(3)); } @@ -606,7 +597,7 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // limitation to this check if the array size is a spec constant or is a // runtime array then we will only check a single element. This means // some improper straddles might be missed. - if (spv::Op::OpTypeStruct == element_inst->opcode()) { + if (SpvOpTypeStruct == element_inst->opcode()) { std::vector seen(16, false); for (uint32_t i = 0; i < num_elements; ++i) { uint32_t next_offset = i * array_stride + offset; @@ -641,10 +632,10 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, } } nextValidOffset = offset + size; - if (!scalar_block_layout && - (spv::Op::OpTypeArray == opcode || spv::Op::OpTypeStruct == opcode)) { - // Non-scalar block layout rules don't permit anything in the padding of - // a struct or array. + if (!scalar_block_layout && blockRules && + (SpvOpTypeArray == opcode || SpvOpTypeStruct == opcode)) { + // Uniform block rules don't permit anything in the padding of a struct + // or array. nextValidOffset = align(nextValidOffset, alignment); } } @@ -653,15 +644,15 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, // Returns true if variable or structure id has given decoration. Handles also // nested structures. -bool hasDecoration(uint32_t id, spv::Decoration decoration, +bool hasDecoration(uint32_t id, SpvDecoration decoration, ValidationState_t& vstate) { for (auto& dec : vstate.id_decorations(id)) { if (decoration == dec.dec_type()) return true; } - if (spv::Op::OpTypeStruct != vstate.FindDef(id)->opcode()) { + if (SpvOpTypeStruct != vstate.FindDef(id)->opcode()) { return false; } - for (auto member_id : getStructMembers(id, spv::Op::OpTypeStruct, vstate)) { + for (auto member_id : getStructMembers(id, SpvOpTypeStruct, vstate)) { if (hasDecoration(member_id, decoration, vstate)) { return true; } @@ -671,8 +662,8 @@ bool hasDecoration(uint32_t id, spv::Decoration decoration, // Returns true if all ids of given type have a specified decoration. bool checkForRequiredDecoration(uint32_t struct_id, - std::function checker, - spv::Op type, ValidationState_t& vstate) { + std::function checker, + SpvOp type, ValidationState_t& vstate) { const auto& members = getStructMembers(struct_id, vstate); for (size_t memberIdx = 0; memberIdx < members.size(); memberIdx++) { const auto id = members[memberIdx]; @@ -691,7 +682,7 @@ bool checkForRequiredDecoration(uint32_t struct_id, return false; } } - for (auto id : getStructMembers(struct_id, spv::Op::OpTypeStruct, vstate)) { + for (auto id : getStructMembers(struct_id, SpvOpTypeStruct, vstate)) { if (!checkForRequiredDecoration(id, checker, type, vstate)) { return false; } @@ -747,8 +738,8 @@ spv_result_t CheckBuiltInVariable(uint32_t var_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(var_id); for (const auto& d : decorations) { if (spvIsVulkanEnv(vstate.context()->target_env)) { - if (d.dec_type() == spv::Decoration::Location || - d.dec_type() == spv::Decoration::Component) { + if (d.dec_type() == SpvDecorationLocation || + d.dec_type() == SpvDecorationComponent) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(4915) << "A BuiltIn variable (id " << var_id << ") cannot have any Location or Component decorations"; @@ -771,18 +762,18 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { std::unordered_set seen_vars; for (auto interface : desc.interfaces) { Instruction* var_instr = vstate.FindDef(interface); - if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) { + if (!var_instr || SpvOpVariable != var_instr->opcode()) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "Interfaces passed to OpEntryPoint must be of type " "OpTypeVariable. Found Op" << spvOpcodeString(var_instr->opcode()) << "."; } - const spv::StorageClass storage_class = - var_instr->GetOperandAs(2); + const SpvStorageClass storage_class = + var_instr->GetOperandAs(2); if (vstate.version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { // Starting in 1.4, OpEntryPoint must list all global variables // it statically uses and those interfaces must be unique. - if (storage_class == spv::StorageClass::Function) { + if (storage_class == SpvStorageClassFunction) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "OpEntryPoint interfaces should only list global " "variables"; @@ -794,14 +785,14 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { << vstate.getIdName(interface) << " is disallowed"; } } else { - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + if (storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << "OpEntryPoint interfaces must be OpVariables with " "Storage Class of Input(1) or Output(3). Found Storage " "Class " - << uint32_t(storage_class) << " for Entry Point id " - << entry_point << "."; + << storage_class << " for Entry Point id " << entry_point + << "."; } } @@ -812,7 +803,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { // to. const uint32_t type_id = ptr_instr->word(3); Instruction* type_instr = vstate.FindDef(type_id); - if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() && + if (type_instr && SpvOpTypeStruct == type_instr->opcode() && isBuiltInStruct(type_id, vstate)) { if (!isBlock(type_id, vstate)) { return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id)) @@ -823,9 +814,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { "OpVariable with a structure type that is a block not " "decorated with Location."; } - if (storage_class == spv::StorageClass::Input) - ++num_builtin_block_inputs; - if (storage_class == spv::StorageClass::Output) + if (storage_class == SpvStorageClassInput) ++num_builtin_block_inputs; + if (storage_class == SpvStorageClassOutput) ++num_builtin_block_outputs; if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) break; @@ -836,13 +826,12 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { return error; } - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { ++num_workgroup_variables; - if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) { - if (hasDecoration(type_id, spv::Decoration::Block, vstate)) + if (type_instr && SpvOpTypeStruct == type_instr->opcode()) { + if (hasDecoration(type_id, SpvDecorationBlock, vstate)) ++num_workgroup_variables_with_block; - if (hasDecoration(var_instr->id(), spv::Decoration::Aliased, - vstate)) + if (hasDecoration(var_instr->id(), SpvDecorationAliased, vstate)) ++num_workgroup_variables_with_aliased; } } @@ -850,32 +839,31 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { if (spvIsVulkanEnv(vstate.context()->target_env)) { const auto* models = vstate.GetExecutionModels(entry_point); const bool has_frag = - models->find(spv::ExecutionModel::Fragment) != models->end(); + models->find(SpvExecutionModelFragment) != models->end(); const bool has_vert = - models->find(spv::ExecutionModel::Vertex) != models->end(); + models->find(SpvExecutionModelVertex) != models->end(); for (const auto& decoration : vstate.id_decorations(var_instr->id())) { - if (decoration == spv::Decoration::Flat || - decoration == spv::Decoration::NoPerspective || - decoration == spv::Decoration::Sample || - decoration == spv::Decoration::Centroid) { + if (decoration == SpvDecorationFlat || + decoration == SpvDecorationNoPerspective || + decoration == SpvDecorationSample || + decoration == SpvDecorationCentroid) { // VUID 04670 already validates these decorations are input/output - if (storage_class == spv::StorageClass::Input && + if (storage_class == SpvStorageClassInput && (models->size() > 1 || has_vert)) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << vstate.VkErrorID(6202) - << vstate.SpvDecorationString(decoration.dec_type()) - << " decorated variable must not be used in vertex " - "execution model as an Input storage class for Entry " - "Point id " + << "OpEntryPoint interfaces variable must not be vertex " + "execution model with an input storage class for " + "Entry Point id " << entry_point << "."; - } else if (storage_class == spv::StorageClass::Output && + } else if (storage_class == SpvStorageClassOutput && (models->size() > 1 || has_frag)) { return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) << vstate.VkErrorID(6201) - << vstate.SpvDecorationString(decoration.dec_type()) - << " decorated variable must not be used in fragment " - "execution model as an Output storage class for " + << "OpEntryPoint interfaces variable must not be " + "fragment " + "execution model with an output storage class for " "Entry Point id " << entry_point << "."; } @@ -883,9 +871,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { } const bool has_flat = - hasDecoration(var_instr->id(), spv::Decoration::Flat, vstate); - if (has_frag && storage_class == spv::StorageClass::Input && - !has_flat && + hasDecoration(var_instr->id(), SpvDecorationFlat, vstate); + if (has_frag && storage_class == SpvStorageClassInput && !has_flat && ((vstate.IsFloatScalarType(type_id) && vstate.GetBitWidth(type_id) == 64) || vstate.IsIntScalarOrVectorType(type_id))) { @@ -910,7 +897,7 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { // The LinkageAttributes Decoration cannot be applied to functions // targeted by an OpEntryPoint instruction for (auto& decoration : vstate.id_decorations(entry_point)) { - if (spv::Decoration::LinkageAttributes == decoration.dec_type()) { + if (SpvDecorationLinkageAttributes == decoration.dec_type()) { const std::string linkage_name = spvtools::utils::MakeString(decoration.params()); return vstate.diag(SPV_ERROR_INVALID_BINARY, @@ -922,9 +909,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { } } - const bool workgroup_blocks_allowed = vstate.HasCapability( - spv::Capability::WorkgroupMemoryExplicitLayoutKHR); - if (workgroup_blocks_allowed && num_workgroup_variables > 0 && + if (vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR) && + num_workgroup_variables > 0 && num_workgroup_variables_with_block > 0) { if (num_workgroup_variables != num_workgroup_variables_with_block) { return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point)) @@ -945,13 +931,6 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { "Entry point id " << entry_point << " does not meet this requirement."; } - } else if (!workgroup_blocks_allowed && - num_workgroup_variables_with_block > 0) { - return vstate.diag(SPV_ERROR_INVALID_BINARY, - vstate.FindDef(entry_point)) - << "Workgroup Storage Class variables can't be decorated with " - "Block unless declaring the WorkgroupMemoryExplicitLayoutKHR " - "capability."; } } } @@ -984,13 +963,13 @@ void ComputeMemberConstraintsForStruct(MemberConstraints* constraints, decoration != member_decorations.end; ++decoration) { assert(decoration->struct_member_index() == (int)memberIdx); switch (decoration->dec_type()) { - case spv::Decoration::RowMajor: + case SpvDecorationRowMajor: constraint.majorness = kRowMajor; break; - case spv::Decoration::ColMajor: + case SpvDecorationColMajor: constraint.majorness = kColumnMajor; break; - case spv::Decoration::MatrixStride: + case SpvDecorationMatrixStride: constraint.matrix_stride = decoration->params()[0]; break; default: @@ -1003,12 +982,12 @@ void ComputeMemberConstraintsForStruct(MemberConstraints* constraints, const auto member_type_inst = vstate.FindDef(member_type_id); const auto opcode = member_type_inst->opcode(); switch (opcode) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: ComputeMemberConstraintsForArray(constraints, member_type_id, inherited, vstate); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: ComputeMemberConstraintsForStruct(constraints, member_type_id, inherited, vstate); break; @@ -1027,12 +1006,12 @@ void ComputeMemberConstraintsForArray(MemberConstraints* constraints, const auto elem_type_inst = vstate.FindDef(elem_type_id); const auto opcode = elem_type_inst->opcode(); switch (opcode) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: ComputeMemberConstraintsForArray(constraints, elem_type_id, inherited, vstate); break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: ComputeMemberConstraintsForStruct(constraints, elem_type_id, inherited, vstate); break; @@ -1046,20 +1025,16 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { std::unordered_set uses_push_constant; for (const auto& inst : vstate.ordered_instructions()) { const auto& words = inst.words(); - auto type_id = inst.type_id(); - const Instruction* type_inst = vstate.FindDef(type_id); - if (spv::Op::OpVariable == inst.opcode()) { + if (SpvOpVariable == inst.opcode()) { const auto var_id = inst.id(); // For storage class / decoration combinations, see Vulkan 14.5.4 "Offset // and Stride Assignment". - const auto storageClass = inst.GetOperandAs(2); - const bool uniform = storageClass == spv::StorageClass::Uniform; + const auto storageClass = words[3]; + const bool uniform = storageClass == SpvStorageClassUniform; const bool uniform_constant = - storageClass == spv::StorageClass::UniformConstant; - const bool push_constant = - storageClass == spv::StorageClass::PushConstant; - const bool storage_buffer = - storageClass == spv::StorageClass::StorageBuffer; + storageClass == SpvStorageClassUniformConstant; + const bool push_constant = storageClass == SpvStorageClassPushConstant; + const bool storage_buffer = storageClass == SpvStorageClassStorageBuffer; if (spvIsVulkanEnv(vstate.context()->target_env)) { // Vulkan: There must be no more than one PushConstant block per entry @@ -1083,7 +1058,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { if (uniform_constant) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, spv::Decoration::DescriptorSet, vstate)) { + !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id << "' is missing DescriptorSet decoration.\n" @@ -1092,7 +1067,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { "decorations specified"; } if (!entry_points.empty() && - !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + !hasDecoration(var_id, SpvDecorationBinding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id << "' is missing Binding decoration.\n" @@ -1104,14 +1079,14 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } if (spvIsOpenGLEnv(vstate.context()->target_env)) { - bool has_block = hasDecoration(var_id, spv::Decoration::Block, vstate); + bool has_block = hasDecoration(var_id, SpvDecorationBlock, vstate); bool has_buffer_block = - hasDecoration(var_id, spv::Decoration::BufferBlock, vstate); + hasDecoration(var_id, SpvDecorationBufferBlock, vstate); if ((uniform && (has_block || has_buffer_block)) || (storage_buffer && has_block)) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + !hasDecoration(var_id, SpvDecorationBinding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << (uniform ? "Uniform" : "Storage Buffer") << " id '" << var_id << "' is missing Binding decoration.\n" @@ -1123,25 +1098,24 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } const bool phys_storage_buffer = - storageClass == spv::StorageClass::PhysicalStorageBuffer; + storageClass == SpvStorageClassPhysicalStorageBuffer; const bool workgroup = - storageClass == spv::StorageClass::Workgroup && - vstate.HasCapability( - spv::Capability::WorkgroupMemoryExplicitLayoutKHR); + storageClass == SpvStorageClassWorkgroup && + vstate.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayoutKHR); if (uniform || push_constant || storage_buffer || phys_storage_buffer || workgroup) { const auto ptrInst = vstate.FindDef(words[1]); - assert(spv::Op::OpTypePointer == ptrInst->opcode()); + assert(SpvOpTypePointer == ptrInst->opcode()); auto id = ptrInst->words()[3]; auto id_inst = vstate.FindDef(id); // Jump through one level of arraying. - if (!workgroup && (id_inst->opcode() == spv::Op::OpTypeArray || - id_inst->opcode() == spv::Op::OpTypeRuntimeArray)) { + if (!workgroup && (id_inst->opcode() == SpvOpTypeArray || + id_inst->opcode() == SpvOpTypeRuntimeArray)) { id = id_inst->GetOperandAs(1u); id_inst = vstate.FindDef(id); } // Struct requirement is checked on variables so just move on here. - if (spv::Op::OpTypeStruct != id_inst->opcode()) continue; + if (SpvOpTypeStruct != id_inst->opcode()) continue; MemberConstraints constraints; ComputeMemberConstraintsForStruct(&constraints, id, LayoutConstraints(), vstate); @@ -1153,9 +1127,9 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { : "StorageBuffer")); if (spvIsVulkanEnv(vstate.context()->target_env)) { - const bool block = hasDecoration(id, spv::Decoration::Block, vstate); + const bool block = hasDecoration(id, SpvDecorationBlock, vstate); const bool buffer_block = - hasDecoration(id, spv::Decoration::BufferBlock, vstate); + hasDecoration(id, SpvDecorationBufferBlock, vstate); if (storage_buffer && buffer_block) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6675) << "Storage buffer id '" << var_id @@ -1193,8 +1167,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { if (uniform || storage_buffer) { auto entry_points = vstate.EntryPointReferences(var_id); if (!entry_points.empty() && - !hasDecoration(var_id, spv::Decoration::DescriptorSet, - vstate)) { + !hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << sc_str << " id '" << var_id << "' is missing DescriptorSet decoration.\n" @@ -1203,7 +1176,7 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { "decorations specified"; } if (!entry_points.empty() && - !hasDecoration(var_id, spv::Decoration::Binding, vstate)) { + !hasDecoration(var_id, SpvDecorationBinding, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id)) << vstate.VkErrorID(6677) << sc_str << " id '" << var_id << "' is missing Binding decoration.\n" @@ -1215,9 +1188,8 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { } for (const auto& dec : vstate.id_decorations(id)) { - const bool blockDeco = spv::Decoration::Block == dec.dec_type(); - const bool bufferDeco = - spv::Decoration::BufferBlock == dec.dec_type(); + const bool blockDeco = SpvDecorationBlock == dec.dec_type(); + const bool bufferDeco = SpvDecorationBufferBlock == dec.dec_type(); const bool blockRules = uniform && blockDeco; const bool bufferRules = (uniform && bufferDeco) || @@ -1245,97 +1217,79 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with Offset " "decorations."; - } - - if (!checkForRequiredDecoration( - id, - [](spv::Decoration d) { - return d == spv::Decoration::ArrayStride; - }, - spv::Op::OpTypeArray, vstate)) { + } else if (hasDecoration(id, SpvDecorationGLSLShared, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must not use GLSLShared decoration."; + } else if (hasDecoration(id, SpvDecorationGLSLPacked, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) + << "Structure id " << id << " decorated as " << deco_str + << " must not use GLSLPacked decoration."; + } else if (!checkForRequiredDecoration( + id, + [](SpvDecoration d) { + return d == SpvDecorationArrayStride; + }, + SpvOpTypeArray, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with ArrayStride " "decorations."; - } - - if (!checkForRequiredDecoration( - id, - [](spv::Decoration d) { - return d == spv::Decoration::MatrixStride; - }, - spv::Op::OpTypeMatrix, vstate)) { + } else if (!checkForRequiredDecoration( + id, + [](SpvDecoration d) { + return d == SpvDecorationMatrixStride; + }, + SpvOpTypeMatrix, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with MatrixStride " "decorations."; - } - - if (!checkForRequiredDecoration( - id, - [](spv::Decoration d) { - return d == spv::Decoration::RowMajor || - d == spv::Decoration::ColMajor; - }, - spv::Op::OpTypeMatrix, vstate)) { + } else if (!checkForRequiredDecoration( + id, + [](SpvDecoration d) { + return d == SpvDecorationRowMajor || + d == SpvDecorationColMajor; + }, + SpvOpTypeMatrix, vstate)) { return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id)) << "Structure id " << id << " decorated as " << deco_str << " must be explicitly laid out with RowMajor or " "ColMajor decorations."; - } - - if (spvIsVulkanEnv(vstate.context()->target_env)) { - if (blockRules && (SPV_SUCCESS != (recursive_status = checkLayout( - id, sc_str, deco_str, true, - scalar_block_layout, 0, - constraints, vstate)))) { - return recursive_status; - } else if (bufferRules && - (SPV_SUCCESS != - (recursive_status = checkLayout( - id, sc_str, deco_str, false, scalar_block_layout, - 0, constraints, vstate)))) { - return recursive_status; - } + } else if (blockRules && + (SPV_SUCCESS != + (recursive_status = checkLayout( + id, sc_str, deco_str, true, scalar_block_layout, 0, + constraints, vstate)))) { + return recursive_status; + } else if (bufferRules && + (SPV_SUCCESS != + (recursive_status = checkLayout( + id, sc_str, deco_str, false, scalar_block_layout, + 0, constraints, vstate)))) { + return recursive_status; } } } } - } else if (type_inst && type_inst->opcode() == spv::Op::OpTypePointer && - type_inst->GetOperandAs(1u) == - spv::StorageClass::PhysicalStorageBuffer) { - const bool scalar_block_layout = vstate.options()->scalar_block_layout; - MemberConstraints constraints; - const bool buffer = true; - const auto data_type_id = type_inst->GetOperandAs(2u); - const auto* data_type_inst = vstate.FindDef(data_type_id); - if (data_type_inst->opcode() == spv::Op::OpTypeStruct) { - ComputeMemberConstraintsForStruct(&constraints, data_type_id, - LayoutConstraints(), vstate); - } - if (auto res = checkLayout(data_type_id, "PhysicalStorageBuffer", "Block", - !buffer, scalar_block_layout, 0, constraints, - vstate)) { - return res; - } } } return SPV_SUCCESS; } // Returns true if |decoration| cannot be applied to the same id more than once. -bool AtMostOncePerId(spv::Decoration decoration) { - return decoration == spv::Decoration::ArrayStride; +bool AtMostOncePerId(SpvDecoration decoration) { + return decoration == SpvDecorationArrayStride; } // Returns true if |decoration| cannot be applied to the same member more than // once. -bool AtMostOncePerMember(spv::Decoration decoration) { +bool AtMostOncePerMember(SpvDecoration decoration) { switch (decoration) { - case spv::Decoration::Offset: - case spv::Decoration::MatrixStride: - case spv::Decoration::RowMajor: - case spv::Decoration::ColMajor: + case SpvDecorationOffset: + case SpvDecorationMatrixStride: + case SpvDecorationRowMajor: + case SpvDecorationColMajor: return true; default: return false; @@ -1343,32 +1297,32 @@ bool AtMostOncePerMember(spv::Decoration decoration) { } spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { - using PerIDKey = std::tuple; - using PerMemberKey = std::tuple; + using PerIDKey = std::tuple; + using PerMemberKey = std::tuple; // An Array of pairs where the decorations in the pair cannot both be applied // to the same id. - static const spv::Decoration mutually_exclusive_per_id[][2] = { - {spv::Decoration::Block, spv::Decoration::BufferBlock}, - {spv::Decoration::Restrict, spv::Decoration::Aliased}}; + static const SpvDecoration mutually_exclusive_per_id[][2] = { + {SpvDecorationBlock, SpvDecorationBufferBlock}, + {SpvDecorationRestrict, SpvDecorationAliased}}; static const auto num_mutually_exclusive_per_id_pairs = - sizeof(mutually_exclusive_per_id) / (2 * sizeof(spv::Decoration)); + sizeof(mutually_exclusive_per_id) / (2 * sizeof(SpvDecoration)); // An Array of pairs where the decorations in the pair cannot both be applied // to the same member. - static const spv::Decoration mutually_exclusive_per_member[][2] = { - {spv::Decoration::RowMajor, spv::Decoration::ColMajor}}; + static const SpvDecoration mutually_exclusive_per_member[][2] = { + {SpvDecorationRowMajor, SpvDecorationColMajor}}; static const auto num_mutually_exclusive_per_mem_pairs = - sizeof(mutually_exclusive_per_member) / (2 * sizeof(spv::Decoration)); + sizeof(mutually_exclusive_per_member) / (2 * sizeof(SpvDecoration)); std::set seen_per_id; std::set seen_per_member; for (const auto& inst : vstate.ordered_instructions()) { const auto& words = inst.words(); - if (spv::Op::OpDecorate == inst.opcode()) { + if (SpvOpDecorate == inst.opcode()) { const auto id = words[1]; - const auto dec_type = static_cast(words[2]); + const auto dec_type = static_cast(words[2]); const auto k = PerIDKey(dec_type, id); const auto already_used = !seen_per_id.insert(k).second; if (already_used && AtMostOncePerId(dec_type)) { @@ -1381,7 +1335,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { // an ID. for (uint32_t pair_idx = 0; pair_idx < num_mutually_exclusive_per_id_pairs; ++pair_idx) { - spv::Decoration excl_dec_type = spv::Decoration::Max; + SpvDecoration excl_dec_type = SpvDecorationMax; if (mutually_exclusive_per_id[pair_idx][0] == dec_type) { excl_dec_type = mutually_exclusive_per_id[pair_idx][1]; } else if (mutually_exclusive_per_id[pair_idx][1] == dec_type) { @@ -1399,10 +1353,10 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { << " is not allowed."; } } - } else if (spv::Op::OpMemberDecorate == inst.opcode()) { + } else if (SpvOpMemberDecorate == inst.opcode()) { const auto id = words[1]; const auto member_id = words[2]; - const auto dec_type = static_cast(words[3]); + const auto dec_type = static_cast(words[3]); const auto k = PerMemberKey(dec_type, id, member_id); const auto already_used = !seen_per_member.insert(k).second; if (already_used && AtMostOncePerMember(dec_type)) { @@ -1415,7 +1369,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { // a (ID, member) tuple. for (uint32_t pair_idx = 0; pair_idx < num_mutually_exclusive_per_mem_pairs; ++pair_idx) { - spv::Decoration excl_dec_type = spv::Decoration::Max; + SpvDecoration excl_dec_type = SpvDecorationMax; if (mutually_exclusive_per_member[pair_idx][0] == dec_type) { excl_dec_type = mutually_exclusive_per_member[pair_idx][1]; } else if (mutually_exclusive_per_member[pair_idx][1] == dec_type) { @@ -1441,7 +1395,7 @@ spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { spv_result_t CheckVulkanMemoryModelDeprecatedDecorations( ValidationState_t& vstate) { - if (vstate.memory_model() != spv::MemoryModel::VulkanKHR) return SPV_SUCCESS; + if (vstate.memory_model() != SpvMemoryModelVulkanKHR) return SPV_SUCCESS; std::string msg; std::ostringstream str(msg); @@ -1450,10 +1404,10 @@ spv_result_t CheckVulkanMemoryModelDeprecatedDecorations( const auto id = inst->id(); for (const auto& dec : vstate.id_decorations(id)) { const auto member = dec.struct_member_index(); - if (dec.dec_type() == spv::Decoration::Coherent || - dec.dec_type() == spv::Decoration::Volatile) { - str << (dec.dec_type() == spv::Decoration::Coherent ? "Coherent" - : "Volatile"); + if (dec.dec_type() == SpvDecorationCoherent || + dec.dec_type() == SpvDecorationVolatile) { + str << (dec.dec_type() == SpvDecorationCoherent ? "Coherent" + : "Volatile"); str << " decoration targeting " << vstate.getIdName(id); if (member != Decoration::kInvalidMember) { str << " (member index " << member << ")"; @@ -1474,7 +1428,7 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, const Decoration& decoration) { // Validates width-only conversion instruction for floating-point object // i.e., OpFConvert - if (inst.opcode() != spv::Op::OpFConvert) { + if (inst.opcode() != SpvOpFConvert) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to a " "width-only conversion instruction for floating-point " @@ -1482,9 +1436,8 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, } if (spvIsVulkanEnv(vstate.context()->target_env)) { - const auto mode = spv::FPRoundingMode(decoration.params()[0]); - if ((mode != spv::FPRoundingMode::RTE) && - (mode != spv::FPRoundingMode::RTZ)) { + const auto mode = decoration.params()[0]; + if ((mode != SpvFPRoundingModeRTE) && (mode != SpvFPRoundingModeRTZ)) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << vstate.VkErrorID(4675) << "In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."; @@ -1494,11 +1447,11 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, // Validates Object operand of an OpStore for (const auto& use : inst.uses()) { const auto store = use.first; - if (store->opcode() == spv::Op::OpFConvert) continue; + if (store->opcode() == SpvOpFConvert) continue; if (spvOpcodeIsDebug(store->opcode())) continue; if (store->IsNonSemantic()) continue; if (spvOpcodeIsDecoration(store->opcode())) continue; - if (store->opcode() != spv::Op::OpStore) { + if (store->opcode() != SpvOpStore) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to the " "Object operand of an OpStore."; @@ -1524,13 +1477,12 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate, } // Validates storage class of the pointer to the OpStore - const auto storage = ptr_type->GetOperandAs(1); - if (storage != spv::StorageClass::StorageBuffer && - storage != spv::StorageClass::Uniform && - storage != spv::StorageClass::PushConstant && - storage != spv::StorageClass::Input && - storage != spv::StorageClass::Output && - storage != spv::StorageClass::PhysicalStorageBuffer) { + const auto storage = ptr_type->GetOperandAs(1); + if (storage != SpvStorageClassStorageBuffer && + storage != SpvStorageClassUniform && + storage != SpvStorageClassPushConstant && + storage != SpvStorageClassInput && storage != SpvStorageClassOutput && + storage != SpvStorageClassPhysicalStorageBuffer) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "FPRoundingMode decoration can be applied only to the " "Object operand of an OpStore in the StorageBuffer, " @@ -1555,17 +1507,16 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, // First, it must be a variable or function parameter. const auto opcode = inst.opcode(); const auto type_id = inst.type_id(); - if (opcode != spv::Op::OpVariable && - opcode != spv::Op::OpFunctionParameter) { + if (opcode != SpvOpVariable && opcode != SpvOpFunctionParameter) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of NonWritable decoration must be a memory object " "declaration (a variable or a function parameter)"; } - const auto var_storage_class = opcode == spv::Op::OpVariable - ? inst.GetOperandAs(2) - : spv::StorageClass::Max; - if ((var_storage_class == spv::StorageClass::Function || - var_storage_class == spv::StorageClass::Private) && + const auto var_storage_class = opcode == SpvOpVariable + ? inst.GetOperandAs(2) + : SpvStorageClassMax; + if ((var_storage_class == SpvStorageClassFunction || + var_storage_class == SpvStorageClassPrivate) && vstate.features().nonwritable_var_in_function_or_private) { // New permitted feature in SPIR-V 1.4. } else if ( @@ -1595,9 +1546,8 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, spv_result_t CheckUniformDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { - const char* const dec_name = decoration.dec_type() == spv::Decoration::Uniform - ? "Uniform" - : "UniformId"; + const char* const dec_name = + decoration.dec_type() == SpvDecorationUniform ? "Uniform" : "UniformId"; // Uniform or UniformId must decorate an "object" // - has a result ID @@ -1611,7 +1561,7 @@ spv_result_t CheckUniformDecoration(ValidationState_t& vstate, << dec_name << " decoration applied to a non-object"; } if (Instruction* type_inst = vstate.FindDef(inst.type_id())) { - if (type_inst->opcode() == spv::Op::OpTypeVoid) { + if (type_inst->opcode() == SpvOpTypeVoid) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << dec_name << " decoration applied to a value with void type"; } @@ -1625,7 +1575,7 @@ spv_result_t CheckUniformDecoration(ValidationState_t& vstate, // Use of Uniform with OpDecorate is checked elsewhere. // Use of UniformId with OpDecorateId is checked elsewhere. - if (decoration.dec_type() == spv::Decoration::UniformId) { + if (decoration.dec_type() == SpvDecorationUniformId) { assert(decoration.params().size() == 1 && "Grammar ensures UniformId has one parameter"); @@ -1646,13 +1596,13 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { switch (inst.opcode()) { - case spv::Op::OpIAdd: - case spv::Op::OpISub: - case spv::Op::OpIMul: - case spv::Op::OpShiftLeftLogical: - case spv::Op::OpSNegate: + case SpvOpIAdd: + case SpvOpISub: + case SpvOpIMul: + case SpvOpShiftLeftLogical: + case SpvOpSNegate: return SPV_SUCCESS; - case spv::Op::OpExtInst: + case SpvOpExtInst: // TODO(dneto): Only certain extended instructions allow these // decorations. For now allow anything. return SPV_SUCCESS; @@ -1661,7 +1611,7 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, } return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << (decoration.dec_type() == spv::Decoration::NoSignedWrap + << (decoration.dec_type() == SpvDecorationNoSignedWrap ? "NoSignedWrap" : "NoUnsignedWrap") << " decoration may not be applied to " @@ -1675,32 +1625,29 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { assert(inst.id() && "Parser ensures the target of the decoration has an ID"); - assert(decoration.params().size() == 1 && - "Grammar ensures Component has one parameter"); uint32_t type_id; if (decoration.struct_member_index() == Decoration::kInvalidMember) { // The target must be a memory object declaration. const auto opcode = inst.opcode(); - if (opcode != spv::Op::OpVariable && - opcode != spv::Op::OpFunctionParameter) { + if (opcode != SpvOpVariable && opcode != SpvOpFunctionParameter) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of Component decoration must be a memory object " "declaration (a variable or a function parameter)"; } // Only valid for the Input and Output Storage Classes. - const auto storage_class = opcode == spv::Op::OpVariable - ? inst.GetOperandAs(2) - : spv::StorageClass::Max; - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output && - storage_class != spv::StorageClass::Max) { + const auto storage_class = opcode == SpvOpVariable + ? inst.GetOperandAs(2) + : SpvStorageClassMax; + if (storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput && + storage_class != SpvStorageClassMax) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of Component decoration is invalid: must point to a " "Storage Class of Input(1) or Output(3). Found Storage " "Class " - << uint32_t(storage_class); + << storage_class; } type_id = inst.type_id(); @@ -1709,7 +1656,7 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, type_id = pointer->GetOperandAs(2); } } else { - if (inst.opcode() != spv::Op::OpTypeStruct) { + if (inst.opcode() != SpvOpTypeStruct) { return vstate.diag(SPV_ERROR_INVALID_DATA, &inst) << "Attempted to get underlying data type via member index for " "non-struct type."; @@ -1719,56 +1666,30 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, if (spvIsVulkanEnv(vstate.context()->target_env)) { // Strip the array, if present. - if (vstate.GetIdOpcode(type_id) == spv::Op::OpTypeArray) { + if (vstate.GetIdOpcode(type_id) == SpvOpTypeArray) { type_id = vstate.FindDef(type_id)->word(2u); } if (!vstate.IsIntScalarOrVectorType(type_id) && !vstate.IsFloatScalarOrVectorType(type_id)) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(4924) << "Component decoration specified for type " << vstate.getIdName(type_id) << " that is not a scalar or vector"; } - const auto component = decoration.params()[0]; - if (component > 3) { - return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(4920) - << "Component decoration value must not be greater than 3"; - } - - const auto dimension = vstate.GetDimension(type_id); + // For 16-, and 32-bit types, it is invalid if this sequence of components + // gets larger than 3. const auto bit_width = vstate.GetBitWidth(type_id); if (bit_width == 16 || bit_width == 32) { - const auto sum_component = component + dimension; - if (sum_component > 4) { + assert(decoration.params().size() == 1 && + "Grammar ensures Component has one parameter"); + + const auto component = decoration.params()[0]; + const auto last_component = component + vstate.GetDimension(type_id) - 1; + if (last_component > 3) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(4921) << "Sequence of components starting with " << component - << " and ending with " << (sum_component - 1) - << " gets larger than 3"; - } - } else if (bit_width == 64) { - if (dimension > 2) { - return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(7703) - << "Component decoration only allowed on 64-bit scalar and " - "2-component vector"; - } - if (component == 1 || component == 3) { - return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(4923) - << "Component decoration value must not be 1 or 3 for 64-bit " - "data types"; - } - // 64-bit is double per component dimension - const auto sum_component = component + (2 * dimension); - if (sum_component > 4) { - return vstate.diag(SPV_ERROR_INVALID_ID, &inst) - << vstate.VkErrorID(4922) - << "Sequence of components starting with " << component - << " and ending with " << (sum_component - 1) + << " and ending with " << last_component << " gets larger than 3"; } } @@ -1784,10 +1705,9 @@ spv_result_t CheckBlockDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { assert(inst.id() && "Parser ensures the target of the decoration has an ID"); - if (inst.opcode() != spv::Op::OpTypeStruct) { - const char* const dec_name = decoration.dec_type() == spv::Decoration::Block - ? "Block" - : "BufferBlock"; + if (inst.opcode() != SpvOpTypeStruct) { + const char* const dec_name = + decoration.dec_type() == SpvDecorationBlock ? "Block" : "BufferBlock"; return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << dec_name << " decoration on a non-struct type."; } @@ -1797,10 +1717,10 @@ spv_result_t CheckBlockDecoration(ValidationState_t& vstate, spv_result_t CheckLocationDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { - if (inst.opcode() == spv::Op::OpVariable) return SPV_SUCCESS; + if (inst.opcode() == SpvOpVariable) return SPV_SUCCESS; if (decoration.struct_member_index() != Decoration::kInvalidMember && - inst.opcode() == spv::Op::OpTypeStruct) { + inst.opcode() == SpvOpTypeStruct) { return SPV_SUCCESS; } @@ -1820,7 +1740,7 @@ spv_result_t CheckRelaxPrecisionDecoration(ValidationState_t& vstate, } if (decoration.struct_member_index() != Decoration::kInvalidMember && - inst.opcode() == spv::Op::OpTypeStruct) { + inst.opcode() == SpvOpTypeStruct) { return SPV_SUCCESS; } return vstate.diag(SPV_ERROR_INVALID_ID, &inst) @@ -1839,7 +1759,7 @@ spv_result_t CheckRelaxPrecisionDecoration(ValidationState_t& vstate, // propagated down to the group members. spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) { // Some rules are only checked for shaders. - const bool is_shader = vstate.HasCapability(spv::Capability::Shader); + const bool is_shader = vstate.HasCapability(SpvCapabilityShader); for (const auto& kv : vstate.id_decorations()) { const uint32_t id = kv.first; @@ -1851,37 +1771,37 @@ spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) { // We assume the decorations applied to a decoration group have already // been propagated down to the group members. - if (inst->opcode() == spv::Op::OpDecorationGroup) continue; + if (inst->opcode() == SpvOpDecorationGroup) continue; for (const auto& decoration : decorations) { switch (decoration.dec_type()) { - case spv::Decoration::Component: + case SpvDecorationComponent: PASS_OR_BAIL(CheckComponentDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::FPRoundingMode: + case SpvDecorationFPRoundingMode: if (is_shader) PASS_OR_BAIL( CheckFPRoundingModeForShaders(vstate, *inst, decoration)); break; - case spv::Decoration::NonWritable: + case SpvDecorationNonWritable: PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::Uniform: - case spv::Decoration::UniformId: + case SpvDecorationUniform: + case SpvDecorationUniformId: PASS_OR_BAIL(CheckUniformDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::NoSignedWrap: - case spv::Decoration::NoUnsignedWrap: + case SpvDecorationNoSignedWrap: + case SpvDecorationNoUnsignedWrap: PASS_OR_BAIL(CheckIntegerWrapDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::Block: - case spv::Decoration::BufferBlock: + case SpvDecorationBlock: + case SpvDecorationBufferBlock: PASS_OR_BAIL(CheckBlockDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::Location: + case SpvDecorationLocation: PASS_OR_BAIL(CheckLocationDecoration(vstate, *inst, decoration)); break; - case spv::Decoration::RelaxedPrecision: + case SpvDecorationRelaxedPrecision: PASS_OR_BAIL( CheckRelaxPrecisionDecoration(vstate, *inst, decoration)); break; diff --git a/source/val/validate_derivatives.cpp b/source/val/validate_derivatives.cpp index 90cf6645..25b941ab 100644 --- a/source/val/validate_derivatives.cpp +++ b/source/val/validate_derivatives.cpp @@ -14,11 +14,13 @@ // Validates correctness of derivative SPIR-V instructions. +#include "source/val/validate.h" + #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -26,26 +28,25 @@ namespace val { // Validates correctness of derivative instructions. spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpDPdx: - case spv::Op::OpDPdy: - case spv::Op::OpFwidth: - case spv::Op::OpDPdxFine: - case spv::Op::OpDPdyFine: - case spv::Op::OpFwidthFine: - case spv::Op::OpDPdxCoarse: - case spv::Op::OpDPdyCoarse: - case spv::Op::OpFwidthCoarse: { + case SpvOpDPdx: + case SpvOpDPdy: + case SpvOpFwidth: + case SpvOpDPdxFine: + case SpvOpDPdyFine: + case SpvOpFwidthFine: + case SpvOpDPdxCoarse: + case SpvOpDPdyCoarse: + case SpvOpFwidthCoarse: { if (!_.IsFloatScalarOrVectorType(result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be float scalar or vector type: " << spvOpcodeString(opcode); } - if (!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat, - 32)) { + if (!_.ContainsSizedIntOrFloatType(result_type, SpvOpTypeFloat, 32)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Result type component width must be 32 bits"; } @@ -57,10 +58,10 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { << spvOpcodeString(opcode); } _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, + ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::Fragment && - model != spv::ExecutionModel::GLCompute) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { if (message) { *message = std::string( @@ -79,11 +80,11 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); if (models && - models->find(spv::ExecutionModel::GLCompute) != models->end() && + models->find(SpvExecutionModelGLCompute) != models->end() && (!modes || - (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + (modes->find(SpvExecutionModeDerivativeGroupLinearNV) == modes->end() && - modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == modes->end()))) { if (message) { *message = std::string( diff --git a/source/val/validate_execution_limitations.cpp b/source/val/validate_execution_limitations.cpp index 0221d7ef..e1f4d7b0 100644 --- a/source/val/validate_execution_limitations.cpp +++ b/source/val/validate_execution_limitations.cpp @@ -13,6 +13,8 @@ // limitations under the License. #include "source/val/validate.h" + +#include "source/val/function.h" #include "source/val/validation_state.h" namespace spvtools { @@ -20,7 +22,7 @@ namespace val { spv_result_t ValidateExecutionLimitations(ValidationState_t& _, const Instruction* inst) { - if (inst->opcode() != spv::Op::OpFunction) { + if (inst->opcode() != SpvOpFunction) { return SPV_SUCCESS; } diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp index 0334b606..1e69cb37 100644 --- a/source/val/validate_extensions.cpp +++ b/source/val/validate_extensions.cpp @@ -18,41 +18,31 @@ #include #include +#include "spirv/unified1/NonSemanticClspvReflection.h" + #include "NonSemanticShaderDebugInfo100.h" #include "OpenCLDebugInfo100.h" #include "source/common_debug_info.h" +#include "source/diagnostic.h" #include "source/enum_string_mapping.h" #include "source/extensions.h" #include "source/latest_version_glsl_std_450_header.h" #include "source/latest_version_opencl_std_header.h" +#include "source/opcode.h" #include "source/spirv_constant.h" +#include "source/spirv_target_env.h" #include "source/val/instruction.h" #include "source/val/validate.h" #include "source/val/validation_state.h" -#include "spirv/unified1/NonSemanticClspvReflection.h" namespace spvtools { namespace val { namespace { -std::string ReflectionInstructionName(ValidationState_t& _, - const Instruction* inst) { - spv_ext_inst_desc desc = nullptr; - if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, - inst->word(4), &desc) != SPV_SUCCESS || - !desc) { - return std::string("Unknown ExtInst"); - } - std::ostringstream ss; - ss << desc->name; - - return ss.str(); -} - uint32_t GetSizeTBitWidth(const ValidationState_t& _) { - if (_.addressing_model() == spv::AddressingModel::Physical32) return 32; + if (_.addressing_model() == SpvAddressingModelPhysical32) return 32; - if (_.addressing_model() == spv::AddressingModel::Physical64) return 64; + if (_.addressing_model() == SpvAddressingModelPhysical64) return 64; return 0; } @@ -60,7 +50,7 @@ uint32_t GetSizeTBitWidth(const ValidationState_t& _) { bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32, bool must_unsigned) { auto type = _.FindDef(id); - if (!type || type->opcode() != spv::Op::OpTypeInt) { + if (!type || type->opcode() != SpvOpTypeInt) { return false; } @@ -73,7 +63,7 @@ bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32, bool IsUint32Constant(ValidationState_t& _, uint32_t id) { auto inst = _.FindDef(id); - if (!inst || inst->opcode() != spv::Op::OpConstant) { + if (!inst || inst->opcode() != SpvOpConstant) { return false; } @@ -89,7 +79,7 @@ uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) { // is a result id of an instruction with |expected_opcode|. spv_result_t ValidateOperandForDebugInfo( ValidationState_t& _, const std::string& operand_name, - spv::Op expected_opcode, const Instruction* inst, uint32_t word_index, + SpvOp expected_opcode, const Instruction* inst, uint32_t word_index, const std::function& ext_inst_name) { auto* operand = _.FindDef(inst->word(word_index)); if (operand->opcode() != expected_opcode) { @@ -147,7 +137,7 @@ bool DoesDebugInfoOperandMatchExpectation( const Instruction* inst, uint32_t word_index) { if (inst->words().size() <= word_index) return false; auto* debug_inst = _.FindDef(inst->word(word_index)); - if (debug_inst->opcode() != spv::Op::OpExtInst || + if (debug_inst->opcode() != SpvOpExtInst || (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 && debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || @@ -165,7 +155,7 @@ bool DoesDebugInfoOperandMatchExpectation( const Instruction* inst, uint32_t word_index) { if (inst->words().size() <= word_index) return false; auto* debug_inst = _.FindDef(inst->word(word_index)); - if (debug_inst->opcode() != spv::Op::OpExtInst || + if (debug_inst->opcode() != SpvOpExtInst || (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || !expectation( @@ -283,14 +273,12 @@ spv_result_t ValidateOperandDebugType( } spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, - const Instruction* inst, - uint32_t version) { - const auto inst_name = ReflectionInstructionName(_, inst); + const Instruction* inst) { const auto kernel_id = inst->GetOperandAs(4); const auto kernel = _.FindDef(kernel_id); - if (kernel->opcode() != spv::Op::OpFunction) { + if (kernel->opcode() != SpvOpFunction) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << inst_name << " does not reference a function"; + << "Kernel does not reference a function"; } bool found_kernel = false; @@ -302,23 +290,23 @@ spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, } if (!found_kernel) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << inst_name << " does not reference an entry-point"; + << "Kernel does not reference an entry-point"; } const auto* exec_models = _.GetExecutionModels(kernel_id); if (!exec_models || exec_models->empty()) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << inst_name << " does not reference an entry-point"; + << "Kernel does not reference an entry-point"; } for (auto exec_model : *exec_models) { - if (exec_model != spv::ExecutionModel::GLCompute) { + if (exec_model != SpvExecutionModelGLCompute) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << inst_name << " must refer only to GLCompute entry-points"; + << "Kernel must refer only to GLCompute entry-points"; } } auto name = _.FindDef(inst->GetOperandAs(5)); - if (!name || name->opcode() != spv::Op::OpString) { + if (!name || name->opcode() != SpvOpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; } @@ -335,48 +323,17 @@ spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, << "Name must match an entry-point for Kernel"; } - const auto num_operands = inst->operands().size(); - if (version < 5 && num_operands > 6) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Version " << version << " of the " << inst_name - << " instruction can only have 2 additional operands"; - } - - if (num_operands > 6) { - const auto num_args_id = inst->GetOperandAs(6); - if (!IsUint32Constant(_, num_args_id)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "NumArguments must be a 32-bit unsigned integer OpConstant"; - } - } - - if (num_operands > 7) { - const auto flags_id = inst->GetOperandAs(7); - if (!IsUint32Constant(_, flags_id)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Flags must be a 32-bit unsigned integer OpConstant"; - } - } - - if (num_operands > 8) { - const auto atts_id = inst->GetOperandAs(8); - if (_.GetIdOpcode(atts_id) != spv::Op::OpString) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Attributes must be an OpString"; - } - } - return SPV_SUCCESS; } spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, const Instruction* inst) { const auto num_operands = inst->operands().size(); - if (_.GetIdOpcode(inst->GetOperandAs(4)) != spv::Op::OpString) { + if (_.GetIdOpcode(inst->GetOperandAs(4)) != SpvOpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Name must be an OpString"; } if (num_operands > 5) { - if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { + if (_.GetIdOpcode(inst->GetOperandAs(5)) != SpvOpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "TypeName must be an OpString"; } @@ -409,7 +366,7 @@ spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { const auto decl_id = inst->GetOperandAs(4); const auto decl = _.FindDef(decl_id); - if (!decl || decl->opcode() != spv::Op::OpExtInst) { + if (!decl || decl->opcode() != SpvOpExtInst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Kernel must be a Kernel extended instruction"; } @@ -432,7 +389,7 @@ spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst, uint32_t info_index) { auto info = _.FindDef(inst->GetOperandAs(info_index)); - if (!info || info->opcode() != spv::Op::OpExtInst) { + if (!info || info->opcode() != SpvOpExtInst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "ArgInfo must be an ArgumentInfo extended instruction"; } @@ -482,8 +439,8 @@ spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionArgumentOffsetBuffer( - ValidationState_t& _, const Instruction* inst) { +spv_result_t ValidateClspvReflectionArgumentPodBuffer(ValidationState_t& _, + const Instruction* inst) { const auto num_operands = inst->operands().size(); if (auto error = ValidateKernelDecl(_, inst)) { return error; @@ -523,7 +480,7 @@ spv_result_t ValidateClspvReflectionArgumentOffsetBuffer( return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionArgumentPushConstant( +spv_result_t ValidateClspvReflectionArgumentPodPushConstant( ValidationState_t& _, const Instruction* inst) { const auto num_operands = inst->operands().size(); if (auto error = ValidateKernelDecl(_, inst)) { @@ -630,8 +587,8 @@ spv_result_t ValidateClspvReflectionPushConstant(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionInitializedData(ValidationState_t& _, - const Instruction* inst) { +spv_result_t ValidateClspvReflectionConstantData(ValidationState_t& _, + const Instruction* inst) { if (!IsUint32Constant(_, inst->GetOperandAs(4))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; @@ -642,7 +599,7 @@ spv_result_t ValidateClspvReflectionInitializedData(ValidationState_t& _, << "Binding must be a 32-bit unsigned integer OpConstant"; } - if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { + if (_.GetIdOpcode(inst->GetOperandAs(6)) != SpvOpString) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; } @@ -693,250 +650,18 @@ spv_result_t ValidateClspvReflectionPropertyRequiredWorkgroupSize( return SPV_SUCCESS; } -spv_result_t ValidateClspvReflectionSubgroupMaxSize(ValidationState_t& _, - const Instruction* inst) { - const auto size_id = inst->GetOperandAs(4); - if (!IsUint32Constant(_, size_id)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionPointerRelocation(ValidationState_t& _, - const Instruction* inst) { - if (!IsUint32Constant(_, inst->GetOperandAs(4))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "ObjectOffset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "PointerOffset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(6))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "PointerSize must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionImageMetadataPushConstant( - ValidationState_t& _, const Instruction* inst) { - if (auto error = ValidateKernelDecl(_, inst)) { - return error; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Ordinal must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(6))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Offset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(7))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionImageMetadataUniform( - ValidationState_t& _, const Instruction* inst) { - if (auto error = ValidateKernelDecl(_, inst)) { - return error; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Ordinal must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(6))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(7))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Binding must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(8))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Offset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(9))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionPushConstantData(ValidationState_t& _, - const Instruction* inst) { - if (!IsUint32Constant(_, inst->GetOperandAs(4))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Offset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - if (_.GetIdOpcode(inst->GetOperandAs(6)) != spv::Op::OpString) { - return _.diag(SPV_ERROR_INVALID_ID, inst) << "Data must be an OpString"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _, - const Instruction* inst) { - if (!IsUint32Constant(_, inst->GetOperandAs(4))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "PrintfID must be a 32-bit unsigned integer OpConstant"; - } - - if (_.GetIdOpcode(inst->GetOperandAs(5)) != spv::Op::OpString) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "FormatString must be an OpString"; - } - - for (size_t i = 6; i < inst->operands().size(); ++i) { - if (!IsUint32Constant(_, inst->GetOperandAs(i))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "ArgumentSizes must be a 32-bit unsigned integer OpConstant"; - } - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionPrintfStorageBuffer( - ValidationState_t& _, const Instruction* inst) { - if (!IsUint32Constant(_, inst->GetOperandAs(4))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "DescriptorSet must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Binding must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(6))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateClspvReflectionPrintfPushConstant( - ValidationState_t& _, const Instruction* inst) { - if (!IsUint32Constant(_, inst->GetOperandAs(4))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Offset must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(5))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Size must be a 32-bit unsigned integer OpConstant"; - } - - if (!IsUint32Constant(_, inst->GetOperandAs(6))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "BufferSize must be a 32-bit unsigned integer OpConstant"; - } - - return SPV_SUCCESS; -} - spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, const Instruction* inst, - uint32_t version) { + uint32_t /*version*/) { if (!_.IsVoidType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Return Type must be OpTypeVoid"; } - uint32_t required_version = 0; - const auto ext_inst = - inst->GetOperandAs(3); + auto ext_inst = inst->GetOperandAs(3); switch (ext_inst) { case NonSemanticClspvReflectionKernel: - case NonSemanticClspvReflectionArgumentInfo: - case NonSemanticClspvReflectionArgumentStorageBuffer: - case NonSemanticClspvReflectionArgumentUniform: - case NonSemanticClspvReflectionArgumentPodStorageBuffer: - case NonSemanticClspvReflectionArgumentPodUniform: - case NonSemanticClspvReflectionArgumentPodPushConstant: - case NonSemanticClspvReflectionArgumentSampledImage: - case NonSemanticClspvReflectionArgumentStorageImage: - case NonSemanticClspvReflectionArgumentSampler: - case NonSemanticClspvReflectionArgumentWorkgroup: - case NonSemanticClspvReflectionSpecConstantWorkgroupSize: - case NonSemanticClspvReflectionSpecConstantGlobalOffset: - case NonSemanticClspvReflectionSpecConstantWorkDim: - case NonSemanticClspvReflectionPushConstantGlobalOffset: - case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize: - case NonSemanticClspvReflectionPushConstantGlobalSize: - case NonSemanticClspvReflectionPushConstantRegionOffset: - case NonSemanticClspvReflectionPushConstantNumWorkgroups: - case NonSemanticClspvReflectionPushConstantRegionGroupOffset: - case NonSemanticClspvReflectionConstantDataStorageBuffer: - case NonSemanticClspvReflectionConstantDataUniform: - case NonSemanticClspvReflectionLiteralSampler: - case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: - required_version = 1; - break; - case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: - required_version = 2; - break; - case NonSemanticClspvReflectionArgumentPointerPushConstant: - case NonSemanticClspvReflectionArgumentPointerUniform: - case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: - case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: - case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: - case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: - case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: - case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: - required_version = 3; - break; - case NonSemanticClspvReflectionArgumentStorageTexelBuffer: - case NonSemanticClspvReflectionArgumentUniformTexelBuffer: - required_version = 4; - break; - case NonSemanticClspvReflectionConstantDataPointerPushConstant: - case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: - case NonSemanticClspvReflectionPrintfInfo: - case NonSemanticClspvReflectionPrintfBufferStorageBuffer: - case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: - required_version = 5; - break; - default: - break; - } - if (version < required_version) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << ReflectionInstructionName(_, inst) << " requires version " - << required_version << ", but parsed version is " << version; - } - - switch (ext_inst) { - case NonSemanticClspvReflectionKernel: - return ValidateClspvReflectionKernel(_, inst, version); + return ValidateClspvReflectionKernel(_, inst); case NonSemanticClspvReflectionArgumentInfo: return ValidateClspvReflectionArgumentInfo(_, inst); case NonSemanticClspvReflectionArgumentStorageBuffer: @@ -944,16 +669,12 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, case NonSemanticClspvReflectionArgumentSampledImage: case NonSemanticClspvReflectionArgumentStorageImage: case NonSemanticClspvReflectionArgumentSampler: - case NonSemanticClspvReflectionArgumentStorageTexelBuffer: - case NonSemanticClspvReflectionArgumentUniformTexelBuffer: return ValidateClspvReflectionArgumentBuffer(_, inst); case NonSemanticClspvReflectionArgumentPodStorageBuffer: case NonSemanticClspvReflectionArgumentPodUniform: - case NonSemanticClspvReflectionArgumentPointerUniform: - return ValidateClspvReflectionArgumentOffsetBuffer(_, inst); + return ValidateClspvReflectionArgumentPodBuffer(_, inst); case NonSemanticClspvReflectionArgumentPodPushConstant: - case NonSemanticClspvReflectionArgumentPointerPushConstant: - return ValidateClspvReflectionArgumentPushConstant(_, inst); + return ValidateClspvReflectionArgumentPodPushConstant(_, inst); case NonSemanticClspvReflectionArgumentWorkgroup: return ValidateClspvReflectionArgumentWorkgroup(_, inst); case NonSemanticClspvReflectionSpecConstantWorkgroupSize: @@ -970,31 +691,11 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, return ValidateClspvReflectionPushConstant(_, inst); case NonSemanticClspvReflectionConstantDataStorageBuffer: case NonSemanticClspvReflectionConstantDataUniform: - case NonSemanticClspvReflectionProgramScopeVariablesStorageBuffer: - return ValidateClspvReflectionInitializedData(_, inst); + return ValidateClspvReflectionConstantData(_, inst); case NonSemanticClspvReflectionLiteralSampler: return ValidateClspvReflectionSampler(_, inst); case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: return ValidateClspvReflectionPropertyRequiredWorkgroupSize(_, inst); - case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: - return ValidateClspvReflectionSubgroupMaxSize(_, inst); - case NonSemanticClspvReflectionProgramScopeVariablePointerRelocation: - return ValidateClspvReflectionPointerRelocation(_, inst); - case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: - case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: - return ValidateClspvReflectionImageMetadataPushConstant(_, inst); - case NonSemanticClspvReflectionImageArgumentInfoChannelOrderUniform: - case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypeUniform: - return ValidateClspvReflectionImageMetadataUniform(_, inst); - case NonSemanticClspvReflectionConstantDataPointerPushConstant: - case NonSemanticClspvReflectionProgramScopeVariablePointerPushConstant: - return ValidateClspvReflectionPushConstantData(_, inst); - case NonSemanticClspvReflectionPrintfInfo: - return ValidateClspvReflectionPrintfInfo(_, inst); - case NonSemanticClspvReflectionPrintfBufferStorageBuffer: - return ValidateClspvReflectionPrintfStorageBuffer(_, inst); - case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: - return ValidateClspvReflectionPrintfPushConstant(_, inst); default: break; } @@ -1004,7 +705,7 @@ spv_result_t ValidateClspvReflectionInstruction(ValidationState_t& _, bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _, Instruction* instr) { - if (instr->opcode() != spv::Op::OpConstant) return false; + if (instr->opcode() != SpvOpConstant) return false; if (!_.IsIntScalarType(instr->type_id())) return false; uint32_t size_in_bits = _.GetBitWidth(instr->type_id()); return size_in_bits == 32 || size_in_bits == 64; @@ -1013,7 +714,7 @@ bool IsConstIntScalarTypeWith32Or64Bits(ValidationState_t& _, bool IsConstWithIntScalarType(ValidationState_t& _, const Instruction* inst, uint32_t word_index) { auto* int_scalar_const = _.FindDef(inst->word(word_index)); - if (int_scalar_const->opcode() == spv::Op::OpConstant && + if (int_scalar_const->opcode() == SpvOpConstant && _.IsIntScalarType(int_scalar_const->type_id())) { return true; } @@ -1056,8 +757,7 @@ spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) { std::string extension = GetExtensionString(&(inst->c_inst())); if (extension == ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) || - extension == ExtensionToString(kSPV_EXT_mesh_shader) || - extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) { + extension == ExtensionToString(kSPV_EXT_mesh_shader)) { return _.diag(SPV_ERROR_WRONG_VERSION, inst) << extension << " extension requires SPIR-V version 1.4 or later."; } @@ -1320,7 +1020,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand X type to be equal to Result Type"; } - spv::StorageClass i_storage_class; + uint32_t i_storage_class = 0; uint32_t i_data_type = 0; if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1375,7 +1075,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand X type to be equal to Result Type"; } - spv::StorageClass exp_storage_class; + uint32_t exp_storage_class = 0; uint32_t exp_data_type = 0; if (!_.GetPointerTypeInfo(exp_type, &exp_data_type, &exp_storage_class)) { @@ -1724,7 +1424,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case GLSLstd450InterpolateAtCentroid: case GLSLstd450InterpolateAtSample: case GLSLstd450InterpolateAtOffset: { - if (!_.HasCapability(spv::Capability::InterpolationFunction)) { + if (!_.HasCapability(SpvCapabilityInterpolationFunction)) { return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) << ext_inst_name() << " requires capability InterpolationFunction"; @@ -1744,11 +1444,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { uint32_t interp_id = inst->GetOperandAs(4); auto* interp_inst = _.FindDef(interp_id); uint32_t interpolant_type = (_.options()->before_hlsl_legalization && - interp_inst->opcode() == spv::Op::OpLoad) + interp_inst->opcode() == SpvOpLoad) ? _.GetOperandTypeId(interp_inst, 2) : _.GetOperandTypeId(inst, 4); - spv::StorageClass interpolant_storage_class; + uint32_t interpolant_storage_class = 0; uint32_t interpolant_data_type = 0; if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type, &interpolant_storage_class)) { @@ -1763,7 +1463,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected Interpolant data type to be equal to Result Type"; } - if (interpolant_storage_class != spv::StorageClass::Input) { + if (interpolant_storage_class != SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected Interpolant storage class to be Input"; @@ -1792,7 +1492,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, ext_inst_name() + std::string(" requires Fragment execution model")); break; @@ -1962,7 +1662,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t p_type = _.GetOperandTypeId(inst, 5); - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1970,10 +1670,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected the last operand to be a pointer"; } - if (p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected storage class of the pointer to be Generic, " @@ -2024,7 +1724,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++); - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2032,10 +1732,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected the last operand to be a pointer"; } - if (p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected storage class of the pointer to be Generic, " @@ -2554,7 +2254,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2562,11 +2262,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != spv::StorageClass::UniformConstant && - p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassUniformConstant && + p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2591,7 +2291,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case OpenCLLIB::Vstoren: { - if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2629,7 +2329,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2637,10 +2337,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be Generic, " @@ -2682,7 +2382,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2690,11 +2390,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != spv::StorageClass::UniformConstant && - p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassUniformConstant && + p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2744,7 +2444,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2752,11 +2452,11 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != spv::StorageClass::UniformConstant && - p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassUniformConstant && + p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be UniformConstant, " @@ -2786,7 +2486,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { case OpenCLLIB::Vstore_halfn_r: case OpenCLLIB::Vstorea_halfn: case OpenCLLIB::Vstorea_halfn_r: { - if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2837,7 +2537,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "-bit integer for the addressing model used in the module)"; } - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2845,10 +2545,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand P to be a pointer"; } - if (p_storage_class != spv::StorageClass::Generic && - p_storage_class != spv::StorageClass::CrossWorkgroup && - p_storage_class != spv::StorageClass::Workgroup && - p_storage_class != spv::StorageClass::Function) { + if (p_storage_class != SpvStorageClassGeneric && + p_storage_class != SpvStorageClassCrossWorkgroup && + p_storage_class != SpvStorageClassWorkgroup && + p_storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand P storage class to be Generic, " @@ -2953,7 +2653,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } const uint32_t format_type = _.GetOperandTypeId(inst, 4); - spv::StorageClass format_storage_class; + uint32_t format_storage_class = 0; uint32_t format_data_type = 0; if (!_.GetPointerTypeInfo(format_type, &format_data_type, &format_storage_class)) { @@ -2962,7 +2662,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Format to be a pointer"; } - if (format_storage_class != spv::StorageClass::UniformConstant) { + if (format_storage_class != SpvStorageClassUniformConstant) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected Format storage class to be UniformConstant"; @@ -2978,7 +2678,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } case OpenCLLIB::Prefetch: { - if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(result_type) != SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": expected Result Type to be void"; } @@ -2986,7 +2686,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { const uint32_t p_type = _.GetOperandTypeId(inst, 4); const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5); - spv::StorageClass p_storage_class; + uint32_t p_storage_class = 0; uint32_t p_data_type = 0; if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2994,7 +2694,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Ptr to be a pointer"; } - if (p_storage_class != spv::StorageClass::CrossWorkgroup) { + if (p_storage_class != SpvStorageClassCrossWorkgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Ptr storage class to be CrossWorkgroup"; @@ -3157,27 +2857,27 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugSource: { - CHECK_OPERAND("File", spv::Op::OpString, 5); - if (num_words == 7) CHECK_OPERAND("Text", spv::Op::OpString, 6); + CHECK_OPERAND("File", SpvOpString, 5); + if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6); break; } case CommonDebugInfoDebugTypeBasic: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); - CHECK_OPERAND("Size", spv::Op::OpConstant, 6); + CHECK_OPERAND("Name", SpvOpString, 5); + CHECK_OPERAND("Size", SpvOpConstant, 6); CHECK_CONST_UINT_OPERAND("Encoding", 7); break; } case CommonDebugInfoDebugTypePointer: { - auto validate_base_type = ValidateOperandDebugType( - _, "Base Type", inst, 5, ext_inst_name, false); + auto validate_base_type = + ValidateOperandBaseType(_, inst, 5, ext_inst_name); if (validate_base_type != SPV_SUCCESS) return validate_base_type; CHECK_CONST_UINT_OPERAND("Storage Class", 6); CHECK_CONST_UINT_OPERAND("Flags", 7); break; } case CommonDebugInfoDebugTypeQualifier: { - auto validate_base_type = ValidateOperandDebugType( - _, "Base Type", inst, 5, ext_inst_name, false); + auto validate_base_type = + ValidateOperandBaseType(_, inst, 5, ext_inst_name); if (validate_base_type != SPV_SUCCESS) return validate_base_type; CHECK_CONST_UINT_OPERAND("Type Qualifier", 6); break; @@ -3266,7 +2966,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypedef: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); auto validate_base_type = ValidateOperandBaseType(_, inst, 6, ext_inst_name); if (validate_base_type != SPV_SUCCESS) return validate_base_type; @@ -3283,7 +2983,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto* return_type = _.FindDef(inst->word(6)); // TODO: We need a spec discussion that we have to allow return and // parameter types of a DebugTypeFunction to have template parameter. - if (return_type->opcode() != spv::Op::OpTypeVoid) { + if (return_type->opcode() != SpvOpTypeVoid) { auto validate_return = ValidateOperandDebugType( _, "Return Type", inst, 6, ext_inst_name, true); if (validate_return != SPV_SUCCESS) return validate_return; @@ -3296,7 +2996,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeEnum: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { @@ -3314,7 +3014,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Size", spv::Op::OpConstant, 11); + CHECK_OPERAND("Size", SpvOpConstant, 11); auto* size = _.FindDef(inst->word(11)); if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -3324,27 +3024,27 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_CONST_UINT_OPERAND("Flags", 12); for (uint32_t word_index = 13; word_index + 1 < num_words; word_index += 2) { - CHECK_OPERAND("Value", spv::Op::OpConstant, word_index); - CHECK_OPERAND("Name", spv::Op::OpString, word_index + 1); + CHECK_OPERAND("Value", SpvOpConstant, word_index); + CHECK_OPERAND("Name", SpvOpString, word_index + 1); } break; } case CommonDebugInfoDebugTypeComposite: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7); CHECK_CONST_UINT_OPERAND("Line", 8); CHECK_CONST_UINT_OPERAND("Column", 9); auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_OPERAND("Linkage Name", SpvOpString, 11); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 12)) { - CHECK_OPERAND("Size", spv::Op::OpConstant, 12); + CHECK_OPERAND("Size", SpvOpConstant, 12); } CHECK_CONST_UINT_OPERAND("Flags", 13); for (uint32_t word_index = 14; word_index < num_words; ++word_index) { @@ -3366,7 +3066,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeMember: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); // TODO: We need a spec discussion that we have to allow member types // to have template parameter. auto validate_type = @@ -3377,19 +3077,17 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_CONST_UINT_OPERAND("Column", 9); // NonSemantic.Shader.DebugInfo doesn't have the Parent operand if (vulkanDebugInfo) { - CHECK_OPERAND("Offset", spv::Op::OpConstant, 10); - CHECK_OPERAND("Size", spv::Op::OpConstant, 11); + CHECK_OPERAND("Offset", SpvOpConstant, 10); + CHECK_OPERAND("Size", SpvOpConstant, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); - if (num_words == 14) - CHECK_OPERAND("Value", spv::Op::OpConstant, 13); + if (num_words == 14) CHECK_OPERAND("Value", SpvOpConstant, 13); } else { CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 10); - CHECK_OPERAND("Offset", spv::Op::OpConstant, 11); - CHECK_OPERAND("Size", spv::Op::OpConstant, 12); + CHECK_OPERAND("Offset", SpvOpConstant, 11); + CHECK_OPERAND("Size", SpvOpConstant, 12); CHECK_CONST_UINT_OPERAND("Flags", 13); - if (num_words == 15) - CHECK_OPERAND("Value", spv::Op::OpConstant, 14); + if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14); } break; } @@ -3416,13 +3114,13 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { << "expected operand Parent must be class or struct debug " "type"; } - CHECK_OPERAND("Offset", spv::Op::OpConstant, 7); - CHECK_OPERAND("Size", spv::Op::OpConstant, 8); + CHECK_OPERAND("Offset", SpvOpConstant, 7); + CHECK_OPERAND("Size", SpvOpConstant, 8); CHECK_CONST_UINT_OPERAND("Flags", 9); break; } case CommonDebugInfoDebugFunction: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3432,7 +3130,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_OPERAND("Linkage Name", SpvOpString, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); CHECK_CONST_UINT_OPERAND("Scope Line", 13); // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the @@ -3449,7 +3147,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 14)) { - CHECK_OPERAND("Function", spv::Op::OpFunction, 14); + CHECK_OPERAND("Function", SpvOpFunction, 14); } if (num_words == 16) { CHECK_DEBUG_OPERAND("Declaration", @@ -3459,7 +3157,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugFunctionDeclaration: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3469,7 +3167,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_OPERAND("Linkage Name", SpvOpString, 11); CHECK_CONST_UINT_OPERAND("Flags", 12); break; } @@ -3480,7 +3178,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_parent = ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name); if (validate_parent != SPV_SUCCESS) return validate_parent; - if (num_words == 10) CHECK_OPERAND("Name", spv::Op::OpString, 9); + if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9); break; } case CommonDebugInfoDebugScope: { @@ -3493,7 +3191,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugLocalVariable: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); // TODO: We need a spec discussion that we have to allow local // variable types to have template parameter. auto validate_type = @@ -3515,8 +3213,8 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { CHECK_DEBUG_OPERAND("Local Variable", CommonDebugInfoDebugLocalVariable, 5); auto* operand = _.FindDef(inst->word(6)); - if (operand->opcode() != spv::Op::OpVariable && - operand->opcode() != spv::Op::OpFunctionParameter) { + if (operand->opcode() != SpvOpVariable && + operand->opcode() != SpvOpFunctionParameter) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Variable must be a result id of " @@ -3578,7 +3276,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugTypeTemplateParameter: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); auto validate_actual_type = ValidateOperandDebugType( _, "Actual Type", inst, 6, ext_inst_name, false); if (validate_actual_type != SPV_SUCCESS) return validate_actual_type; @@ -3588,7 +3286,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { return dbg_inst == CommonDebugInfoDebugInfoNone; }, inst, 7)) { - CHECK_OPERAND("Value", spv::Op::OpConstant, 7); + CHECK_OPERAND("Value", SpvOpConstant, 7); } CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8); CHECK_CONST_UINT_OPERAND("Line", 9); @@ -3596,7 +3294,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { break; } case CommonDebugInfoDebugGlobalVariable: { - CHECK_OPERAND("Name", spv::Op::OpString, 5); + CHECK_OPERAND("Name", SpvOpString, 5); auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false); if (validate_type != SPV_SUCCESS) return validate_type; @@ -3606,7 +3304,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { auto validate_scope = ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name); if (validate_scope != SPV_SUCCESS) return validate_scope; - CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11); + CHECK_OPERAND("Linkage Name", SpvOpString, 11); if (!DoesDebugInfoOperandMatchExpectation( _, [](CommonDebugInfoInstructions dbg_inst) { @@ -3614,8 +3312,8 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { }, inst, 12)) { auto* operand = _.FindDef(inst->word(12)); - if (operand->opcode() != spv::Op::OpVariable && - operand->opcode() != spv::Op::OpConstant) { + if (operand->opcode() != SpvOpVariable && + operand->opcode() != SpvOpConstant) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << ext_inst_name() << ": " << "expected operand Variable must be a result id of " @@ -3703,10 +3401,10 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { } spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); - if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst); - if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst); - if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst); + const SpvOp opcode = inst->opcode(); + if (opcode == SpvOpExtension) return ValidateExtension(_, inst); + if (opcode == SpvOpExtInstImport) return ValidateExtInstImport(_, inst); + if (opcode == SpvOpExtInst) return ValidateExtInst(_, inst); return SPV_SUCCESS; } diff --git a/source/val/validate_function.cpp b/source/val/validate_function.cpp index 639817fe..0ccf5a9e 100644 --- a/source/val/validate_function.cpp +++ b/source/val/validate_function.cpp @@ -14,7 +14,6 @@ #include -#include "source/enum_string_mapping.h" #include "source/opcode.h" #include "source/val/instruction.h" #include "source/val/validate.h" @@ -29,8 +28,7 @@ namespace { // of the decorations that apply to |a|. bool DoPointeesLogicallyMatch(val::Instruction* a, val::Instruction* b, ValidationState_t& _) { - if (a->opcode() != spv::Op::OpTypePointer || - b->opcode() != spv::Op::OpTypePointer) { + if (a->opcode() != SpvOpTypePointer || b->opcode() != SpvOpTypePointer) { return false; } @@ -58,7 +56,7 @@ bool DoPointeesLogicallyMatch(val::Instruction* a, val::Instruction* b, spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { const auto function_type_id = inst->GetOperandAs(3); const auto function_type = _.FindDef(function_type_id); - if (!function_type || spv::Op::OpTypeFunction != function_type->opcode()) { + if (!function_type || SpvOpTypeFunction != function_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpFunction Function Type " << _.getIdName(function_type_id) << " is not a function type."; @@ -72,21 +70,21 @@ spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) { << _.getIdName(return_id) << "."; } - const std::vector acceptable = { - spv::Op::OpGroupDecorate, - spv::Op::OpDecorate, - spv::Op::OpEnqueueKernel, - spv::Op::OpEntryPoint, - spv::Op::OpExecutionMode, - spv::Op::OpExecutionModeId, - spv::Op::OpFunctionCall, - spv::Op::OpGetKernelNDrangeSubGroupCount, - spv::Op::OpGetKernelNDrangeMaxSubGroupSize, - spv::Op::OpGetKernelWorkGroupSize, - spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple, - spv::Op::OpGetKernelLocalSizeForSubgroupCount, - spv::Op::OpGetKernelMaxNumSubgroups, - spv::Op::OpName}; + const std::vector acceptable = { + SpvOpGroupDecorate, + SpvOpDecorate, + SpvOpEnqueueKernel, + SpvOpEntryPoint, + SpvOpExecutionMode, + SpvOpExecutionModeId, + SpvOpFunctionCall, + SpvOpGetKernelNDrangeSubGroupCount, + SpvOpGetKernelNDrangeMaxSubGroupSize, + SpvOpGetKernelWorkGroupSize, + SpvOpGetKernelPreferredWorkGroupSizeMultiple, + SpvOpGetKernelLocalSizeForSubgroupCount, + SpvOpGetKernelMaxNumSubgroups, + SpvOpName}; for (auto& pair : inst->uses()) { const auto* use = pair.first; if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) == @@ -114,14 +112,14 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, auto func_inst = &_.ordered_instructions()[inst_num]; while (--inst_num) { func_inst = &_.ordered_instructions()[inst_num]; - if (func_inst->opcode() == spv::Op::OpFunction) { + if (func_inst->opcode() == SpvOpFunction) { break; - } else if (func_inst->opcode() == spv::Op::OpFunctionParameter) { + } else if (func_inst->opcode() == SpvOpFunctionParameter) { ++param_index; } } - if (func_inst->opcode() != spv::Op::OpFunction) { + if (func_inst->opcode() != SpvOpFunction) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function parameter must be preceded by a function."; } @@ -152,25 +150,25 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, // Validate that PhysicalStorageBuffer have one of Restrict, Aliased, // RestrictPointer, or AliasedPointer. auto param_nonarray_type_id = param_type->id(); - while (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypeArray) { + while (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypeArray) { param_nonarray_type_id = _.FindDef(param_nonarray_type_id)->GetOperandAs(1u); } - if (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypePointer) { + if (_.GetIdOpcode(param_nonarray_type_id) == SpvOpTypePointer) { auto param_nonarray_type = _.FindDef(param_nonarray_type_id); - if (param_nonarray_type->GetOperandAs(1u) == - spv::StorageClass::PhysicalStorageBuffer) { + if (param_nonarray_type->GetOperandAs(1u) == + SpvStorageClassPhysicalStorageBuffer) { // check for Aliased or Restrict const auto& decorations = _.id_decorations(inst->id()); bool foundAliased = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::Aliased == d.dec_type(); + return SpvDecorationAliased == d.dec_type(); }); bool foundRestrict = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::Restrict == d.dec_type(); + return SpvDecorationRestrict == d.dec_type(); }); if (!foundAliased && !foundRestrict) { @@ -189,20 +187,20 @@ spv_result_t ValidateFunctionParameter(ValidationState_t& _, const auto pointee_type_id = param_nonarray_type->GetOperandAs(2); const auto pointee_type = _.FindDef(pointee_type_id); - if (spv::Op::OpTypePointer == pointee_type->opcode() && - pointee_type->GetOperandAs(1u) == - spv::StorageClass::PhysicalStorageBuffer) { + if (SpvOpTypePointer == pointee_type->opcode() && + pointee_type->GetOperandAs(1u) == + SpvStorageClassPhysicalStorageBuffer) { // check for AliasedPointer/RestrictPointer const auto& decorations = _.id_decorations(inst->id()); bool foundAliased = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::AliasedPointer == d.dec_type(); + return SpvDecorationAliasedPointer == d.dec_type(); }); bool foundRestrict = std::any_of( decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::RestrictPointer == d.dec_type(); + return SpvDecorationRestrictPointer == d.dec_type(); }); if (!foundAliased && !foundRestrict) { @@ -228,7 +226,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, const Instruction* inst) { const auto function_id = inst->GetOperandAs(2); const auto function = _.FindDef(function_id); - if (!function || spv::Op::OpFunction != function->opcode()) { + if (!function || SpvOpFunction != function->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpFunctionCall Function " << _.getIdName(function_id) << " is not a function."; @@ -244,7 +242,7 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, const auto function_type_id = function->GetOperandAs(3); const auto function_type = _.FindDef(function_type_id); - if (!function_type || function_type->opcode() != spv::Op::OpTypeFunction) { + if (!function_type || function_type->opcode() != SpvOpTypeFunction) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Missing function type definition."; } @@ -287,21 +285,20 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, } } - if (_.addressing_model() == spv::AddressingModel::Logical) { - if (parameter_type->opcode() == spv::Op::OpTypePointer && + if (_.addressing_model() == SpvAddressingModelLogical) { + if (parameter_type->opcode() == SpvOpTypePointer && !_.options()->relax_logical_pointer) { - spv::StorageClass sc = - parameter_type->GetOperandAs(1u); + SpvStorageClass sc = parameter_type->GetOperandAs(1u); // Validate which storage classes can be pointer operands. switch (sc) { - case spv::StorageClass::UniformConstant: - case spv::StorageClass::Function: - case spv::StorageClass::Private: - case spv::StorageClass::Workgroup: - case spv::StorageClass::AtomicCounter: + case SpvStorageClassUniformConstant: + case SpvStorageClassFunction: + case SpvStorageClassPrivate: + case SpvStorageClassWorkgroup: + case SpvStorageClassAtomicCounter: // These are always allowed. break; - case spv::StorageClass::StorageBuffer: + case SpvStorageClassStorageBuffer: if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "StorageBuffer pointer operand " @@ -316,14 +313,13 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, } // Validate memory object declaration requirements. - if (argument->opcode() != spv::Op::OpVariable && - argument->opcode() != spv::Op::OpFunctionParameter) { + if (argument->opcode() != SpvOpVariable && + argument->opcode() != SpvOpFunctionParameter) { const bool ssbo_vptr = _.features().variable_pointers && - sc == spv::StorageClass::StorageBuffer; - const bool wg_vptr = - _.HasCapability(spv::Capability::VariablePointers) && - sc == spv::StorageClass::Workgroup; - const bool uc_ptr = sc == spv::StorageClass::UniformConstant; + sc == SpvStorageClassStorageBuffer; + const bool wg_vptr = _.HasCapability(SpvCapabilityVariablePointers) && + sc == SpvStorageClassWorkgroup; + const bool uc_ptr = sc == SpvStorageClassUniformConstant; if (!ssbo_vptr && !wg_vptr && !uc_ptr) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Pointer operand " << _.getIdName(argument_id) @@ -340,13 +336,13 @@ spv_result_t ValidateFunctionCall(ValidationState_t& _, spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpFunction: + case SpvOpFunction: if (auto error = ValidateFunction(_, inst)) return error; break; - case spv::Op::OpFunctionParameter: + case SpvOpFunctionParameter: if (auto error = ValidateFunctionParameter(_, inst)) return error; break; - case spv::Op::OpFunctionCall: + case SpvOpFunctionCall: if (auto error = ValidateFunctionCall(_, inst)) return error; break; default: diff --git a/source/val/validate_id.cpp b/source/val/validate_id.cpp index bcfeb591..2bab2034 100644 --- a/source/val/validate_id.cpp +++ b/source/val/validate_id.cpp @@ -12,14 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "source/val/validate.h" + +#include + +#include +#include +#include +#include +#include #include +#include #include +#include "source/diagnostic.h" #include "source/instruction.h" #include "source/opcode.h" #include "source/operand.h" +#include "source/spirv_validator_options.h" #include "source/val/function.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" #include "spirv-tools/libspirv.h" @@ -60,7 +71,7 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { const Instruction* use = use_index_pair.first; if (const BasicBlock* use_block = use->block()) { if (use_block->reachable() == false) continue; - if (use->opcode() == spv::Op::OpPhi) { + if (use->opcode() == SpvOpPhi) { if (phi_ids.insert(use->id()).second) { phi_instructions.push_back(use); } @@ -120,7 +131,7 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { // instruction operand's ID can be forward referenced. spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { auto can_have_forward_declared_ids = - inst->opcode() == spv::Op::OpExtInst && + inst->opcode() == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type()) ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction( inst->ext_inst_type(), inst->word(4)) @@ -161,33 +172,23 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { if (spvOpcodeGeneratesType(def->opcode()) && !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && !inst->IsNonSemantic() && - !spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction && - opcode != spv::Op::OpCooperativeMatrixLengthNV && - opcode != spv::Op::OpCooperativeMatrixLengthKHR && - !(opcode == spv::Op::OpSpecConstantOp && - (spv::Op(inst->word(3)) == - spv::Op::OpCooperativeMatrixLengthNV || - spv::Op(inst->word(3)) == - spv::Op::OpCooperativeMatrixLengthKHR))) { + !spvOpcodeIsDecoration(opcode) && opcode != SpvOpFunction && + opcode != SpvOpCooperativeMatrixLengthNV && + !(opcode == SpvOpSpecConstantOp && + inst->word(3) == SpvOpCooperativeMatrixLengthNV)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand " << _.getIdName(operand_word) << " cannot be a type"; } else if (def->type_id() == 0 && !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() && !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) && - !spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi && - opcode != spv::Op::OpExtInst && - opcode != spv::Op::OpExtInstImport && - opcode != spv::Op::OpSelectionMerge && - opcode != spv::Op::OpLoopMerge && - opcode != spv::Op::OpFunction && - opcode != spv::Op::OpCooperativeMatrixLengthNV && - opcode != spv::Op::OpCooperativeMatrixLengthKHR && - !(opcode == spv::Op::OpSpecConstantOp && - (spv::Op(inst->word(3)) == - spv::Op::OpCooperativeMatrixLengthNV || - spv::Op(inst->word(3)) == - spv::Op::OpCooperativeMatrixLengthKHR))) { + !spvOpcodeIsBranch(opcode) && opcode != SpvOpPhi && + opcode != SpvOpExtInst && opcode != SpvOpExtInstImport && + opcode != SpvOpSelectionMerge && + opcode != SpvOpLoopMerge && opcode != SpvOpFunction && + opcode != SpvOpCooperativeMatrixLengthNV && + !(opcode == SpvOpSpecConstantOp && + inst->word(3) == SpvOpCooperativeMatrixLengthNV)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand " << _.getIdName(operand_word) << " requires a type"; diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp index 39eeb4bd..9c7c8c1c 100644 --- a/source/val/validate_image.cpp +++ b/source/val/validate_image.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Google Inc. +// Copyright (c) 2017 Google Inc. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights // reserved. // @@ -18,6 +18,7 @@ #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" @@ -31,47 +32,47 @@ namespace spvtools { namespace val { namespace { -// Performs compile time check that all spv::ImageOperandsMask::XXX cases are -// handled in this module. If spv::ImageOperandsMask::XXX list changes, this -// function will fail the build. For all other purposes this is a placeholder -// function. +// Performs compile time check that all SpvImageOperandsXXX cases are handled in +// this module. If SpvImageOperandsXXX list changes, this function will fail the +// build. +// For all other purposes this is a placeholder function. bool CheckAllImageOperandsHandled() { - spv::ImageOperandsMask enum_val = spv::ImageOperandsMask::Bias; + SpvImageOperandsMask enum_val = SpvImageOperandsBiasMask; // Some improvised code to prevent the compiler from considering enum_val // constant and optimizing the switch away. uint32_t stack_var = 0; if (reinterpret_cast(&stack_var) % 256) - enum_val = spv::ImageOperandsMask::Lod; + enum_val = SpvImageOperandsLodMask; switch (enum_val) { // Please update the validation rules in this module if you are changing // the list of image operands, and add new enum values to this switch. - case spv::ImageOperandsMask::MaskNone: + case SpvImageOperandsMaskNone: return false; - case spv::ImageOperandsMask::Bias: - case spv::ImageOperandsMask::Lod: - case spv::ImageOperandsMask::Grad: - case spv::ImageOperandsMask::ConstOffset: - case spv::ImageOperandsMask::Offset: - case spv::ImageOperandsMask::ConstOffsets: - case spv::ImageOperandsMask::Sample: - case spv::ImageOperandsMask::MinLod: + case SpvImageOperandsBiasMask: + case SpvImageOperandsLodMask: + case SpvImageOperandsGradMask: + case SpvImageOperandsConstOffsetMask: + case SpvImageOperandsOffsetMask: + case SpvImageOperandsConstOffsetsMask: + case SpvImageOperandsSampleMask: + case SpvImageOperandsMinLodMask: // TODO(dneto): Support image operands related to the Vulkan memory model. // https://gitlab.khronos.org/spirv/spirv-tools/issues/32 - case spv::ImageOperandsMask::MakeTexelAvailableKHR: - case spv::ImageOperandsMask::MakeTexelVisibleKHR: - case spv::ImageOperandsMask::NonPrivateTexelKHR: - case spv::ImageOperandsMask::VolatileTexelKHR: - case spv::ImageOperandsMask::SignExtend: - case spv::ImageOperandsMask::ZeroExtend: + case SpvImageOperandsMakeTexelAvailableKHRMask: + case SpvImageOperandsMakeTexelVisibleKHRMask: + case SpvImageOperandsNonPrivateTexelKHRMask: + case SpvImageOperandsVolatileTexelKHRMask: + case SpvImageOperandsSignExtendMask: + case SpvImageOperandsZeroExtendMask: // TODO(jaebaek): Move this line properly after handling image offsets // operand. This line temporarily fixes CI failure that // blocks other PRs. // https://github.com/KhronosGroup/SPIRV-Tools/issues/4565 - case spv::ImageOperandsMask::Offsets: - case spv::ImageOperandsMask::Nontemporal: + case SpvImageOperandsOffsetsMask: + case SpvImageOperandsNontemporalMask: return true; } return false; @@ -80,13 +81,13 @@ bool CheckAllImageOperandsHandled() { // Used by GetImageTypeInfo. See OpTypeImage spec for more information. struct ImageTypeInfo { uint32_t sampled_type = 0; - spv::Dim dim = spv::Dim::Max; + SpvDim dim = SpvDimMax; uint32_t depth = 0; uint32_t arrayed = 0; uint32_t multisampled = 0; uint32_t sampled = 0; - spv::ImageFormat format = spv::ImageFormat::Max; - spv::AccessQualifier access_qualifier = spv::AccessQualifier::Max; + SpvImageFormat format = SpvImageFormatMax; + SpvAccessQualifier access_qualifier = SpvAccessQualifierMax; }; // Provides information on image type. |id| should be object of either @@ -99,39 +100,39 @@ bool GetImageTypeInfo(const ValidationState_t& _, uint32_t id, const Instruction* inst = _.FindDef(id); assert(inst); - if (inst->opcode() == spv::Op::OpTypeSampledImage) { + if (inst->opcode() == SpvOpTypeSampledImage) { inst = _.FindDef(inst->word(2)); assert(inst); } - if (inst->opcode() != spv::Op::OpTypeImage) return false; + if (inst->opcode() != SpvOpTypeImage) return false; const size_t num_words = inst->words().size(); if (num_words != 9 && num_words != 10) return false; info->sampled_type = inst->word(2); - info->dim = static_cast(inst->word(3)); + info->dim = static_cast(inst->word(3)); info->depth = inst->word(4); info->arrayed = inst->word(5); info->multisampled = inst->word(6); info->sampled = inst->word(7); - info->format = static_cast(inst->word(8)); - info->access_qualifier = - num_words < 10 ? spv::AccessQualifier::Max - : static_cast(inst->word(9)); + info->format = static_cast(inst->word(8)); + info->access_qualifier = num_words < 10 + ? SpvAccessQualifierMax + : static_cast(inst->word(9)); return true; } -bool IsImplicitLod(spv::Op opcode) { +bool IsImplicitLod(SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: return true; default: break; @@ -139,16 +140,16 @@ bool IsImplicitLod(spv::Op opcode) { return false; } -bool IsExplicitLod(spv::Op opcode) { +bool IsExplicitLod(SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: return true; default: break; @@ -156,22 +157,22 @@ bool IsExplicitLod(spv::Op opcode) { return false; } -bool IsValidLodOperand(const ValidationState_t& _, spv::Op opcode) { +bool IsValidLodOperand(const ValidationState_t& _, SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageRead: - case spv::Op::OpImageWrite: - case spv::Op::OpImageSparseRead: - return _.HasCapability(spv::Capability::ImageReadWriteLodAMD); + case SpvOpImageRead: + case SpvOpImageWrite: + case SpvOpImageSparseRead: + return _.HasCapability(SpvCapabilityImageReadWriteLodAMD); default: return IsExplicitLod(opcode); } } -bool IsValidGatherLodBiasAMD(const ValidationState_t& _, spv::Op opcode) { +bool IsValidGatherLodBiasAMD(const ValidationState_t& _, SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageGather: - case spv::Op::OpImageSparseGather: - return _.HasCapability(spv::Capability::ImageGatherBiasLodAMD); + case SpvOpImageGather: + case SpvOpImageSparseGather: + return _.HasCapability(SpvCapabilityImageGatherBiasLodAMD); default: break; } @@ -180,16 +181,16 @@ bool IsValidGatherLodBiasAMD(const ValidationState_t& _, spv::Op opcode) { // Returns true if the opcode is a Image instruction which applies // homogenous projection to the coordinates. -bool IsProj(spv::Op opcode) { +bool IsProj(SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: return true; default: break; @@ -203,23 +204,21 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) { uint32_t plane_size = 0; // If this switch breaks your build, please add new values below. switch (info.dim) { - case spv::Dim::Dim1D: - case spv::Dim::Buffer: + case SpvDim1D: + case SpvDimBuffer: plane_size = 1; break; - case spv::Dim::Dim2D: - case spv::Dim::Rect: - case spv::Dim::SubpassData: - case spv::Dim::TileImageDataEXT: + case SpvDim2D: + case SpvDimRect: + case SpvDimSubpassData: plane_size = 2; break; - case spv::Dim::Dim3D: - case spv::Dim::Cube: + case SpvDim3D: + case SpvDimCube: // For Cube direction vector is used instead of UV. plane_size = 3; break; - case spv::Dim::Max: - default: + case SpvDimMax: assert(0); break; } @@ -229,10 +228,10 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) { // Returns minimal number of coordinates based on image dim, arrayed and whether // the instruction uses projection coordinates. -uint32_t GetMinCoordSize(spv::Op opcode, const ImageTypeInfo& info) { - if (info.dim == spv::Dim::Cube && - (opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite || - opcode == spv::Op::OpImageSparseRead)) { +uint32_t GetMinCoordSize(SpvOp opcode, const ImageTypeInfo& info) { + if (info.dim == SpvDimCube && + (opcode == SpvOpImageRead || opcode == SpvOpImageWrite || + opcode == SpvOpImageSparseRead)) { // These opcodes use UV for Cube, not direction vector. return 3; } @@ -249,7 +248,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled(); (void)kAllImageOperandsHandled; - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const size_t num_words = inst->words().size(); const bool have_explicit_mask = (word_index - 1 < num_words); @@ -258,14 +257,14 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (have_explicit_mask) { // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words. const uint32_t mask_bits_having_operands = - mask & ~uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR | - spv::ImageOperandsMask::VolatileTexelKHR | - spv::ImageOperandsMask::SignExtend | - spv::ImageOperandsMask::ZeroExtend | - spv::ImageOperandsMask::Nontemporal); + mask & ~uint32_t(SpvImageOperandsNonPrivateTexelKHRMask | + SpvImageOperandsVolatileTexelKHRMask | + SpvImageOperandsSignExtendMask | + SpvImageOperandsZeroExtendMask | + SpvImageOperandsNontemporalMask); size_t expected_num_image_operand_words = spvtools::utils::CountSetBits(mask_bits_having_operands); - if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + if (mask & SpvImageOperandsGradMask) { // Grad uses two words. ++expected_num_image_operand_words; } @@ -280,8 +279,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Number of image operand ids doesn't correspond to the bit mask"; } - if (info.multisampled & - (0 == (mask & uint32_t(spv::ImageOperandsMask::Sample)))) { + if (info.multisampled & (0 == (mask & SpvImageOperandsSampleMask))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Sample is required for operation on " "multi-sampled image"; @@ -291,12 +289,12 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // the module to be invalid. if (mask == 0) return SPV_SUCCESS; - if (spvtools::utils::CountSetBits( - mask & uint32_t(spv::ImageOperandsMask::Offset | - spv::ImageOperandsMask::ConstOffset | - spv::ImageOperandsMask::ConstOffsets | - spv::ImageOperandsMask::Offsets)) > 1) { + if (spvtools::utils::CountSetBits(mask & (SpvImageOperandsOffsetMask | + SpvImageOperandsConstOffsetMask | + SpvImageOperandsConstOffsetsMask | + SpvImageOperandsOffsetsMask)) > 1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4662) << "Image Operands Offset, ConstOffset, ConstOffsets, Offsets " "cannot be used together"; } @@ -308,7 +306,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // The checks should be done in the order of definition of OperandImage. - if (mask & uint32_t(spv::ImageOperandsMask::Bias)) { + if (mask & SpvImageOperandsBiasMask) { if (!is_implicit_lod && !is_valid_gather_lod_bias_amd) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Bias can only be used with ImplicitLod opcodes"; @@ -320,8 +318,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Expected Image Operand Bias to be float scalar"; } - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D " "or Cube"; @@ -330,16 +328,15 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & uint32_t(spv::ImageOperandsMask::Lod)) { - if (!is_valid_lod_operand && opcode != spv::Op::OpImageFetch && - opcode != spv::Op::OpImageSparseFetch && - !is_valid_gather_lod_bias_amd) { + if (mask & SpvImageOperandsLodMask) { + if (!is_valid_lod_operand && opcode != SpvOpImageFetch && + opcode != SpvOpImageSparseFetch && !is_valid_gather_lod_bias_amd) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Lod can only be used with ExplicitLod opcodes " << "and OpImageFetch"; } - if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + if (mask & SpvImageOperandsGradMask) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand bits Lod and Grad cannot be set at the same " "time"; @@ -360,8 +357,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D " "or Cube"; @@ -370,7 +367,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { + if (mask & SpvImageOperandsGradMask) { if (!is_explicit_lod) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Grad can only be used with ExplicitLod opcodes"; @@ -403,8 +400,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Multisampled is already checked. } - if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { - if (info.dim == spv::Dim::Cube) { + if (mask & SpvImageOperandsConstOffsetMask) { + if (info.dim == SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffset cannot be used with Cube Image " "'Dim'"; @@ -432,8 +429,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & uint32_t(spv::ImageOperandsMask::Offset)) { - if (info.dim == spv::Dim::Cube) { + if (mask & SpvImageOperandsOffsetMask) { + if (info.dim == SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Offset cannot be used with Cube Image 'Dim'"; } @@ -456,10 +453,9 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (!_.options()->before_hlsl_legalization && spvIsVulkanEnv(_.context()->target_env)) { - if (opcode != spv::Op::OpImageGather && - opcode != spv::Op::OpImageDrefGather && - opcode != spv::Op::OpImageSparseGather && - opcode != spv::Op::OpImageSparseDrefGather) { + if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather && + opcode != SpvOpImageSparseGather && + opcode != SpvOpImageSparseDrefGather) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4663) << "Image Operand Offset can only be used with " @@ -468,17 +464,16 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & uint32_t(spv::ImageOperandsMask::ConstOffsets)) { - if (opcode != spv::Op::OpImageGather && - opcode != spv::Op::OpImageDrefGather && - opcode != spv::Op::OpImageSparseGather && - opcode != spv::Op::OpImageSparseDrefGather) { + if (mask & SpvImageOperandsConstOffsetsMask) { + if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather && + opcode != SpvOpImageSparseGather && + opcode != SpvOpImageSparseDrefGather) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffsets can only be used with " "OpImageGather and OpImageDrefGather"; } - if (info.dim == spv::Dim::Cube) { + if (info.dim == SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand ConstOffsets cannot be used with Cube Image " "'Dim'"; @@ -489,7 +484,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, const Instruction* type_inst = _.FindDef(type_id); assert(type_inst); - if (type_inst->opcode() != spv::Op::OpTypeArray) { + if (type_inst->opcode() != SpvOpTypeArray) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image Operand ConstOffsets to be an array of size 4"; } @@ -518,11 +513,10 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & uint32_t(spv::ImageOperandsMask::Sample)) { - if (opcode != spv::Op::OpImageFetch && opcode != spv::Op::OpImageRead && - opcode != spv::Op::OpImageWrite && - opcode != spv::Op::OpImageSparseFetch && - opcode != spv::Op::OpImageSparseRead) { + if (mask & SpvImageOperandsSampleMask) { + if (opcode != SpvOpImageFetch && opcode != SpvOpImageRead && + opcode != SpvOpImageWrite && opcode != SpvOpImageSparseFetch && + opcode != SpvOpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand Sample can only be used with OpImageFetch, " << "OpImageRead, OpImageWrite, OpImageSparseFetch and " @@ -541,8 +535,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & uint32_t(spv::ImageOperandsMask::MinLod)) { - if (!is_implicit_lod && !(mask & uint32_t(spv::ImageOperandsMask::Grad))) { + if (mask & SpvImageOperandsMinLodMask) { + if (!is_implicit_lod && !(mask & SpvImageOperandsGradMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MinLod can only be used with ImplicitLod " << "opcodes or together with Image Operand Grad"; @@ -554,8 +548,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, << "Expected Image Operand MinLod to be float scalar"; } - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MinLod requires 'Dim' parameter to be 1D, 2D, " "3D or Cube"; @@ -567,16 +561,16 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, } } - if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR)) { + if (mask & SpvImageOperandsMakeTexelAvailableKHRMask) { // Checked elsewhere: capability and memory model are correct. - if (opcode != spv::Op::OpImageWrite) { + if (opcode != SpvOpImageWrite) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelAvailableKHR can only be used with Op" - << spvOpcodeString(spv::Op::OpImageWrite) << ": Op" + << spvOpcodeString(SpvOpImageWrite) << ": Op" << spvOpcodeString(opcode); } - if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { + if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelAvailableKHR requires " "NonPrivateTexelKHR is also specified: Op" @@ -588,18 +582,17 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, return error; } - if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR)) { + if (mask & SpvImageOperandsMakeTexelVisibleKHRMask) { // Checked elsewhere: capability and memory model are correct. - if (opcode != spv::Op::OpImageRead && - opcode != spv::Op::OpImageSparseRead) { + if (opcode != SpvOpImageRead && opcode != SpvOpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelVisibleKHR can only be used with Op" - << spvOpcodeString(spv::Op::OpImageRead) << " or Op" - << spvOpcodeString(spv::Op::OpImageSparseRead) << ": Op" + << spvOpcodeString(SpvOpImageRead) << " or Op" + << spvOpcodeString(SpvOpImageSparseRead) << ": Op" << spvOpcodeString(opcode); } - if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) { + if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Operand MakeTexelVisibleKHR requires NonPrivateTexelKHR " "is also specified: Op" @@ -610,7 +603,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; } - if (mask & uint32_t(spv::ImageOperandsMask::SignExtend)) { + if (mask & SpvImageOperandsSignExtendMask) { // Checked elsewhere: SPIR-V 1.4 version or later. // "The texel value is converted to the target value via sign extension. @@ -623,7 +616,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // setup. } - if (mask & uint32_t(spv::ImageOperandsMask::ZeroExtend)) { + if (mask & SpvImageOperandsZeroExtendMask) { // Checked elsewhere: SPIR-V 1.4 version or later. // "The texel value is converted to the target value via zero extension. @@ -636,11 +629,11 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // setup. } - if (mask & uint32_t(spv::ImageOperandsMask::Offsets)) { + if (mask & SpvImageOperandsOffsetsMask) { // TODO: add validation } - if (mask & uint32_t(spv::ImageOperandsMask::Nontemporal)) { + if (mask & SpvImageOperandsNontemporalMask) { // Checked elsewhere: SPIR-V 1.6 version or later. } @@ -650,8 +643,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _, // Validate OpImage*Proj* instructions spv_result_t ValidateImageProj(ValidationState_t& _, const Instruction* inst, const ImageTypeInfo& info) { - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Rect) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimRect) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect"; } @@ -674,30 +667,33 @@ spv_result_t ValidateImageReadWrite(ValidationState_t& _, const Instruction* inst, const ImageTypeInfo& info) { if (info.sampled == 2) { - if (info.dim == spv::Dim::Dim1D && - !_.HasCapability(spv::Capability::Image1D)) { + if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability Image1D is required to access storage image"; - } else if (info.dim == spv::Dim::Rect && - !_.HasCapability(spv::Capability::ImageRect)) { + } else if (info.dim == SpvDimRect && + !_.HasCapability(SpvCapabilityImageRect)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageRect is required to access storage image"; - } else if (info.dim == spv::Dim::Buffer && - !_.HasCapability(spv::Capability::ImageBuffer)) { + } else if (info.dim == SpvDimBuffer && + !_.HasCapability(SpvCapabilityImageBuffer)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageBuffer is required to access storage image"; - } else if (info.dim == spv::Dim::Cube && info.arrayed == 1 && - !_.HasCapability(spv::Capability::ImageCubeArray)) { + } else if (info.dim == SpvDimCube && info.arrayed == 1 && + !_.HasCapability(SpvCapabilityImageCubeArray)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability ImageCubeArray is required to access " << "storage image"; } - if (info.multisampled == 1 && info.arrayed == 1 && info.sampled == 2 && - !_.HasCapability(spv::Capability::ImageMSArray)) { + if (info.multisampled == 1 && !_.HasCapability(SpvCapabilityImageMSArray)) { +#if 0 + // TODO(atgoo@github.com) The description of this rule in the spec + // is unclear and Glslang doesn't declare ImageMSArray. Need to clarify + // and reenable. return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Capability ImageMSArray is required to access storage " - << "image"; + << "Capability ImageMSArray is required to access storage " + << "image"; +#endif } } else if (info.sampled != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -708,21 +704,21 @@ spv_result_t ValidateImageReadWrite(ValidationState_t& _, } // Returns true if opcode is *ImageSparse*, false otherwise. -bool IsSparse(spv::Op opcode) { +bool IsSparse(SpvOp opcode) { switch (opcode) { - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageSparseTexelsResident: - case spv::Op::OpImageSparseRead: { + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseFetch: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpImageSparseTexelsResident: + case SpvOpImageSparseRead: { return true; } @@ -737,13 +733,13 @@ bool IsSparse(spv::Op opcode) { // Not valid for sparse image opcodes which do not return a struct. spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst, uint32_t* actual_result_type) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (IsSparse(opcode)) { const Instruction* const type_inst = _.FindDef(inst->type_id()); assert(type_inst); - if (!type_inst || type_inst->opcode() != spv::Op::OpTypeStruct) { + if (!type_inst || type_inst->opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeStruct"; } @@ -765,7 +761,7 @@ spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst, // Returns a string describing actual result type of an opcode. // Not valid for sparse image opcodes which do not return a struct. -const char* GetActualResultTypeStr(spv::Op opcode) { +const char* GetActualResultTypeStr(SpvOp opcode) { if (IsSparse(opcode)) return "Result Type's second member"; return "Result Type"; } @@ -781,7 +777,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { if (_.IsIntScalarType(info.sampled_type) && (64 == _.GetBitWidth(info.sampled_type)) && - !_.HasCapability(spv::Capability::Int64ImageEXT)) { + !_.HasCapability(SpvCapabilityInt64ImageEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability Int64ImageEXT is required when using Sampled Type of " "64-bit int"; @@ -806,10 +802,10 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled Type must be OpTypeVoid in the OpenCL environment."; } } else { - const spv::Op sampled_type_opcode = _.GetIdOpcode(info.sampled_type); - if (sampled_type_opcode != spv::Op::OpTypeVoid && - sampled_type_opcode != spv::Op::OpTypeInt && - sampled_type_opcode != spv::Op::OpTypeFloat) { + const SpvOp sampled_type_opcode = _.GetIdOpcode(info.sampled_type); + if (sampled_type_opcode != SpvOpTypeVoid && + sampled_type_opcode != SpvOpTypeInt && + sampled_type_opcode != SpvOpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Type to be either void or" << " numerical scalar type"; @@ -839,41 +835,19 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; } - if (info.dim == spv::Dim::SubpassData) { + if (info.dim == SpvDimSubpassData) { if (info.sampled != 2) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(6214) << "Dim SubpassData requires Sampled to be 2"; } - if (info.format != spv::ImageFormat::Unknown) { + if (info.format != SpvImageFormatUnknown) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Dim SubpassData requires format Unknown"; } - } else if (info.dim == spv::Dim::TileImageDataEXT) { - if (_.IsVoidType(info.sampled_type)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Dim TileImageDataEXT requires Sampled Type to be not " - "OpTypeVoid"; - } - if (info.sampled != 2) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Dim TileImageDataEXT requires Sampled to be 2"; - } - if (info.format != spv::ImageFormat::Unknown) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Dim TileImageDataEXT requires format Unknown"; - } - if (info.depth != 0) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Dim TileImageDataEXT requires Depth to be 0"; - } - if (info.arrayed != 0) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Dim TileImageDataEXT requires Arrayed to be 0"; - } } else { if (info.multisampled && (info.sampled == 2) && - !_.HasCapability(spv::Capability::StorageImageMultisample)) { + !_.HasCapability(SpvCapabilityStorageImageMultisample)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageMultisample is required when using " "multisampled storage image"; @@ -881,8 +855,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { } if (spvIsOpenCLEnv(target_env)) { - if ((info.arrayed == 1) && (info.dim != spv::Dim::Dim1D) && - (info.dim != spv::Dim::Dim2D)) { + if ((info.arrayed == 1) && (info.dim != SpvDim1D) && + (info.dim != SpvDim2D)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "In the OpenCL environment, Arrayed may only be set to 1 " << "when Dim is either 1D or 2D."; @@ -898,7 +872,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled must be 0 in the OpenCL environment."; } - if (info.access_qualifier == spv::AccessQualifier::Max) { + if (info.access_qualifier == SpvAccessQualifierMax) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "In the OpenCL environment, the optional Access Qualifier" << " must be present."; @@ -912,7 +886,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Sampled must be 1 or 2 in the Vulkan environment."; } - if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) { + if (info.dim == SpvDimSubpassData && info.arrayed != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0"; } @@ -924,7 +898,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateTypeSampledImage(ValidationState_t& _, const Instruction* inst) { const uint32_t image_type = inst->word(2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -936,8 +910,6 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _, } // OpenCL requires Sampled=0, checked elsewhere. // Vulkan uses the Sampled=1 case. - // If Dim is TileImageDataEXT, Sampled must be 2 and this is validated - // elsewhere. if ((info.sampled != 0) && (info.sampled != 1)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4657) @@ -946,8 +918,7 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _, } // This covers both OpTypeSampledImage and OpSampledImage. - if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && - info.dim == spv::Dim::Buffer) { + if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && info.dim == SpvDimBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In SPIR-V 1.6 or later, sampled image dimension must not be " "Buffer"; @@ -956,35 +927,31 @@ spv_result_t ValidateTypeSampledImage(ValidationState_t& _, return SPV_SUCCESS; } -bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { +bool IsAllowedSampledImageOperand(SpvOp opcode, ValidationState_t& _) { switch (opcode) { - case spv::Op::OpSampledImage: - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImage: - case spv::Op::OpImageQueryLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpCopyObject: - case spv::Op::OpImageSampleWeightedQCOM: - case spv::Op::OpImageBoxFilterQCOM: - case spv::Op::OpImageBlockMatchSSDQCOM: - case spv::Op::OpImageBlockMatchSADQCOM: + case SpvOpSampledImage: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImage: + case SpvOpImageQueryLod: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: + case SpvOpCopyObject: return true; - case spv::Op::OpStore: - if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true; + case SpvOpStore: + if (_.HasCapability(SpvCapabilityBindlessTextureNV)) return true; return false; default: return false; @@ -993,13 +960,13 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { spv_result_t ValidateSampledImage(ValidationState_t& _, const Instruction* inst) { - if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) { + if (_.GetIdOpcode(inst->type_id()) != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeSampledImage."; } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage."; } @@ -1027,12 +994,12 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, } } - if (info.dim == spv::Dim::SubpassData) { + if (info.dim == SpvDimSubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image 'Dim' parameter to be not SubpassData."; } - if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != spv::Op::OpTypeSampler) { + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != SpvOpTypeSampler) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampler to be of type OpTypeSampler"; } @@ -1060,13 +1027,12 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, << _.getIdName(consumer_instr->id()) << "."; } - if (consumer_opcode == spv::Op::OpPhi || - consumer_opcode == spv::Op::OpSelect) { + if (consumer_opcode == SpvOpPhi || consumer_opcode == SpvOpSelect) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result from OpSampledImage instruction must not appear " "as " "operands of Op" - << spvOpcodeString(static_cast(consumer_opcode)) << "." + << spvOpcodeString(static_cast(consumer_opcode)) << "." << " Found result " << _.getIdName(inst->id()) << " as an operand of " << _.getIdName(consumer_instr->id()) << "."; @@ -1076,7 +1042,7 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result from OpSampledImage instruction must not appear " "as operand for Op" - << spvOpcodeString(static_cast(consumer_opcode)) + << spvOpcodeString(static_cast(consumer_opcode)) << ", since it is not specified as taking an " << "OpTypeSampledImage." << " Found result " << _.getIdName(inst->id()) @@ -1085,31 +1051,19 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, } } } - - const Instruction* ld_inst; - { - int t_idx = inst->GetOperandAs(2); - ld_inst = _.FindDef(t_idx); - } - - if (ld_inst->opcode() == spv::Op::OpLoad) { - int texture_id = ld_inst->GetOperandAs(2); // variable to load - _.RegisterQCOMImageProcessingTextureConsumer(texture_id, ld_inst, inst); - } - return SPV_SUCCESS; } spv_result_t ValidateImageTexelPointer(ValidationState_t& _, const Instruction* inst) { const auto result_type = _.FindDef(inst->type_id()); - if (result_type->opcode() != spv::Op::OpTypePointer) { + if (result_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer"; } - const auto storage_class = result_type->GetOperandAs(1); - if (storage_class != spv::StorageClass::Image) { + const auto storage_class = result_type->GetOperandAs(1); + if (storage_class != SpvStorageClassImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer whose Storage Class " "operand is Image"; @@ -1117,21 +1071,21 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, const auto ptr_type = result_type->GetOperandAs(2); const auto ptr_opcode = _.GetIdOpcode(ptr_type); - if (ptr_opcode != spv::Op::OpTypeInt && ptr_opcode != spv::Op::OpTypeFloat && - ptr_opcode != spv::Op::OpTypeVoid) { + if (ptr_opcode != SpvOpTypeInt && ptr_opcode != SpvOpTypeFloat && + ptr_opcode != SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypePointer whose Type operand " "must be a scalar numerical type or OpTypeVoid"; } const auto image_ptr = _.FindDef(_.GetOperandTypeId(inst, 2)); - if (!image_ptr || image_ptr->opcode() != spv::Op::OpTypePointer) { + if (!image_ptr || image_ptr->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be OpTypePointer"; } const auto image_type = image_ptr->GetOperandAs(2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be OpTypePointer with Type OpTypeImage"; } @@ -1148,17 +1102,11 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, "pointed to by Result Type"; } - if (info.dim == spv::Dim::SubpassData) { + if (info.dim == SpvDimSubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Dim SubpassData cannot be used with OpImageTexelPointer"; } - if (info.dim == spv::Dim::TileImageDataEXT) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Image Dim TileImageDataEXT cannot be used with " - "OpImageTexelPointer"; - } - const uint32_t coord_type = _.GetOperandTypeId(inst, 3); if (!coord_type || !_.IsIntScalarOrVectorType(coord_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1170,11 +1118,11 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, expected_coord_size = GetPlaneCoordSize(info); } else if (info.arrayed == 1) { switch (info.dim) { - case spv::Dim::Dim1D: + case SpvDim1D: expected_coord_size = 2; break; - case spv::Dim::Cube: - case spv::Dim::Dim2D: + case SpvDimCube: + case SpvDim2D: expected_coord_size = 3; break; default: @@ -1209,11 +1157,11 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((info.format != spv::ImageFormat::R64i) && - (info.format != spv::ImageFormat::R64ui) && - (info.format != spv::ImageFormat::R32f) && - (info.format != spv::ImageFormat::R32i) && - (info.format != spv::ImageFormat::R32ui)) { + if ((info.format != SpvImageFormatR64i) && + (info.format != SpvImageFormatR64ui) && + (info.format != SpvImageFormatR32f) && + (info.format != SpvImageFormatR32i) && + (info.format != SpvImageFormatR32ui)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4658) << "Expected the Image Format in Image to be R64i, R64ui, R32f, " @@ -1225,7 +1173,7 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _, } spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1245,7 +1193,7 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1268,7 +1216,7 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { << "Sampling operation is invalid for multisample image"; } - if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { const uint32_t texel_component_type = _.GetComponentType(actual_result_type); if (texel_component_type != info.sampled_type) { @@ -1279,9 +1227,9 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { } const uint32_t coord_type = _.GetOperandTypeId(inst, 3); - if ((opcode == spv::Op::OpImageSampleExplicitLod || - opcode == spv::Op::OpImageSparseSampleExplicitLod) && - _.HasCapability(spv::Capability::Kernel)) { + if ((opcode == SpvOpImageSampleExplicitLod || + opcode == SpvOpImageSparseSampleExplicitLod) && + _.HasCapability(SpvCapabilityKernel)) { if (!_.IsFloatScalarOrVectorType(coord_type) && !_.IsIntScalarOrVectorType(coord_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1304,9 +1252,9 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) { const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); - if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + if (mask & SpvImageOperandsConstOffsetMask) { if (spvIsOpenCLEnv(_.context()->target_env)) { - if (opcode == spv::Op::OpImageSampleExplicitLod) { + if (opcode == SpvOpImageSampleExplicitLod) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "ConstOffset image operand not allowed " << "in the OpenCL environment."; @@ -1331,7 +1279,7 @@ spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.dim == spv::Dim::Dim3D) { + if (info.dim == SpvDim3D) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4777) << "In Vulkan, OpImage*Dref* instructions must not use images " @@ -1344,7 +1292,7 @@ spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateImageDrefLod(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1358,7 +1306,7 @@ spv_result_t ValidateImageDrefLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1416,7 +1364,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { return error; } - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (!_.IsIntVectorType(actual_result_type) && !_.IsFloatVectorType(actual_result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1431,7 +1379,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1442,7 +1390,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { << "Corrupt image type definition"; } - if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1452,7 +1400,7 @@ spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) { } } - if (info.dim == spv::Dim::Cube) { + if (info.dim == SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be Cube"; } @@ -1488,7 +1436,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) return error; - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (!_.IsIntVectorType(actual_result_type) && !_.IsFloatVectorType(actual_result_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1503,7 +1451,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sampled Image to be of type OpTypeSampledImage"; } @@ -1522,9 +1470,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, << "Gather operation is invalid for multisample image"; } - if (opcode == spv::Op::OpImageDrefGather || - opcode == spv::Op::OpImageSparseDrefGather || - _.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + if (opcode == SpvOpImageDrefGather || opcode == SpvOpImageSparseDrefGather || + _.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1534,8 +1481,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } } - if (info.dim != spv::Dim::Dim2D && info.dim != spv::Dim::Cube && - info.dim != spv::Dim::Rect) { + if (info.dim != SpvDim2D && info.dim != SpvDimCube && + info.dim != SpvDimRect) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4777) << "Expected Image 'Dim' to be 2D, Cube, or Rect"; @@ -1555,8 +1502,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, << " components, but given only " << actual_coord_size; } - if (opcode == spv::Op::OpImageGather || - opcode == spv::Op::OpImageSparseGather) { + if (opcode == SpvOpImageGather || opcode == SpvOpImageSparseGather) { const uint32_t component = inst->GetOperandAs(4); const uint32_t component_index_type = _.GetTypeId(component); if (!_.IsIntScalarType(component_index_type) || @@ -1573,8 +1519,8 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } } } else { - assert(opcode == spv::Op::OpImageDrefGather || - opcode == spv::Op::OpImageSparseDrefGather); + assert(opcode == SpvOpImageDrefGather || + opcode == SpvOpImageSparseDrefGather); if (spv_result_t result = ValidateImageDref(_, inst, info)) return result; } @@ -1586,7 +1532,7 @@ spv_result_t ValidateImageGather(ValidationState_t& _, } spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); uint32_t actual_result_type = 0; if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) { return error; @@ -1611,7 +1557,7 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } // Check OpenCL below, after we get the image info. const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1645,33 +1591,27 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5); - if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) { + if (mask & SpvImageOperandsConstOffsetMask) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "ConstOffset image operand not allowed " << "in the OpenCL environment."; } } - if (info.dim == spv::Dim::SubpassData) { - if (opcode == spv::Op::OpImageSparseRead) { + if (info.dim == SpvDimSubpassData) { + if (opcode == SpvOpImageSparseRead) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image Dim SubpassData cannot be used with ImageSparseRead"; } _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, std::string("Dim SubpassData requires Fragment execution model: ") + spvOpcodeString(opcode)); } - if (info.dim == spv::Dim::TileImageDataEXT) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Image Dim TileImageDataEXT cannot be used with " - << spvOpcodeString(opcode); - } - - if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { const uint32_t result_component_type = _.GetComponentType(actual_result_type); if (result_component_type != info.sampled_type) { @@ -1699,9 +1639,8 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.format == spv::ImageFormat::Unknown && - info.dim != spv::Dim::SubpassData && - !_.HasCapability(spv::Capability::StorageImageReadWithoutFormat)) { + if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData && + !_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageReadWithoutFormat is required to " << "read storage image"; @@ -1717,7 +1656,7 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { const uint32_t image_type = _.GetOperandTypeId(inst, 0); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1728,16 +1667,11 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { << "Corrupt image type definition"; } - if (info.dim == spv::Dim::SubpassData) { + if (info.dim == SpvDimSubpassData) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be SubpassData"; } - if (info.dim == spv::Dim::TileImageDataEXT) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Image 'Dim' cannot be TileImageDataEXT"; - } - if (spv_result_t result = ValidateImageReadWrite(_, inst, info)) return result; @@ -1763,7 +1697,7 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { << "Expected Texel to be int or float vector or scalar"; } - if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) { + if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) { const uint32_t texel_component_type = _.GetComponentType(texel_type); if (texel_component_type != info.sampled_type) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -1773,9 +1707,8 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env)) { - if (info.format == spv::ImageFormat::Unknown && - info.dim != spv::Dim::SubpassData && - !_.HasCapability(spv::Capability::StorageImageWriteWithoutFormat)) { + if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData && + !_.HasCapability(SpvCapabilityStorageImageWriteWithoutFormat)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Capability StorageImageWriteWithoutFormat is required to " "write " @@ -1800,7 +1733,7 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) { const uint32_t result_type = inst->type_id(); - if (_.GetIdOpcode(result_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(result_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeImage"; } @@ -1809,7 +1742,7 @@ spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) { const Instruction* sampled_image_type_inst = _.FindDef(sampled_image_type); assert(sampled_image_type_inst); - if (sampled_image_type_inst->opcode() != spv::Op::OpTypeSampledImage) { + if (sampled_image_type_inst->opcode() != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Sample Image to be of type OpTypeSampleImage"; } @@ -1831,7 +1764,7 @@ spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1844,14 +1777,14 @@ spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _, uint32_t expected_num_components = info.arrayed; switch (info.dim) { - case spv::Dim::Dim1D: + case SpvDim1D: expected_num_components += 1; break; - case spv::Dim::Dim2D: - case spv::Dim::Cube: + case SpvDim2D: + case SpvDimCube: expected_num_components += 2; break; - case spv::Dim::Dim3D: + case SpvDim3D: expected_num_components += 3; break; default: @@ -1897,7 +1830,7 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -1910,16 +1843,16 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, uint32_t expected_num_components = info.arrayed; switch (info.dim) { - case spv::Dim::Dim1D: - case spv::Dim::Buffer: + case SpvDim1D: + case SpvDimBuffer: expected_num_components += 1; break; - case spv::Dim::Dim2D: - case spv::Dim::Cube: - case spv::Dim::Rect: + case SpvDim2D: + case SpvDimCube: + case SpvDimRect: expected_num_components += 2; break; - case spv::Dim::Dim3D: + case SpvDim3D: expected_num_components += 3; break; default: @@ -1927,8 +1860,8 @@ spv_result_t ValidateImageQuerySize(ValidationState_t& _, << "Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect"; } - if (info.dim == spv::Dim::Dim1D || info.dim == spv::Dim::Dim2D || - info.dim == spv::Dim::Dim3D || info.dim == spv::Dim::Cube) { + if (info.dim == SpvDim1D || info.dim == SpvDim2D || info.dim == SpvDim3D || + info.dim == SpvDimCube) { if (info.multisampled != 1 && info.sampled != 0 && info.sampled != 2) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2"; @@ -1952,22 +1885,10 @@ spv_result_t ValidateImageQueryFormatOrOrder(ValidationState_t& _, << "Expected Result Type to be int scalar type"; } - const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected operand to be of type OpTypeImage"; } - - ImageTypeInfo info; - if (!GetImageTypeInfo(_, image_type, &info)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Corrupt image type definition"; - } - - if (info.dim == spv::Dim::TileImageDataEXT) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Image 'Dim' cannot be TileImageDataEXT"; - } return SPV_SUCCESS; } @@ -1975,9 +1896,9 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, const Instruction* inst) { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [&](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::Fragment && - model != spv::ExecutionModel::GLCompute) { + [&](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { if (message) { *message = std::string( "OpImageQueryLod requires Fragment or GLCompute execution " @@ -1993,10 +1914,10 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, std::string* message) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); - if (models->find(spv::ExecutionModel::GLCompute) != models->end() && - modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + if (models->find(SpvExecutionModelGLCompute) != models->end() && + modes->find(SpvExecutionModeDerivativeGroupLinearNV) == modes->end() && - modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == modes->end()) { if (message) { *message = std::string( @@ -2021,7 +1942,7 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image operand to be of type OpTypeSampledImage"; } @@ -2032,14 +1953,14 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, << "Corrupt image type definition"; } - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 1D, 2D, 3D or Cube"; } const uint32_t coord_type = _.GetOperandTypeId(inst, 3); - if (_.HasCapability(spv::Capability::Kernel)) { + if (_.HasCapability(SpvCapabilityKernel)) { if (!_.IsFloatScalarOrVectorType(coord_type) && !_.IsIntScalarOrVectorType(coord_type)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2060,11 +1981,11 @@ spv_result_t ValidateImageQueryLod(ValidationState_t& _, << " components, but given only " << actual_coord_size; } - // The operand is a sampled image. + // The operad is a sampled image. // The sampled image type is already checked to be parameterized by an image // type with Sampled=0 or Sampled=1. Vulkan bans Sampled=0, and so we have // Sampled=1. So the validator already enforces Vulkan VUID 4659: - // OpImageQuerySizeLod must only consume an "Image" operand whose type has + // OpImageQuerySizeLod must only consume an “Image” operand whose type has // its "Sampled" operand set to 1 return SPV_SUCCESS; } @@ -2084,7 +2005,7 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, } const uint32_t image_type = _.GetOperandTypeId(inst, 2); - if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) { + if (_.GetIdOpcode(image_type) != SpvOpTypeImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Image to be of type OpTypeImage"; } @@ -2095,10 +2016,10 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, << "Corrupt image type definition"; } - const spv::Op opcode = inst->opcode(); - if (opcode == spv::Op::OpImageQueryLevels) { - if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D && - info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) { + const SpvOp opcode = inst->opcode(); + if (opcode == SpvOpImageQueryLevels) { + if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && + info.dim != SpvDimCube) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 1D, 2D, 3D or Cube"; } @@ -2112,8 +2033,8 @@ spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _, } } } else { - assert(opcode == spv::Op::OpImageQuerySamples); - if (info.dim != spv::Dim::Dim2D) { + assert(opcode == SpvOpImageQuerySamples); + if (info.dim != SpvDim2D) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D"; } @@ -2140,67 +2061,17 @@ spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id, - spv::Decoration decor) { - const Instruction* si_inst = nullptr; - const Instruction* ld_inst = _.FindDef(id); - if (ld_inst->opcode() == spv::Op::OpSampledImage) { - si_inst = ld_inst; - int t_idx = si_inst->GetOperandAs(2); // texture - ld_inst = _.FindDef(t_idx); - } - if (ld_inst->opcode() != spv::Op::OpLoad) { - return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad"; - } - int texture_id = ld_inst->GetOperandAs(2); // variable to load - if (!_.HasDecoration(texture_id, decor)) { - return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) - << "Missing decoration WeightTextureQCOM/BlockMatchTextureQCOM"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _, - const Instruction* inst) { - spv_result_t res = SPV_SUCCESS; - const spv::Op opcode = inst->opcode(); - switch (opcode) { - case spv::Op::OpImageSampleWeightedQCOM: { - int wi_idx = inst->GetOperandAs(4); // weight - res = ValidateImageProcessingQCOMDecoration( - _, wi_idx, spv::Decoration::WeightTextureQCOM); - break; - } - case spv::Op::OpImageBlockMatchSSDQCOM: - case spv::Op::OpImageBlockMatchSADQCOM: { - int tgt_idx = inst->GetOperandAs(2); // target - res = ValidateImageProcessingQCOMDecoration( - _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM); - if (res != SPV_SUCCESS) break; - int ref_idx = inst->GetOperandAs(4); // reference - res = ValidateImageProcessingQCOMDecoration( - _, ref_idx, spv::Decoration::BlockMatchTextureQCOM); - break; - } - default: - break; - } - - return res; -} - } // namespace // Validates correctness of image instructions. spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (IsImplicitLod(opcode)) { _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model, + ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::Fragment && - model != spv::ExecutionModel::GLCompute) { + if (model != SpvExecutionModelFragment && + model != SpvExecutionModelGLCompute) { if (message) { *message = std::string( @@ -2219,11 +2090,11 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { const auto* models = state.GetExecutionModels(entry_point->id()); const auto* modes = state.GetExecutionModes(entry_point->id()); if (models && - models->find(spv::ExecutionModel::GLCompute) != models->end() && + models->find(SpvExecutionModelGLCompute) != models->end() && (!modes || - (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) == + (modes->find(SpvExecutionModeDerivativeGroupLinearNV) == modes->end() && - modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) == + modes->find(SpvExecutionModeDerivativeGroupQuadsNV) == modes->end()))) { if (message) { *message = @@ -2240,81 +2111,75 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { } switch (opcode) { - case spv::Op::OpTypeImage: + case SpvOpTypeImage: return ValidateTypeImage(_, inst); - case spv::Op::OpTypeSampledImage: + case SpvOpTypeSampledImage: return ValidateTypeSampledImage(_, inst); - case spv::Op::OpSampledImage: + case SpvOpSampledImage: return ValidateSampledImage(_, inst); - case spv::Op::OpImageTexelPointer: + case SpvOpImageTexelPointer: return ValidateImageTexelPointer(_, inst); - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: + case SpvOpImageSampleImplicitLod: + case SpvOpImageSampleExplicitLod: + case SpvOpImageSampleProjImplicitLod: + case SpvOpImageSampleProjExplicitLod: + case SpvOpImageSparseSampleImplicitLod: + case SpvOpImageSparseSampleExplicitLod: return ValidateImageLod(_, inst); - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: + case SpvOpImageSampleDrefImplicitLod: + case SpvOpImageSampleDrefExplicitLod: + case SpvOpImageSampleProjDrefImplicitLod: + case SpvOpImageSampleProjDrefExplicitLod: + case SpvOpImageSparseSampleDrefImplicitLod: + case SpvOpImageSparseSampleDrefExplicitLod: return ValidateImageDrefLod(_, inst); - case spv::Op::OpImageFetch: - case spv::Op::OpImageSparseFetch: + case SpvOpImageFetch: + case SpvOpImageSparseFetch: return ValidateImageFetch(_, inst); - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: + case SpvOpImageGather: + case SpvOpImageDrefGather: + case SpvOpImageSparseGather: + case SpvOpImageSparseDrefGather: return ValidateImageGather(_, inst); - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseRead: + case SpvOpImageRead: + case SpvOpImageSparseRead: return ValidateImageRead(_, inst); - case spv::Op::OpImageWrite: + case SpvOpImageWrite: return ValidateImageWrite(_, inst); - case spv::Op::OpImage: + case SpvOpImage: return ValidateImage(_, inst); - case spv::Op::OpImageQueryFormat: - case spv::Op::OpImageQueryOrder: + case SpvOpImageQueryFormat: + case SpvOpImageQueryOrder: return ValidateImageQueryFormatOrOrder(_, inst); - case spv::Op::OpImageQuerySizeLod: + case SpvOpImageQuerySizeLod: return ValidateImageQuerySizeLod(_, inst); - case spv::Op::OpImageQuerySize: + case SpvOpImageQuerySize: return ValidateImageQuerySize(_, inst); - case spv::Op::OpImageQueryLod: + case SpvOpImageQueryLod: return ValidateImageQueryLod(_, inst); - case spv::Op::OpImageQueryLevels: - case spv::Op::OpImageQuerySamples: + case SpvOpImageQueryLevels: + case SpvOpImageQuerySamples: return ValidateImageQueryLevelsOrSamples(_, inst); - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: return ValidateImageSparseLod(_, inst); - case spv::Op::OpImageSparseTexelsResident: + case SpvOpImageSparseTexelsResident: return ValidateImageSparseTexelsResident(_, inst); - case spv::Op::OpImageSampleWeightedQCOM: - case spv::Op::OpImageBoxFilterQCOM: - case spv::Op::OpImageBlockMatchSSDQCOM: - case spv::Op::OpImageBlockMatchSADQCOM: - return ValidateImageProcessingQCOM(_, inst); - default: break; } @@ -2322,89 +2187,5 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { return SPV_SUCCESS; } -bool IsImageInstruction(const spv::Op opcode) { - switch (opcode) { - case spv::Op::OpImageSampleImplicitLod: - case spv::Op::OpImageSampleDrefImplicitLod: - case spv::Op::OpImageSampleProjImplicitLod: - case spv::Op::OpImageSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleImplicitLod: - case spv::Op::OpImageSparseSampleDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - - case spv::Op::OpImageSampleExplicitLod: - case spv::Op::OpImageSampleDrefExplicitLod: - case spv::Op::OpImageSampleProjExplicitLod: - case spv::Op::OpImageSampleProjDrefExplicitLod: - case spv::Op::OpImageSparseSampleExplicitLod: - case spv::Op::OpImageSparseSampleDrefExplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: - - case spv::Op::OpImage: - case spv::Op::OpImageFetch: - case spv::Op::OpImageSparseFetch: - case spv::Op::OpImageGather: - case spv::Op::OpImageDrefGather: - case spv::Op::OpImageSparseGather: - case spv::Op::OpImageSparseDrefGather: - case spv::Op::OpImageRead: - case spv::Op::OpImageSparseRead: - case spv::Op::OpImageWrite: - - case spv::Op::OpImageQueryFormat: - case spv::Op::OpImageQueryOrder: - case spv::Op::OpImageQuerySizeLod: - case spv::Op::OpImageQuerySize: - case spv::Op::OpImageQueryLod: - case spv::Op::OpImageQueryLevels: - case spv::Op::OpImageQuerySamples: - - case spv::Op::OpImageSampleWeightedQCOM: - case spv::Op::OpImageBoxFilterQCOM: - case spv::Op::OpImageBlockMatchSSDQCOM: - case spv::Op::OpImageBlockMatchSADQCOM: - return true; - default: - break; - } - return false; -} - -spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _, - const Instruction* inst) { - const spv::Op opcode = inst->opcode(); - if (!IsImageInstruction(opcode)) return SPV_SUCCESS; - - switch (opcode) { - case spv::Op::OpImageSampleWeightedQCOM: - case spv::Op::OpImageBoxFilterQCOM: - case spv::Op::OpImageBlockMatchSSDQCOM: - case spv::Op::OpImageBlockMatchSADQCOM: - break; - default: - for (size_t i = 0; i < inst->operands().size(); ++i) { - int id = inst->GetOperandAs(i); - const Instruction* operand_inst = _.FindDef(id); - if (operand_inst == nullptr) continue; - if (operand_inst->opcode() == spv::Op::OpLoad) { - if (_.IsQCOMImageProcessingTextureConsumer(id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Illegal use of QCOM image processing decorated texture"; - } - } - if (operand_inst->opcode() == spv::Op::OpSampledImage) { - if (_.IsQCOMImageProcessingTextureConsumer(id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Illegal use of QCOM image processing decorated texture"; - } - } - } - break; - } - return SPV_SUCCESS; -} - } // namespace val } // namespace spvtools diff --git a/source/val/validate_instruction.cpp b/source/val/validate_instruction.cpp index 8710ffa4..767c0cee 100644 --- a/source/val/validate_instruction.cpp +++ b/source/val/validate_instruction.cpp @@ -14,20 +14,26 @@ // Performs validation on instructions that appear inside of a SPIR-V block. +#include #include +#include #include #include #include +#include "source/binary.h" +#include "source/diagnostic.h" #include "source/enum_set.h" #include "source/enum_string_mapping.h" #include "source/extensions.h" #include "source/opcode.h" #include "source/operand.h" #include "source/spirv_constant.h" +#include "source/spirv_definition.h" #include "source/spirv_target_env.h" #include "source/spirv_validator_options.h" #include "source/util/string_utils.h" +#include "source/val/function.h" #include "source/val/validate.h" #include "source/val/validation_state.h" @@ -38,14 +44,14 @@ namespace { std::string ToString(const CapabilitySet& capabilities, const AssemblyGrammar& grammar) { std::stringstream ss; - for (auto capability : capabilities) { + capabilities.ForEach([&grammar, &ss](SpvCapability cap) { spv_operand_desc desc; - if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, - uint32_t(capability), &desc)) + if (SPV_SUCCESS == + grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) ss << desc->name << " "; else - ss << uint32_t(capability) << " "; - } + ss << cap << " "; + }); return ss.str(); } @@ -54,18 +60,18 @@ std::string ToString(const CapabilitySet& capabilities, // the opcode may only be used if at least one of the capabilities is specified // by the module. CapabilitySet EnablingCapabilitiesForOp(const ValidationState_t& state, - spv::Op opcode) { + SpvOp opcode) { // Exceptions for SPV_AMD_shader_ballot switch (opcode) { // Normally these would require Group capability - case spv::Op::OpGroupIAddNonUniformAMD: - case spv::Op::OpGroupFAddNonUniformAMD: - case spv::Op::OpGroupFMinNonUniformAMD: - case spv::Op::OpGroupUMinNonUniformAMD: - case spv::Op::OpGroupSMinNonUniformAMD: - case spv::Op::OpGroupFMaxNonUniformAMD: - case spv::Op::OpGroupUMaxNonUniformAMD: - case spv::Op::OpGroupSMaxNonUniformAMD: + case SpvOpGroupIAddNonUniformAMD: + case SpvOpGroupFAddNonUniformAMD: + case SpvOpGroupFMinNonUniformAMD: + case SpvOpGroupUMinNonUniformAMD: + case SpvOpGroupSMinNonUniformAMD: + case SpvOpGroupFMaxNonUniformAMD: + case SpvOpGroupUMaxNonUniformAMD: + case SpvOpGroupSMaxNonUniformAMD: if (state.HasExtension(kSPV_AMD_shader_ballot)) return CapabilitySet(); break; default: @@ -145,10 +151,10 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // not implemented yet. This rule is independent of target environment. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 if (operand.type == SPV_OPERAND_TYPE_BUILT_IN) { - switch (spv::BuiltIn(word)) { - case spv::BuiltIn::PointSize: - case spv::BuiltIn::ClipDistance: - case spv::BuiltIn::CullDistance: + switch (word) { + case SpvBuiltInPointSize: + case SpvBuiltInClipDistance: + case SpvBuiltInCullDistance: return SPV_SUCCESS; default: break; @@ -160,7 +166,7 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, } } else if (operand.type == SPV_OPERAND_TYPE_GROUP_OPERATION && state.features().group_ops_reduce_and_scans && - (word <= uint32_t(spv::GroupOperation::ExclusiveScan))) { + (word <= uint32_t(SpvGroupOperationExclusiveScan))) { // Allow certain group operations if requested. return SPV_SUCCESS; } @@ -172,17 +178,15 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, if (lookup_result == SPV_SUCCESS) { // Allow FPRoundingMode decoration if requested. if (operand.type == SPV_OPERAND_TYPE_DECORATION && - spv::Decoration(operand_desc->value) == - spv::Decoration::FPRoundingMode) { + operand_desc->value == SpvDecorationFPRoundingMode) { if (state.features().free_fp_rounding_mode) return SPV_SUCCESS; // Vulkan API requires more capabilities on rounding mode. if (spvIsVulkanEnv(state.context()->target_env)) { - enabling_capabilities.insert( - spv::Capability::StorageUniformBufferBlock16); - enabling_capabilities.insert(spv::Capability::StorageUniform16); - enabling_capabilities.insert(spv::Capability::StoragePushConstant16); - enabling_capabilities.insert(spv::Capability::StorageInputOutput16); + enabling_capabilities.Add(SpvCapabilityStorageUniformBufferBlock16); + enabling_capabilities.Add(SpvCapabilityStorageUniform16); + enabling_capabilities.Add(SpvCapabilityStoragePushConstant16); + enabling_capabilities.Add(SpvCapabilityStorageInputOutput16); } } else { enabling_capabilities = state.grammar().filterCapsAgainstTargetEnv( @@ -193,10 +197,10 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // registers a capability with the module *before* checking capabilities. // So in the case of an OpCapability instruction, don't bother checking // enablement by another capability. - if (inst->opcode() != spv::Op::OpCapability) { + if (inst->opcode() != SpvOpCapability) { const bool enabled_by_cap = state.HasAnyOfCapabilities(enabling_capabilities); - if (!enabling_capabilities.empty() && !enabled_by_cap) { + if (!enabling_capabilities.IsEmpty() && !enabled_by_cap) { return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst) << "Operand " << which_operand << " of " << spvOpcodeString(inst->opcode()) @@ -214,14 +218,14 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state, // is explicitly reserved in the SPIR-V core spec. Otherwise return // SPV_SUCCESS. spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); switch (opcode) { // These instructions are enabled by a capability, but should never // be used anyway. - case spv::Op::OpImageSparseSampleProjImplicitLod: - case spv::Op::OpImageSparseSampleProjExplicitLod: - case spv::Op::OpImageSparseSampleProjDrefImplicitLod: - case spv::Op::OpImageSparseSampleProjDrefExplicitLod: { + case SpvOpImageSparseSampleProjImplicitLod: + case SpvOpImageSparseSampleProjExplicitLod: + case SpvOpImageSparseSampleProjDrefImplicitLod: + case SpvOpImageSparseSampleProjDrefExplicitLod: { spv_opcode_desc inst_desc; _.grammar().lookupOpcode(opcode, &inst_desc); return _.diag(SPV_ERROR_INVALID_BINARY, inst) @@ -237,7 +241,7 @@ spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) { // instruction is invalid because the required capability isn't declared // in the module. spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode); if (!_.HasAnyOfCapabilities(opcode_caps)) { return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) @@ -295,7 +299,7 @@ spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) { // OpTerminateInvocation is special because it is enabled by Shader // capability, but also requires an extension and/or version check. const bool capability_check_is_sufficient = - inst->opcode() != spv::Op::OpTerminateInvocation; + inst->opcode() != SpvOpTerminateInvocation; if (capability_check_is_sufficient && (inst_desc->numCapabilities > 0u)) { // We already checked that the direct capability dependency has been @@ -304,7 +308,7 @@ spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) { } ExtensionSet exts(inst_desc->numExtensions, inst_desc->extensions); - if (exts.empty()) { + if (exts.IsEmpty()) { // If no extensions can enable this instruction, then emit error // messages only concerning core SPIR-V versions if errors happen. if (min_version == ~0u) { @@ -353,7 +357,7 @@ spv_result_t LimitCheckIdBound(ValidationState_t& _, const Instruction* inst) { // Checks that the number of OpTypeStruct members is within the limit. spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { - if (spv::Op::OpTypeStruct != inst->opcode()) { + if (SpvOpTypeStruct != inst->opcode()) { return SPV_SUCCESS; } @@ -378,7 +382,7 @@ spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { auto member = inst->word(word_i); auto memberTypeInstr = _.FindDef(member); - if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { + if (memberTypeInstr && SpvOpTypeStruct == memberTypeInstr->opcode()) { max_member_depth = std::max( max_member_depth, _.struct_nesting_depth(memberTypeInstr->id())); } @@ -398,7 +402,7 @@ spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) { // Checks that the number of (literal, label) pairs in OpSwitch is within // the limit. spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) { - if (spv::Op::OpSwitch == inst->opcode()) { + if (SpvOpSwitch == inst->opcode()) { // The instruction syntax is as follows: // OpSwitch literal label literal label ... // literal,label pairs come after the first 2 operands. @@ -418,8 +422,8 @@ spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) { // Ensure the number of variables of the given class does not exceed the // limit. spv_result_t LimitCheckNumVars(ValidationState_t& _, const uint32_t var_id, - const spv::StorageClass storage_class) { - if (spv::StorageClass::Function == storage_class) { + const SpvStorageClass storage_class) { + if (SpvStorageClassFunction == storage_class) { _.registerLocalVariable(var_id); const uint32_t num_local_vars_limit = _.options()->universal_limits_.max_local_variables; @@ -458,29 +462,29 @@ spv_result_t CheckIfKnownExtension(ValidationState_t& _, } // namespace spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); - if (opcode == spv::Op::OpExtension) { + const SpvOp opcode = inst->opcode(); + if (opcode == SpvOpExtension) { CheckIfKnownExtension(_, inst); - } else if (opcode == spv::Op::OpCapability) { - _.RegisterCapability(inst->GetOperandAs(0)); - } else if (opcode == spv::Op::OpMemoryModel) { + } else if (opcode == SpvOpCapability) { + _.RegisterCapability(inst->GetOperandAs(0)); + } else if (opcode == SpvOpMemoryModel) { if (_.has_memory_model_specified()) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "OpMemoryModel should only be provided once."; } - _.set_addressing_model(inst->GetOperandAs(0)); - _.set_memory_model(inst->GetOperandAs(1)); - } else if (opcode == spv::Op::OpExecutionMode) { + _.set_addressing_model(inst->GetOperandAs(0)); + _.set_memory_model(inst->GetOperandAs(1)); + } else if (opcode == SpvOpExecutionMode) { const uint32_t entry_point = inst->word(1); _.RegisterExecutionModeForEntryPoint(entry_point, - spv::ExecutionMode(inst->word(2))); - } else if (opcode == spv::Op::OpVariable) { - const auto storage_class = inst->GetOperandAs(2); + SpvExecutionMode(inst->word(2))); + } else if (opcode == SpvOpVariable) { + const auto storage_class = inst->GetOperandAs(2); if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) { return error; } - } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) { - if (!_.HasCapability(spv::Capability::BindlessTextureNV)) { + } else if (opcode == SpvOpSamplerImageAddressingModeNV) { + if (!_.HasCapability(SpvCapabilityBindlessTextureNV)) { return _.diag(SPV_ERROR_MISSING_EXTENSION, inst) << "OpSamplerImageAddressingModeNV supported only with extension " "SPV_NV_bindless_texture"; diff --git a/source/val/validate_interfaces.cpp b/source/val/validate_interfaces.cpp index 291b4b82..7f2d6488 100644 --- a/source/val/validate_interfaces.cpp +++ b/source/val/validate_interfaces.cpp @@ -15,6 +15,7 @@ #include #include +#include "source/diagnostic.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" #include "source/val/function.h" @@ -34,15 +35,12 @@ const uint32_t kMaxLocations = 4096 * 4; bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) { if (is_spv_1_4) { // Starting in SPIR-V 1.4, all global variables are interface variables. - return inst->opcode() == spv::Op::OpVariable && - inst->GetOperandAs(2u) != - spv::StorageClass::Function; + return inst->opcode() == SpvOpVariable && + inst->word(3u) != SpvStorageClassFunction; } else { - return inst->opcode() == spv::Op::OpVariable && - (inst->GetOperandAs(2u) == - spv::StorageClass::Input || - inst->GetOperandAs(2u) == - spv::StorageClass::Output); + return inst->opcode() == SpvOpVariable && + (inst->word(3u) == SpvStorageClassInput || + inst->word(3u) == SpvStorageClassOutput); } } @@ -116,30 +114,29 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, uint32_t* num_locations) { *num_locations = 0; switch (type->opcode()) { - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeFloat: // Scalars always consume a single location. *num_locations = 1; break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: // 3- and 4-component 64-bit vectors consume two locations. - if ((_.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeInt, 64) || - _.ContainsSizedIntOrFloatType(type->id(), spv::Op::OpTypeFloat, - 64)) && + if ((_.ContainsSizedIntOrFloatType(type->id(), SpvOpTypeInt, 64) || + _.ContainsSizedIntOrFloatType(type->id(), SpvOpTypeFloat, 64)) && (type->GetOperandAs(2) > 2)) { *num_locations = 2; } else { *num_locations = 1; } break; - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: // Matrices consume locations equal to the underlying vector type for // each column. NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), num_locations); *num_locations *= type->GetOperandAs(2); break; - case spv::Op::OpTypeArray: { + case SpvOpTypeArray: { // Arrays consume locations equal to the underlying type times the number // of elements in the vector. NumConsumedLocations(_, _.FindDef(type->GetOperandAs(1)), @@ -153,9 +150,9 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, if (is_int && is_const) *num_locations *= value; break; } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // Members cannot have location decorations at this point. - if (_.HasDecoration(type->id(), spv::Decoration::Location)) { + if (_.HasDecoration(type->id(), SpvDecorationLocation)) { return _.diag(SPV_ERROR_INVALID_DATA, type) << _.VkErrorID(4918) << "Members cannot be assigned a location"; } @@ -173,19 +170,8 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, } break; } - case spv::Op::OpTypePointer: { - if (_.addressing_model() == - spv::AddressingModel::PhysicalStorageBuffer64 && - type->GetOperandAs(1) == - spv::StorageClass::PhysicalStorageBuffer) { - *num_locations = 1; - break; - } - [[fallthrough]]; - } default: - return _.diag(SPV_ERROR_INVALID_DATA, type) - << "Invalid type to assign a location"; + break; } return SPV_SUCCESS; @@ -196,8 +182,8 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type, uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { uint32_t num_components = 0; switch (type->opcode()) { - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeFloat: // 64-bit types consume two components. if (type->GetOperandAs(1) == 64) { num_components = 2; @@ -205,7 +191,7 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { num_components = 1; } break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: // Vectors consume components equal to the underlying type's consumption // times the number of elements in the vector. Note that 3- and 4-element // vectors cannot have a component decoration (i.e. assumed to be zero). @@ -213,18 +199,10 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) { NumConsumedComponents(_, _.FindDef(type->GetOperandAs(1))); num_components *= type->GetOperandAs(2); break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: // Skip the array. return NumConsumedComponents(_, _.FindDef(type->GetOperandAs(1))); - case spv::Op::OpTypePointer: - if (_.addressing_model() == - spv::AddressingModel::PhysicalStorageBuffer64 && - type->GetOperandAs(1) == - spv::StorageClass::PhysicalStorageBuffer) { - return 2; - } - break; default: // This is an error that is validated elsewhere. break; @@ -240,10 +218,10 @@ spv_result_t GetLocationsForVariable( ValidationState_t& _, const Instruction* entry_point, const Instruction* variable, std::unordered_set* locations, std::unordered_set* output_index1_locations) { - const bool is_fragment = entry_point->GetOperandAs(0) == - spv::ExecutionModel::Fragment; + const bool is_fragment = entry_point->GetOperandAs(0) == + SpvExecutionModelFragment; const bool is_output = - variable->GetOperandAs(2) == spv::StorageClass::Output; + variable->GetOperandAs(2) == SpvStorageClassOutput; auto ptr_type_id = variable->GetOperandAs(0); auto ptr_type = _.FindDef(ptr_type_id); auto type_id = ptr_type->GetOperandAs(2); @@ -262,21 +240,21 @@ spv_result_t GetLocationsForVariable( bool has_per_task_nv = false; bool has_per_vertex_khr = false; for (auto& dec : _.id_decorations(variable->id())) { - if (dec.dec_type() == spv::Decoration::Location) { + if (dec.dec_type() == SpvDecorationLocation) { if (has_location && dec.params()[0] != location) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Variable has conflicting location decorations"; } has_location = true; location = dec.params()[0]; - } else if (dec.dec_type() == spv::Decoration::Component) { + } else if (dec.dec_type() == SpvDecorationComponent) { if (has_component && dec.params()[0] != component) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Variable has conflicting component decorations"; } has_component = true; component = dec.params()[0]; - } else if (dec.dec_type() == spv::Decoration::Index) { + } else if (dec.dec_type() == SpvDecorationIndex) { if (!is_output || !is_fragment) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Index can only be applied to Fragment output variables"; @@ -287,22 +265,22 @@ spv_result_t GetLocationsForVariable( } has_index = true; index = dec.params()[0]; - } else if (dec.dec_type() == spv::Decoration::BuiltIn) { + } else if (dec.dec_type() == SpvDecorationBuiltIn) { // Don't check built-ins. return SPV_SUCCESS; - } else if (dec.dec_type() == spv::Decoration::Patch) { + } else if (dec.dec_type() == SpvDecorationPatch) { has_patch = true; - } else if (dec.dec_type() == spv::Decoration::PerTaskNV) { + } else if (dec.dec_type() == SpvDecorationPerTaskNV) { has_per_task_nv = true; - } else if (dec.dec_type() == spv::Decoration::PerVertexKHR) { + } else if (dec.dec_type() == SpvDecorationPerVertexKHR) { if (!is_fragment) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(6777) << "PerVertexKHR can only be applied to Fragment Execution " "Models"; } - if (type->opcode() != spv::Op::OpTypeArray && - type->opcode() != spv::Op::OpTypeRuntimeArray) { + if (type->opcode() != SpvOpTypeArray && + type->opcode() != SpvOpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(6778) << "PerVertexKHR must be declared as arrays"; @@ -315,28 +293,28 @@ spv_result_t GetLocationsForVariable( // tessellation control, evaluation and geometry per-vertex inputs have a // layer of arraying that is not included in interface matching. bool is_arrayed = false; - switch (entry_point->GetOperandAs(0)) { - case spv::ExecutionModel::TessellationControl: + switch (entry_point->GetOperandAs(0)) { + case SpvExecutionModelTessellationControl: if (!has_patch) { is_arrayed = true; } break; - case spv::ExecutionModel::TessellationEvaluation: + case SpvExecutionModelTessellationEvaluation: if (!is_output && !has_patch) { is_arrayed = true; } break; - case spv::ExecutionModel::Geometry: + case SpvExecutionModelGeometry: if (!is_output) { is_arrayed = true; } break; - case spv::ExecutionModel::Fragment: + case SpvExecutionModelFragment: if (!is_output && has_per_vertex_khr) { is_arrayed = true; } break; - case spv::ExecutionModel::MeshNV: + case SpvExecutionModelMeshNV: if (is_output && !has_per_task_nv) { is_arrayed = true; } @@ -346,21 +324,21 @@ spv_result_t GetLocationsForVariable( } // Unpack arrayness. - if (is_arrayed && (type->opcode() == spv::Op::OpTypeArray || - type->opcode() == spv::Op::OpTypeRuntimeArray)) { + if (is_arrayed && (type->opcode() == SpvOpTypeArray || + type->opcode() == SpvOpTypeRuntimeArray)) { type_id = type->GetOperandAs(1); type = _.FindDef(type_id); } - if (type->opcode() == spv::Op::OpTypeStruct) { + if (type->opcode() == SpvOpTypeStruct) { // Don't check built-ins. - if (_.HasDecoration(type_id, spv::Decoration::BuiltIn)) return SPV_SUCCESS; + if (_.HasDecoration(type_id, SpvDecorationBuiltIn)) return SPV_SUCCESS; } // Only block-decorated structs don't need a location on the variable. - const bool is_block = _.HasDecoration(type_id, spv::Decoration::Block); + const bool is_block = _.HasDecoration(type_id, SpvDecorationBlock); if (!has_location && !is_block) { - const auto vuid = (type->opcode() == spv::Op::OpTypeStruct) ? 4917 : 4916; + const auto vuid = (type->opcode() == SpvOpTypeStruct) ? 4917 : 4916; return _.diag(SPV_ERROR_INVALID_DATA, variable) << _.VkErrorID(vuid) << "Variable must be decorated with a location"; } @@ -373,7 +351,7 @@ spv_result_t GetLocationsForVariable( uint32_t array_size = 1; // If the variable is still arrayed, mark the locations/components per // index. - if (type->opcode() == spv::Op::OpTypeArray) { + if (type->opcode() == SpvOpTypeArray) { // Determine the array size if possible and get the element type. std::tie(is_int, is_const, array_size) = _.EvalInt32IfConst(type->GetOperandAs(2)); @@ -382,12 +360,12 @@ spv_result_t GetLocationsForVariable( sub_type = _.FindDef(sub_type_id); } - uint32_t num_locations = 0; - if (auto error = NumConsumedLocations(_, sub_type, &num_locations)) - return error; - uint32_t num_components = NumConsumedComponents(_, sub_type); - for (uint32_t array_idx = 0; array_idx < array_size; ++array_idx) { + uint32_t num_locations = 0; + if (auto error = NumConsumedLocations(_, sub_type, &num_locations)) + return error; + + uint32_t num_components = NumConsumedComponents(_, sub_type); uint32_t array_location = location + (num_locations * array_idx); uint32_t start = array_location * 4; if (kMaxLocations <= start) { @@ -407,7 +385,6 @@ spv_result_t GetLocationsForVariable( for (uint32_t i = start; i < end; ++i) { if (!locs->insert(i).second) { return _.diag(SPV_ERROR_INVALID_DATA, entry_point) - << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) << "Entry-point has conflicting " << storage_class << " location assignment at location " << i / 4 << ", component " << i % 4; @@ -422,7 +399,7 @@ spv_result_t GetLocationsForVariable( std::unordered_map member_locations; std::unordered_map member_components; for (auto& dec : _.id_decorations(type_id)) { - if (dec.dec_type() == spv::Decoration::Location) { + if (dec.dec_type() == SpvDecorationLocation) { auto where = member_locations.find(dec.struct_member_index()); if (where == member_locations.end()) { member_locations[dec.struct_member_index()] = dec.params()[0]; @@ -431,7 +408,7 @@ spv_result_t GetLocationsForVariable( << "Member index " << dec.struct_member_index() << " has conflicting location assignments"; } - } else if (dec.dec_type() == spv::Decoration::Component) { + } else if (dec.dec_type() == SpvDecorationComponent) { auto where = member_components.find(dec.struct_member_index()); if (where == member_components.end()) { member_components[dec.struct_member_index()] = dec.params()[0]; @@ -470,7 +447,7 @@ spv_result_t GetLocationsForVariable( continue; } - if (member->opcode() == spv::Op::OpTypeArray && num_components >= 1 && + if (member->opcode() == SpvOpTypeArray && num_components >= 1 && num_components < 4) { // When an array has an element that takes less than a location in // size, calculate the used locations in a strided manner. @@ -479,7 +456,6 @@ spv_result_t GetLocationsForVariable( uint32_t check = 4 * l + c; if (!locations->insert(check).second) { return _.diag(SPV_ERROR_INVALID_DATA, entry_point) - << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) << "Entry-point has conflicting " << storage_class << " location assignment at location " << l << ", component " << c; @@ -497,7 +473,6 @@ spv_result_t GetLocationsForVariable( for (uint32_t l = start; l < end; ++l) { if (!locations->insert(l).second) { return _.diag(SPV_ERROR_INVALID_DATA, entry_point) - << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721)) << "Entry-point has conflicting " << storage_class << " location assignment at location " << l / 4 << ", component " << l % 4; @@ -517,12 +492,12 @@ spv_result_t ValidateLocations(ValidationState_t& _, // TODO(dneto): SPV_NV_ray_tracing also uses locations on interface variables, // in other shader stages. Similarly, the *provisional* version of // SPV_KHR_ray_tracing did as well, but not the final version. - switch (entry_point->GetOperandAs(0)) { - case spv::ExecutionModel::Vertex: - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::Fragment: + switch (entry_point->GetOperandAs(0)) { + case SpvExecutionModelVertex: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelFragment: break; default: return SPV_SUCCESS; @@ -536,9 +511,9 @@ spv_result_t ValidateLocations(ValidationState_t& _, for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { auto interface_id = entry_point->GetOperandAs(i); auto interface_var = _.FindDef(interface_id); - auto storage_class = interface_var->GetOperandAs(2); - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { + auto storage_class = interface_var->GetOperandAs(2); + if (storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { continue; } if (!seen.insert(interface_id).second) { @@ -547,7 +522,7 @@ spv_result_t ValidateLocations(ValidationState_t& _, continue; } - auto locations = (storage_class == spv::StorageClass::Input) + auto locations = (storage_class == SpvStorageClassInput) ? &input_locations : &output_locations_index0; if (auto error = GetLocationsForVariable( @@ -572,12 +547,12 @@ spv_result_t ValidateInterfaces(ValidationState_t& _) { if (spvIsVulkanEnv(_.context()->target_env)) { for (auto& inst : _.ordered_instructions()) { - if (inst.opcode() == spv::Op::OpEntryPoint) { + if (inst.opcode() == SpvOpEntryPoint) { if (auto error = ValidateLocations(_, &inst)) { return error; } } - if (inst.opcode() == spv::Op::OpTypeVoid) break; + if (inst.opcode() == SpvOpTypeVoid) break; } } diff --git a/source/val/validate_layout.cpp b/source/val/validate_layout.cpp index dbc1f1e5..6f951352 100644 --- a/source/val/validate_layout.cpp +++ b/source/val/validate_layout.cpp @@ -14,9 +14,12 @@ // Source code for logical layout validation as described in section 2.4 +#include + #include "DebugInfo.h" #include "NonSemanticShaderDebugInfo100.h" #include "OpenCLDebugInfo100.h" +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/operand.h" #include "source/val/function.h" @@ -32,9 +35,9 @@ namespace { // is part of the current layout section. If it is not then the next sections is // checked. spv_result_t ModuleScopedInstructions(ValidationState_t& _, - const Instruction* inst, spv::Op opcode) { + const Instruction* inst, SpvOp opcode) { switch (opcode) { - case spv::Op::OpExtInst: + case SpvOpExtInst: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; @@ -128,7 +131,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, switch (_.current_layout_section()) { case kLayoutMemoryModel: - if (opcode != spv::Op::OpMemoryModel) { + if (opcode != SpvOpMemoryModel) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << spvOpcodeString(opcode) << " cannot appear before the memory model instruction"; @@ -151,8 +154,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, // inside of another function. This stage ends when the first label is // encountered inside of a function. spv_result_t FunctionScopedInstructions(ValidationState_t& _, - const Instruction* inst, - spv::Op opcode) { + const Instruction* inst, SpvOp opcode) { // Make sure we advance into the function definitions when we hit // non-function declaration instructions. if (_.current_layout_section() == kLayoutFunctionDeclarations && @@ -169,12 +171,12 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, if (_.IsOpcodeInCurrentLayoutSection(opcode)) { switch (opcode) { - case spv::Op::OpFunction: { + case SpvOpFunction: { if (_.in_function_body()) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Cannot declare a function in a function body"; } - auto control_mask = inst->GetOperandAs(2); + auto control_mask = inst->GetOperandAs(2); if (auto error = _.RegisterFunction(inst->id(), inst->type_id(), control_mask, inst->GetOperandAs(3))) @@ -186,7 +188,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, } } break; - case spv::Op::OpFunctionParameter: + case SpvOpFunctionParameter: if (_.in_function_body() == false) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function parameter instructions must be in a " @@ -202,7 +204,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, return error; break; - case spv::Op::OpFunctionEnd: + case SpvOpFunctionEnd: if (_.in_function_body() == false) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Function end instructions must be in a function body"; @@ -225,10 +227,10 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, if (auto error = _.RegisterFunctionEnd()) return error; break; - case spv::Op::OpLine: - case spv::Op::OpNoLine: + case SpvOpLine: + case SpvOpNoLine: break; - case spv::Op::OpLabel: + case SpvOpLabel: // If the label is encountered then the current function is a // definition so set the function to a declaration and update the // module section @@ -242,7 +244,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, } break; - case spv::Op::OpExtInst: + case SpvOpExtInst: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; @@ -354,7 +356,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, // NOTE: This function does not handle CFG related validation // Performs logical layout validation. See Section 2.4 spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); switch (_.current_layout_section()) { case kLayoutCapabilities: diff --git a/source/val/validate_literals.cpp b/source/val/validate_literals.cpp index 15cc27a9..53aae076 100644 --- a/source/val/validate_literals.cpp +++ b/source/val/validate_literals.cpp @@ -14,10 +14,13 @@ // Validates literal numbers. +#include "source/val/validate.h" + #include +#include "source/diagnostic.h" +#include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { diff --git a/source/val/validate_logicals.cpp b/source/val/validate_logicals.cpp index 4479e439..ec1e207b 100644 --- a/source/val/validate_logicals.cpp +++ b/source/val/validate_logicals.cpp @@ -14,9 +14,11 @@ // Validates correctness of logical SPIR-V instructions. +#include "source/val/validate.h" + +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -24,12 +26,12 @@ namespace val { // Validates correctness of logical instructions. spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpAny: - case spv::Op::OpAll: { + case SpvOpAny: + case SpvOpAll: { if (!_.IsBoolScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar type as Result Type: " @@ -44,11 +46,11 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpIsNan: - case spv::Op::OpIsInf: - case spv::Op::OpIsFinite: - case spv::Op::OpIsNormal: - case spv::Op::OpSignBitSet: { + case SpvOpIsNan: + case SpvOpIsInf: + case SpvOpIsFinite: + case SpvOpIsNormal: + case SpvOpSignBitSet: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -70,21 +72,21 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpFOrdEqual: - case spv::Op::OpFUnordEqual: - case spv::Op::OpFOrdNotEqual: - case spv::Op::OpFUnordNotEqual: - case spv::Op::OpFOrdLessThan: - case spv::Op::OpFUnordLessThan: - case spv::Op::OpFOrdGreaterThan: - case spv::Op::OpFUnordGreaterThan: - case spv::Op::OpFOrdLessThanEqual: - case spv::Op::OpFUnordLessThanEqual: - case spv::Op::OpFOrdGreaterThanEqual: - case spv::Op::OpFUnordGreaterThanEqual: - case spv::Op::OpLessOrGreater: - case spv::Op::OpOrdered: - case spv::Op::OpUnordered: { + case SpvOpFOrdEqual: + case SpvOpFUnordEqual: + case SpvOpFOrdNotEqual: + case SpvOpFUnordNotEqual: + case SpvOpFOrdLessThan: + case SpvOpFUnordLessThan: + case SpvOpFOrdGreaterThan: + case SpvOpFUnordGreaterThan: + case SpvOpFOrdLessThanEqual: + case SpvOpFUnordLessThanEqual: + case SpvOpFOrdGreaterThanEqual: + case SpvOpFUnordGreaterThanEqual: + case SpvOpLessOrGreater: + case SpvOpOrdered: + case SpvOpUnordered: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -111,10 +113,10 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpLogicalEqual: - case spv::Op::OpLogicalNotEqual: - case spv::Op::OpLogicalOr: - case spv::Op::OpLogicalAnd: { + case SpvOpLogicalEqual: + case SpvOpLogicalNotEqual: + case SpvOpLogicalOr: + case SpvOpLogicalAnd: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -129,7 +131,7 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpLogicalNot: { + case SpvOpLogicalNot: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " @@ -143,7 +145,7 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpSelect: { + case SpvOpSelect: { uint32_t dimension = 1; { const Instruction* type_inst = _.FindDef(result_type); @@ -157,10 +159,10 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { << " type as Result Type: " << spvOpcodeString(opcode); }; - const spv::Op type_opcode = type_inst->opcode(); + const SpvOp type_opcode = type_inst->opcode(); switch (type_opcode) { - case spv::Op::OpTypePointer: { - if (_.addressing_model() == spv::AddressingModel::Logical && + case SpvOpTypePointer: { + if (_.addressing_model() == SpvAddressingModelLogical && !_.features().variable_pointers) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using pointers with OpSelect requires capability " @@ -168,31 +170,31 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampler: { - if (!_.HasCapability(spv::Capability::BindlessTextureNV)) + case SpvOpTypeSampledImage: + case SpvOpTypeImage: + case SpvOpTypeSampler: { + if (!_.HasCapability(SpvCapabilityBindlessTextureNV)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Using image/sampler with OpSelect requires capability " << "BindlessTextureNV"; break; } - case spv::Op::OpTypeVector: { + case SpvOpTypeVector: { dimension = type_inst->word(3); break; } - case spv::Op::OpTypeBool: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeFloat: { + case SpvOpTypeBool: + case SpvOpTypeInt: + case SpvOpTypeFloat: { break; } // Not RuntimeArray because of other rules. - case spv::Op::OpTypeArray: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeStruct: { + case SpvOpTypeArray: + case SpvOpTypeMatrix: + case SpvOpTypeStruct: { if (!composites) return fail(); break; } @@ -233,16 +235,16 @@ spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) { } } - case spv::Op::OpIEqual: - case spv::Op::OpINotEqual: - case spv::Op::OpUGreaterThan: - case spv::Op::OpUGreaterThanEqual: - case spv::Op::OpULessThan: - case spv::Op::OpULessThanEqual: - case spv::Op::OpSGreaterThan: - case spv::Op::OpSGreaterThanEqual: - case spv::Op::OpSLessThan: - case spv::Op::OpSLessThanEqual: { + case SpvOpIEqual: + case SpvOpINotEqual: + case SpvOpUGreaterThan: + case SpvOpUGreaterThanEqual: + case SpvOpULessThan: + case SpvOpULessThanEqual: + case SpvOpSGreaterThan: + case SpvOpSGreaterThanEqual: + case SpvOpSLessThan: + case SpvOpSLessThanEqual: { if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected bool scalar or vector type as Result Type: " diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 5b25eeb3..074bdb88 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -39,13 +39,13 @@ bool HasConflictingMemberOffsets(const std::set&, const std::set&); bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type, - std::initializer_list allowed) { + std::initializer_list allowed) { if (std::find(allowed.begin(), allowed.end(), type->opcode()) != allowed.end()) { return true; } - if (type->opcode() == spv::Op::OpTypeArray || - type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (type->opcode() == SpvOpTypeArray || + type->opcode() == SpvOpTypeRuntimeArray) { auto elem_type = _.FindDef(type->word(2)); return std::find(allowed.begin(), allowed.end(), elem_type->opcode()) != allowed.end(); @@ -57,10 +57,10 @@ bool IsAllowedTypeOrArrayOfSame(ValidationState_t& _, const Instruction* type, // validator can tell, have the exact same data layout. bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - if (type1->opcode() != spv::Op::OpTypeStruct) { + if (type1->opcode() != SpvOpTypeStruct) { return false; } - if (type2->opcode() != spv::Op::OpTypeStruct) { + if (type2->opcode() != SpvOpTypeStruct) { return false; } @@ -74,9 +74,9 @@ bool AreLayoutCompatibleStructs(ValidationState_t& _, const Instruction* type1, // be OpTypeStruct instructions. bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - assert(type1->opcode() == spv::Op::OpTypeStruct && + assert(type1->opcode() == SpvOpTypeStruct && "type1 must be an OpTypeStruct instruction."); - assert(type2->opcode() == spv::Op::OpTypeStruct && + assert(type2->opcode() == SpvOpTypeStruct && "type2 must be an OpTypeStruct instruction."); const auto& type1_operands = type1->operands(); const auto& type2_operands = type2->operands(); @@ -101,9 +101,9 @@ bool HaveLayoutCompatibleMembers(ValidationState_t& _, const Instruction* type1, // OpTypeStruct instructions. bool HaveSameLayoutDecorations(ValidationState_t& _, const Instruction* type1, const Instruction* type2) { - assert(type1->opcode() == spv::Op::OpTypeStruct && + assert(type1->opcode() == SpvOpTypeStruct && "type1 must be an OpTypeStruct instruction."); - assert(type2->opcode() == spv::Op::OpTypeStruct && + assert(type2->opcode() == SpvOpTypeStruct && "type2 must be an OpTypeStruct instruction."); const std::set& type1_decorations = _.id_decorations(type1->id()); const std::set& type2_decorations = _.id_decorations(type2->id()); @@ -130,11 +130,11 @@ bool HasConflictingMemberOffsets( // type1_decoration. Therefore, it cannot lead to a conflict. for (const Decoration& decoration : type1_decorations) { switch (decoration.dec_type()) { - case spv::Decoration::Offset: { + case SpvDecorationOffset: { // Since these affect the layout of the struct, they must be present // in both structs. auto compare = [&decoration](const Decoration& rhs) { - if (rhs.dec_type() != spv::Decoration::Offset) return false; + if (rhs.dec_type() != SpvDecorationOffset) return false; return decoration.struct_member_index() == rhs.struct_member_index(); }; @@ -163,7 +163,7 @@ bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage, bool skip_builtin) { if (skip_builtin) { for (const Decoration& decoration : _.id_decorations(storage->id())) { - if (decoration.dec_type() == spv::Decoration::BuiltIn) return false; + if (decoration.dec_type() == SpvDecorationBuiltIn) return false; } } @@ -172,16 +172,16 @@ bool ContainsInvalidBool(ValidationState_t& _, const Instruction* storage, Instruction* elem_type; switch (storage->opcode()) { - case spv::Op::OpTypeBool: + case SpvOpTypeBool: return true; - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: elem_type_id = storage->GetOperandAs(elem_type_index); elem_type = _.FindDef(elem_type_id); return ContainsInvalidBool(_, elem_type, skip_builtin); - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: for (size_t member_type_index = 1; member_type_index < storage->operands().size(); ++member_type_index) { @@ -203,15 +203,14 @@ bool ContainsCooperativeMatrix(ValidationState_t& _, Instruction* elem_type; switch (storage->opcode()) { - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: + case SpvOpTypeCooperativeMatrixNV: return true; - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: elem_type_id = storage->GetOperandAs(elem_type_index); elem_type = _.FindDef(elem_type_id); return ContainsCooperativeMatrix(_, elem_type); - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: for (size_t member_type_index = 1; member_type_index < storage->operands().size(); ++member_type_index) { @@ -227,35 +226,33 @@ bool ContainsCooperativeMatrix(ValidationState_t& _, return false; } -std::pair GetStorageClass( +std::pair GetStorageClass( ValidationState_t& _, const Instruction* inst) { - spv::StorageClass dst_sc = spv::StorageClass::Max; - spv::StorageClass src_sc = spv::StorageClass::Max; + SpvStorageClass dst_sc = SpvStorageClassMax; + SpvStorageClass src_sc = SpvStorageClassMax; switch (inst->opcode()) { - case spv::Op::OpCooperativeMatrixLoadNV: - case spv::Op::OpCooperativeMatrixLoadKHR: - case spv::Op::OpLoad: { + case SpvOpCooperativeMatrixLoadNV: + case SpvOpLoad: { auto load_pointer = _.FindDef(inst->GetOperandAs(2)); auto load_pointer_type = _.FindDef(load_pointer->type_id()); - dst_sc = load_pointer_type->GetOperandAs(1); + dst_sc = load_pointer_type->GetOperandAs(1); break; } - case spv::Op::OpCooperativeMatrixStoreNV: - case spv::Op::OpCooperativeMatrixStoreKHR: - case spv::Op::OpStore: { + case SpvOpCooperativeMatrixStoreNV: + case SpvOpStore: { auto store_pointer = _.FindDef(inst->GetOperandAs(0)); auto store_pointer_type = _.FindDef(store_pointer->type_id()); - dst_sc = store_pointer_type->GetOperandAs(1); + dst_sc = store_pointer_type->GetOperandAs(1); break; } - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: { + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: { auto dst = _.FindDef(inst->GetOperandAs(0)); auto dst_type = _.FindDef(dst->type_id()); - dst_sc = dst_type->GetOperandAs(1); + dst_sc = dst_type->GetOperandAs(1); auto src = _.FindDef(inst->GetOperandAs(1)); auto src_type = _.FindDef(src->type_id()); - src_sc = src_type->GetOperandAs(1); + src_sc = src_type->GetOperandAs(1); break; } default: @@ -269,9 +266,9 @@ std::pair GetStorageClass( // argument and its implied operands. int MemoryAccessNumWords(uint32_t mask) { int result = 1; // Count the mask - if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++result; - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) ++result; - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) ++result; + if (mask & SpvMemoryAccessAlignedMask) ++result; + if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) ++result; + if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) ++result; return result; } @@ -282,8 +279,8 @@ int MemoryAccessNumWords(uint32_t mask) { // OpCooperativeMatrixStoreNV. uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask, uint32_t mask_index) { - assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)); - uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR); + assert(mask & SpvMemoryAccessMakePointerAvailableKHRMask); + uint32_t this_bit = uint32_t(SpvMemoryAccessMakePointerAvailableKHRMask); uint32_t index = mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); return inst->GetOperandAs(index); @@ -294,8 +291,8 @@ uint32_t GetMakeAvailableScope(const Instruction* inst, uint32_t mask, // OpCooperativeMatrixStoreNV. uint32_t GetMakeVisibleScope(const Instruction* inst, uint32_t mask, uint32_t mask_index) { - assert(mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)); - uint32_t this_bit = uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR); + assert(mask & SpvMemoryAccessMakePointerVisibleKHRMask); + uint32_t this_bit = uint32_t(SpvMemoryAccessMakePointerVisibleKHRMask); uint32_t index = mask_index - 1 + MemoryAccessNumWords(mask & (this_bit | (this_bit - 1))); return inst->GetOperandAs(index); @@ -306,19 +303,19 @@ bool DoesStructContainRTA(const ValidationState_t& _, const Instruction* inst) { ++member_index) { const auto member_id = inst->GetOperandAs(member_index); const auto member_type = _.FindDef(member_id); - if (member_type->opcode() == spv::Op::OpTypeRuntimeArray) return true; + if (member_type->opcode() == SpvOpTypeRuntimeArray) return true; } return false; } spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, uint32_t index) { - spv::StorageClass dst_sc, src_sc; + SpvStorageClass dst_sc, src_sc; std::tie(dst_sc, src_sc) = GetStorageClass(_, inst); if (inst->operands().size() <= index) { // Cases where lack of some operand is invalid - if (src_sc == spv::StorageClass::PhysicalStorageBuffer || - dst_sc == spv::StorageClass::PhysicalStorageBuffer) { + if (src_sc == SpvStorageClassPhysicalStorageBuffer || + dst_sc == SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4708) << "Memory accesses with PhysicalStorageBuffer must use Aligned."; @@ -327,15 +324,14 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, } const uint32_t mask = inst->GetOperandAs(index); - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { - if (inst->opcode() == spv::Op::OpLoad || - inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV || - inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { + if (mask & SpvMemoryAccessMakePointerAvailableKHRMask) { + if (inst->opcode() == SpvOpLoad || + inst->opcode() == SpvOpCooperativeMatrixLoadNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerAvailableKHR cannot be used with OpLoad."; } - if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { + if (!(mask & SpvMemoryAccessNonPrivatePointerKHRMask)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR must be specified if " "MakePointerAvailableKHR is specified."; @@ -347,14 +343,14 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, return error; } - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { - if (inst->opcode() == spv::Op::OpStore || - inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV) { + if (mask & SpvMemoryAccessMakePointerVisibleKHRMask) { + if (inst->opcode() == SpvOpStore || + inst->opcode() == SpvOpCooperativeMatrixStoreNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerVisibleKHR cannot be used with OpStore."; } - if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) { + if (!(mask & SpvMemoryAccessNonPrivatePointerKHRMask)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR must be specified if " << "MakePointerVisibleKHR is specified."; @@ -365,27 +361,24 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error; } - if (mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR)) { - if (dst_sc != spv::StorageClass::Uniform && - dst_sc != spv::StorageClass::Workgroup && - dst_sc != spv::StorageClass::CrossWorkgroup && - dst_sc != spv::StorageClass::Generic && - dst_sc != spv::StorageClass::Image && - dst_sc != spv::StorageClass::StorageBuffer && - dst_sc != spv::StorageClass::PhysicalStorageBuffer) { + if (mask & SpvMemoryAccessNonPrivatePointerKHRMask) { + if (dst_sc != SpvStorageClassUniform && + dst_sc != SpvStorageClassWorkgroup && + dst_sc != SpvStorageClassCrossWorkgroup && + dst_sc != SpvStorageClassGeneric && dst_sc != SpvStorageClassImage && + dst_sc != SpvStorageClassStorageBuffer && + dst_sc != SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR requires a pointer in Uniform, " << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " << "storage classes."; } - if (src_sc != spv::StorageClass::Max && - src_sc != spv::StorageClass::Uniform && - src_sc != spv::StorageClass::Workgroup && - src_sc != spv::StorageClass::CrossWorkgroup && - src_sc != spv::StorageClass::Generic && - src_sc != spv::StorageClass::Image && - src_sc != spv::StorageClass::StorageBuffer && - src_sc != spv::StorageClass::PhysicalStorageBuffer) { + if (src_sc != SpvStorageClassMax && src_sc != SpvStorageClassUniform && + src_sc != SpvStorageClassWorkgroup && + src_sc != SpvStorageClassCrossWorkgroup && + src_sc != SpvStorageClassGeneric && src_sc != SpvStorageClassImage && + src_sc != SpvStorageClassStorageBuffer && + src_sc != SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "NonPrivatePointerKHR requires a pointer in Uniform, " << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer " @@ -393,9 +386,9 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, } } - if (!(mask & uint32_t(spv::MemoryAccessMask::Aligned))) { - if (src_sc == spv::StorageClass::PhysicalStorageBuffer || - dst_sc == spv::StorageClass::PhysicalStorageBuffer) { + if (!(mask & SpvMemoryAccessAlignedMask)) { + if (src_sc == SpvStorageClassPhysicalStorageBuffer || + dst_sc == SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4708) << "Memory accesses with PhysicalStorageBuffer must use Aligned."; @@ -407,7 +400,7 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { auto result_type = _.FindDef(inst->type_id()); - if (!result_type || result_type->opcode() != spv::Op::OpTypePointer) { + if (!result_type || result_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable Result Type " << _.getIdName(inst->type_id()) << " is not a pointer type."; @@ -423,9 +416,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { const auto initializer_id = inst->GetOperandAs(initializer_index); const auto initializer = _.FindDef(initializer_id); const auto is_module_scope_var = - initializer && (initializer->opcode() == spv::Op::OpVariable) && - (initializer->GetOperandAs(storage_class_index) != - spv::StorageClass::Function); + initializer && (initializer->opcode() == SpvOpVariable) && + (initializer->GetOperandAs(storage_class_index) != + SpvStorageClassFunction); const auto is_constant = initializer && spvOpcodeIsConstant(initializer->opcode()); if (!initializer || !(is_constant || is_module_scope_var)) { @@ -440,26 +433,23 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - auto storage_class = - inst->GetOperandAs(storage_class_index); - if (storage_class != spv::StorageClass::Workgroup && - storage_class != spv::StorageClass::CrossWorkgroup && - storage_class != spv::StorageClass::Private && - storage_class != spv::StorageClass::Function && - storage_class != spv::StorageClass::UniformConstant && - storage_class != spv::StorageClass::RayPayloadKHR && - storage_class != spv::StorageClass::IncomingRayPayloadKHR && - storage_class != spv::StorageClass::HitAttributeKHR && - storage_class != spv::StorageClass::CallableDataKHR && - storage_class != spv::StorageClass::IncomingCallableDataKHR && - storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT && - storage_class != spv::StorageClass::HitObjectAttributeNV) { - bool storage_input_or_output = storage_class == spv::StorageClass::Input || - storage_class == spv::StorageClass::Output; + auto storage_class = inst->GetOperandAs(storage_class_index); + if (storage_class != SpvStorageClassWorkgroup && + storage_class != SpvStorageClassCrossWorkgroup && + storage_class != SpvStorageClassPrivate && + storage_class != SpvStorageClassFunction && + storage_class != SpvStorageClassRayPayloadKHR && + storage_class != SpvStorageClassIncomingRayPayloadKHR && + storage_class != SpvStorageClassHitAttributeKHR && + storage_class != SpvStorageClassCallableDataKHR && + storage_class != SpvStorageClassIncomingCallableDataKHR && + storage_class != SpvStorageClassTaskPayloadWorkgroupEXT) { + bool storage_input_or_output = storage_class == SpvStorageClassInput || + storage_class == SpvStorageClassOutput; bool builtin = false; if (storage_input_or_output) { for (const Decoration& decoration : _.id_decorations(inst->id())) { - if (decoration.dec_type() == spv::Decoration::BuiltIn) { + if (decoration.dec_type() == SpvDecorationBuiltIn) { builtin = true; break; } @@ -480,8 +470,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "can only be used with non-externally visible shader Storage " "Classes: Workgroup, CrossWorkgroup, Private, Function, " "Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, " - "HitAttributeKHR, CallableDataKHR, " - "IncomingCallableDataKHR, or UniformConstant"; + "HitAttributeKHR, CallableDataKHR, or " + "IncomingCallableDataKHR"; } } } @@ -492,18 +482,18 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { << "Invalid storage class for target environment"; } - if (storage_class == spv::StorageClass::Generic) { + if (storage_class == SpvStorageClassGeneric) { return _.diag(SPV_ERROR_INVALID_BINARY, inst) << "OpVariable storage class cannot be Generic"; } - if (inst->function() && storage_class != spv::StorageClass::Function) { + if (inst->function() && storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Variables must have a function[7] storage class inside" " of a function"; } - if (!inst->function() && storage_class == spv::StorageClass::Function) { + if (!inst->function() && storage_class == SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) << "Variables can not have a function[7] storage class " "outside of a function"; @@ -513,7 +503,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // storage class. const auto result_storage_class_index = 1; const auto result_storage_class = - result_type->GetOperandAs(result_storage_class_index); + result_type->GetOperandAs(result_storage_class_index); if (storage_class != result_storage_class) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "From SPIR-V spec, section 3.32.8 on OpVariable:\n" @@ -523,16 +513,16 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Variable pointer related restrictions. const auto pointee = _.FindDef(result_type->word(3)); - if (_.addressing_model() == spv::AddressingModel::Logical && + if (_.addressing_model() == SpvAddressingModelLogical && !_.options()->relax_logical_pointer) { // VariablePointersStorageBuffer is implied by VariablePointers. - if (pointee->opcode() == spv::Op::OpTypePointer) { - if (!_.HasCapability(spv::Capability::VariablePointersStorageBuffer)) { + if (pointee->opcode() == SpvOpTypePointer) { + if (!_.HasCapability(SpvCapabilityVariablePointersStorageBuffer)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In Logical addressing, variables may not allocate a pointer " << "type"; - } else if (storage_class != spv::StorageClass::Function && - storage_class != spv::StorageClass::Private) { + } else if (storage_class != SpvStorageClassFunction && + storage_class != SpvStorageClassPrivate) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "In Logical addressing with variable pointers, variables " << "that allocate pointers must be in Function or Private " @@ -544,8 +534,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { if (spvIsVulkanEnv(_.context()->target_env)) { // Vulkan Push Constant Interface section: Check type of PushConstant // variables. - if (storage_class == spv::StorageClass::PushConstant) { - if (pointee->opcode() != spv::Op::OpTypeStruct) { + if (storage_class == SpvStorageClassPushConstant) { + if (pointee->opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6808) << "PushConstant OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -556,12 +546,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Vulkan Descriptor Set Interface: Check type of UniformConstant and // Uniform variables. - if (storage_class == spv::StorageClass::UniformConstant) { + if (storage_class == SpvStorageClassUniformConstant) { if (!IsAllowedTypeOrArrayOfSame( _, pointee, - {spv::Op::OpTypeImage, spv::Op::OpTypeSampler, - spv::Op::OpTypeSampledImage, - spv::Op::OpTypeAccelerationStructureKHR})) { + {SpvOpTypeImage, SpvOpTypeSampler, SpvOpTypeSampledImage, + SpvOpTypeAccelerationStructureKHR})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4655) << "UniformConstant OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -573,8 +562,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - if (storage_class == spv::StorageClass::Uniform) { - if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { + if (storage_class == SpvStorageClassUniform) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6807) << "Uniform OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -586,8 +575,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - if (storage_class == spv::StorageClass::StorageBuffer) { - if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) { + if (storage_class == SpvStorageClassStorageBuffer) { + if (!IsAllowedTypeOrArrayOfSame(_, pointee, {SpvOpTypeStruct})) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6807) << "StorageBuffer OpVariable " << _.getIdName(inst->id()) << " has illegal type.\n" @@ -600,9 +589,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Check for invalid use of Invariant - if (storage_class != spv::StorageClass::Input && - storage_class != spv::StorageClass::Output) { - if (_.HasDecoration(inst->id(), spv::Decoration::Invariant)) { + if (storage_class != SpvStorageClassInput && + storage_class != SpvStorageClassOutput) { + if (_.HasDecoration(inst->id(), SpvDecorationInvariant)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4677) << "Variable decorated with Invariant must only be identified " @@ -610,8 +599,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "environment."; } // Need to check if only the members in a struct are decorated - if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { - if (_.HasDecoration(value_id, spv::Decoration::Invariant)) { + if (value_type && value_type->opcode() == SpvOpTypeStruct) { + if (_.HasDecoration(value_id, SpvDecorationInvariant)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4677) << "Variable struct member decorated with Invariant must only " @@ -623,10 +612,10 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // Initializers in Vulkan are only allowed in some storage clases if (inst->operands().size() > 3) { - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { auto init_id = inst->GetOperandAs(3); auto init = _.FindDef(init_id); - if (init->opcode() != spv::Op::OpConstantNull) { + if (init->opcode() != SpvOpConstantNull) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4734) << "OpVariable, " << _.getIdName(inst->id()) @@ -634,9 +623,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "Workgroup " "storage class"; } - } else if (storage_class != spv::StorageClass::Output && - storage_class != spv::StorageClass::Private && - storage_class != spv::StorageClass::Function) { + } else if (storage_class != SpvStorageClassOutput && + storage_class != SpvStorageClassPrivate && + storage_class != SpvStorageClassFunction) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4651) << "OpVariable, " << _.getIdName(inst->id()) @@ -652,40 +641,35 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } if (inst->operands().size() > 3) { - if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { + if (storage_class == SpvStorageClassTaskPayloadWorkgroupEXT) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable, " << _.getIdName(inst->id()) << ", initializer are not allowed for TaskPayloadWorkgroupEXT"; } - if (storage_class == spv::StorageClass::Input) { + if (storage_class == SpvStorageClassInput) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable, " << _.getIdName(inst->id()) << ", initializer are not allowed for Input"; } - if (storage_class == spv::StorageClass::HitObjectAttributeNV) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpVariable, " << _.getIdName(inst->id()) - << ", initializer are not allowed for HitObjectAttributeNV"; - } } - if (storage_class == spv::StorageClass::PhysicalStorageBuffer) { + if (storage_class == SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "PhysicalStorageBuffer must not be used with OpVariable."; } auto pointee_base = pointee; - while (pointee_base->opcode() == spv::Op::OpTypeArray) { + while (pointee_base->opcode() == SpvOpTypeArray) { pointee_base = _.FindDef(pointee_base->GetOperandAs(1u)); } - if (pointee_base->opcode() == spv::Op::OpTypePointer) { - if (pointee_base->GetOperandAs(1u) == - spv::StorageClass::PhysicalStorageBuffer) { + if (pointee_base->opcode() == SpvOpTypePointer) { + if (pointee_base->GetOperandAs(1u) == + SpvStorageClassPhysicalStorageBuffer) { // check for AliasedPointer/RestrictPointer bool foundAliased = - _.HasDecoration(inst->id(), spv::Decoration::AliasedPointer); + _.HasDecoration(inst->id(), SpvDecorationAliasedPointer); bool foundRestrict = - _.HasDecoration(inst->id(), spv::Decoration::RestrictPointer); + _.HasDecoration(inst->id(), SpvDecorationRestrictPointer); if (!foundAliased && !foundRestrict) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpVariable " << inst->id() @@ -706,8 +690,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct, // so should never appear as a bare variable. // Unless the module has the RuntimeDescriptorArrayEXT capability. - if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) { - if (!_.HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) { + if (value_type && value_type->opcode() == SpvOpTypeRuntimeArray) { + if (!_.HasCapability(SpvCapabilityRuntimeDescriptorArrayEXT)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpVariable, " << _.getIdName(inst->id()) @@ -718,9 +702,9 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } else { // A bare variable OpTypeRuntimeArray is allowed in this context, but // still need to check the storage class. - if (storage_class != spv::StorageClass::StorageBuffer && - storage_class != spv::StorageClass::Uniform && - storage_class != spv::StorageClass::UniformConstant) { + if (storage_class != SpvStorageClassStorageBuffer && + storage_class != SpvStorageClassUniform && + storage_class != SpvStorageClassUniformConstant) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan with RuntimeDescriptorArrayEXT, a variable " @@ -734,11 +718,11 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { // must either have the storage class StorageBuffer and be decorated // with Block, or it must be in the Uniform storage class and be decorated // as BufferBlock. - if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) { + if (value_type && value_type->opcode() == SpvOpTypeStruct) { if (DoesStructContainRTA(_, value_type)) { - if (storage_class == spv::StorageClass::StorageBuffer || - storage_class == spv::StorageClass::PhysicalStorageBuffer) { - if (!_.HasDecoration(value_id, spv::Decoration::Block)) { + if (storage_class == SpvStorageClassStorageBuffer || + storage_class == SpvStorageClassPhysicalStorageBuffer) { + if (!_.HasDecoration(value_id, SpvDecorationBlock)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan, an OpTypeStruct variable containing an " @@ -746,8 +730,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { << "has storage class StorageBuffer or " "PhysicalStorageBuffer."; } - } else if (storage_class == spv::StorageClass::Uniform) { - if (!_.HasDecoration(value_id, spv::Decoration::BufferBlock)) { + } else if (storage_class == SpvStorageClassUniform) { + if (!_.HasDecoration(value_id, SpvDecorationBufferBlock)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "For Vulkan, an OpTypeStruct variable containing an " @@ -766,8 +750,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Cooperative matrix types can only be allocated in Function or Private - if ((storage_class != spv::StorageClass::Function && - storage_class != spv::StorageClass::Private) && + if ((storage_class != SpvStorageClassFunction && + storage_class != SpvStorageClassPrivate) && ContainsCooperativeMatrix(_, pointee)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cooperative matrix types (or types containing them) can only be " @@ -776,59 +760,57 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { "parameters"; } - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { // Don't allow variables containing 16-bit elements without the appropriate // capabilities. - if ((!_.HasCapability(spv::Capability::Int16) && - _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) || - (!_.HasCapability(spv::Capability::Float16) && - _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) { + if ((!_.HasCapability(SpvCapabilityInt16) && + _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeInt, 16)) || + (!_.HasCapability(SpvCapabilityFloat16) && + _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeFloat, 16))) { auto underlying_type = value_type; - while (underlying_type->opcode() == spv::Op::OpTypePointer) { - storage_class = underlying_type->GetOperandAs(1u); + while (underlying_type->opcode() == SpvOpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); underlying_type = _.FindDef(underlying_type->GetOperandAs(2u)); } bool storage_class_ok = true; std::string sc_name = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); + SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class); switch (storage_class) { - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) { + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess)) { storage_class_ok = false; } break; - case spv::StorageClass::Uniform: + case SpvStorageClassUniform: if (!_.HasCapability( - spv::Capability::UniformAndStorageBuffer16BitAccess)) { - if (underlying_type->opcode() == spv::Op::OpTypeArray || - underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { + SpvCapabilityUniformAndStorageBuffer16BitAccess)) { + if (underlying_type->opcode() == SpvOpTypeArray || + underlying_type->opcode() == SpvOpTypeRuntimeArray) { underlying_type = _.FindDef(underlying_type->GetOperandAs(1u)); } - if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) || + if (!_.HasCapability(SpvCapabilityStorageBuffer16BitAccess) || !_.HasDecoration(underlying_type->id(), - spv::Decoration::BufferBlock)) { + SpvDecorationBufferBlock)) { storage_class_ok = false; } } break; - case spv::StorageClass::PushConstant: - if (!_.HasCapability(spv::Capability::StoragePushConstant16)) { + case SpvStorageClassPushConstant: + if (!_.HasCapability(SpvCapabilityStoragePushConstant16)) { storage_class_ok = false; } break; - case spv::StorageClass::Input: - case spv::StorageClass::Output: - if (!_.HasCapability(spv::Capability::StorageInputOutput16)) { + case SpvStorageClassInput: + case SpvStorageClassOutput: + if (!_.HasCapability(SpvCapabilityStorageInputOutput16)) { storage_class_ok = false; } break; - case spv::StorageClass::Workgroup: - if (!_.HasCapability( - spv::Capability:: - WorkgroupMemoryExplicitLayout16BitAccessKHR)) { + case SpvStorageClassWorkgroup: + if (!_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR)) { storage_class_ok = false; } break; @@ -845,48 +827,46 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } // Don't allow variables containing 8-bit elements without the appropriate // capabilities. - if (!_.HasCapability(spv::Capability::Int8) && - _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 8)) { + if (!_.HasCapability(SpvCapabilityInt8) && + _.ContainsSizedIntOrFloatType(value_id, SpvOpTypeInt, 8)) { auto underlying_type = value_type; - while (underlying_type->opcode() == spv::Op::OpTypePointer) { - storage_class = underlying_type->GetOperandAs(1u); + while (underlying_type->opcode() == SpvOpTypePointer) { + storage_class = underlying_type->GetOperandAs(1u); underlying_type = _.FindDef(underlying_type->GetOperandAs(2u)); } bool storage_class_ok = true; std::string sc_name = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class)); + SPV_OPERAND_TYPE_STORAGE_CLASS, storage_class); switch (storage_class) { - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::PhysicalStorageBuffer: - if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess)) { + case SpvStorageClassStorageBuffer: + case SpvStorageClassPhysicalStorageBuffer: + if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess)) { storage_class_ok = false; } break; - case spv::StorageClass::Uniform: + case SpvStorageClassUniform: if (!_.HasCapability( - spv::Capability::UniformAndStorageBuffer8BitAccess)) { - if (underlying_type->opcode() == spv::Op::OpTypeArray || - underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) { + SpvCapabilityUniformAndStorageBuffer8BitAccess)) { + if (underlying_type->opcode() == SpvOpTypeArray || + underlying_type->opcode() == SpvOpTypeRuntimeArray) { underlying_type = _.FindDef(underlying_type->GetOperandAs(1u)); } - if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess) || + if (!_.HasCapability(SpvCapabilityStorageBuffer8BitAccess) || !_.HasDecoration(underlying_type->id(), - spv::Decoration::BufferBlock)) { + SpvDecorationBufferBlock)) { storage_class_ok = false; } } break; - case spv::StorageClass::PushConstant: - if (!_.HasCapability(spv::Capability::StoragePushConstant8)) { + case SpvStorageClassPushConstant: + if (!_.HasCapability(SpvCapabilityStoragePushConstant8)) { storage_class_ok = false; } break; - case spv::StorageClass::Workgroup: - if (!_.HasCapability( - spv::Capability:: - WorkgroupMemoryExplicitLayout8BitAccessKHR)) { + case SpvStorageClassWorkgroup: + if (!_.HasCapability(SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR)) { storage_class_ok = false; } break; @@ -918,7 +898,7 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - ((_.addressing_model() == spv::AddressingModel::Logical) && + ((_.addressing_model() == SpvAddressingModelLogical) && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -929,14 +909,14 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { } const auto pointer_type = _.FindDef(pointer->type_id()); - if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpLoad type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; } uint32_t pointee_data_type; - spv::StorageClass storage_class; + uint32_t storage_class; if (!_.GetPointerTypeInfo(pointer_type->id(), &pointee_data_type, &storage_class) || result_type->id() != pointee_data_type) { @@ -954,20 +934,18 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { if (auto error = CheckMemoryAccess(_, inst, 3)) return error; - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && - result_type->opcode() != spv::Op::OpTypePointer) { - if (result_type->opcode() != spv::Op::OpTypeInt && - result_type->opcode() != spv::Op::OpTypeFloat && - result_type->opcode() != spv::Op::OpTypeVector && - result_type->opcode() != spv::Op::OpTypeMatrix) { + result_type->opcode() != SpvOpTypePointer) { + if (result_type->opcode() != SpvOpTypeInt && + result_type->opcode() != SpvOpTypeFloat && + result_type->opcode() != SpvOpTypeVector && + result_type->opcode() != SpvOpTypeMatrix) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "8- or 16-bit loads must be a scalar, vector or matrix type"; } } - _.RegisterQCOMImageProcessingTextureConsumer(pointer_id, inst, nullptr); - return SPV_SUCCESS; } @@ -976,7 +954,7 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - (_.addressing_model() == spv::AddressingModel::Logical && + (_.addressing_model() == SpvAddressingModelLogical && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -986,14 +964,14 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { << " is not a logical pointer."; } const auto pointer_type = _.FindDef(pointer->type_id()); - if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; } const auto type_id = pointer_type->GetOperandAs(2); const auto type = _.FindDef(type_id); - if (!type || spv::Op::OpTypeVoid == type->opcode()) { + if (!type || SpvOpTypeVoid == type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << "s type is void."; @@ -1002,29 +980,29 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { // validate storage class { uint32_t data_type; - spv::StorageClass storage_class; + uint32_t storage_class; if (!_.GetPointerTypeInfo(pointer_type->id(), &data_type, &storage_class)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << " is not pointer type"; } - if (storage_class == spv::StorageClass::UniformConstant || - storage_class == spv::StorageClass::Input || - storage_class == spv::StorageClass::PushConstant) { + if (storage_class == SpvStorageClassUniformConstant || + storage_class == SpvStorageClassInput || + storage_class == SpvStorageClassPushConstant) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << " storage class is read-only"; - } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { + } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "ShaderRecordBufferKHR Storage Class variables are read only"; - } else if (storage_class == spv::StorageClass::HitAttributeKHR) { + } else if (storage_class == SpvStorageClassHitAttributeKHR) { std::string errorVUID = _.VkErrorID(4703); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model == spv::ExecutionModel::AnyHitKHR || - model == spv::ExecutionModel::ClosestHitKHR) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model == SpvExecutionModelAnyHitKHR || + model == SpvExecutionModelClosestHitKHR) { if (message) { *message = errorVUID + @@ -1038,18 +1016,18 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env) && - storage_class == spv::StorageClass::Uniform) { + storage_class == SpvStorageClassUniform) { auto base_ptr = _.TracePointer(pointer); - if (base_ptr->opcode() == spv::Op::OpVariable) { + if (base_ptr->opcode() == SpvOpVariable) { // If it's not a variable a different check should catch the problem. auto base_type = _.FindDef(base_ptr->GetOperandAs(0)); // Get the pointed-to type. base_type = _.FindDef(base_type->GetOperandAs(2u)); - if (base_type->opcode() == spv::Op::OpTypeArray || - base_type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (base_type->opcode() == SpvOpTypeArray || + base_type->opcode() == SpvOpTypeRuntimeArray) { base_type = _.FindDef(base_type->GetOperandAs(1u)); } - if (_.HasDecoration(base_type->id(), spv::Decoration::Block)) { + if (_.HasDecoration(base_type->id(), SpvDecorationBlock)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(6925) << "In the Vulkan environment, cannot store to Uniform Blocks"; @@ -1067,16 +1045,15 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { << " is not an object."; } const auto object_type = _.FindDef(object->type_id()); - if (!object_type || spv::Op::OpTypeVoid == object_type->opcode()) { + if (!object_type || SpvOpTypeVoid == object_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Object " << _.getIdName(object_id) << "s type is void."; } if (type->id() != object_type->id()) { - if (!_.options()->relax_struct_store || - type->opcode() != spv::Op::OpTypeStruct || - object_type->opcode() != spv::Op::OpTypeStruct) { + if (!_.options()->relax_struct_store || type->opcode() != SpvOpTypeStruct || + object_type->opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpStore Pointer " << _.getIdName(pointer_id) << "s type does not match Object " @@ -1094,13 +1071,13 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { if (auto error = CheckMemoryAccess(_, inst, 2)) return error; - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && - object_type->opcode() != spv::Op::OpTypePointer) { - if (object_type->opcode() != spv::Op::OpTypeInt && - object_type->opcode() != spv::Op::OpTypeFloat && - object_type->opcode() != spv::Op::OpTypeVector && - object_type->opcode() != spv::Op::OpTypeMatrix) { + object_type->opcode() != SpvOpTypePointer) { + if (object_type->opcode() != SpvOpTypeInt && + object_type->opcode() != SpvOpTypeFloat && + object_type->opcode() != SpvOpTypeVector && + object_type->opcode() != SpvOpTypeMatrix) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "8- or 16-bit stores must be a scalar, vector or matrix type"; } @@ -1111,10 +1088,9 @@ spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _, const Instruction* inst) { - assert(inst->opcode() == spv::Op::OpCopyMemory || - inst->opcode() == spv::Op::OpCopyMemorySized); - const uint32_t first_access_index = - inst->opcode() == spv::Op::OpCopyMemory ? 2 : 3; + assert(inst->opcode() == SpvOpCopyMemory || + inst->opcode() == SpvOpCopyMemorySized); + const uint32_t first_access_index = inst->opcode() == SpvOpCopyMemory ? 2 : 3; if (inst->operands().size() > first_access_index) { if (auto error = CheckMemoryAccess(_, inst, first_access_index)) return error; @@ -1132,23 +1108,21 @@ spv_result_t ValidateCopyMemoryMemoryAccess(ValidationState_t& _, // make-visible. // - the second is the source (read) access and it can't have // make-available. - if (first_access & - uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { + if (first_access & SpvMemoryAccessMakePointerVisibleKHRMask) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Target memory access must not include " "MakePointerVisibleKHR"; } const auto second_access = inst->GetOperandAs(second_access_index); - if (second_access & - uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) { + if (second_access & SpvMemoryAccessMakePointerAvailableKHRMask) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Source memory access must not include " "MakePointerAvailableKHR"; } } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(static_cast(inst->opcode())) + << spvOpcodeString(static_cast(inst->opcode())) << " with two memory access operands requires SPIR-V 1.4 or " "later"; } @@ -1178,7 +1152,7 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto target_pointer_type = _.FindDef(target->type_id()); if (!target_pointer_type || - target_pointer_type->opcode() != spv::Op::OpTypePointer) { + target_pointer_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Target operand " << _.getIdName(target_id) << " is not a pointer."; @@ -1186,16 +1160,16 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto source_pointer_type = _.FindDef(source->type_id()); if (!source_pointer_type || - source_pointer_type->opcode() != spv::Op::OpTypePointer) { + source_pointer_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Source operand " << _.getIdName(source_id) << " is not a pointer."; } - if (inst->opcode() == spv::Op::OpCopyMemory) { + if (inst->opcode() == SpvOpCopyMemory) { const auto target_type = _.FindDef(target_pointer_type->GetOperandAs(2)); - if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) { + if (!target_type || target_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Target operand " << _.getIdName(target_id) << " cannot be a void pointer."; @@ -1203,7 +1177,7 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { const auto source_type = _.FindDef(source_pointer_type->GetOperandAs(2)); - if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) { + if (!source_type || source_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Source operand " << _.getIdName(source_id) << " cannot be a void pointer."; @@ -1233,11 +1207,11 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { bool is_zero = true; switch (size->opcode()) { - case spv::Op::OpConstantNull: + case SpvOpConstantNull: return _.diag(SPV_ERROR_INVALID_ID, inst) << "Size operand " << _.getIdName(size_id) << " cannot be a constant zero."; - case spv::Op::OpConstant: + case SpvOpConstant: if (size_type->word(3) == 1 && size->word(size->words().size() - 1) & 0x80000000) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -1262,10 +1236,10 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { // Get past the pointers to avoid checking a pointer copy. auto sub_type = _.FindDef(target_pointer_type->GetOperandAs(2)); - while (sub_type->opcode() == spv::Op::OpTypePointer) { + while (sub_type->opcode() == SpvOpTypePointer) { sub_type = _.FindDef(sub_type->GetOperandAs(2)); } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(sub_type->id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot copy memory of objects containing 8- or 16-bit types"; @@ -1277,16 +1251,15 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateAccessChain(ValidationState_t& _, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // The result type must be OpTypePointer. auto result_type = _.FindDef(inst->type_id()); - if (spv::Op::OpTypePointer != result_type->opcode()) { + if (SpvOpTypePointer != result_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Result Type of " << instr_name << " " << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op" - << spvOpcodeString(static_cast(result_type->opcode())) - << "."; + << spvOpcodeString(static_cast(result_type->opcode())) << "."; } // Result type is a pointer. Find out what it's pointing to. @@ -1299,7 +1272,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, const auto base_id = inst->GetOperandAs(base_index); const auto base = _.FindDef(base_id); const auto base_type = _.FindDef(base->type_id()); - if (!base_type || spv::Op::OpTypePointer != base_type->opcode()) { + if (!base_type || SpvOpTypePointer != base_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "The Base " << _.getIdName(base_id) << " in " << instr_name << " instruction must be a pointer."; @@ -1323,8 +1296,8 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, // The number of indexes passed to OpAccessChain may not exceed 255 // The instruction includes 4 words + N words (for N indexes) size_t num_indexes = inst->words().size() - 4; - if (inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + if (inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain) { // In pointer access chains, the element operand is required, but not // counted as an index. --num_indexes; @@ -1344,8 +1317,8 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, // on. Once any non-composite type is reached, there must be no remaining // (unused) indexes. auto starting_index = 4; - if (inst->opcode() == spv::Op::OpPtrAccessChain || - inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) { + if (inst->opcode() == SpvOpPtrAccessChain || + inst->opcode() == SpvOpInBoundsPtrAccessChain) { ++starting_index; } for (size_t i = starting_index; i < inst->words().size(); ++i) { @@ -1354,27 +1327,26 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, auto cur_word_instr = _.FindDef(cur_word); // The index must be a scalar integer type (See OpAccessChain in the Spec.) auto index_type = _.FindDef(cur_word_instr->type_id()); - if (!index_type || spv::Op::OpTypeInt != index_type->opcode()) { + if (!index_type || SpvOpTypeInt != index_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Indexes passed to " << instr_name << " must be of type integer."; } switch (type_pointee->opcode()) { - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: { - // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV, + case SpvOpTypeMatrix: + case SpvOpTypeVector: + case SpvOpTypeCooperativeMatrixNV: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: { + // In OpTypeMatrix, OpTypeVector, SpvOpTypeCooperativeMatrixNV, // OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type. type_pointee = _.FindDef(type_pointee->word(2)); break; } - case spv::Op::OpTypeStruct: { + case SpvOpTypeStruct: { // In case of structures, there is an additional constraint on the // index: the index must be an OpConstant. - if (spv::Op::OpConstant != cur_word_instr->opcode()) { + if (SpvOpConstant != cur_word_instr->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) << "The passed to " << instr_name << " to index into a " @@ -1406,7 +1378,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, } default: { // Give an error. reached non-composite type while indexes still remain. - return _.diag(SPV_ERROR_INVALID_ID, inst) + return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) << instr_name << " reached non-composite type while indexes " "still remain to be traversed."; @@ -1418,12 +1390,11 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, if (type_pointee->id() != result_type_pointee->id()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << instr_name << " result type (Op" - << spvOpcodeString( - static_cast(result_type_pointee->opcode())) + << spvOpcodeString(static_cast(result_type_pointee->opcode())) << ") does not match the type that results from indexing into the " "base " " (Op" - << spvOpcodeString(static_cast(type_pointee->opcode())) + << spvOpcodeString(static_cast(type_pointee->opcode())) << ")."; } @@ -1432,72 +1403,24 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, spv_result_t ValidatePtrAccessChain(ValidationState_t& _, const Instruction* inst) { - if (_.addressing_model() == spv::AddressingModel::Logical) { + if (_.addressing_model() == SpvAddressingModelLogical) { if (!_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Generating variable pointers requires capability " << "VariablePointers or VariablePointersStorageBuffer"; } } - - // Need to call first, will make sure Base is a valid ID - if (auto error = ValidateAccessChain(_, inst)) return error; - - const auto base_id = inst->GetOperandAs(2); - const auto base = _.FindDef(base_id); - const auto base_type = _.FindDef(base->type_id()); - const auto base_type_storage_class = - base_type->GetOperandAs(1); - - if (_.HasCapability(spv::Capability::Shader) && - (base_type_storage_class == spv::StorageClass::Uniform || - base_type_storage_class == spv::StorageClass::StorageBuffer || - base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer || - base_type_storage_class == spv::StorageClass::PushConstant || - (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) && - base_type_storage_class == spv::StorageClass::Workgroup)) && - !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "OpPtrAccessChain must have a Base whose type is decorated " - "with ArrayStride"; - } - - if (spvIsVulkanEnv(_.context()->target_env)) { - if (base_type_storage_class == spv::StorageClass::Workgroup) { - if (!_.HasCapability(spv::Capability::VariablePointers)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(7651) - << "OpPtrAccessChain Base operand pointing to Workgroup " - "storage class must use VariablePointers capability"; - } - } else if (base_type_storage_class == spv::StorageClass::StorageBuffer) { - if (!_.features().variable_pointers) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(7652) - << "OpPtrAccessChain Base operand pointing to StorageBuffer " - "storage class must use VariablePointers or " - "VariablePointersStorageBuffer capability"; - } - } else if (base_type_storage_class != - spv::StorageClass::PhysicalStorageBuffer) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(7650) - << "OpPtrAccessChain Base operand must point to Workgroup, " - "StorageBuffer, or PhysicalStorageBuffer storage class"; - } - } - - return SPV_SUCCESS; + return ValidateAccessChain(_, inst); } spv_result_t ValidateArrayLength(ValidationState_t& state, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // Result type must be a 32-bit unsigned int. auto result_type = state.FindDef(inst->type_id()); - if (result_type->opcode() != spv::Op::OpTypeInt || + if (result_type->opcode() != SpvOpTypeInt || result_type->GetOperandAs(1) != 32 || result_type->GetOperandAs(2) != 0) { return state.diag(SPV_ERROR_INVALID_ID, inst) @@ -1510,7 +1433,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, // last element is a runtime array. auto pointer = state.FindDef(inst->GetOperandAs(2)); auto pointer_type = state.FindDef(pointer->type_id()); - if (pointer_type->opcode() != spv::Op::OpTypePointer) { + if (pointer_type->opcode() != SpvOpTypePointer) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's type in " << instr_name << " " << state.getIdName(inst->id()) @@ -1518,7 +1441,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, } auto structure_type = state.FindDef(pointer_type->GetOperandAs(2)); - if (structure_type->opcode() != spv::Op::OpTypeStruct) { + if (structure_type->opcode() != SpvOpTypeStruct) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's type in " << instr_name << " " << state.getIdName(inst->id()) @@ -1528,7 +1451,7 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, auto num_of_members = structure_type->operands().size() - 1; auto last_member = state.FindDef(structure_type->GetOperandAs(num_of_members)); - if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) { + if (last_member->opcode() != SpvOpTypeRuntimeArray) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The Structure's last member in " << instr_name << " " << state.getIdName(inst->id()) << " must be an OpTypeRuntimeArray."; @@ -1548,11 +1471,11 @@ spv_result_t ValidateArrayLength(ValidationState_t& state, spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state, const Instruction* inst) { std::string instr_name = - "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); + "Op" + std::string(spvOpcodeString(static_cast(inst->opcode()))); // Result type must be a 32-bit unsigned int. auto result_type = state.FindDef(inst->type_id()); - if (result_type->opcode() != spv::Op::OpTypeInt || + if (result_type->opcode() != SpvOpTypeInt || result_type->GetOperandAs(1) != 32 || result_type->GetOperandAs(2) != 0) { return state.diag(SPV_ERROR_INVALID_ID, inst) @@ -1561,15 +1484,9 @@ spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state, << " must be OpTypeInt with width 32 and signedness 0."; } - bool isKhr = inst->opcode() == spv::Op::OpCooperativeMatrixLengthKHR; auto type_id = inst->GetOperandAs(2); auto type = state.FindDef(type_id); - if (isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) { - return state.diag(SPV_ERROR_INVALID_ID, inst) - << "The type in " << instr_name << " " - << state.getIdName(type_id) - << " must be OpTypeCooperativeMatrixKHR."; - } else if (!isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { + if (type->opcode() != SpvOpTypeCooperativeMatrixNV) { return state.diag(SPV_ERROR_INVALID_ID, inst) << "The type in " << instr_name << " " << state.getIdName(type_id) << " must be OpTypeCooperativeMatrixNV."; @@ -1581,35 +1498,35 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const Instruction* inst) { uint32_t type_id; const char* opname; - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { + if (inst->opcode() == SpvOpCooperativeMatrixLoadNV) { type_id = inst->type_id(); - opname = "spv::Op::OpCooperativeMatrixLoadNV"; + opname = "SpvOpCooperativeMatrixLoadNV"; } else { // get Object operand's type type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); - opname = "spv::Op::OpCooperativeMatrixStoreNV"; + opname = "SpvOpCooperativeMatrixStoreNV"; } auto matrix_type = _.FindDef(type_id); - if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) { - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) { + if (matrix_type->opcode() != SpvOpTypeCooperativeMatrixNV) { + if (inst->opcode() == SpvOpCooperativeMatrixLoadNV) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "spv::Op::OpCooperativeMatrixLoadNV Result Type " + << "SpvOpCooperativeMatrixLoadNV Result Type " << _.getIdName(type_id) << " is not a cooperative matrix type."; } else { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "spv::Op::OpCooperativeMatrixStoreNV Object type " + << "SpvOpCooperativeMatrixStoreNV Object type " << _.getIdName(type_id) << " is not a cooperative matrix type."; } } const auto pointer_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 2u : 0u; + (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 2u : 0u; const auto pointer_id = inst->GetOperandAs(pointer_index); const auto pointer = _.FindDef(pointer_id); if (!pointer || - ((_.addressing_model() == spv::AddressingModel::Logical) && + ((_.addressing_model() == SpvAddressingModelLogical) && ((!_.features().variable_pointers && !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || (_.features().variable_pointers && @@ -1621,7 +1538,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const auto pointer_type_id = pointer->type_id(); const auto pointer_type = _.FindDef(pointer_type_id); - if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { + if (!pointer_type || pointer_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opname << " type for pointer " << _.getIdName(pointer_id) << " is not a pointer type."; @@ -1629,11 +1546,11 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, const auto storage_class_index = 1u; const auto storage_class = - pointer_type->GetOperandAs(storage_class_index); + pointer_type->GetOperandAs(storage_class_index); - if (storage_class != spv::StorageClass::Workgroup && - storage_class != spv::StorageClass::StorageBuffer && - storage_class != spv::StorageClass::PhysicalStorageBuffer) { + if (storage_class != SpvStorageClassWorkgroup && + storage_class != SpvStorageClassStorageBuffer && + storage_class != SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << opname << " storage class for pointer type " << _.getIdName(pointer_type_id) @@ -1650,7 +1567,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto stride_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 3u : 2u; + (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 3u : 2u; const auto stride_id = inst->GetOperandAs(stride_index); const auto stride = _.FindDef(stride_id); if (!stride || !_.IsIntScalarType(stride->type_id())) { @@ -1660,7 +1577,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto colmajor_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 4u : 3u; + (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 4u : 3u; const auto colmajor_id = inst->GetOperandAs(colmajor_index); const auto colmajor = _.FindDef(colmajor_id); if (!colmajor || !_.IsBoolScalarType(colmajor->type_id()) || @@ -1672,114 +1589,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _, } const auto memory_access_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) ? 5u : 4u; - if (inst->operands().size() > memory_access_index) { - if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) - return error; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _, - const Instruction* inst) { - uint32_t type_id; - const char* opname; - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { - type_id = inst->type_id(); - opname = "spv::Op::OpCooperativeMatrixLoadKHR"; - } else { - // get Object operand's type - type_id = _.FindDef(inst->GetOperandAs(1))->type_id(); - opname = "spv::Op::OpCooperativeMatrixStoreKHR"; - } - - auto matrix_type = _.FindDef(type_id); - - if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) { - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "spv::Op::OpCooperativeMatrixLoadKHR Result Type " - << _.getIdName(type_id) << " is not a cooperative matrix type."; - } else { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "spv::Op::OpCooperativeMatrixStoreKHR Object type " - << _.getIdName(type_id) << " is not a cooperative matrix type."; - } - } - - const auto pointer_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 2u : 0u; - const auto pointer_id = inst->GetOperandAs(pointer_index); - const auto pointer = _.FindDef(pointer_id); - if (!pointer || - ((_.addressing_model() == spv::AddressingModel::Logical) && - ((!_.features().variable_pointers && - !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || - (_.features().variable_pointers && - !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << opname << " Pointer " << _.getIdName(pointer_id) - << " is not a logical pointer."; - } - - const auto pointer_type_id = pointer->type_id(); - const auto pointer_type = _.FindDef(pointer_type_id); - if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << opname << " type for pointer " << _.getIdName(pointer_id) - << " is not a pointer type."; - } - - const auto storage_class_index = 1u; - const auto storage_class = - pointer_type->GetOperandAs(storage_class_index); - - if (storage_class != spv::StorageClass::Workgroup && - storage_class != spv::StorageClass::StorageBuffer && - storage_class != spv::StorageClass::PhysicalStorageBuffer) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << _.VkErrorID(8973) << opname - << " storage class for pointer type " - << _.getIdName(pointer_type_id) - << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer."; - } - - const auto pointee_id = pointer_type->GetOperandAs(2); - const auto pointee_type = _.FindDef(pointee_id); - if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) || - _.IsFloatScalarOrVectorType(pointee_id))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << opname << " Pointer " << _.getIdName(pointer->id()) - << "s Type must be a scalar or vector type."; - } - - const auto layout_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 3u : 2u; - const auto colmajor_id = inst->GetOperandAs(layout_index); - const auto colmajor = _.FindDef(colmajor_id); - if (!colmajor || !_.IsIntScalarType(colmajor->type_id()) || - !(spvOpcodeIsConstant(colmajor->opcode()) || - spvOpcodeIsSpecConstant(colmajor->opcode()))) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "MemoryLayout operand " << _.getIdName(colmajor_id) - << " must be a 32-bit integer constant instruction."; - } - - const auto stride_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 4u : 3u; - if (inst->operands().size() > stride_index) { - const auto stride_id = inst->GetOperandAs(stride_index); - const auto stride = _.FindDef(stride_id); - if (!stride || !_.IsIntScalarType(stride->type_id())) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "Stride operand " << _.getIdName(stride_id) - << " must be a scalar integer type."; - } - } - - const auto memory_access_index = - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 5u : 4u; + (inst->opcode() == SpvOpCooperativeMatrixLoadNV) ? 5u : 4u; if (inst->operands().size() > memory_access_index) { if (auto error = CheckMemoryAccess(_, inst, memory_access_index)) return error; @@ -1790,7 +1600,7 @@ spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _, spv_result_t ValidatePtrComparison(ValidationState_t& _, const Instruction* inst) { - if (_.addressing_model() == spv::AddressingModel::Logical && + if (_.addressing_model() == SpvAddressingModelLogical && !_.features().variable_pointers) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Instruction cannot for logical addressing model be used without " @@ -1798,13 +1608,13 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, } const auto result_type = _.FindDef(inst->type_id()); - if (inst->opcode() == spv::Op::OpPtrDiff) { - if (!result_type || result_type->opcode() != spv::Op::OpTypeInt) { + if (inst->opcode() == SpvOpPtrDiff) { + if (!result_type || result_type->opcode() != SpvOpTypeInt) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result Type must be an integer scalar"; } } else { - if (!result_type || result_type->opcode() != spv::Op::OpTypeBool) { + if (!result_type || result_type->opcode() != SpvOpTypeBool) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Result Type must be OpTypeBool"; } @@ -1817,26 +1627,25 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, << "The types of Operand 1 and Operand 2 must match"; } const auto op1_type = _.FindDef(op1->type_id()); - if (!op1_type || op1_type->opcode() != spv::Op::OpTypePointer) { + if (!op1_type || op1_type->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Operand type must be a pointer"; } - spv::StorageClass sc = op1_type->GetOperandAs(1u); - if (_.addressing_model() == spv::AddressingModel::Logical) { - if (sc != spv::StorageClass::Workgroup && - sc != spv::StorageClass::StorageBuffer) { + SpvStorageClass sc = op1_type->GetOperandAs(1u); + if (_.addressing_model() == SpvAddressingModelLogical) { + if (sc != SpvStorageClassWorkgroup && sc != SpvStorageClassStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Invalid pointer storage class"; } - if (sc == spv::StorageClass::Workgroup && - !_.HasCapability(spv::Capability::VariablePointers)) { + if (sc == SpvStorageClassWorkgroup && + !_.HasCapability(SpvCapabilityVariablePointers)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Workgroup storage class pointer requires VariablePointers " "capability to be specified"; } - } else if (sc == spv::StorageClass::PhysicalStorageBuffer) { + } else if (sc == SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot use a pointer in the PhysicalStorageBuffer storage class"; } @@ -1848,51 +1657,45 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _, spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpVariable: + case SpvOpVariable: if (auto error = ValidateVariable(_, inst)) return error; break; - case spv::Op::OpLoad: + case SpvOpLoad: if (auto error = ValidateLoad(_, inst)) return error; break; - case spv::Op::OpStore: + case SpvOpStore: if (auto error = ValidateStore(_, inst)) return error; break; - case spv::Op::OpCopyMemory: - case spv::Op::OpCopyMemorySized: + case SpvOpCopyMemory: + case SpvOpCopyMemorySized: if (auto error = ValidateCopyMemory(_, inst)) return error; break; - case spv::Op::OpPtrAccessChain: + case SpvOpPtrAccessChain: if (auto error = ValidatePtrAccessChain(_, inst)) return error; break; - case spv::Op::OpAccessChain: - case spv::Op::OpInBoundsAccessChain: - case spv::Op::OpInBoundsPtrAccessChain: + case SpvOpAccessChain: + case SpvOpInBoundsAccessChain: + case SpvOpInBoundsPtrAccessChain: if (auto error = ValidateAccessChain(_, inst)) return error; break; - case spv::Op::OpArrayLength: + case SpvOpArrayLength: if (auto error = ValidateArrayLength(_, inst)) return error; break; - case spv::Op::OpCooperativeMatrixLoadNV: - case spv::Op::OpCooperativeMatrixStoreNV: + case SpvOpCooperativeMatrixLoadNV: + case SpvOpCooperativeMatrixStoreNV: if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst)) return error; break; - case spv::Op::OpCooperativeMatrixLengthKHR: - case spv::Op::OpCooperativeMatrixLengthNV: + case SpvOpCooperativeMatrixLengthNV: if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error; break; - case spv::Op::OpCooperativeMatrixLoadKHR: - case spv::Op::OpCooperativeMatrixStoreKHR: - if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst)) - return error; - break; - case spv::Op::OpPtrEqual: - case spv::Op::OpPtrNotEqual: - case spv::Op::OpPtrDiff: + case SpvOpPtrEqual: + case SpvOpPtrNotEqual: + case SpvOpPtrDiff: if (auto error = ValidatePtrComparison(_, inst)) return error; break; - case spv::Op::OpImageTexelPointer: - case spv::Op::OpGenericPtrMemSemantics: + case SpvOpImageTexelPointer: + case SpvOpGenericPtrMemSemantics: default: break; } diff --git a/source/val/validate_memory_semantics.cpp b/source/val/validate_memory_semantics.cpp index c4f22a61..d9189313 100644 --- a/source/val/validate_memory_semantics.cpp +++ b/source/val/validate_memory_semantics.cpp @@ -14,6 +14,7 @@ #include "source/val/validate_memory_semantics.h" +#include "source/diagnostic.h" #include "source/spirv_target_env.h" #include "source/util/bitutils.h" #include "source/val/instruction.h" @@ -26,7 +27,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, const Instruction* inst, uint32_t operand_index, uint32_t memory_scope) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const auto id = inst->GetOperandAs(operand_index); bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; @@ -39,15 +40,15 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } if (!is_const_int32) { - if (_.HasCapability(spv::Capability::Shader) && - !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { + if (_.HasCapability(SpvCapabilityShader) && + !_.HasCapability(SpvCapabilityCooperativeMatrixNV)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics ids must be OpConstant when Shader " "capability is present"; } - if (_.HasCapability(spv::Capability::Shader) && - _.HasCapability(spv::Capability::CooperativeMatrixNV) && + if (_.HasCapability(SpvCapabilityShader) && + _.HasCapability(SpvCapabilityCooperativeMatrixNV) && !spvOpcodeIsConstant(_.GetIdOpcode(id))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics must be a constant instruction when " @@ -57,10 +58,9 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits( - value & uint32_t(spv::MemorySemanticsMask::Acquire | - spv::MemorySemanticsMask::Release | - spv::MemorySemanticsMask::AcquireRelease | - spv::MemorySemanticsMask::SequentiallyConsistent)); + value & (SpvMemorySemanticsAcquireMask | SpvMemorySemanticsReleaseMask | + SpvMemorySemanticsAcquireReleaseMask | + SpvMemorySemanticsSequentiallyConsistentMask)); if (num_memory_order_set_bits > 1) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -71,40 +71,40 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, "SequentiallyConsistent"; } - if (_.memory_model() == spv::MemoryModel::VulkanKHR && - value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent)) { + if (_.memory_model() == SpvMemoryModelVulkanKHR && + value & SpvMemorySemanticsSequentiallyConsistentMask) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "SequentiallyConsistent memory " "semantics cannot be used with " "the VulkanKHR memory model."; } - if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && - !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (value & SpvMemorySemanticsMakeAvailableKHRMask && + !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics MakeAvailableKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && - !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (value & SpvMemorySemanticsMakeVisibleKHRMask && + !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics MakeVisibleKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR) && - !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (value & SpvMemorySemanticsOutputMemoryKHRMask && + !_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics OutputMemoryKHR requires capability " << "VulkanMemoryModelKHR"; } - if (value & uint32_t(spv::MemorySemanticsMask::Volatile)) { - if (!_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (value & SpvMemorySemanticsVolatileMask) { + if (!_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics Volatile requires capability " @@ -118,27 +118,26 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (value & uint32_t(spv::MemorySemanticsMask::UniformMemory) && - !_.HasCapability(spv::Capability::Shader)) { + if (value & SpvMemorySemanticsUniformMemoryMask && + !_.HasCapability(SpvCapabilityShader)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics UniformMemory requires capability Shader"; } - // Checking for spv::Capability::AtomicStorage is intentionally not done here. - // See https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning - // why. + // Checking for SpvCapabilityAtomicStorage is intentionally not done here. See + // https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning why. - if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR | - spv::MemorySemanticsMask::MakeVisibleKHR)) { + if (value & (SpvMemorySemanticsMakeAvailableKHRMask | + SpvMemorySemanticsMakeVisibleKHRMask)) { const bool includes_storage_class = - value & uint32_t(spv::MemorySemanticsMask::UniformMemory | - spv::MemorySemanticsMask::SubgroupMemory | - spv::MemorySemanticsMask::WorkgroupMemory | - spv::MemorySemanticsMask::CrossWorkgroupMemory | - spv::MemorySemanticsMask::AtomicCounterMemory | - spv::MemorySemanticsMask::ImageMemory | - spv::MemorySemanticsMask::OutputMemoryKHR); + value & (SpvMemorySemanticsUniformMemoryMask | + SpvMemorySemanticsSubgroupMemoryMask | + SpvMemorySemanticsWorkgroupMemoryMask | + SpvMemorySemanticsCrossWorkgroupMemoryMask | + SpvMemorySemanticsAtomicCounterMemoryMask | + SpvMemorySemanticsImageMemoryMask | + SpvMemorySemanticsOutputMemoryKHRMask); if (!includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -147,18 +146,18 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) && - !(value & uint32_t(spv::MemorySemanticsMask::Acquire | - spv::MemorySemanticsMask::AcquireRelease))) { + if (value & SpvMemorySemanticsMakeVisibleKHRMask && + !(value & (SpvMemorySemanticsAcquireMask | + SpvMemorySemanticsAcquireReleaseMask))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": MakeVisibleKHR Memory Semantics also requires either Acquire " "or AcquireRelease Memory Semantics"; } - if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) && - !(value & uint32_t(spv::MemorySemanticsMask::Release | - spv::MemorySemanticsMask::AcquireRelease))) { + if (value & SpvMemorySemanticsMakeAvailableKHRMask && + !(value & (SpvMemorySemanticsReleaseMask | + SpvMemorySemanticsAcquireReleaseMask))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": MakeAvailableKHR Memory Semantics also requires either " @@ -167,12 +166,12 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, if (spvIsVulkanEnv(_.context()->target_env)) { const bool includes_storage_class = - value & uint32_t(spv::MemorySemanticsMask::UniformMemory | - spv::MemorySemanticsMask::WorkgroupMemory | - spv::MemorySemanticsMask::ImageMemory | - spv::MemorySemanticsMask::OutputMemoryKHR); + value & (SpvMemorySemanticsUniformMemoryMask | + SpvMemorySemanticsWorkgroupMemoryMask | + SpvMemorySemanticsImageMemoryMask | + SpvMemorySemanticsOutputMemoryKHRMask); - if (opcode == spv::Op::OpMemoryBarrier && !num_memory_order_set_bits) { + if (opcode == SpvOpMemoryBarrier && !num_memory_order_set_bits) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4732) << spvOpcodeString(opcode) << ": Vulkan specification requires Memory Semantics to have " @@ -180,15 +179,13 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, "of the following bits set: Acquire, Release, " "AcquireRelease " "or SequentiallyConsistent"; - } else if (opcode != spv::Op::OpMemoryBarrier && - num_memory_order_set_bits) { + } else if (opcode != SpvOpMemoryBarrier && num_memory_order_set_bits) { // should leave only atomics and control barriers for Vulkan env bool memory_is_int32 = false, memory_is_const_int32 = false; uint32_t memory_value = 0; std::tie(memory_is_int32, memory_is_const_int32, memory_value) = _.EvalInt32IfConst(memory_scope); - if (memory_is_int32 && - spv::Scope(memory_value) == spv::Scope::Invocation) { + if (memory_is_int32 && memory_value == SpvScopeInvocation) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4641) << spvOpcodeString(opcode) << ": Vulkan specification requires Memory Semantics to be None " @@ -196,7 +193,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } } - if (opcode == spv::Op::OpMemoryBarrier && !includes_storage_class) { + if (opcode == SpvOpMemoryBarrier && !includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4733) << spvOpcodeString(opcode) << ": expected Memory Semantics to include a Vulkan-supported " @@ -205,7 +202,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, #if 0 // TODO(atgoo@github.com): this check fails Vulkan CTS, reenable once fixed. - if (opcode == spv::Op::OpControlBarrier && value && !includes_storage_class) { + if (opcode == SpvOpControlBarrier && value && !includes_storage_class) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": expected Memory Semantics to include a Vulkan-supported " @@ -214,18 +211,18 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, #endif } - if (opcode == spv::Op::OpAtomicFlagClear && - (value & uint32_t(spv::MemorySemanticsMask::Acquire) || - value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { + if (opcode == SpvOpAtomicFlagClear && + (value & SpvMemorySemanticsAcquireMask || + value & SpvMemorySemanticsAcquireReleaseMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory Semantics Acquire and AcquireRelease cannot be used " "with " << spvOpcodeString(opcode); } - if (opcode == spv::Op::OpAtomicCompareExchange && operand_index == 5 && - (value & uint32_t(spv::MemorySemanticsMask::Release) || - value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) { + if (opcode == SpvOpAtomicCompareExchange && operand_index == 5 && + (value & SpvMemorySemanticsReleaseMask || + value & SpvMemorySemanticsAcquireReleaseMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Memory Semantics Release and AcquireRelease cannot be " @@ -234,20 +231,20 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (opcode == spv::Op::OpAtomicLoad && - (value & uint32_t(spv::MemorySemanticsMask::Release) || - value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || - value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { + if (opcode == SpvOpAtomicLoad && + (value & SpvMemorySemanticsReleaseMask || + value & SpvMemorySemanticsAcquireReleaseMask || + value & SpvMemorySemanticsSequentiallyConsistentMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4731) << "Vulkan spec disallows OpAtomicLoad with Memory Semantics " "Release, AcquireRelease and SequentiallyConsistent"; } - if (opcode == spv::Op::OpAtomicStore && - (value & uint32_t(spv::MemorySemanticsMask::Acquire) || - value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) || - value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) { + if (opcode == SpvOpAtomicStore && + (value & SpvMemorySemanticsAcquireMask || + value & SpvMemorySemanticsAcquireReleaseMask || + value & SpvMemorySemanticsSequentiallyConsistentMask)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4730) << "Vulkan spec disallows OpAtomicStore with Memory Semantics " diff --git a/source/val/validate_mesh_shading.cpp b/source/val/validate_mesh_shading.cpp index e569e251..a7f07267 100644 --- a/source/val/validate_mesh_shading.cpp +++ b/source/val/validate_mesh_shading.cpp @@ -23,13 +23,13 @@ namespace spvtools { namespace val { spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); switch (opcode) { - case spv::Op::OpEmitMeshTasksEXT: { + case SpvOpEmitMeshTasksEXT: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::TaskEXT) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelTaskEXT) { if (message) { *message = "OpEmitMeshTasksEXT requires TaskEXT execution model"; @@ -62,12 +62,12 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { if (inst->operands().size() == 4) { const auto payload = _.FindDef(inst->GetOperandAs(3)); - if (payload->opcode() != spv::Op::OpVariable) { + if (payload->opcode() != SpvOpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must be the result of a OpVariable"; } - if (payload->GetOperandAs(2) != - spv::StorageClass::TaskPayloadWorkgroupEXT) { + if (SpvStorageClass(payload->GetOperandAs(2)) != + SpvStorageClassTaskPayloadWorkgroupEXT) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload OpVariable must have a storage class of " "TaskPayloadWorkgroupEXT"; @@ -76,11 +76,11 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpSetMeshOutputsEXT: { + case SpvOpSetMeshOutputsEXT: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::MeshEXT) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelMeshEXT) { if (message) { *message = "OpSetMeshOutputsEXT requires MeshEXT execution model"; @@ -107,7 +107,7 @@ spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpWritePackedPrimitiveIndices4x8NV: { + case SpvOpWritePackedPrimitiveIndices4x8NV: { // No validation rules (for the moment). break; } diff --git a/source/val/validate_misc.cpp b/source/val/validate_misc.cpp index d71fd2d2..5acc21ea 100644 --- a/source/val/validate_misc.cpp +++ b/source/val/validate_misc.cpp @@ -30,7 +30,7 @@ spv_result_t ValidateUndef(ValidationState_t& _, const Instruction* inst) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Cannot create undefined values with void type"; } - if (_.HasCapability(spv::Capability::Shader) && + if (_.HasCapability(SpvCapabilityShader) && _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && !_.IsPointerType(inst->type_id())) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -50,8 +50,7 @@ spv_result_t ValidateShaderClock(ValidationState_t& _, bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); - if (is_const_int32 && spv::Scope(value) != spv::Scope::Subgroup && - spv::Scope(value) != spv::Scope::Device) { + if (is_const_int32 && value != SpvScopeSubgroup && value != SpvScopeDevice) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4652) << "Scope must be Subgroup or Device"; } @@ -105,18 +104,18 @@ spv_result_t ValidateExpect(ValidationState_t& _, const Instruction* inst) { spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpUndef: + case SpvOpUndef: if (auto error = ValidateUndef(_, inst)) return error; break; default: break; } switch (inst->opcode()) { - case spv::Op::OpBeginInvocationInterlockEXT: - case spv::Op::OpEndInvocationInterlockEXT: + case SpvOpBeginInvocationInterlockEXT: + case SpvOpEndInvocationInterlockEXT: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT " "require Fragment execution model"); @@ -127,14 +126,14 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { const auto* execution_modes = state.GetExecutionModes(entry_point->id()); - auto find_interlock = [](const spv::ExecutionMode& mode) { + auto find_interlock = [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::PixelInterlockOrderedEXT: - case spv::ExecutionMode::PixelInterlockUnorderedEXT: - case spv::ExecutionMode::SampleInterlockOrderedEXT: - case spv::ExecutionMode::SampleInterlockUnorderedEXT: - case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: - case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: + case SpvExecutionModePixelInterlockOrderedEXT: + case SpvExecutionModePixelInterlockUnorderedEXT: + case SpvExecutionModeSampleInterlockOrderedEXT: + case SpvExecutionModeSampleInterlockUnorderedEXT: + case SpvExecutionModeShadingRateInterlockOrderedEXT: + case SpvExecutionModeShadingRateInterlockUnorderedEXT: return true; default: return false; @@ -157,18 +156,18 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { return true; }); break; - case spv::Op::OpDemoteToHelperInvocationEXT: + case SpvOpDemoteToHelperInvocationEXT: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, "OpDemoteToHelperInvocationEXT requires Fragment execution " "model"); break; - case spv::Op::OpIsHelperInvocationEXT: { + case SpvOpIsHelperInvocationEXT: { const uint32_t result_type = inst->type_id(); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Fragment, + SpvExecutionModelFragment, "OpIsHelperInvocationEXT requires Fragment execution model"); if (!_.IsBoolScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -176,17 +175,17 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) { << spvOpcodeString(inst->opcode()); break; } - case spv::Op::OpReadClockKHR: + case SpvOpReadClockKHR: if (auto error = ValidateShaderClock(_, inst)) { return error; } break; - case spv::Op::OpAssumeTrueKHR: + case SpvOpAssumeTrueKHR: if (auto error = ValidateAssumeTrue(_, inst)) { return error; } break; - case spv::Op::OpExpectKHR: + case SpvOpExpectKHR: if (auto error = ValidateExpect(_, inst)) { return error; } diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp index d757d4f8..672192b9 100644 --- a/source/val/validate_mode_setting.cpp +++ b/source/val/validate_mode_setting.cpp @@ -27,16 +27,16 @@ namespace { spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { const auto entry_point_id = inst->GetOperandAs(1); auto entry_point = _.FindDef(entry_point_id); - if (!entry_point || spv::Op::OpFunction != entry_point->opcode()) { + if (!entry_point || SpvOpFunction != entry_point->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpEntryPoint Entry Point " << _.getIdName(entry_point_id) << " is not a function."; } // Only check the shader execution models - const spv::ExecutionModel execution_model = - inst->GetOperandAs(0); - if (execution_model != spv::ExecutionModel::Kernel) { + const SpvExecutionModel execution_model = + inst->GetOperandAs(0); + if (execution_model != SpvExecutionModelKernel) { const auto entry_point_type_id = entry_point->GetOperandAs(3); const auto entry_point_type = _.FindDef(entry_point_type_id); if (!entry_point_type || 3 != entry_point_type->words().size()) { @@ -48,7 +48,7 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } auto return_type = _.FindDef(entry_point->type_id()); - if (!return_type || spv::Op::OpTypeVoid != return_type->opcode()) { + if (!return_type || SpvOpTypeVoid != return_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4633) << "OpEntryPoint Entry Point " << _.getIdName(entry_point_id) @@ -56,31 +56,31 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } const auto* execution_modes = _.GetExecutionModes(entry_point_id); - if (_.HasCapability(spv::Capability::Shader)) { + if (_.HasCapability(SpvCapabilityShader)) { switch (execution_model) { - case spv::ExecutionModel::Fragment: + case SpvExecutionModelFragment: if (execution_modes && - execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && - execution_modes->count(spv::ExecutionMode::OriginLowerLeft)) { + execution_modes->count(SpvExecutionModeOriginUpperLeft) && + execution_modes->count(SpvExecutionModeOriginLowerLeft)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Fragment execution model entry points can only specify " "one of OriginUpperLeft or OriginLowerLeft execution " "modes."; } if (!execution_modes || - (!execution_modes->count(spv::ExecutionMode::OriginUpperLeft) && - !execution_modes->count(spv::ExecutionMode::OriginLowerLeft))) { + (!execution_modes->count(SpvExecutionModeOriginUpperLeft) && + !execution_modes->count(SpvExecutionModeOriginLowerLeft))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Fragment execution model entry points require either an " "OriginUpperLeft or OriginLowerLeft execution mode."; } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::DepthGreater: - case spv::ExecutionMode::DepthLess: - case spv::ExecutionMode::DepthUnchanged: + case SpvExecutionModeDepthGreater: + case SpvExecutionModeDepthLess: + case SpvExecutionModeDepthUnchanged: return true; default: return false; @@ -94,15 +94,14 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::PixelInterlockOrderedEXT: - case spv::ExecutionMode::PixelInterlockUnorderedEXT: - case spv::ExecutionMode::SampleInterlockOrderedEXT: - case spv::ExecutionMode::SampleInterlockUnorderedEXT: - case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: - case spv::ExecutionMode:: - ShadingRateInterlockUnorderedEXT: + case SpvExecutionModePixelInterlockOrderedEXT: + case SpvExecutionModePixelInterlockUnorderedEXT: + case SpvExecutionModeSampleInterlockOrderedEXT: + case SpvExecutionModeSampleInterlockUnorderedEXT: + case SpvExecutionModeShadingRateInterlockOrderedEXT: + case SpvExecutionModeShadingRateInterlockUnorderedEXT: return true; default: return false; @@ -115,11 +114,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::StencilRefUnchangedFrontAMD: - case spv::ExecutionMode::StencilRefLessFrontAMD: - case spv::ExecutionMode::StencilRefGreaterFrontAMD: + case SpvExecutionModeStencilRefUnchangedFrontAMD: + case SpvExecutionModeStencilRefLessFrontAMD: + case SpvExecutionModeStencilRefGreaterFrontAMD: return true; default: return false; @@ -134,11 +133,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (execution_modes && 1 < std::count_if( execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::StencilRefUnchangedBackAMD: - case spv::ExecutionMode::StencilRefLessBackAMD: - case spv::ExecutionMode::StencilRefGreaterBackAMD: + case SpvExecutionModeStencilRefUnchangedBackAMD: + case SpvExecutionModeStencilRefLessBackAMD: + case SpvExecutionModeStencilRefGreaterBackAMD: return true; default: return false; @@ -151,21 +150,20 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "execution modes."; } break; - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: if (execution_modes && - 1 < std::count_if( - execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { - switch (mode) { - case spv::ExecutionMode::SpacingEqual: - case spv::ExecutionMode::SpacingFractionalEven: - case spv::ExecutionMode::SpacingFractionalOdd: - return true; - default: - return false; - } - })) { + 1 < std::count_if(execution_modes->begin(), execution_modes->end(), + [](const SpvExecutionMode& mode) { + switch (mode) { + case SpvExecutionModeSpacingEqual: + case SpvExecutionModeSpacingFractionalEven: + case SpvExecutionModeSpacingFractionalOdd: + return true; + default: + return false; + } + })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Tessellation execution model entry points can specify at " "most one of SpacingEqual, SpacingFractionalOdd or " @@ -173,11 +171,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::Triangles: - case spv::ExecutionMode::Quads: - case spv::ExecutionMode::Isolines: + case SpvExecutionModeTriangles: + case SpvExecutionModeQuads: + case SpvExecutionModeIsolines: return true; default: return false; @@ -189,10 +187,10 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (execution_modes && 1 < std::count_if(execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::VertexOrderCw: - case spv::ExecutionMode::VertexOrderCcw: + case SpvExecutionModeVertexOrderCw: + case SpvExecutionModeVertexOrderCcw: return true; default: return false; @@ -204,22 +202,21 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "modes."; } break; - case spv::ExecutionModel::Geometry: + case SpvExecutionModelGeometry: if (!execution_modes || - 1 != std::count_if( - execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { - switch (mode) { - case spv::ExecutionMode::InputPoints: - case spv::ExecutionMode::InputLines: - case spv::ExecutionMode::InputLinesAdjacency: - case spv::ExecutionMode::Triangles: - case spv::ExecutionMode::InputTrianglesAdjacency: - return true; - default: - return false; - } - })) { + 1 != std::count_if(execution_modes->begin(), execution_modes->end(), + [](const SpvExecutionMode& mode) { + switch (mode) { + case SpvExecutionModeInputPoints: + case SpvExecutionModeInputLines: + case SpvExecutionModeInputLinesAdjacency: + case SpvExecutionModeTriangles: + case SpvExecutionModeInputTrianglesAdjacency: + return true; + default: + return false; + } + })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Geometry execution model entry points must specify " "exactly one of InputPoints, InputLines, " @@ -228,11 +225,11 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { } if (!execution_modes || 1 != std::count_if(execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::OutputPoints: - case spv::ExecutionMode::OutputLineStrip: - case spv::ExecutionMode::OutputTriangleStrip: + case SpvExecutionModeOutputPoints: + case SpvExecutionModeOutputLineStrip: + case SpvExecutionModeOutputTriangleStrip: return true; default: return false; @@ -244,14 +241,14 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "OutputTriangleStrip execution modes."; } break; - case spv::ExecutionModel::MeshEXT: + case SpvExecutionModelMeshEXT: if (!execution_modes || 1 != std::count_if(execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::OutputPoints: - case spv::ExecutionMode::OutputLinesEXT: - case spv::ExecutionMode::OutputTrianglesEXT: + case SpvExecutionModeOutputPoints: + case SpvExecutionModeOutputLinesEXT: + case SpvExecutionModeOutputTrianglesEXT: return true; default: return false; @@ -263,10 +260,10 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { "OutputTrianglesEXT Execution Modes."; } else if (2 != std::count_if( execution_modes->begin(), execution_modes->end(), - [](const spv::ExecutionMode& mode) { + [](const SpvExecutionMode& mode) { switch (mode) { - case spv::ExecutionMode::OutputPrimitivesEXT: - case spv::ExecutionMode::OutputVertices: + case SpvExecutionModeOutputPrimitivesEXT: + case SpvExecutionModeOutputVertices: return true; default: return false; @@ -284,25 +281,23 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) { if (spvIsVulkanEnv(_.context()->target_env)) { switch (execution_model) { - case spv::ExecutionModel::GLCompute: + case SpvExecutionModelGLCompute: if (!execution_modes || - !execution_modes->count(spv::ExecutionMode::LocalSize)) { + !execution_modes->count(SpvExecutionModeLocalSize)) { bool ok = false; for (auto& i : _.ordered_instructions()) { - if (i.opcode() == spv::Op::OpDecorate) { + if (i.opcode() == SpvOpDecorate) { if (i.operands().size() > 2) { - if (i.GetOperandAs(1) == - spv::Decoration::BuiltIn && - i.GetOperandAs(2) == - spv::BuiltIn::WorkgroupSize) { + if (i.GetOperandAs(1) == SpvDecorationBuiltIn && + i.GetOperandAs(2) == SpvBuiltInWorkgroupSize) { ok = true; break; } } } - if (i.opcode() == spv::Op::OpExecutionModeId) { - const auto mode = i.GetOperandAs(1); - if (mode == spv::ExecutionMode::LocalSizeId) { + if (i.opcode() == SpvOpExecutionModeId) { + const auto mode = i.GetOperandAs(1); + if (mode == SpvExecutionModeLocalSizeId) { ok = true; break; } @@ -338,15 +333,15 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "operand of an OpEntryPoint."; } - const auto mode = inst->GetOperandAs(1); - if (inst->opcode() == spv::Op::OpExecutionModeId) { + const auto mode = inst->GetOperandAs(1); + if (inst->opcode() == SpvOpExecutionModeId) { size_t operand_count = inst->operands().size(); for (size_t i = 2; i < operand_count; ++i) { const auto operand_id = inst->GetOperandAs(2); const auto* operand_inst = _.FindDef(operand_id); - if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || - mode == spv::ExecutionMode::LocalSizeHintId || - mode == spv::ExecutionMode::LocalSizeId) { + if (mode == SpvExecutionModeSubgroupsPerWorkgroupId || + mode == SpvExecutionModeLocalSizeHintId || + mode == SpvExecutionModeLocalSizeId) { if (!spvOpcodeIsConstant(operand_inst->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "For OpExecutionModeId all Extra Operand ids must be " @@ -360,9 +355,9 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "operands."; } } - } else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId || - mode == spv::ExecutionMode::LocalSizeHintId || - mode == spv::ExecutionMode::LocalSizeId) { + } else if (mode == SpvExecutionModeSubgroupsPerWorkgroupId || + mode == SpvExecutionModeLocalSizeHintId || + mode == SpvExecutionModeLocalSizeId) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "OpExecutionMode is only valid when the Mode operand is an " "execution mode that takes no Extra Operands, or takes Extra " @@ -371,39 +366,39 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, const auto* models = _.GetExecutionModels(entry_point_id); switch (mode) { - case spv::ExecutionMode::Invocations: - case spv::ExecutionMode::InputPoints: - case spv::ExecutionMode::InputLines: - case spv::ExecutionMode::InputLinesAdjacency: - case spv::ExecutionMode::InputTrianglesAdjacency: - case spv::ExecutionMode::OutputLineStrip: - case spv::ExecutionMode::OutputTriangleStrip: + case SpvExecutionModeInvocations: + case SpvExecutionModeInputPoints: + case SpvExecutionModeInputLines: + case SpvExecutionModeInputLinesAdjacency: + case SpvExecutionModeInputTrianglesAdjacency: + case SpvExecutionModeOutputLineStrip: + case SpvExecutionModeOutputTriangleStrip: if (!std::all_of(models->begin(), models->end(), - [](const spv::ExecutionModel& model) { - return model == spv::ExecutionModel::Geometry; + [](const SpvExecutionModel& model) { + return model == SpvExecutionModelGeometry; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Geometry execution " "model."; } break; - case spv::ExecutionMode::OutputPoints: - if (!std::all_of( - models->begin(), models->end(), - [&_](const spv::ExecutionModel& model) { - switch (model) { - case spv::ExecutionModel::Geometry: - return true; - case spv::ExecutionModel::MeshNV: - return _.HasCapability(spv::Capability::MeshShadingNV); - case spv::ExecutionModel::MeshEXT: - return _.HasCapability(spv::Capability::MeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(spv::Capability::MeshShadingNV) || - _.HasCapability(spv::Capability::MeshShadingEXT)) { + case SpvExecutionModeOutputPoints: + if (!std::all_of(models->begin(), models->end(), + [&_](const SpvExecutionModel& model) { + switch (model) { + case SpvExecutionModelGeometry: + return true; + case SpvExecutionModelMeshNV: + return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Geometry " "MeshNV or MeshEXT execution model."; @@ -415,32 +410,32 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } } break; - case spv::ExecutionMode::SpacingEqual: - case spv::ExecutionMode::SpacingFractionalEven: - case spv::ExecutionMode::SpacingFractionalOdd: - case spv::ExecutionMode::VertexOrderCw: - case spv::ExecutionMode::VertexOrderCcw: - case spv::ExecutionMode::PointMode: - case spv::ExecutionMode::Quads: - case spv::ExecutionMode::Isolines: + case SpvExecutionModeSpacingEqual: + case SpvExecutionModeSpacingFractionalEven: + case SpvExecutionModeSpacingFractionalOdd: + case SpvExecutionModeVertexOrderCw: + case SpvExecutionModeVertexOrderCcw: + case SpvExecutionModePointMode: + case SpvExecutionModeQuads: + case SpvExecutionModeIsolines: if (!std::all_of( models->begin(), models->end(), - [](const spv::ExecutionModel& model) { - return (model == spv::ExecutionModel::TessellationControl) || - (model == spv::ExecutionModel::TessellationEvaluation); + [](const SpvExecutionModel& model) { + return (model == SpvExecutionModelTessellationControl) || + (model == SpvExecutionModelTessellationEvaluation); })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a tessellation " "execution model."; } break; - case spv::ExecutionMode::Triangles: + case SpvExecutionModeTriangles: if (!std::all_of(models->begin(), models->end(), - [](const spv::ExecutionModel& model) { + [](const SpvExecutionModel& model) { switch (model) { - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: + case SpvExecutionModelGeometry: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: return true; default: return false; @@ -451,25 +446,25 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "tessellation execution model."; } break; - case spv::ExecutionMode::OutputVertices: - if (!std::all_of( - models->begin(), models->end(), - [&_](const spv::ExecutionModel& model) { - switch (model) { - case spv::ExecutionModel::Geometry: - case spv::ExecutionModel::TessellationControl: - case spv::ExecutionModel::TessellationEvaluation: - return true; - case spv::ExecutionModel::MeshNV: - return _.HasCapability(spv::Capability::MeshShadingNV); - case spv::ExecutionModel::MeshEXT: - return _.HasCapability(spv::Capability::MeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(spv::Capability::MeshShadingNV) || - _.HasCapability(spv::Capability::MeshShadingEXT)) { + case SpvExecutionModeOutputVertices: + if (!std::all_of(models->begin(), models->end(), + [&_](const SpvExecutionModel& model) { + switch (model) { + case SpvExecutionModelGeometry: + case SpvExecutionModelTessellationControl: + case SpvExecutionModelTessellationEvaluation: + return true; + case SpvExecutionModelMeshNV: + return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Geometry, " "tessellation, MeshNV or MeshEXT execution model."; @@ -480,13 +475,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } } break; - case spv::ExecutionMode::OutputLinesEXT: - case spv::ExecutionMode::OutputTrianglesEXT: - case spv::ExecutionMode::OutputPrimitivesEXT: + case SpvExecutionModeOutputLinesEXT: + case SpvExecutionModeOutputTrianglesEXT: + case SpvExecutionModeOutputPrimitivesEXT: if (!std::all_of(models->begin(), models->end(), - [](const spv::ExecutionModel& model) { - return (model == spv::ExecutionModel::MeshEXT || - model == spv::ExecutionModel::MeshNV); + [](const SpvExecutionModel& model) { + return (model == SpvExecutionModelMeshEXT || + model == SpvExecutionModelMeshNV); })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the MeshEXT or MeshNV " @@ -494,77 +489,74 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, "model."; } break; - case spv::ExecutionMode::PixelCenterInteger: - case spv::ExecutionMode::OriginUpperLeft: - case spv::ExecutionMode::OriginLowerLeft: - case spv::ExecutionMode::EarlyFragmentTests: - case spv::ExecutionMode::DepthReplacing: - case spv::ExecutionMode::DepthGreater: - case spv::ExecutionMode::DepthLess: - case spv::ExecutionMode::DepthUnchanged: - case spv::ExecutionMode::NonCoherentColorAttachmentReadEXT: - case spv::ExecutionMode::NonCoherentDepthAttachmentReadEXT: - case spv::ExecutionMode::NonCoherentStencilAttachmentReadEXT: - case spv::ExecutionMode::PixelInterlockOrderedEXT: - case spv::ExecutionMode::PixelInterlockUnorderedEXT: - case spv::ExecutionMode::SampleInterlockOrderedEXT: - case spv::ExecutionMode::SampleInterlockUnorderedEXT: - case spv::ExecutionMode::ShadingRateInterlockOrderedEXT: - case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT: - case spv::ExecutionMode::EarlyAndLateFragmentTestsAMD: - case spv::ExecutionMode::StencilRefUnchangedFrontAMD: - case spv::ExecutionMode::StencilRefGreaterFrontAMD: - case spv::ExecutionMode::StencilRefLessFrontAMD: - case spv::ExecutionMode::StencilRefUnchangedBackAMD: - case spv::ExecutionMode::StencilRefGreaterBackAMD: - case spv::ExecutionMode::StencilRefLessBackAMD: + case SpvExecutionModePixelCenterInteger: + case SpvExecutionModeOriginUpperLeft: + case SpvExecutionModeOriginLowerLeft: + case SpvExecutionModeEarlyFragmentTests: + case SpvExecutionModeDepthReplacing: + case SpvExecutionModeDepthGreater: + case SpvExecutionModeDepthLess: + case SpvExecutionModeDepthUnchanged: + case SpvExecutionModePixelInterlockOrderedEXT: + case SpvExecutionModePixelInterlockUnorderedEXT: + case SpvExecutionModeSampleInterlockOrderedEXT: + case SpvExecutionModeSampleInterlockUnorderedEXT: + case SpvExecutionModeShadingRateInterlockOrderedEXT: + case SpvExecutionModeShadingRateInterlockUnorderedEXT: + case SpvExecutionModeEarlyAndLateFragmentTestsAMD: + case SpvExecutionModeStencilRefUnchangedFrontAMD: + case SpvExecutionModeStencilRefGreaterFrontAMD: + case SpvExecutionModeStencilRefLessFrontAMD: + case SpvExecutionModeStencilRefUnchangedBackAMD: + case SpvExecutionModeStencilRefGreaterBackAMD: + case SpvExecutionModeStencilRefLessBackAMD: if (!std::all_of(models->begin(), models->end(), - [](const spv::ExecutionModel& model) { - return model == spv::ExecutionModel::Fragment; + [](const SpvExecutionModel& model) { + return model == SpvExecutionModelFragment; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Fragment execution " "model."; } break; - case spv::ExecutionMode::LocalSizeHint: - case spv::ExecutionMode::VecTypeHint: - case spv::ExecutionMode::ContractionOff: - case spv::ExecutionMode::LocalSizeHintId: + case SpvExecutionModeLocalSizeHint: + case SpvExecutionModeVecTypeHint: + case SpvExecutionModeContractionOff: + case SpvExecutionModeLocalSizeHintId: if (!std::all_of(models->begin(), models->end(), - [](const spv::ExecutionModel& model) { - return model == spv::ExecutionModel::Kernel; + [](const SpvExecutionModel& model) { + return model == SpvExecutionModelKernel; })) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with the Kernel execution " "model."; } break; - case spv::ExecutionMode::LocalSize: - case spv::ExecutionMode::LocalSizeId: - if (mode == spv::ExecutionMode::LocalSizeId && !_.IsLocalSizeIdAllowed()) + case SpvExecutionModeLocalSize: + case SpvExecutionModeLocalSizeId: + if (mode == SpvExecutionModeLocalSizeId && !_.IsLocalSizeIdAllowed()) return _.diag(SPV_ERROR_INVALID_DATA, inst) << "LocalSizeId mode is not allowed by the current environment."; - if (!std::all_of( - models->begin(), models->end(), - [&_](const spv::ExecutionModel& model) { - switch (model) { - case spv::ExecutionModel::Kernel: - case spv::ExecutionModel::GLCompute: - return true; - case spv::ExecutionModel::TaskNV: - case spv::ExecutionModel::MeshNV: - return _.HasCapability(spv::Capability::MeshShadingNV); - case spv::ExecutionModel::TaskEXT: - case spv::ExecutionModel::MeshEXT: - return _.HasCapability(spv::Capability::MeshShadingEXT); - default: - return false; - } - })) { - if (_.HasCapability(spv::Capability::MeshShadingNV) || - _.HasCapability(spv::Capability::MeshShadingEXT)) { + if (!std::all_of(models->begin(), models->end(), + [&_](const SpvExecutionModel& model) { + switch (model) { + case SpvExecutionModelKernel: + case SpvExecutionModelGLCompute: + return true; + case SpvExecutionModelTaskNV: + case SpvExecutionModelMeshNV: + return _.HasCapability(SpvCapabilityMeshShadingNV); + case SpvExecutionModelTaskEXT: + case SpvExecutionModelMeshEXT: + return _.HasCapability( + SpvCapabilityMeshShadingEXT); + default: + return false; + } + })) { + if (_.HasCapability(SpvCapabilityMeshShadingNV) || + _.HasCapability(SpvCapabilityMeshShadingEXT)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Execution mode can only be used with a Kernel, GLCompute, " "MeshNV, MeshEXT, TaskNV or TaskEXT execution model."; @@ -580,13 +572,13 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } if (spvIsVulkanEnv(_.context()->target_env)) { - if (mode == spv::ExecutionMode::OriginLowerLeft) { + if (mode == SpvExecutionModeOriginLowerLeft) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4653) << "In the Vulkan environment, the OriginLowerLeft execution mode " "must not be used."; } - if (mode == spv::ExecutionMode::PixelCenterInteger) { + if (mode == SpvExecutionModePixelCenterInteger) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4654) << "In the Vulkan environment, the PixelCenterInteger execution " @@ -601,30 +593,29 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, const Instruction* inst) { // Already produced an error if multiple memory model instructions are // present. - if (_.memory_model() != spv::MemoryModel::VulkanKHR && - _.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (_.memory_model() != SpvMemoryModelVulkanKHR && + _.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "VulkanMemoryModelKHR capability must only be specified if " "the VulkanKHR memory model is used."; } if (spvIsOpenCLEnv(_.context()->target_env)) { - if ((_.addressing_model() != spv::AddressingModel::Physical32) && - (_.addressing_model() != spv::AddressingModel::Physical64)) { + if ((_.addressing_model() != SpvAddressingModelPhysical32) && + (_.addressing_model() != SpvAddressingModelPhysical64)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Addressing model must be Physical32 or Physical64 " << "in the OpenCL environment."; } - if (_.memory_model() != spv::MemoryModel::OpenCL) { + if (_.memory_model() != SpvMemoryModelOpenCL) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Memory model must be OpenCL in the OpenCL environment."; } } if (spvIsVulkanEnv(_.context()->target_env)) { - if ((_.addressing_model() != spv::AddressingModel::Logical) && - (_.addressing_model() != - spv::AddressingModel::PhysicalStorageBuffer64)) { + if ((_.addressing_model() != SpvAddressingModelLogical) && + (_.addressing_model() != SpvAddressingModelPhysicalStorageBuffer64)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4635) << "Addressing model must be Logical or PhysicalStorageBuffer64 " @@ -638,14 +629,14 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpEntryPoint: + case SpvOpEntryPoint: if (auto error = ValidateEntryPoint(_, inst)) return error; break; - case spv::Op::OpExecutionMode: - case spv::Op::OpExecutionModeId: + case SpvOpExecutionMode: + case SpvOpExecutionModeId: if (auto error = ValidateExecutionMode(_, inst)) return error; break; - case spv::Op::OpMemoryModel: + case SpvOpMemoryModel: if (auto error = ValidateMemoryModel(_, inst)) return error; break; default: diff --git a/source/val/validate_non_uniform.cpp b/source/val/validate_non_uniform.cpp index 2c36ce33..6d4f8a28 100644 --- a/source/val/validate_non_uniform.cpp +++ b/source/val/validate_non_uniform.cpp @@ -14,11 +14,14 @@ // Validates correctness of barrier SPIR-V instructions. +#include "source/val/validate.h" + +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" +#include "source/util/bitutils.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validate_scopes.h" #include "source/val/validation_state.h" @@ -26,207 +29,6 @@ namespace spvtools { namespace val { namespace { -spv_result_t ValidateGroupNonUniformElect(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsBoolScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar type"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformAnyAll(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsBoolScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar type"; - } - - if (!_.IsBoolScalarType(_.GetOperandTypeId(inst, 3))) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Predicate must be a boolean scalar type"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformAllEqual(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsBoolScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar type"; - } - - const auto value_type = _.GetOperandTypeId(inst, 3); - if (!_.IsFloatScalarOrVectorType(value_type) && - !_.IsIntScalarOrVectorType(value_type) && - !_.IsBoolScalarOrVectorType(value_type)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a scalar or vector of integer, floating-point, or " - "boolean type"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformBroadcastShuffle(ValidationState_t& _, - const Instruction* inst) { - const auto type_id = inst->type_id(); - if (!_.IsFloatScalarOrVectorType(type_id) && - !_.IsIntScalarOrVectorType(type_id) && - !_.IsBoolScalarOrVectorType(type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a scalar or vector of integer, floating-point, " - "or boolean type"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 3); - if (value_type_id != type_id) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "The type of Value must match the Result type"; - } - - const auto GetOperandName = [](const spv::Op opcode) { - std::string operand; - switch (opcode) { - case spv::Op::OpGroupNonUniformBroadcast: - case spv::Op::OpGroupNonUniformShuffle: - operand = "Id"; - break; - case spv::Op::OpGroupNonUniformShuffleXor: - operand = "Mask"; - break; - case spv::Op::OpGroupNonUniformQuadBroadcast: - operand = "Index"; - break; - case spv::Op::OpGroupNonUniformQuadSwap: - operand = "Direction"; - break; - case spv::Op::OpGroupNonUniformShuffleUp: - case spv::Op::OpGroupNonUniformShuffleDown: - default: - operand = "Delta"; - break; - } - return operand; - }; - - const auto id_type_id = _.GetOperandTypeId(inst, 4); - if (!_.IsUnsignedIntScalarType(id_type_id)) { - std::string operand = GetOperandName(inst->opcode()); - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << operand << " must be an unsigned integer scalar"; - } - - const bool should_be_constant = - inst->opcode() == spv::Op::OpGroupNonUniformQuadSwap || - ((inst->opcode() == spv::Op::OpGroupNonUniformBroadcast || - inst->opcode() == spv::Op::OpGroupNonUniformQuadBroadcast) && - _.version() < SPV_SPIRV_VERSION_WORD(1, 5)); - if (should_be_constant) { - const auto id_id = inst->GetOperandAs(4); - const auto id_op = _.GetIdOpcode(id_id); - if (!spvOpcodeIsConstant(id_op)) { - std::string operand = GetOperandName(inst->opcode()); - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Before SPIR-V 1.5, " << operand - << " must be a constant instruction"; - } - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformBroadcastFirst(ValidationState_t& _, - const Instruction* inst) { - const auto type_id = inst->type_id(); - if (!_.IsFloatScalarOrVectorType(type_id) && - !_.IsIntScalarOrVectorType(type_id) && - !_.IsBoolScalarOrVectorType(type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a scalar or vector of integer, floating-point, " - "or boolean type"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 3); - if (value_type_id != type_id) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "The type of Value must match the Result type"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformBallot(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsUnsignedIntVectorType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a 4-component unsigned integer vector"; - } - - if (_.GetDimension(inst->type_id()) != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a 4-component unsigned integer vector"; - } - - const auto pred_type_id = _.GetOperandTypeId(inst, 3); - if (!_.IsBoolScalarType(pred_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Predicate must be a boolean scalar"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformInverseBallot(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsBoolScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 3); - if (!_.IsUnsignedIntVectorType(value_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - if (_.GetDimension(value_type_id) != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformBallotBitExtract(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsBoolScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 3); - if (!_.IsUnsignedIntVectorType(value_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - if (_.GetDimension(value_type_id) != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - const auto id_type_id = _.GetOperandTypeId(inst, 4); - if (!_.IsUnsignedIntScalarType(id_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Id must be an unsigned integer scalar"; - } - - return SPV_SUCCESS; -} - spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, const Instruction* inst) { // Scope is already checked by ValidateExecutionScope() above. @@ -246,11 +48,11 @@ spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, "of integer type scalar"; } - const auto group = inst->GetOperandAs(3); + const auto group = inst->GetOperandAs(3); if (spvIsVulkanEnv(_.context()->target_env)) { - if ((group != spv::GroupOperation::Reduce) && - (group != spv::GroupOperation::InclusiveScan) && - (group != spv::GroupOperation::ExclusiveScan)) { + if ((group != SpvGroupOperationReduce) && + (group != SpvGroupOperationInclusiveScan) && + (group != SpvGroupOperationExclusiveScan)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4685) << "In Vulkan: The OpGroupNonUniformBallotBitCount group " @@ -261,107 +63,6 @@ spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateGroupNonUniformBallotFind(ValidationState_t& _, - const Instruction* inst) { - if (!_.IsUnsignedIntScalarType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be an unsigned integer scalar"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 3); - if (!_.IsUnsignedIntVectorType(value_type_id)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - if (_.GetDimension(value_type_id) != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Value must be a 4-component unsigned integer vector"; - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateGroupNonUniformArithmetic(ValidationState_t& _, - const Instruction* inst) { - const bool is_unsigned = inst->opcode() == spv::Op::OpGroupNonUniformUMin || - inst->opcode() == spv::Op::OpGroupNonUniformUMax; - const bool is_float = inst->opcode() == spv::Op::OpGroupNonUniformFAdd || - inst->opcode() == spv::Op::OpGroupNonUniformFMul || - inst->opcode() == spv::Op::OpGroupNonUniformFMin || - inst->opcode() == spv::Op::OpGroupNonUniformFMax; - const bool is_bool = inst->opcode() == spv::Op::OpGroupNonUniformLogicalAnd || - inst->opcode() == spv::Op::OpGroupNonUniformLogicalOr || - inst->opcode() == spv::Op::OpGroupNonUniformLogicalXor; - if (is_float) { - if (!_.IsFloatScalarOrVectorType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a floating-point scalar or vector"; - } - } else if (is_bool) { - if (!_.IsBoolScalarOrVectorType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be a boolean scalar or vector"; - } - } else if (is_unsigned) { - if (!_.IsUnsignedIntScalarOrVectorType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be an unsigned integer scalar or vector"; - } - } else if (!_.IsIntScalarOrVectorType(inst->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Result must be an integer scalar or vector"; - } - - const auto value_type_id = _.GetOperandTypeId(inst, 4); - if (value_type_id != inst->type_id()) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "The type of Value must match the Result type"; - } - - const auto group_op = inst->GetOperandAs(3); - bool is_clustered_reduce = group_op == spv::GroupOperation::ClusteredReduce; - bool is_partitioned_nv = - group_op == spv::GroupOperation::PartitionedReduceNV || - group_op == spv::GroupOperation::PartitionedInclusiveScanNV || - group_op == spv::GroupOperation::PartitionedExclusiveScanNV; - if (inst->operands().size() <= 5) { - if (is_clustered_reduce) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "ClusterSize must be present when Operation is ClusteredReduce"; - } else if (is_partitioned_nv) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ballot must be present when Operation is PartitionedReduceNV, " - "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV"; - } - } else { - const auto operand_id = inst->GetOperandAs(5); - const auto* operand = _.FindDef(operand_id); - if (is_partitioned_nv) { - if (!operand || !_.IsIntScalarOrVectorType(operand->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ballot must be a 4-component integer vector"; - } - - if (_.GetDimension(operand->type_id()) != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ballot must be a 4-component integer vector"; - } - } else { - if (!operand || !_.IsUnsignedIntScalarType(operand->type_id())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "ClusterSize must be an unsigned integer scalar"; - } - - if (!spvOpcodeIsConstant(operand->opcode())) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "ClusterSize must be a constant instruction"; - } - } - } - return SPV_SUCCESS; -} - spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, const Instruction* inst) { // Scope is already checked by ValidateExecutionScope() above. @@ -419,62 +120,19 @@ spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _, // Validates correctness of non-uniform group instructions. spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); if (spvOpcodeIsNonUniformGroupOperation(opcode)) { - const uint32_t execution_scope = inst->GetOperandAs(2); + const uint32_t execution_scope = inst->word(3); if (auto error = ValidateExecutionScope(_, inst, execution_scope)) { return error; } } switch (opcode) { - case spv::Op::OpGroupNonUniformElect: - return ValidateGroupNonUniformElect(_, inst); - case spv::Op::OpGroupNonUniformAny: - case spv::Op::OpGroupNonUniformAll: - return ValidateGroupNonUniformAnyAll(_, inst); - case spv::Op::OpGroupNonUniformAllEqual: - return ValidateGroupNonUniformAllEqual(_, inst); - case spv::Op::OpGroupNonUniformBroadcast: - case spv::Op::OpGroupNonUniformShuffle: - case spv::Op::OpGroupNonUniformShuffleXor: - case spv::Op::OpGroupNonUniformShuffleUp: - case spv::Op::OpGroupNonUniformShuffleDown: - case spv::Op::OpGroupNonUniformQuadBroadcast: - case spv::Op::OpGroupNonUniformQuadSwap: - return ValidateGroupNonUniformBroadcastShuffle(_, inst); - case spv::Op::OpGroupNonUniformBroadcastFirst: - return ValidateGroupNonUniformBroadcastFirst(_, inst); - case spv::Op::OpGroupNonUniformBallot: - return ValidateGroupNonUniformBallot(_, inst); - case spv::Op::OpGroupNonUniformInverseBallot: - return ValidateGroupNonUniformInverseBallot(_, inst); - case spv::Op::OpGroupNonUniformBallotBitExtract: - return ValidateGroupNonUniformBallotBitExtract(_, inst); - case spv::Op::OpGroupNonUniformBallotBitCount: + case SpvOpGroupNonUniformBallotBitCount: return ValidateGroupNonUniformBallotBitCount(_, inst); - case spv::Op::OpGroupNonUniformBallotFindLSB: - case spv::Op::OpGroupNonUniformBallotFindMSB: - return ValidateGroupNonUniformBallotFind(_, inst); - case spv::Op::OpGroupNonUniformIAdd: - case spv::Op::OpGroupNonUniformFAdd: - case spv::Op::OpGroupNonUniformIMul: - case spv::Op::OpGroupNonUniformFMul: - case spv::Op::OpGroupNonUniformSMin: - case spv::Op::OpGroupNonUniformUMin: - case spv::Op::OpGroupNonUniformFMin: - case spv::Op::OpGroupNonUniformSMax: - case spv::Op::OpGroupNonUniformUMax: - case spv::Op::OpGroupNonUniformFMax: - case spv::Op::OpGroupNonUniformBitwiseAnd: - case spv::Op::OpGroupNonUniformBitwiseOr: - case spv::Op::OpGroupNonUniformBitwiseXor: - case spv::Op::OpGroupNonUniformLogicalAnd: - case spv::Op::OpGroupNonUniformLogicalOr: - case spv::Op::OpGroupNonUniformLogicalXor: - return ValidateGroupNonUniformArithmetic(_, inst); - case spv::Op::OpGroupNonUniformRotateKHR: + case SpvOpGroupNonUniformRotateKHR: return ValidateGroupNonUniformRotateKHR(_, inst); default: break; diff --git a/source/val/validate_primitives.cpp b/source/val/validate_primitives.cpp index 6769090d..7d11f2e7 100644 --- a/source/val/validate_primitives.cpp +++ b/source/val/validate_primitives.cpp @@ -14,11 +14,13 @@ // Validates correctness of primitive SPIR-V instructions. +#include "source/val/validate.h" + #include +#include "source/diagnostic.h" #include "source/opcode.h" #include "source/val/instruction.h" -#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -26,16 +28,16 @@ namespace val { // Validates correctness of primitive instructions. spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); switch (opcode) { - case spv::Op::OpEmitVertex: - case spv::Op::OpEndPrimitive: - case spv::Op::OpEmitStreamVertex: - case spv::Op::OpEndStreamPrimitive: + case SpvOpEmitVertex: + case SpvOpEndPrimitive: + case SpvOpEmitStreamVertex: + case SpvOpEndStreamPrimitive: _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - spv::ExecutionModel::Geometry, + SpvExecutionModelGeometry, std::string(spvOpcodeString(opcode)) + " instructions require Geometry execution model"); break; @@ -44,8 +46,8 @@ spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { } switch (opcode) { - case spv::Op::OpEmitStreamVertex: - case spv::Op::OpEndStreamPrimitive: { + case SpvOpEmitStreamVertex: + case SpvOpEndStreamPrimitive: { const uint32_t stream_id = inst->word(1); const uint32_t stream_type = _.GetTypeId(stream_id); if (!_.IsIntScalarType(stream_type)) { @@ -54,7 +56,7 @@ spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) { << ": expected Stream to be int scalar"; } - const spv::Op stream_opcode = _.GetIdOpcode(stream_id); + const SpvOp stream_opcode = _.GetIdOpcode(stream_id); if (!spvOpcodeIsConstant(stream_opcode)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) diff --git a/source/val/validate_ray_query.cpp b/source/val/validate_ray_query.cpp index 9b67fc92..b553449d 100644 --- a/source/val/validate_ray_query.cpp +++ b/source/val/validate_ray_query.cpp @@ -29,19 +29,19 @@ spv_result_t ValidateRayQueryPointer(ValidationState_t& _, const uint32_t ray_query_id = inst->GetOperandAs(ray_query_index); auto variable = _.FindDef(ray_query_id); const auto var_opcode = variable->opcode(); - if (!variable || (var_opcode != spv::Op::OpVariable && - var_opcode != spv::Op::OpFunctionParameter && - var_opcode != spv::Op::OpAccessChain)) { + if (!variable || + (var_opcode != SpvOpVariable && var_opcode != SpvOpFunctionParameter && + var_opcode != SpvOpAccessChain)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a memory object declaration"; } auto pointer = _.FindDef(variable->GetOperandAs(0)); - if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { + if (!pointer || pointer->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a pointer"; } auto type = _.FindDef(pointer->GetOperandAs(2)); - if (!type || type->opcode() != spv::Op::OpTypeRayQueryKHR) { + if (!type || type->opcode() != SpvOpTypeRayQueryKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Ray Query must be a pointer to OpTypeRayQueryKHR"; } @@ -54,7 +54,7 @@ spv_result_t ValidateIntersectionId(ValidationState_t& _, const uint32_t intersection_id = inst->GetOperandAs(intersection_index); const uint32_t intersection_type = _.GetTypeId(intersection_id); - const spv::Op intersection_opcode = _.GetIdOpcode(intersection_id); + const SpvOp intersection_opcode = _.GetIdOpcode(intersection_id); if (!_.IsIntScalarType(intersection_type) || _.GetBitWidth(intersection_type) != 32 || !spvOpcodeIsConstant(intersection_opcode)) { @@ -68,15 +68,15 @@ spv_result_t ValidateIntersectionId(ValidationState_t& _, } // namespace spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpRayQueryInitializeKHR: { + case SpvOpRayQueryInitializeKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; if (_.GetIdOpcode(_.GetOperandTypeId(inst, 1)) != - spv::Op::OpTypeAccelerationStructureKHR) { + SpvOpTypeAccelerationStructureKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Acceleration Structure to be of type " "OpTypeAccelerationStructureKHR"; @@ -123,13 +123,13 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpRayQueryTerminateKHR: - case spv::Op::OpRayQueryConfirmIntersectionKHR: { + case SpvOpRayQueryTerminateKHR: + case SpvOpRayQueryConfirmIntersectionKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; break; } - case spv::Op::OpRayQueryGenerateIntersectionKHR: { + case SpvOpRayQueryGenerateIntersectionKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error; const uint32_t hit_t_id = _.GetOperandTypeId(inst, 1); @@ -141,9 +141,9 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpRayQueryGetIntersectionFrontFaceKHR: - case spv::Op::OpRayQueryProceedKHR: - case spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: { + case SpvOpRayQueryGetIntersectionFrontFaceKHR: + case SpvOpRayQueryProceedKHR: + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsBoolScalarType(result_type)) { @@ -151,15 +151,15 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be bool scalar type"; } - if (opcode == spv::Op::OpRayQueryGetIntersectionFrontFaceKHR) { + if (opcode == SpvOpRayQueryGetIntersectionFrontFaceKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case spv::Op::OpRayQueryGetIntersectionTKHR: - case spv::Op::OpRayQueryGetRayTMinKHR: { + case SpvOpRayQueryGetIntersectionTKHR: + case SpvOpRayQueryGetRayTMinKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsFloatScalarType(result_type) || @@ -168,21 +168,20 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be 32-bit float scalar type"; } - if (opcode == spv::Op::OpRayQueryGetIntersectionTKHR) { + if (opcode == SpvOpRayQueryGetIntersectionTKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case spv::Op::OpRayQueryGetIntersectionTypeKHR: - case spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: - case spv::Op::OpRayQueryGetIntersectionInstanceIdKHR: - case spv::Op:: - OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: - case spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR: - case spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: - case spv::Op::OpRayQueryGetRayFlagsKHR: { + case SpvOpRayQueryGetIntersectionTypeKHR: + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: + case SpvOpRayQueryGetIntersectionInstanceIdKHR: + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: + case SpvOpRayQueryGetRayFlagsKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32) { @@ -190,17 +189,17 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { << "expected Result Type to be 32-bit int scalar type"; } - if (opcode != spv::Op::OpRayQueryGetRayFlagsKHR) { + if (opcode != SpvOpRayQueryGetRayFlagsKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: - case spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR: - case spv::Op::OpRayQueryGetWorldRayDirectionKHR: - case spv::Op::OpRayQueryGetWorldRayOriginKHR: { + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: + case SpvOpRayQueryGetWorldRayDirectionKHR: + case SpvOpRayQueryGetWorldRayOriginKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (!_.IsFloatVectorType(result_type) || @@ -211,15 +210,15 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { "vector type"; } - if (opcode == spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR || - opcode == spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR) { + if (opcode == SpvOpRayQueryGetIntersectionObjectRayDirectionKHR || + opcode == SpvOpRayQueryGetIntersectionObjectRayOriginKHR) { if (auto error = ValidateIntersectionId(_, inst, 3)) return error; } break; } - case spv::Op::OpRayQueryGetIntersectionBarycentricsKHR: { + case SpvOpRayQueryGetIntersectionBarycentricsKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (auto error = ValidateIntersectionId(_, inst, 3)) return error; @@ -234,8 +233,8 @@ spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR: - case spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR: { + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: { if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error; if (auto error = ValidateIntersectionId(_, inst, 3)) return error; diff --git a/source/val/validate_ray_tracing.cpp b/source/val/validate_ray_tracing.cpp index f74e9d4b..5b5c8da1 100644 --- a/source/val/validate_ray_tracing.cpp +++ b/source/val/validate_ray_tracing.cpp @@ -23,17 +23,17 @@ namespace spvtools { namespace val { spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); const uint32_t result_type = inst->type_id(); switch (opcode) { - case spv::Op::OpTraceRayKHR: { + case SpvOpTraceRayKHR: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelMissKHR) { if (message) { *message = "OpTraceRayKHR requires RayGenerationKHR, " @@ -45,7 +45,7 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { }); if (_.GetIdOpcode(_.GetOperandTypeId(inst, 0)) != - spv::Op::OpTypeAccelerationStructureKHR) { + SpvOpTypeAccelerationStructureKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Acceleration Structure to be of type " "OpTypeAccelerationStructureKHR"; @@ -109,13 +109,13 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { } const Instruction* payload = _.FindDef(inst->GetOperandAs(10)); - if (payload->opcode() != spv::Op::OpVariable) { + if (payload->opcode() != SpvOpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must be the result of a OpVariable"; - } else if (payload->GetOperandAs(2) != - spv::StorageClass::RayPayloadKHR && - payload->GetOperandAs(2) != - spv::StorageClass::IncomingRayPayloadKHR) { + } else if (payload->GetOperandAs(2) != + SpvStorageClassRayPayloadKHR && + payload->GetOperandAs(2) != + SpvStorageClassIncomingRayPayloadKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Payload must have storage class RayPayloadKHR or " "IncomingRayPayloadKHR"; @@ -123,11 +123,11 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpReportIntersectionKHR: { + case SpvOpReportIntersectionKHR: { _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::IntersectionKHR) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelIntersectionKHR) { if (message) { *message = "OpReportIntersectionKHR requires IntersectionKHR " @@ -158,14 +158,14 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { break; } - case spv::Op::OpExecuteCallableKHR: { + case SpvOpExecuteCallableKHR: { _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, + ->RegisterExecutionModelLimitation([](SpvExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR && - model != spv::ExecutionModel::CallableKHR) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelMissKHR && + model != SpvExecutionModelCallableKHR) { if (message) { *message = "OpExecuteCallableKHR requires RayGenerationKHR, " @@ -184,13 +184,13 @@ spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) { } const auto callable_data = _.FindDef(inst->GetOperandAs(1)); - if (callable_data->opcode() != spv::Op::OpVariable) { + if (callable_data->opcode() != SpvOpVariable) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Callable Data must be the result of a OpVariable"; - } else if (callable_data->GetOperandAs(2) != - spv::StorageClass::CallableDataKHR && - callable_data->GetOperandAs(2) != - spv::StorageClass::IncomingCallableDataKHR) { + } else if (callable_data->GetOperandAs(2) != + SpvStorageClassCallableDataKHR && + callable_data->GetOperandAs(2) != + SpvStorageClassIncomingCallableDataKHR) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Callable Data must have storage class CallableDataKHR or " "IncomingCallableDataKHR"; diff --git a/source/val/validate_ray_tracing_reorder.cpp b/source/val/validate_ray_tracing_reorder.cpp deleted file mode 100755 index cb190f91..00000000 --- a/source/val/validate_ray_tracing_reorder.cpp +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// -// 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. - -// Validates ray tracing instructions from SPV_NV_shader_execution_reorder - -#include "source/opcode.h" -#include "source/val/instruction.h" -#include "source/val/validate.h" -#include "source/val/validation_state.h" - -#include - -namespace spvtools { -namespace val { - -static const uint32_t KRayParamInvalidId = std::numeric_limits::max(); - -spv_result_t ValidateHitObjectPointer(ValidationState_t& _, - const Instruction* inst, - uint32_t hit_object_index) { - const uint32_t hit_object_id = inst->GetOperandAs(hit_object_index); - auto variable = _.FindDef(hit_object_id); - const auto var_opcode = variable->opcode(); - if (!variable || (var_opcode != spv::Op::OpVariable && - var_opcode != spv::Op::OpFunctionParameter && - var_opcode != spv::Op::OpAccessChain)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Object must be a memory object declaration"; - } - auto pointer = _.FindDef(variable->GetOperandAs(0)); - if (!pointer || pointer->opcode() != spv::Op::OpTypePointer) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Object must be a pointer"; - } - auto type = _.FindDef(pointer->GetOperandAs(2)); - if (!type || type->opcode() != spv::Op::OpTypeHitObjectNV) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Type must be OpTypeHitObjectNV"; - } - return SPV_SUCCESS; -} - -spv_result_t ValidateHitObjectInstructionCommonParameters( - ValidationState_t& _, const Instruction* inst, - uint32_t acceleration_struct_index, uint32_t instance_id_index, - uint32_t primtive_id_index, uint32_t geometry_index, - uint32_t ray_flags_index, uint32_t cull_mask_index, uint32_t hit_kind_index, - uint32_t sbt_index, uint32_t sbt_offset_index, uint32_t sbt_stride_index, - uint32_t sbt_record_offset_index, uint32_t sbt_record_stride_index, - uint32_t miss_index, uint32_t ray_origin_index, uint32_t ray_tmin_index, - uint32_t ray_direction_index, uint32_t ray_tmax_index, - uint32_t payload_index, uint32_t hit_object_attr_index) { - auto isValidId = [](uint32_t spvid) { return spvid < KRayParamInvalidId; }; - if (isValidId(acceleration_struct_index) && - _.GetIdOpcode(_.GetOperandTypeId(inst, acceleration_struct_index)) != - spv::Op::OpTypeAccelerationStructureKHR) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Acceleration Structure to be of type " - "OpTypeAccelerationStructureKHR"; - } - - if (isValidId(instance_id_index)) { - const uint32_t instance_id = _.GetOperandTypeId(inst, instance_id_index); - if (!_.IsIntScalarType(instance_id) || _.GetBitWidth(instance_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Instance Id must be a 32-bit int scalar"; - } - } - - if (isValidId(primtive_id_index)) { - const uint32_t primitive_id = _.GetOperandTypeId(inst, primtive_id_index); - if (!_.IsIntScalarType(primitive_id) || _.GetBitWidth(primitive_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Primitive Id must be a 32-bit int scalar"; - } - } - - if (isValidId(geometry_index)) { - const uint32_t geometry_index_id = _.GetOperandTypeId(inst, geometry_index); - if (!_.IsIntScalarType(geometry_index_id) || - _.GetBitWidth(geometry_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Geometry Index must be a 32-bit int scalar"; - } - } - - if (isValidId(miss_index)) { - const uint32_t miss_index_id = _.GetOperandTypeId(inst, miss_index); - if (!_.IsUnsignedIntScalarType(miss_index_id) || - _.GetBitWidth(miss_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Miss Index must be a 32-bit int scalar"; - } - } - - if (isValidId(cull_mask_index)) { - const uint32_t cull_mask_id = _.GetOperandTypeId(inst, cull_mask_index); - if (!_.IsUnsignedIntScalarType(cull_mask_id) || - _.GetBitWidth(cull_mask_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Cull mask must be a 32-bit int scalar"; - } - } - - if (isValidId(sbt_index)) { - const uint32_t sbt_index_id = _.GetOperandTypeId(inst, sbt_index); - if (!_.IsUnsignedIntScalarType(sbt_index_id) || - _.GetBitWidth(sbt_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "SBT Index must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(sbt_offset_index)) { - const uint32_t sbt_offset_id = _.GetOperandTypeId(inst, sbt_offset_index); - if (!_.IsUnsignedIntScalarType(sbt_offset_id) || - _.GetBitWidth(sbt_offset_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "SBT Offset must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(sbt_stride_index)) { - const uint32_t sbt_stride_index_id = - _.GetOperandTypeId(inst, sbt_stride_index); - if (!_.IsUnsignedIntScalarType(sbt_stride_index_id) || - _.GetBitWidth(sbt_stride_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "SBT Stride must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(sbt_record_offset_index)) { - const uint32_t sbt_record_offset_index_id = - _.GetOperandTypeId(inst, sbt_record_offset_index); - if (!_.IsUnsignedIntScalarType(sbt_record_offset_index_id) || - _.GetBitWidth(sbt_record_offset_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "SBT record offset must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(sbt_record_stride_index)) { - const uint32_t sbt_record_stride_index_id = - _.GetOperandTypeId(inst, sbt_record_stride_index); - if (!_.IsUnsignedIntScalarType(sbt_record_stride_index_id) || - _.GetBitWidth(sbt_record_stride_index_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "SBT record stride must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(ray_origin_index)) { - const uint32_t ray_origin_id = _.GetOperandTypeId(inst, ray_origin_index); - if (!_.IsFloatVectorType(ray_origin_id) || - _.GetDimension(ray_origin_id) != 3 || - _.GetBitWidth(ray_origin_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray Origin must be a 32-bit float 3-component vector"; - } - } - - if (isValidId(ray_tmin_index)) { - const uint32_t ray_tmin_id = _.GetOperandTypeId(inst, ray_tmin_index); - if (!_.IsFloatScalarType(ray_tmin_id) || _.GetBitWidth(ray_tmin_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray TMin must be a 32-bit float scalar"; - } - } - - if (isValidId(ray_direction_index)) { - const uint32_t ray_direction_id = - _.GetOperandTypeId(inst, ray_direction_index); - if (!_.IsFloatVectorType(ray_direction_id) || - _.GetDimension(ray_direction_id) != 3 || - _.GetBitWidth(ray_direction_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray Direction must be a 32-bit float 3-component vector"; - } - } - - if (isValidId(ray_tmax_index)) { - const uint32_t ray_tmax_id = _.GetOperandTypeId(inst, ray_tmax_index); - if (!_.IsFloatScalarType(ray_tmax_id) || _.GetBitWidth(ray_tmax_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray TMax must be a 32-bit float scalar"; - } - } - - if (isValidId(ray_flags_index)) { - const uint32_t ray_flags_id = _.GetOperandTypeId(inst, ray_flags_index); - if (!_.IsIntScalarType(ray_flags_id) || _.GetBitWidth(ray_flags_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray Flags must be a 32-bit int scalar"; - } - } - - if (isValidId(payload_index)) { - const uint32_t payload_id = inst->GetOperandAs(payload_index); - auto variable = _.FindDef(payload_id); - const auto var_opcode = variable->opcode(); - if (!variable || var_opcode != spv::Op::OpVariable || - (variable->GetOperandAs(2) != - spv::StorageClass::RayPayloadKHR && - variable->GetOperandAs(2) != - spv::StorageClass::IncomingRayPayloadKHR)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "payload must be a OpVariable of storage " - "class RayPayloadKHR or IncomingRayPayloadKHR"; - } - } - - if (isValidId(hit_kind_index)) { - const uint32_t hit_kind_id = _.GetOperandTypeId(inst, hit_kind_index); - if (!_.IsUnsignedIntScalarType(hit_kind_id) || - _.GetBitWidth(hit_kind_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Kind must be a 32-bit unsigned int scalar"; - } - } - - if (isValidId(hit_object_attr_index)) { - const uint32_t hit_object_attr_id = - inst->GetOperandAs(hit_object_attr_index); - auto variable = _.FindDef(hit_object_attr_id); - const auto var_opcode = variable->opcode(); - if (!variable || var_opcode != spv::Op::OpVariable || - (variable->GetOperandAs(2)) != - spv::StorageClass::HitObjectAttributeNV) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Object Attributes id must be a OpVariable of storage " - "class HitObjectAttributeNV"; - } - } - - return SPV_SUCCESS; -} - -spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) { - const spv::Op opcode = inst->opcode(); - const uint32_t result_type = inst->type_id(); - - auto RegisterOpcodeForValidModel = [](ValidationState_t& vs, - const Instruction* rtinst) { - std::string opcode_name = spvOpcodeString(rtinst->opcode()); - vs.function(rtinst->function()->id()) - ->RegisterExecutionModelLimitation( - [opcode_name](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR) { - if (message) { - *message = opcode_name + - " requires RayGenerationKHR, ClosestHitKHR and " - "MissKHR execution models"; - } - return false; - } - return true; - }); - return; - }; - - switch (opcode) { - case spv::Op::OpHitObjectIsMissNV: - case spv::Op::OpHitObjectIsHitNV: - case spv::Op::OpHitObjectIsEmptyNV: { - RegisterOpcodeForValidModel(_, inst); - if (!_.IsBoolScalarType(result_type)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "expected Result Type to be bool scalar type"; - } - - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - break; - } - - case spv::Op::OpHitObjectGetShaderRecordBufferHandleNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - - if (!_.IsIntVectorType(result_type) || - (_.GetDimension(result_type) != 2) || - (_.GetBitWidth(result_type) != 32)) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected 32-bit integer type 2-component vector as Result " - "Type: " - << spvOpcodeString(opcode); - break; - } - - case spv::Op::OpHitObjectGetHitKindNV: - case spv::Op::OpHitObjectGetPrimitiveIndexNV: - case spv::Op::OpHitObjectGetGeometryIndexNV: - case spv::Op::OpHitObjectGetInstanceIdNV: - case spv::Op::OpHitObjectGetInstanceCustomIndexNV: - case spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - - if (!_.IsIntScalarType(result_type) || !_.GetBitWidth(result_type)) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected 32-bit integer type scalar as Result Type: " - << spvOpcodeString(opcode); - break; - } - - case spv::Op::OpHitObjectGetCurrentTimeNV: - case spv::Op::OpHitObjectGetRayTMaxNV: - case spv::Op::OpHitObjectGetRayTMinNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - - if (!_.IsFloatScalarType(result_type) || _.GetBitWidth(result_type) != 32) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected 32-bit floating-point type scalar as Result Type: " - << spvOpcodeString(opcode); - break; - } - - case spv::Op::OpHitObjectGetObjectToWorldNV: - case spv::Op::OpHitObjectGetWorldToObjectNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - - uint32_t num_rows = 0; - uint32_t num_cols = 0; - uint32_t col_type = 0; - uint32_t component_type = 0; - - if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type, - &component_type)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "expected matrix type as Result Type: " - << spvOpcodeString(opcode); - } - - if (num_cols != 4) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "expected Result Type matrix to have a Column Count of 4" - << spvOpcodeString(opcode); - } - - if (!_.IsFloatScalarType(component_type) || - _.GetBitWidth(result_type) != 32 || num_rows != 3) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "expected Result Type matrix to have a Column Type of " - "3-component 32-bit float vectors: " - << spvOpcodeString(opcode); - } - break; - } - - case spv::Op::OpHitObjectGetObjectRayOriginNV: - case spv::Op::OpHitObjectGetObjectRayDirectionNV: - case spv::Op::OpHitObjectGetWorldRayDirectionNV: - case spv::Op::OpHitObjectGetWorldRayOriginNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error; - - if (!_.IsFloatVectorType(result_type) || - (_.GetDimension(result_type) != 3) || - (_.GetBitWidth(result_type) != 32)) - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected 32-bit floating-point type 3-component vector as " - "Result Type: " - << spvOpcodeString(opcode); - break; - } - - case spv::Op::OpHitObjectGetAttributesNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - const uint32_t hit_object_attr_id = inst->GetOperandAs(1); - auto variable = _.FindDef(hit_object_attr_id); - const auto var_opcode = variable->opcode(); - if (!variable || var_opcode != spv::Op::OpVariable || - variable->GetOperandAs(2) != - spv::StorageClass::HitObjectAttributeNV) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Object Attributes id must be a OpVariable of storage " - "class HitObjectAttributeNV"; - } - break; - } - - case spv::Op::OpHitObjectExecuteShaderNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - const uint32_t hit_object_attr_id = inst->GetOperandAs(1); - auto variable = _.FindDef(hit_object_attr_id); - const auto var_opcode = variable->opcode(); - if (!variable || var_opcode != spv::Op::OpVariable || - (variable->GetOperandAs(2)) != - spv::StorageClass::RayPayloadKHR) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hit Object Attributes id must be a OpVariable of storage " - "class RayPayloadKHR"; - } - break; - } - - case spv::Op::OpHitObjectRecordEmptyNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - break; - } - - case spv::Op::OpHitObjectRecordMissNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - const uint32_t miss_index = _.GetOperandTypeId(inst, 1); - if (!_.IsUnsignedIntScalarType(miss_index) || - _.GetBitWidth(miss_index) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Miss Index must be a 32-bit int scalar"; - } - - const uint32_t ray_origin = _.GetOperandTypeId(inst, 2); - if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 || - _.GetBitWidth(ray_origin) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray Origin must be a 32-bit float 3-component vector"; - } - - const uint32_t ray_tmin = _.GetOperandTypeId(inst, 3); - if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray TMin must be a 32-bit float scalar"; - } - - const uint32_t ray_direction = _.GetOperandTypeId(inst, 4); - if (!_.IsFloatVectorType(ray_direction) || - _.GetDimension(ray_direction) != 3 || - _.GetBitWidth(ray_direction) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray Direction must be a 32-bit float 3-component vector"; - } - - const uint32_t ray_tmax = _.GetOperandTypeId(inst, 5); - if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Ray TMax must be a 32-bit float scalar"; - } - break; - } - - case spv::Op::OpHitObjectRecordHitWithIndexNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - if (auto error = ValidateHitObjectInstructionCommonParameters( - _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, - 3 /* Primtive Id */, 4 /* Geometry Index */, - KRayParamInvalidId /* Ray Flags */, - KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, - 6 /* SBT index */, KRayParamInvalidId /* SBT Offset */, - KRayParamInvalidId /* SBT Stride */, - KRayParamInvalidId /* SBT Record Offset */, - KRayParamInvalidId /* SBT Record Stride */, - KRayParamInvalidId /* Miss Index */, 7 /* Ray Origin */, - 8 /* Ray TMin */, 9 /* Ray Direction */, 10 /* Ray TMax */, - KRayParamInvalidId /* Payload */, 11 /* Hit Object Attribute */)) - return error; - - break; - } - - case spv::Op::OpHitObjectRecordHitNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - if (auto error = ValidateHitObjectInstructionCommonParameters( - _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */, - 3 /* Primtive Id */, 4 /* Geometry Index */, - KRayParamInvalidId /* Ray Flags */, - KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/, - KRayParamInvalidId /* SBT index */, - KRayParamInvalidId /* SBT Offset */, - KRayParamInvalidId /* SBT Stride */, 6 /* SBT Record Offset */, - 7 /* SBT Record Stride */, KRayParamInvalidId /* Miss Index */, - 8 /* Ray Origin */, 9 /* Ray TMin */, 10 /* Ray Direction */, - 11 /* Ray TMax */, KRayParamInvalidId /* Payload */, - 12 /* Hit Object Attribute */)) - return error; - - break; - } - - case spv::Op::OpHitObjectTraceRayMotionNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - if (auto error = ValidateHitObjectInstructionCommonParameters( - _, inst, 1 /* Acceleration Struct */, - KRayParamInvalidId /* Instance Id */, - KRayParamInvalidId /* Primtive Id */, - KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, - 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, - KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, - 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, - KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, - 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, - 10 /* Ray TMax */, 12 /* Payload */, - KRayParamInvalidId /* Hit Object Attribute */)) - return error; - // Current Time - const uint32_t current_time_id = _.GetOperandTypeId(inst, 11); - if (!_.IsFloatScalarType(current_time_id) || - _.GetBitWidth(current_time_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Current Times must be a 32-bit float scalar type"; - } - - break; - } - - case spv::Op::OpHitObjectTraceRayNV: { - RegisterOpcodeForValidModel(_, inst); - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - if (auto error = ValidateHitObjectInstructionCommonParameters( - _, inst, 1 /* Acceleration Struct */, - KRayParamInvalidId /* Instance Id */, - KRayParamInvalidId /* Primtive Id */, - KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */, - 3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/, - KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */, - 5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */, - KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */, - 7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */, - 10 /* Ray TMax */, 11 /* Payload */, - KRayParamInvalidId /* Hit Object Attribute */)) - return error; - break; - } - - case spv::Op::OpReorderThreadWithHitObjectNV: { - std::string opcode_name = spvOpcodeString(inst->opcode()); - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - [opcode_name](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR) { - if (message) { - *message = opcode_name + - " requires RayGenerationKHR execution model"; - } - return false; - } - return true; - }); - - if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error; - - if (inst->operands().size() > 1) { - if (inst->operands().size() != 3) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hint and Bits are optional together i.e " - << " Either both Hint and Bits should be provided or neither."; - } - - // Validate the optional opreands Hint and Bits - const uint32_t hint_id = _.GetOperandTypeId(inst, 1); - if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hint must be a 32-bit int scalar"; - } - const uint32_t bits_id = _.GetOperandTypeId(inst, 2); - if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "bits must be a 32-bit int scalar"; - } - } - break; - } - - case spv::Op::OpReorderThreadWithHintNV: { - std::string opcode_name = spvOpcodeString(inst->opcode()); - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - [opcode_name](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR) { - if (message) { - *message = opcode_name + - " requires RayGenerationKHR execution model"; - } - return false; - } - return true; - }); - - const uint32_t hint_id = _.GetOperandTypeId(inst, 0); - if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Hint must be a 32-bit int scalar"; - } - - const uint32_t bits_id = _.GetOperandTypeId(inst, 1); - if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "bits must be a 32-bit int scalar"; - } - } - - default: - break; - } - return SPV_SUCCESS; -} -} // namespace val -} // namespace spvtools diff --git a/source/val/validate_scopes.cpp b/source/val/validate_scopes.cpp index 40c49d1f..e9781802 100644 --- a/source/val/validate_scopes.cpp +++ b/source/val/validate_scopes.cpp @@ -14,6 +14,7 @@ #include "source/val/validate_scopes.h" +#include "source/diagnostic.h" #include "source/spirv_target_env.h" #include "source/val/instruction.h" #include "source/val/validation_state.h" @@ -24,16 +25,16 @@ namespace val { bool IsValidScope(uint32_t scope) { // Deliberately avoid a default case so we have to update the list when the // scopes list changes. - switch (static_cast(scope)) { - case spv::Scope::CrossDevice: - case spv::Scope::Device: - case spv::Scope::Workgroup: - case spv::Scope::Subgroup: - case spv::Scope::Invocation: - case spv::Scope::QueueFamilyKHR: - case spv::Scope::ShaderCallKHR: + switch (static_cast(scope)) { + case SpvScopeCrossDevice: + case SpvScopeDevice: + case SpvScopeWorkgroup: + case SpvScopeSubgroup: + case SpvScopeInvocation: + case SpvScopeQueueFamilyKHR: + case SpvScopeShaderCallKHR: return true; - case spv::Scope::Max: + case SpvScopeMax: break; } return false; @@ -41,7 +42,7 @@ bool IsValidScope(uint32_t scope) { spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); @@ -52,14 +53,14 @@ spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, } if (!is_const_int32) { - if (_.HasCapability(spv::Capability::Shader) && - !_.HasCapability(spv::Capability::CooperativeMatrixNV)) { + if (_.HasCapability(SpvCapabilityShader) && + !_.HasCapability(SpvCapabilityCooperativeMatrixNV)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Scope ids must be OpConstant when Shader capability is " << "present"; } - if (_.HasCapability(spv::Capability::Shader) && - _.HasCapability(spv::Capability::CooperativeMatrixNV) && + if (_.HasCapability(SpvCapabilityShader) && + _.HasCapability(SpvCapabilityCooperativeMatrixNV) && !spvOpcodeIsConstant(_.GetIdOpcode(scope))) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Scope ids must be constant or specialization constant when " @@ -77,10 +78,10 @@ spv_result_t ValidateScope(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateExecutionScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - spv::Op opcode = inst->opcode(); + SpvOp opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; - uint32_t tmp_value = 0; - std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); + uint32_t value = 0; + std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); if (auto error = ValidateScope(_, inst, scope)) { return error; @@ -90,15 +91,13 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, return SPV_SUCCESS; } - spv::Scope value = spv::Scope(tmp_value); - // Vulkan specific rules if (spvIsVulkanEnv(_.context()->target_env)) { // Vulkan 1.1 specific rules if (_.context()->target_env != SPV_ENV_VULKAN_1_0) { // Scope for Non Uniform Group Operations must be limited to Subgroup if (spvOpcodeIsNonUniformGroupOperation(opcode) && - value != spv::Scope::Subgroup) { + value != SpvScopeSubgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4642) << spvOpcodeString(opcode) << ": in Vulkan environment Execution scope is limited to " @@ -108,21 +107,21 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // OpControlBarrier must only use Subgroup execution scope for a subset of // execution models. - if (opcode == spv::Op::OpControlBarrier && value != spv::Scope::Subgroup) { + if (opcode == SpvOpControlBarrier && value != SpvScopeSubgroup) { std::string errorVUID = _.VkErrorID(4682); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - spv::ExecutionModel model, + SpvExecutionModel model, std::string* message) { - if (model == spv::ExecutionModel::Fragment || - model == spv::ExecutionModel::Vertex || - model == spv::ExecutionModel::Geometry || - model == spv::ExecutionModel::TessellationEvaluation || - model == spv::ExecutionModel::RayGenerationKHR || - model == spv::ExecutionModel::IntersectionKHR || - model == spv::ExecutionModel::AnyHitKHR || - model == spv::ExecutionModel::ClosestHitKHR || - model == spv::ExecutionModel::MissKHR) { + if (model == SpvExecutionModelFragment || + model == SpvExecutionModelVertex || + model == SpvExecutionModelGeometry || + model == SpvExecutionModelTessellationEvaluation || + model == SpvExecutionModelRayGenerationKHR || + model == SpvExecutionModelIntersectionKHR || + model == SpvExecutionModelAnyHitKHR || + model == SpvExecutionModelClosestHitKHR || + model == SpvExecutionModelMissKHR) { if (message) { *message = errorVUID + @@ -138,17 +137,17 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, } // Only subset of execution models support Workgroup. - if (value == spv::Scope::Workgroup) { + if (value == SpvScopeWorkgroup) { std::string errorVUID = _.VkErrorID(4637); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::TaskNV && - model != spv::ExecutionModel::MeshNV && - model != spv::ExecutionModel::TaskEXT && - model != spv::ExecutionModel::MeshEXT && - model != spv::ExecutionModel::TessellationControl && - model != spv::ExecutionModel::GLCompute) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelTaskNV && + model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT && + model != SpvExecutionModelTessellationControl && + model != SpvExecutionModelGLCompute) { if (message) { *message = errorVUID + @@ -164,7 +163,7 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // Vulkan generic rules // Scope for execution must be limited to Workgroup or Subgroup - if (value != spv::Scope::Workgroup && value != spv::Scope::Subgroup) { + if (value != SpvScopeWorkgroup && value != SpvScopeSubgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4636) << spvOpcodeString(opcode) << ": in Vulkan environment Execution Scope is limited to " @@ -178,7 +177,7 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, // Scope for execution must be limited to Workgroup or Subgroup for // non-uniform operations if (spvOpcodeIsNonUniformGroupOperation(opcode) && - value != spv::Scope::Subgroup && value != spv::Scope::Workgroup) { + value != SpvScopeSubgroup && value != SpvScopeWorkgroup) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << spvOpcodeString(opcode) << ": Execution scope is limited to Subgroup or Workgroup"; @@ -189,10 +188,10 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, uint32_t scope) { - const spv::Op opcode = inst->opcode(); + const SpvOp opcode = inst->opcode(); bool is_int32 = false, is_const_int32 = false; - uint32_t tmp_value = 0; - std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope); + uint32_t value = 0; + std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); if (auto error = ValidateScope(_, inst, scope)) { return error; @@ -202,10 +201,8 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, return SPV_SUCCESS; } - spv::Scope value = spv::Scope(tmp_value); - - if (value == spv::Scope::QueueFamilyKHR) { - if (_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) { + if (value == SpvScopeQueueFamilyKHR) { + if (_.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) { return SPV_SUCCESS; } else { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -215,9 +212,9 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, } } - if (value == spv::Scope::Device && - _.HasCapability(spv::Capability::VulkanMemoryModelKHR) && - !_.HasCapability(spv::Capability::VulkanMemoryModelDeviceScopeKHR)) { + if (value == SpvScopeDevice && + _.HasCapability(SpvCapabilityVulkanMemoryModelKHR) && + !_.HasCapability(SpvCapabilityVulkanMemoryModelDeviceScopeKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Use of device scope with VulkanKHR memory model requires the " << "VulkanMemoryModelDeviceScopeKHR capability"; @@ -225,37 +222,36 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, // Vulkan Specific rules if (spvIsVulkanEnv(_.context()->target_env)) { - if (value != spv::Scope::Device && value != spv::Scope::Workgroup && - value != spv::Scope::Subgroup && value != spv::Scope::Invocation && - value != spv::Scope::ShaderCallKHR && - value != spv::Scope::QueueFamily) { + if (value != SpvScopeDevice && value != SpvScopeWorkgroup && + value != SpvScopeSubgroup && value != SpvScopeInvocation && + value != SpvScopeShaderCallKHR && value != SpvScopeQueueFamily) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << _.VkErrorID(4638) << spvOpcodeString(opcode) << ": in Vulkan environment Memory Scope is limited to Device, " "QueueFamily, Workgroup, ShaderCallKHR, Subgroup, or " "Invocation"; } else if (_.context()->target_env == SPV_ENV_VULKAN_1_0 && - value == spv::Scope::Subgroup && - !_.HasCapability(spv::Capability::SubgroupBallotKHR) && - !_.HasCapability(spv::Capability::SubgroupVoteKHR)) { + value == SpvScopeSubgroup && + !_.HasCapability(SpvCapabilitySubgroupBallotKHR) && + !_.HasCapability(SpvCapabilitySubgroupVoteKHR)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(7951) << spvOpcodeString(opcode) + << _.VkErrorID(6997) << spvOpcodeString(opcode) << ": in Vulkan 1.0 environment Memory Scope is can not be " "Subgroup without SubgroupBallotKHR or SubgroupVoteKHR " "declared"; } - if (value == spv::Scope::ShaderCallKHR) { + if (value == SpvScopeShaderCallKHR) { std::string errorVUID = _.VkErrorID(4640); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::IntersectionKHR && - model != spv::ExecutionModel::AnyHitKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR && - model != spv::ExecutionModel::CallableKHR) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelIntersectionKHR && + model != SpvExecutionModelAnyHitKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelMissKHR && + model != SpvExecutionModelCallableKHR) { if (message) { *message = errorVUID + @@ -268,17 +264,17 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, }); } - if (value == spv::Scope::Workgroup) { + if (value == SpvScopeWorkgroup) { std::string errorVUID = _.VkErrorID(7321); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::GLCompute && - model != spv::ExecutionModel::TessellationControl && - model != spv::ExecutionModel::TaskNV && - model != spv::ExecutionModel::MeshNV && - model != spv::ExecutionModel::TaskEXT && - model != spv::ExecutionModel::MeshEXT) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelGLCompute && + model != SpvExecutionModelTessellationControl && + model != SpvExecutionModelTaskNV && + model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT) { if (message) { *message = errorVUID + "Workgroup Memory Scope is limited to MeshNV, " @@ -290,12 +286,12 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, return true; }); - if (_.memory_model() == spv::MemoryModel::GLSL450) { + if (_.memory_model() == SpvMemoryModelGLSL450) { errorVUID = _.VkErrorID(7320); _.function(inst->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model == spv::ExecutionModel::TessellationControl) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model == SpvExecutionModelTessellationControl) { if (message) { *message = errorVUID + diff --git a/source/val/validate_small_type_uses.cpp b/source/val/validate_small_type_uses.cpp index 69f61ee4..9db82e7c 100644 --- a/source/val/validate_small_type_uses.cpp +++ b/source/val/validate_small_type_uses.cpp @@ -22,7 +22,7 @@ namespace val { spv_result_t ValidateSmallTypeUses(ValidationState_t& _, const Instruction* inst) { - if (!_.HasCapability(spv::Capability::Shader) || inst->type_id() == 0 || + if (!_.HasCapability(SpvCapabilityShader) || inst->type_id() == 0 || !_.ContainsLimitedUseIntOrFloatType(inst->type_id())) { return SPV_SUCCESS; } @@ -36,13 +36,13 @@ spv_result_t ValidateSmallTypeUses(ValidationState_t& _, for (auto use : inst->uses()) { const auto* user = use.first; switch (user->opcode()) { - case spv::Op::OpDecorate: - case spv::Op::OpDecorateId: - case spv::Op::OpCopyObject: - case spv::Op::OpStore: - case spv::Op::OpFConvert: - case spv::Op::OpUConvert: - case spv::Op::OpSConvert: + case SpvOpDecorate: + case SpvOpDecorateId: + case SpvOpCopyObject: + case SpvOpStore: + case SpvOpFConvert: + case SpvOpUConvert: + case SpvOpSConvert: break; default: return _.diag(SPV_ERROR_INVALID_ID, user) diff --git a/source/val/validate_type.cpp b/source/val/validate_type.cpp index 7edd12ff..6b0881cf 100644 --- a/source/val/validate_type.cpp +++ b/source/val/validate_type.cpp @@ -19,6 +19,7 @@ #include "source/val/instruction.h" #include "source/val/validate.h" #include "source/val/validation_state.h" +#include "spirv/unified1/spirv.h" namespace spvtools { namespace val { @@ -49,8 +50,8 @@ spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) { return SPV_SUCCESS; const auto opcode = inst->opcode(); - if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray && - opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer && + if (opcode != SpvOpTypeArray && opcode != SpvOpTypeRuntimeArray && + opcode != SpvOpTypeStruct && opcode != SpvOpTypePointer && !_.RegisterUniqueTypeDeclaration(inst)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Duplicate non-aggregate type declarations are not allowed. " @@ -83,7 +84,7 @@ spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) { << "Using a 16-bit integer type requires the Int16 capability," " or an extension that explicitly enables 16-bit integers."; } else if (num_bits == 64) { - if (_.HasCapability(spv::Capability::Int64)) { + if (_.HasCapability(SpvCapabilityInt64)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -104,8 +105,7 @@ spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) { // SPIR-V Spec 2.16.3: Validation Rules for Kernel Capabilities: The // Signedness in OpTypeInt must always be 0. - if (spv::Op::OpTypeInt == inst->opcode() && - _.HasCapability(spv::Capability::Kernel) && + if (SpvOpTypeInt == inst->opcode() && _.HasCapability(SpvCapabilityKernel) && inst->GetOperandAs(2) != 0u) { return _.diag(SPV_ERROR_INVALID_BINARY, inst) << "The Signedness in OpTypeInt " @@ -135,7 +135,7 @@ spv_result_t ValidateTypeFloat(ValidationState_t& _, const Instruction* inst) { " or an extension that explicitly enables 16-bit floating point."; } if (num_bits == 64) { - if (_.HasCapability(spv::Capability::Float64)) { + if (_.HasCapability(SpvCapabilityFloat64)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -163,7 +163,7 @@ spv_result_t ValidateTypeVector(ValidationState_t& _, const Instruction* inst) { if (num_components == 2 || num_components == 3 || num_components == 4) { return SPV_SUCCESS; } else if (num_components == 8 || num_components == 16) { - if (_.HasCapability(spv::Capability::Vector16)) { + if (_.HasCapability(SpvCapabilityVector16)) { return SPV_SUCCESS; } return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -183,7 +183,7 @@ spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) { const auto column_type_index = 1; const auto column_type_id = inst->GetOperandAs(column_type_index); const auto column_type = _.FindDef(column_type_id); - if (!column_type || spv::Op::OpTypeVector != column_type->opcode()) { + if (!column_type || SpvOpTypeVector != column_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Columns in a matrix must be of type vector."; } @@ -192,7 +192,7 @@ spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) { // Operand 1 is the of the type of data in the vector. const auto comp_type_id = column_type->GetOperandAs(1); auto comp_type_instruction = _.FindDef(comp_type_id); - if (comp_type_instruction->opcode() != spv::Op::OpTypeFloat) { + if (comp_type_instruction->opcode() != SpvOpTypeFloat) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be " "parameterized with " "floating-point types."; @@ -219,14 +219,14 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << " is not a type."; } - if (element_type->opcode() == spv::Op::OpTypeVoid) { + if (element_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Element Type " << _.getIdName(element_type_id) << " is a void type."; } if (spvIsVulkanEnv(_.context()->target_env) && - element_type->opcode() == spv::Op::OpTypeRuntimeArray) { + element_type->opcode() == SpvOpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpTypeArray Element Type " << _.getIdName(element_type_id) << " is not valid in " @@ -246,15 +246,15 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { const auto const_inst = length->words(); const auto const_result_type_index = 1; const auto const_result_type = _.FindDef(const_inst[const_result_type_index]); - if (!const_result_type || spv::Op::OpTypeInt != const_result_type->opcode()) { + if (!const_result_type || SpvOpTypeInt != const_result_type->opcode()) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Length " << _.getIdName(length_id) << " is not a constant integer type."; } switch (length->opcode()) { - case spv::Op::OpSpecConstant: - case spv::Op::OpConstant: { + case SpvOpSpecConstant: + case SpvOpConstant: { auto& type_words = const_result_type->words(); const bool is_signed = type_words[3] > 0; const uint32_t width = type_words[2]; @@ -265,11 +265,11 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << " default value must be at least 1: found " << ivalue; } } break; - case spv::Op::OpConstantNull: + case SpvOpConstantNull: return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Length " << _.getIdName(length_id) << " default value must be at least 1."; - case spv::Op::OpSpecConstantOp: + case SpvOpSpecConstantOp: // Assume it's OK, rather than try to evaluate the operation. break; default: @@ -289,14 +289,14 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _, << " is not a type."; } - if (element_type->opcode() == spv::Op::OpTypeVoid) { + if (element_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) << " is a void type."; } if (spvIsVulkanEnv(_.context()->target_env) && - element_type->opcode() == spv::Op::OpTypeRuntimeArray) { + element_type->opcode() == SpvOpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4680) << "OpTypeRuntimeArray Element Type " << _.getIdName(element_id) << " is not valid in " @@ -322,11 +322,11 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { << "OpTypeStruct Member Type " << _.getIdName(member_type_id) << " is not a type."; } - if (member_type->opcode() == spv::Op::OpTypeVoid) { + if (member_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Structures cannot contain a void type."; } - if (spv::Op::OpTypeStruct == member_type->opcode() && + if (SpvOpTypeStruct == member_type->opcode() && _.IsStructTypeWithBuiltInMember(member_type_id)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Structure " << _.getIdName(member_type_id) @@ -339,7 +339,7 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { } if (spvIsVulkanEnv(_.context()->target_env) && - member_type->opcode() == spv::Op::OpTypeRuntimeArray) { + member_type->opcode() == SpvOpTypeRuntimeArray) { const bool is_last_member = member_type_index == inst->operands().size() - 1; if (!is_last_member) { @@ -349,15 +349,6 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { << ", OpTypeRuntimeArray must only be used for the last member " "of an OpTypeStruct"; } - - if (!_.HasDecoration(inst->id(), spv::Decoration::Block) && - !_.HasDecoration(inst->id(), spv::Decoration::BufferBlock)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << _.VkErrorID(4680) - << spvLogStringForEnv(_.context()->target_env) - << ", OpTypeStruct containing an OpTypeRuntimeArray " - << "must be decorated with Block or BufferBlock."; - } } } @@ -366,10 +357,9 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) { auto member = inst->word(word_i); auto memberTypeInstr = _.FindDef(member); - if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) { - if (_.HasDecoration(memberTypeInstr->id(), spv::Decoration::Block) || - _.HasDecoration(memberTypeInstr->id(), - spv::Decoration::BufferBlock) || + if (memberTypeInstr && SpvOpTypeStruct == memberTypeInstr->opcode()) { + if (_.HasDecoration(memberTypeInstr->id(), SpvDecorationBlock) || + _.HasDecoration(memberTypeInstr->id(), SpvDecorationBufferBlock) || _.GetHasNestedBlockOrBufferBlockStruct(memberTypeInstr->id())) has_nested_blockOrBufferBlock_struct = true; } @@ -378,8 +368,8 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { _.SetHasNestedBlockOrBufferBlockStruct(inst->id(), has_nested_blockOrBufferBlock_struct); if (_.GetHasNestedBlockOrBufferBlockStruct(inst->id()) && - (_.HasDecoration(inst->id(), spv::Decoration::BufferBlock) || - _.HasDecoration(inst->id(), spv::Decoration::Block))) { + (_.HasDecoration(inst->id(), SpvDecorationBufferBlock) || + _.HasDecoration(inst->id(), SpvDecorationBlock))) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "rules: A Block or BufferBlock cannot be nested within another " "Block or BufferBlock. "; @@ -387,7 +377,7 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { std::unordered_set built_in_members; for (auto decoration : _.id_decorations(struct_id)) { - if (decoration.dec_type() == spv::Decoration::BuiltIn && + if (decoration.dec_type() == SpvDecorationBuiltIn && decoration.struct_member_index() != Decoration::kInvalidMember) { built_in_members.insert(decoration.struct_member_index()); } @@ -408,9 +398,9 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { const auto isOpaqueType = [&_](const Instruction* opaque_inst) { auto opcode = opaque_inst->opcode(); - if (_.HasCapability(spv::Capability::BindlessTextureNV) && - (opcode == spv::Op::OpTypeImage || opcode == spv::Op::OpTypeSampler || - opcode == spv::Op::OpTypeSampledImage)) { + if (_.HasCapability(SpvCapabilityBindlessTextureNV) && + (opcode == SpvOpTypeImage || opcode == SpvOpTypeSampler || + opcode == SpvOpTypeSampledImage)) { return false; } else if (spvOpcodeIsBaseOpaqueType(opcode)) { return true; @@ -440,15 +430,15 @@ spv_result_t ValidateTypePointer(ValidationState_t& _, << " is not a type."; } // See if this points to a storage image. - const auto storage_class = inst->GetOperandAs(1); - if (storage_class == spv::StorageClass::UniformConstant) { + const auto storage_class = inst->GetOperandAs(1); + if (storage_class == SpvStorageClassUniformConstant) { // Unpack an optional level of arraying. - if (type->opcode() == spv::Op::OpTypeArray || - type->opcode() == spv::Op::OpTypeRuntimeArray) { + if (type->opcode() == SpvOpTypeArray || + type->opcode() == SpvOpTypeRuntimeArray) { type_id = type->GetOperandAs(1); type = _.FindDef(type_id); } - if (type->opcode() == spv::Op::OpTypeImage) { + if (type->opcode() == SpvOpTypeImage) { const auto sampled = type->GetOperandAs(6); // 2 indicates this image is known to be be used without a sampler, i.e. // a storage image. @@ -485,7 +475,7 @@ spv_result_t ValidateTypeFunction(ValidationState_t& _, << " is not a type."; } - if (param_type->opcode() == spv::Op::OpTypeVoid) { + if (param_type->opcode() == SpvOpTypeVoid) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeFunction Parameter Type " << _.getIdName(param_id) << " cannot be OpTypeVoid."; @@ -505,9 +495,8 @@ spv_result_t ValidateTypeFunction(ValidationState_t& _, // decoration instruction. for (auto& pair : inst->uses()) { const auto* use = pair.first; - if (use->opcode() != spv::Op::OpFunction && - !spvOpcodeIsDebug(use->opcode()) && !use->IsNonSemantic() && - !spvOpcodeIsDecoration(use->opcode())) { + if (use->opcode() != SpvOpFunction && !spvOpcodeIsDebug(use->opcode()) && + !use->IsNonSemantic() && !spvOpcodeIsDecoration(use->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, use) << "Invalid use of function type result id " << _.getIdName(inst->id()) << "."; @@ -521,13 +510,13 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, const Instruction* inst) { const auto pointer_type_id = inst->GetOperandAs(0); const auto pointer_type_inst = _.FindDef(pointer_type_id); - if (pointer_type_inst->opcode() != spv::Op::OpTypePointer) { + if (pointer_type_inst->opcode() != SpvOpTypePointer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Pointer type in OpTypeForwardPointer is not a pointer type."; } - const auto storage_class = inst->GetOperandAs(1); - if (storage_class != pointer_type_inst->GetOperandAs(1)) { + const auto storage_class = inst->GetOperandAs(1); + if (storage_class != pointer_type_inst->GetOperandAs(1)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Storage class in OpTypeForwardPointer does not match the " << "pointer definition."; @@ -535,13 +524,13 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, const auto pointee_type_id = pointer_type_inst->GetOperandAs(2); const auto pointee_type = _.FindDef(pointee_type_id); - if (!pointee_type || pointee_type->opcode() != spv::Op::OpTypeStruct) { + if (!pointee_type || pointee_type->opcode() != SpvOpTypeStruct) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Forward pointers must point to a structure"; } if (spvIsVulkanEnv(_.context()->target_env)) { - if (storage_class != spv::StorageClass::PhysicalStorageBuffer) { + if (storage_class != SpvStorageClassPhysicalStorageBuffer) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4711) << "In Vulkan, OpTypeForwardPointer must have " @@ -552,16 +541,16 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _, return SPV_SUCCESS; } -spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, - const Instruction* inst) { +spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _, + const Instruction* inst) { const auto component_type_index = 1; const auto component_type_id = inst->GetOperandAs(component_type_index); const auto component_type = _.FindDef(component_type_id); - if (!component_type || (spv::Op::OpTypeFloat != component_type->opcode() && - spv::Op::OpTypeInt != component_type->opcode())) { + if (!component_type || (SpvOpTypeFloat != component_type->opcode() && + SpvOpTypeInt != component_type->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeCooperativeMatrix Component Type " + << "OpTypeCooperativeMatrixNV Component Type " << _.getIdName(component_type_id) << " is not a scalar numerical type."; } @@ -572,7 +561,7 @@ spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, if (!scope || !_.IsIntScalarType(scope->type_id()) || !spvOpcodeIsConstant(scope->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeCooperativeMatrix Scope " << _.getIdName(scope_id) + << "OpTypeCooperativeMatrixNV Scope " << _.getIdName(scope_id) << " is not a constant instruction with scalar integer type."; } @@ -582,7 +571,7 @@ spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, if (!rows || !_.IsIntScalarType(rows->type_id()) || !spvOpcodeIsConstant(rows->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeCooperativeMatrix Rows " << _.getIdName(rows_id) + << "OpTypeCooperativeMatrixNV Rows " << _.getIdName(rows_id) << " is not a constant instruction with scalar integer type."; } @@ -592,68 +581,55 @@ spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _, if (!cols || !_.IsIntScalarType(cols->type_id()) || !spvOpcodeIsConstant(cols->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeCooperativeMatrix Cols " << _.getIdName(cols_id) + << "OpTypeCooperativeMatrixNV Cols " << _.getIdName(cols_id) << " is not a constant instruction with scalar integer type."; } - if (inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) { - const auto use_index = 5; - const auto use_id = inst->GetOperandAs(use_index); - const auto use = _.FindDef(use_id); - if (!use || !_.IsIntScalarType(use->type_id()) || - !spvOpcodeIsConstant(use->opcode())) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeCooperativeMatrixKHR Use " << _.getIdName(use_id) - << " is not a constant instruction with scalar integer type."; - } - } - return SPV_SUCCESS; } } // namespace spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) { if (!spvOpcodeGeneratesType(inst->opcode()) && - inst->opcode() != spv::Op::OpTypeForwardPointer) { + inst->opcode() != SpvOpTypeForwardPointer) { return SPV_SUCCESS; } if (auto error = ValidateUniqueness(_, inst)) return error; switch (inst->opcode()) { - case spv::Op::OpTypeInt: + case SpvOpTypeInt: if (auto error = ValidateTypeInt(_, inst)) return error; break; - case spv::Op::OpTypeFloat: + case SpvOpTypeFloat: if (auto error = ValidateTypeFloat(_, inst)) return error; break; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: if (auto error = ValidateTypeVector(_, inst)) return error; break; - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: if (auto error = ValidateTypeMatrix(_, inst)) return error; break; - case spv::Op::OpTypeArray: + case SpvOpTypeArray: if (auto error = ValidateTypeArray(_, inst)) return error; break; - case spv::Op::OpTypeRuntimeArray: + case SpvOpTypeRuntimeArray: if (auto error = ValidateTypeRuntimeArray(_, inst)) return error; break; - case spv::Op::OpTypeStruct: + case SpvOpTypeStruct: if (auto error = ValidateTypeStruct(_, inst)) return error; break; - case spv::Op::OpTypePointer: + case SpvOpTypePointer: if (auto error = ValidateTypePointer(_, inst)) return error; break; - case spv::Op::OpTypeFunction: + case SpvOpTypeFunction: if (auto error = ValidateTypeFunction(_, inst)) return error; break; - case spv::Op::OpTypeForwardPointer: + case SpvOpTypeForwardPointer: if (auto error = ValidateTypeForwardPointer(_, inst)) return error; break; - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: - if (auto error = ValidateTypeCooperativeMatrix(_, inst)) return error; + case SpvOpTypeCooperativeMatrixNV: + if (auto error = ValidateTypeCooperativeMatrixNV(_, inst)) return error; break; default: break; diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index 6685985b..d5ddc9c1 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -21,7 +21,6 @@ #include "source/opcode.h" #include "source/spirv_constant.h" #include "source/spirv_target_env.h" -#include "source/util/make_unique.h" #include "source/val/basic_block.h" #include "source/val/construct.h" #include "source/val/function.h" @@ -32,66 +31,66 @@ namespace val { namespace { ModuleLayoutSection InstructionLayoutSection( - ModuleLayoutSection current_section, spv::Op op) { + ModuleLayoutSection current_section, SpvOp op) { // See Section 2.4 if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op)) return kLayoutTypes; switch (op) { - case spv::Op::OpCapability: + case SpvOpCapability: return kLayoutCapabilities; - case spv::Op::OpExtension: + case SpvOpExtension: return kLayoutExtensions; - case spv::Op::OpExtInstImport: + case SpvOpExtInstImport: return kLayoutExtInstImport; - case spv::Op::OpMemoryModel: + case SpvOpMemoryModel: return kLayoutMemoryModel; - case spv::Op::OpEntryPoint: + case SpvOpEntryPoint: return kLayoutEntryPoint; - case spv::Op::OpExecutionMode: - case spv::Op::OpExecutionModeId: + case SpvOpExecutionMode: + case SpvOpExecutionModeId: return kLayoutExecutionMode; - case spv::Op::OpSourceContinued: - case spv::Op::OpSource: - case spv::Op::OpSourceExtension: - case spv::Op::OpString: + case SpvOpSourceContinued: + case SpvOpSource: + case SpvOpSourceExtension: + case SpvOpString: return kLayoutDebug1; - case spv::Op::OpName: - case spv::Op::OpMemberName: + case SpvOpName: + case SpvOpMemberName: return kLayoutDebug2; - case spv::Op::OpModuleProcessed: + case SpvOpModuleProcessed: return kLayoutDebug3; - case spv::Op::OpDecorate: - case spv::Op::OpMemberDecorate: - case spv::Op::OpGroupDecorate: - case spv::Op::OpGroupMemberDecorate: - case spv::Op::OpDecorationGroup: - case spv::Op::OpDecorateId: - case spv::Op::OpDecorateStringGOOGLE: - case spv::Op::OpMemberDecorateStringGOOGLE: + case SpvOpDecorate: + case SpvOpMemberDecorate: + case SpvOpGroupDecorate: + case SpvOpGroupMemberDecorate: + case SpvOpDecorationGroup: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: return kLayoutAnnotations; - case spv::Op::OpTypeForwardPointer: + case SpvOpTypeForwardPointer: return kLayoutTypes; - case spv::Op::OpVariable: + case SpvOpVariable: if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case spv::Op::OpExtInst: - // spv::Op::OpExtInst is only allowed in types section for certain - // extended instruction sets. This will be checked separately. + case SpvOpExtInst: + // SpvOpExtInst is only allowed in types section for certain extended + // instruction sets. This will be checked separately. if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case spv::Op::OpLine: - case spv::Op::OpNoLine: - case spv::Op::OpUndef: + case SpvOpLine: + case SpvOpNoLine: + case SpvOpUndef: if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; - case spv::Op::OpFunction: - case spv::Op::OpFunctionParameter: - case spv::Op::OpFunctionEnd: + case SpvOpFunction: + case SpvOpFunctionParameter: + case SpvOpFunctionEnd: if (current_section == kLayoutFunctionDeclarations) return kLayoutFunctionDeclarations; return kLayoutFunctionDefinitions; - case spv::Op::OpSamplerImageAddressingModeNV: + case SpvOpSamplerImageAddressingModeNV: return kLayoutSamplerImageAddressMode; default: break; @@ -99,7 +98,7 @@ ModuleLayoutSection InstructionLayoutSection( return kLayoutFunctionDefinitions; } -bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) { +bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) { return layout == InstructionLayoutSection(layout, op); } @@ -107,9 +106,7 @@ bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) { spv_result_t CountInstructions(void* user_data, const spv_parsed_instruction_t* inst) { ValidationState_t& _ = *(reinterpret_cast(user_data)); - if (spv::Op(inst->opcode) == spv::Op::OpFunction) { - _.increment_total_functions(); - } + if (inst->opcode == SpvOpFunction) _.increment_total_functions(); _.increment_total_instructions(); return SPV_SUCCESS; @@ -163,8 +160,8 @@ ValidationState_t::ValidationState_t(const spv_const_context ctx, struct_nesting_depth_(), struct_has_nested_blockorbufferblock_struct_(), grammar_(ctx), - addressing_model_(spv::AddressingModel::Max), - memory_model_(spv::MemoryModel::Max), + addressing_model_(SpvAddressingModelMax), + memory_model_(SpvMemoryModelMax), pointer_size_and_alignment_(0), sampler_image_addressing_mode_(0), in_function_(false), @@ -293,13 +290,13 @@ void ValidationState_t::ProgressToNextLayoutSectionOrder() { } } -bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) { +bool ValidationState_t::IsOpcodeInPreviousLayoutSection(SpvOp op) { ModuleLayoutSection section = InstructionLayoutSection(current_layout_section_, op); return section < current_layout_section_; } -bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) { +bool ValidationState_t::IsOpcodeInCurrentLayoutSection(SpvOp op) { return IsInstructionInLayoutSection(current_layout_section_, op); } @@ -356,61 +353,59 @@ bool ValidationState_t::in_block() const { module_functions_.back().current_block() != nullptr; } -void ValidationState_t::RegisterCapability(spv::Capability cap) { +void ValidationState_t::RegisterCapability(SpvCapability cap) { // Avoid redundant work. Otherwise the recursion could induce work // quadrdatic in the capability dependency depth. (Ok, not much, but // it's something.) - if (module_capabilities_.contains(cap)) return; + if (module_capabilities_.Contains(cap)) return; - module_capabilities_.insert(cap); + module_capabilities_.Add(cap); spv_operand_desc desc; - if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, - uint32_t(cap), &desc)) { - for (auto capability : - CapabilitySet(desc->numCapabilities, desc->capabilities)) { - RegisterCapability(capability); - } + if (SPV_SUCCESS == + grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, cap, &desc)) { + CapabilitySet(desc->numCapabilities, desc->capabilities) + .ForEach([this](SpvCapability c) { RegisterCapability(c); }); } switch (cap) { - case spv::Capability::Kernel: + case SpvCapabilityKernel: features_.group_ops_reduce_and_scans = true; break; - case spv::Capability::Int8: + case SpvCapabilityInt8: features_.use_int8_type = true; features_.declare_int8_type = true; break; - case spv::Capability::StorageBuffer8BitAccess: - case spv::Capability::UniformAndStorageBuffer8BitAccess: - case spv::Capability::StoragePushConstant8: - case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: + case SpvCapabilityStorageBuffer8BitAccess: + case SpvCapabilityUniformAndStorageBuffer8BitAccess: + case SpvCapabilityStoragePushConstant8: + case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: features_.declare_int8_type = true; break; - case spv::Capability::Int16: + case SpvCapabilityInt16: features_.declare_int16_type = true; break; - case spv::Capability::Float16: - case spv::Capability::Float16Buffer: + case SpvCapabilityFloat16: + case SpvCapabilityFloat16Buffer: features_.declare_float16_type = true; break; - case spv::Capability::StorageUniformBufferBlock16: - case spv::Capability::StorageUniform16: - case spv::Capability::StoragePushConstant16: - case spv::Capability::StorageInputOutput16: - case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: + case SpvCapabilityStorageUniformBufferBlock16: + case SpvCapabilityStorageUniform16: + case SpvCapabilityStoragePushConstant16: + case SpvCapabilityStorageInputOutput16: + case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: features_.declare_int16_type = true; features_.declare_float16_type = true; features_.free_fp_rounding_mode = true; break; - case spv::Capability::VariablePointers: - case spv::Capability::VariablePointersStorageBuffer: + case SpvCapabilityVariablePointers: + case SpvCapabilityVariablePointersStorageBuffer: features_.variable_pointers = true; break; default: // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses - // capability spv::Capability::RayTracingNV. - // spv::Capability::RayTracingProvisionalKHR would need the same - // treatment. One of the differences going from SPV_KHR_ray_tracing from + // capability SpvCapabilityRayTracingNV. + // SpvCapabilityRayTracingProvisionalKHR would need the same treatment. + // One of the differences going from SPV_KHR_ray_tracing from // provisional to final spec was the provisional spec uses Locations // for variables in certain storage classes, just like the // SPV_NV_ray_tracing extension. So it mimics the NVIDIA extension. @@ -421,9 +416,9 @@ void ValidationState_t::RegisterCapability(spv::Capability cap) { } void ValidationState_t::RegisterExtension(Extension ext) { - if (module_extensions_.contains(ext)) return; + if (module_extensions_.Contains(ext)) return; - module_extensions_.insert(ext); + module_extensions_.Add(ext); switch (ext) { case kSPV_AMD_gpu_shader_half_float: @@ -459,32 +454,30 @@ bool ValidationState_t::HasAnyOfExtensions( return module_extensions_.HasAnyOf(extensions); } -void ValidationState_t::set_addressing_model(spv::AddressingModel am) { +void ValidationState_t::set_addressing_model(SpvAddressingModel am) { addressing_model_ = am; switch (am) { - case spv::AddressingModel::Physical32: + case SpvAddressingModelPhysical32: pointer_size_and_alignment_ = 4; break; default: // fall through - case spv::AddressingModel::Physical64: - case spv::AddressingModel::PhysicalStorageBuffer64: + case SpvAddressingModelPhysical64: + case SpvAddressingModelPhysicalStorageBuffer64: pointer_size_and_alignment_ = 8; break; } } -spv::AddressingModel ValidationState_t::addressing_model() const { +SpvAddressingModel ValidationState_t::addressing_model() const { return addressing_model_; } -void ValidationState_t::set_memory_model(spv::MemoryModel mm) { +void ValidationState_t::set_memory_model(SpvMemoryModel mm) { memory_model_ = mm; } -spv::MemoryModel ValidationState_t::memory_model() const { - return memory_model_; -} +SpvMemoryModel ValidationState_t::memory_model() const { return memory_model_; } void ValidationState_t::set_samplerimage_variable_address_mode( uint32_t bit_width) { @@ -496,8 +489,8 @@ uint32_t ValidationState_t::samplerimage_variable_address_mode() const { } spv_result_t ValidationState_t::RegisterFunction( - uint32_t id, uint32_t ret_type_id, - spv::FunctionControlMask function_control, uint32_t function_type_id) { + uint32_t id, uint32_t ret_type_id, SpvFunctionControlMask function_control, + uint32_t function_type_id) { assert(in_function_body() == false && "RegisterFunction can only be called when parsing the binary outside " "of another function"); @@ -533,24 +526,24 @@ Instruction* ValidationState_t::AddOrderedInstruction( // Improves diagnostic messages by collecting names of IDs void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) { switch (inst->opcode()) { - case spv::Op::OpName: { + case SpvOpName: { const auto target = inst->GetOperandAs(0); const std::string str = inst->GetOperandAs(1); AssignNameToId(target, str); break; } - case spv::Op::OpMemberName: { + case SpvOpMemberName: { const auto target = inst->GetOperandAs(0); const std::string str = inst->GetOperandAs(2); AssignNameToId(target, str); break; } - case spv::Op::OpSourceContinued: - case spv::Op::OpSource: - case spv::Op::OpSourceExtension: - case spv::Op::OpString: - case spv::Op::OpLine: - case spv::Op::OpNoLine: + case SpvOpSourceContinued: + case SpvOpSource: + case SpvOpSourceExtension: + case SpvOpString: + case SpvOpLine: + case SpvOpNoLine: default: break; } @@ -574,7 +567,7 @@ void ValidationState_t::RegisterInstruction(Instruction* inst) { // should be recorded. The validator will ensure that all usages of an // OpTypeSampledImage and its definition are in the same basic block. if ((SPV_OPERAND_TYPE_ID == operand.type) && - (spv::Op::OpSampledImage == operand_inst->opcode())) { + (SpvOpSampledImage == operand_inst->opcode())) { RegisterSampledImageConsumer(operand_word, inst); } @@ -584,12 +577,12 @@ void ValidationState_t::RegisterInstruction(Instruction* inst) { // Instead just need to register storage class usage for consumers in a // function block. if (inst->function()) { - if (operand_inst->opcode() == spv::Op::OpTypePointer) { + if (operand_inst->opcode() == SpvOpTypePointer) { RegisterStorageClassConsumer( - operand_inst->GetOperandAs(1), inst); - } else if (operand_inst->opcode() == spv::Op::OpVariable) { + operand_inst->GetOperandAs(1), inst); + } else if (operand_inst->opcode() == SpvOpVariable) { RegisterStorageClassConsumer( - operand_inst->GetOperandAs(2), inst); + operand_inst->GetOperandAs(2), inst); } } } @@ -611,34 +604,22 @@ void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id, sampled_image_consumers_[sampled_image_id].push_back(consumer); } -void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer( - uint32_t texture_id, const Instruction* consumer0, - const Instruction* consumer1) { - if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) || - HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM)) { - qcom_image_processing_consumers_.insert(consumer0->id()); - if (consumer1) { - qcom_image_processing_consumers_.insert(consumer1->id()); - } - } -} - void ValidationState_t::RegisterStorageClassConsumer( - spv::StorageClass storage_class, Instruction* consumer) { + SpvStorageClass storage_class, Instruction* consumer) { if (spvIsVulkanEnv(context()->target_env)) { - if (storage_class == spv::StorageClass::Output) { + if (storage_class == SpvStorageClassOutput) { std::string errorVUID = VkErrorID(4644); function(consumer->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - spv::ExecutionModel model, + SpvExecutionModel model, std::string* message) { - if (model == spv::ExecutionModel::GLCompute || - model == spv::ExecutionModel::RayGenerationKHR || - model == spv::ExecutionModel::IntersectionKHR || - model == spv::ExecutionModel::AnyHitKHR || - model == spv::ExecutionModel::ClosestHitKHR || - model == spv::ExecutionModel::MissKHR || - model == spv::ExecutionModel::CallableKHR) { + if (model == SpvExecutionModelGLCompute || + model == SpvExecutionModelRayGenerationKHR || + model == SpvExecutionModelIntersectionKHR || + model == SpvExecutionModelAnyHitKHR || + model == SpvExecutionModelClosestHitKHR || + model == SpvExecutionModelMissKHR || + model == SpvExecutionModelCallableKHR) { if (message) { *message = errorVUID + @@ -653,17 +634,17 @@ void ValidationState_t::RegisterStorageClassConsumer( }); } - if (storage_class == spv::StorageClass::Workgroup) { + if (storage_class == SpvStorageClassWorkgroup) { std::string errorVUID = VkErrorID(4645); function(consumer->function()->id()) ->RegisterExecutionModelLimitation([errorVUID]( - spv::ExecutionModel model, + SpvExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::GLCompute && - model != spv::ExecutionModel::TaskNV && - model != spv::ExecutionModel::MeshNV && - model != spv::ExecutionModel::TaskEXT && - model != spv::ExecutionModel::MeshEXT) { + if (model != SpvExecutionModelGLCompute && + model != SpvExecutionModelTaskNV && + model != SpvExecutionModelMeshNV && + model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT) { if (message) { *message = errorVUID + @@ -677,51 +658,48 @@ void ValidationState_t::RegisterStorageClassConsumer( } } - if (storage_class == spv::StorageClass::CallableDataKHR) { + if (storage_class == SpvStorageClassCallableDataKHR) { std::string errorVUID = VkErrorID(4704); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::CallableKHR && - model != spv::ExecutionModel::MissKHR) { - if (message) { - *message = - errorVUID + - "CallableDataKHR Storage Class is limited to " - "RayGenerationKHR, ClosestHitKHR, CallableKHR, and " - "MissKHR execution model"; - } - return false; - } - return true; - }); - } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) { + ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, + std::string* message) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelCallableKHR && + model != SpvExecutionModelMissKHR) { + if (message) { + *message = errorVUID + + "CallableDataKHR Storage Class is limited to " + "RayGenerationKHR, ClosestHitKHR, CallableKHR, and " + "MissKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == SpvStorageClassIncomingCallableDataKHR) { std::string errorVUID = VkErrorID(4705); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::CallableKHR) { - if (message) { - *message = - errorVUID + - "IncomingCallableDataKHR Storage Class is limited to " - "CallableKHR execution model"; - } - return false; - } - return true; - }); - } else if (storage_class == spv::StorageClass::RayPayloadKHR) { + ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, + std::string* message) { + if (model != SpvExecutionModelCallableKHR) { + if (message) { + *message = errorVUID + + "IncomingCallableDataKHR Storage Class is limited to " + "CallableKHR execution model"; + } + return false; + } + return true; + }); + } else if (storage_class == SpvStorageClassRayPayloadKHR) { std::string errorVUID = VkErrorID(4698); function(consumer->function()->id()) - ->RegisterExecutionModelLimitation([errorVUID]( - spv::ExecutionModel model, - std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR) { + ->RegisterExecutionModelLimitation([errorVUID](SpvExecutionModel model, + std::string* message) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelMissKHR) { if (message) { *message = errorVUID + @@ -732,14 +710,14 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == spv::StorageClass::HitAttributeKHR) { + } else if (storage_class == SpvStorageClassHitAttributeKHR) { std::string errorVUID = VkErrorID(4701); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::IntersectionKHR && - model != spv::ExecutionModel::AnyHitKHR && - model != spv::ExecutionModel::ClosestHitKHR) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelIntersectionKHR && + model != SpvExecutionModelAnyHitKHR && + model != SpvExecutionModelClosestHitKHR) { if (message) { *message = errorVUID + "HitAttributeKHR Storage Class is limited to " @@ -750,14 +728,14 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) { + } else if (storage_class == SpvStorageClassIncomingRayPayloadKHR) { std::string errorVUID = VkErrorID(4699); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::AnyHitKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelAnyHitKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelMissKHR) { if (message) { *message = errorVUID + @@ -768,17 +746,17 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) { + } else if (storage_class == SpvStorageClassShaderRecordBufferKHR) { std::string errorVUID = VkErrorID(7119); function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [errorVUID](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::IntersectionKHR && - model != spv::ExecutionModel::AnyHitKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::CallableKHR && - model != spv::ExecutionModel::MissKHR) { + [errorVUID](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelRayGenerationKHR && + model != SpvExecutionModelIntersectionKHR && + model != SpvExecutionModelAnyHitKHR && + model != SpvExecutionModelClosestHitKHR && + model != SpvExecutionModelCallableKHR && + model != SpvExecutionModelMissKHR) { if (message) { *message = errorVUID + @@ -790,12 +768,12 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) { + } else if (storage_class == SpvStorageClassTaskPayloadWorkgroupEXT) { function(consumer->function()->id()) ->RegisterExecutionModelLimitation( - [](spv::ExecutionModel model, std::string* message) { - if (model != spv::ExecutionModel::TaskEXT && - model != spv::ExecutionModel::MeshEXT) { + [](SpvExecutionModel model, std::string* message) { + if (model != SpvExecutionModelTaskEXT && + model != SpvExecutionModelMeshEXT) { if (message) { *message = "TaskPayloadWorkgroupEXT Storage Class is limited to " @@ -805,22 +783,6 @@ void ValidationState_t::RegisterStorageClassConsumer( } return true; }); - } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) { - function(consumer->function()->id()) - ->RegisterExecutionModelLimitation([](spv::ExecutionModel model, - std::string* message) { - if (model != spv::ExecutionModel::RayGenerationKHR && - model != spv::ExecutionModel::ClosestHitKHR && - model != spv::ExecutionModel::MissKHR) { - if (message) { - *message = - "HitObjectAttributeNV Storage Class is limited to " - "RayGenerationKHR, ClosestHitKHR or MissKHR execution model"; - } - return false; - } - return true; - }); } } @@ -852,9 +814,9 @@ uint32_t ValidationState_t::GetTypeId(uint32_t id) const { return inst ? inst->type_id() : 0; } -spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const { +SpvOp ValidationState_t::GetIdOpcode(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst ? inst->opcode() : spv::Op::OpNop; + return inst ? inst->opcode() : SpvOpNop; } uint32_t ValidationState_t::GetComponentType(uint32_t id) const { @@ -862,19 +824,18 @@ uint32_t ValidationState_t::GetComponentType(uint32_t id) const { assert(inst); switch (inst->opcode()) { - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeBool: return id; - case spv::Op::OpTypeVector: + case SpvOpTypeVector: return inst->word(2); - case spv::Op::OpTypeMatrix: + case SpvOpTypeMatrix: return GetComponentType(inst->word(2)); - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: + case SpvOpTypeCooperativeMatrixNV: return inst->word(2); default: @@ -892,17 +853,16 @@ uint32_t ValidationState_t::GetDimension(uint32_t id) const { assert(inst); switch (inst->opcode()) { - case spv::Op::OpTypeFloat: - case spv::Op::OpTypeInt: - case spv::Op::OpTypeBool: + case SpvOpTypeFloat: + case SpvOpTypeInt: + case SpvOpTypeBool: return 1; - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: + case SpvOpTypeVector: + case SpvOpTypeMatrix: return inst->word(3); - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: + case SpvOpTypeCooperativeMatrixNV: // Actual dimension isn't known, return 0 return 0; @@ -921,11 +881,10 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { const Instruction* inst = FindDef(component_type_id); assert(inst); - if (inst->opcode() == spv::Op::OpTypeFloat || - inst->opcode() == spv::Op::OpTypeInt) + if (inst->opcode() == SpvOpTypeFloat || inst->opcode() == SpvOpTypeInt) return inst->word(2); - if (inst->opcode() == spv::Op::OpTypeBool) return 1; + if (inst->opcode() == SpvOpTypeBool) return 1; assert(0); return 0; @@ -933,12 +892,12 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const { bool ValidationState_t::IsVoidType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeVoid; + return inst && inst->opcode() == SpvOpTypeVoid; } bool ValidationState_t::IsFloatScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeFloat; + return inst && inst->opcode() == SpvOpTypeFloat; } bool ValidationState_t::IsFloatVectorType(uint32_t id) const { @@ -947,7 +906,7 @@ bool ValidationState_t::IsFloatVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsFloatScalarType(GetComponentType(id)); } @@ -960,11 +919,11 @@ bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeFloat) { + if (inst->opcode() == SpvOpTypeFloat) { return true; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsFloatScalarType(GetComponentType(id)); } @@ -973,7 +932,7 @@ bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const { bool ValidationState_t::IsIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeInt; + return inst && inst->opcode() == SpvOpTypeInt; } bool ValidationState_t::IsIntVectorType(uint32_t id) const { @@ -982,7 +941,7 @@ bool ValidationState_t::IsIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsIntScalarType(GetComponentType(id)); } @@ -995,11 +954,11 @@ bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeInt) { + if (inst->opcode() == SpvOpTypeInt) { return true; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsIntScalarType(GetComponentType(id)); } @@ -1008,7 +967,7 @@ bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const { bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0; + return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 0; } bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { @@ -1017,24 +976,7 @@ bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeVector) { - return IsUnsignedIntScalarType(GetComponentType(id)); - } - - return false; -} - -bool ValidationState_t::IsUnsignedIntScalarOrVectorType(uint32_t id) const { - const Instruction* inst = FindDef(id); - if (!inst) { - return false; - } - - if (inst->opcode() == spv::Op::OpTypeInt) { - return inst->GetOperandAs(2) == 0; - } - - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsUnsignedIntScalarType(GetComponentType(id)); } @@ -1043,7 +985,7 @@ bool ValidationState_t::IsUnsignedIntScalarOrVectorType(uint32_t id) const { bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1; + return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 1; } bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { @@ -1052,7 +994,7 @@ bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsSignedIntScalarType(GetComponentType(id)); } @@ -1061,7 +1003,7 @@ bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const { bool ValidationState_t::IsBoolScalarType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeBool; + return inst && inst->opcode() == SpvOpTypeBool; } bool ValidationState_t::IsBoolVectorType(uint32_t id) const { @@ -1070,7 +1012,7 @@ bool ValidationState_t::IsBoolVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsBoolScalarType(GetComponentType(id)); } @@ -1083,11 +1025,11 @@ bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeBool) { + if (inst->opcode() == SpvOpTypeBool) { return true; } - if (inst->opcode() == spv::Op::OpTypeVector) { + if (inst->opcode() == SpvOpTypeVector) { return IsBoolScalarType(GetComponentType(id)); } @@ -1100,7 +1042,7 @@ bool ValidationState_t::IsFloatMatrixType(uint32_t id) const { return false; } - if (inst->opcode() == spv::Op::OpTypeMatrix) { + if (inst->opcode() == SpvOpTypeMatrix) { return IsFloatScalarType(GetComponentType(id)); } @@ -1115,13 +1057,13 @@ bool ValidationState_t::GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, const Instruction* mat_inst = FindDef(id); assert(mat_inst); - if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false; + if (mat_inst->opcode() != SpvOpTypeMatrix) return false; const uint32_t vec_type = mat_inst->word(2); const Instruction* vec_inst = FindDef(vec_type); assert(vec_inst); - if (vec_inst->opcode() != spv::Op::OpTypeVector) { + if (vec_inst->opcode() != SpvOpTypeVector) { assert(0); return false; } @@ -1141,7 +1083,7 @@ bool ValidationState_t::GetStructMemberTypes( const Instruction* inst = FindDef(struct_type_id); assert(inst); - if (inst->opcode() != spv::Op::OpTypeStruct) return false; + if (inst->opcode() != SpvOpTypeStruct) return false; *member_types = std::vector(inst->words().cbegin() + 2, inst->words().cend()); @@ -1153,91 +1095,44 @@ bool ValidationState_t::GetStructMemberTypes( bool ValidationState_t::IsPointerType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypePointer; + return inst && inst->opcode() == SpvOpTypePointer; } -bool ValidationState_t::GetPointerTypeInfo( - uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const { - *storage_class = spv::StorageClass::Max; +bool ValidationState_t::GetPointerTypeInfo(uint32_t id, uint32_t* data_type, + uint32_t* storage_class) const { if (!id) return false; const Instruction* inst = FindDef(id); assert(inst); - if (inst->opcode() != spv::Op::OpTypePointer) return false; + if (inst->opcode() != SpvOpTypePointer) return false; - *storage_class = spv::StorageClass(inst->word(2)); + *storage_class = inst->word(2); *data_type = inst->word(3); return true; } bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeAccelerationStructureKHR; + return inst && inst->opcode() == SpvOpTypeAccelerationStructureKHR; } bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const { const Instruction* inst = FindDef(id); - return inst && (inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV || - inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR); -} - -bool ValidationState_t::IsCooperativeMatrixNVType(uint32_t id) const { - const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV; -} - -bool ValidationState_t::IsCooperativeMatrixKHRType(uint32_t id) const { - const Instruction* inst = FindDef(id); - return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR; -} - -bool ValidationState_t::IsCooperativeMatrixAType(uint32_t id) const { - if (!IsCooperativeMatrixKHRType(id)) return false; - const Instruction* inst = FindDef(id); - uint64_t matrixUse = 0; - if (GetConstantValUint64(inst->word(6), &matrixUse)) { - return matrixUse == - static_cast(spv::CooperativeMatrixUse::MatrixAKHR); - } - return false; -} - -bool ValidationState_t::IsCooperativeMatrixBType(uint32_t id) const { - if (!IsCooperativeMatrixKHRType(id)) return false; - const Instruction* inst = FindDef(id); - uint64_t matrixUse = 0; - if (GetConstantValUint64(inst->word(6), &matrixUse)) { - return matrixUse == - static_cast(spv::CooperativeMatrixUse::MatrixBKHR); - } - return false; -} -bool ValidationState_t::IsCooperativeMatrixAccType(uint32_t id) const { - if (!IsCooperativeMatrixKHRType(id)) return false; - const Instruction* inst = FindDef(id); - uint64_t matrixUse = 0; - if (GetConstantValUint64(inst->word(6), &matrixUse)) { - return matrixUse == static_cast( - spv::CooperativeMatrixUse::MatrixAccumulatorKHR); - } - return false; + return inst && inst->opcode() == SpvOpTypeCooperativeMatrixNV; } bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const { - if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) - return false; + if (!IsCooperativeMatrixType(id)) return false; return IsFloatScalarType(FindDef(id)->word(2)); } bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const { - if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) - return false; + if (!IsCooperativeMatrixType(id)) return false; return IsIntScalarType(FindDef(id)->word(2)); } bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const { - if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id)) - return false; + if (!IsCooperativeMatrixType(id)) return false; return IsUnsignedIntScalarType(FindDef(id)->word(2)); } @@ -1253,7 +1148,8 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( const auto m1_type = FindDef(m1); const auto m2_type = FindDef(m2); - if (m1_type->opcode() != m2_type->opcode()) { + if (m1_type->opcode() != SpvOpTypeCooperativeMatrixNV || + m2_type->opcode() != SpvOpTypeCooperativeMatrixNV) { return diag(SPV_ERROR_INVALID_DATA, inst) << "Expected cooperative matrix types"; } @@ -1303,21 +1199,6 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch( << "identical"; } - if (m1_type->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) { - uint32_t m1_use_id = m1_type->GetOperandAs(5); - uint32_t m2_use_id = m2_type->GetOperandAs(5); - std::tie(m1_is_int32, m1_is_const_int32, m1_value) = - EvalInt32IfConst(m1_use_id); - std::tie(m2_is_int32, m2_is_const_int32, m2_value) = - EvalInt32IfConst(m2_use_id); - - if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) { - return diag(SPV_ERROR_INVALID_DATA, inst) - << "Expected Use of Matrix type and Result Type to be " - << "identical"; - } - } - return SPV_SUCCESS; } @@ -1333,8 +1214,7 @@ bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const { return false; } - if (inst->opcode() != spv::Op::OpConstant && - inst->opcode() != spv::Op::OpSpecConstant) + if (inst->opcode() != SpvOpConstant && inst->opcode() != SpvOpSpecConstant) return false; if (!IsIntScalarType(inst->type_id())) return false; @@ -1366,7 +1246,7 @@ std::tuple ValidationState_t::EvalInt32IfConst( return std::make_tuple(true, false, 0); } - if (inst->opcode() == spv::Op::OpConstantNull) { + if (inst->opcode() == SpvOpConstantNull) { return std::make_tuple(true, true, 0); } @@ -1500,7 +1380,7 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, } } - if (lhs->opcode() == spv::Op::OpTypeArray) { + if (lhs->opcode() == SpvOpTypeArray) { // Size operands must match. if (lhs->GetOperandAs(2u) != rhs->GetOperandAs(2u)) { return false; @@ -1519,7 +1399,7 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, return false; } return LogicallyMatch(lhs_ele, rhs_ele, check_decorations); - } else if (lhs->opcode() == spv::Op::OpTypeStruct) { + } else if (lhs->opcode() == SpvOpTypeStruct) { // Number of elements must match. if (lhs->operands().size() != rhs->operands().size()) { return false; @@ -1557,11 +1437,11 @@ bool ValidationState_t::LogicallyMatch(const Instruction* lhs, const Instruction* ValidationState_t::TracePointer( const Instruction* inst) const { auto base_ptr = inst; - while (base_ptr->opcode() == spv::Op::OpAccessChain || - base_ptr->opcode() == spv::Op::OpInBoundsAccessChain || - base_ptr->opcode() == spv::Op::OpPtrAccessChain || - base_ptr->opcode() == spv::Op::OpInBoundsPtrAccessChain || - base_ptr->opcode() == spv::Op::OpCopyObject) { + while (base_ptr->opcode() == SpvOpAccessChain || + base_ptr->opcode() == SpvOpInBoundsAccessChain || + base_ptr->opcode() == SpvOpPtrAccessChain || + base_ptr->opcode() == SpvOpInBoundsPtrAccessChain || + base_ptr->opcode() == SpvOpCopyObject) { base_ptr = FindDef(base_ptr->GetOperandAs(2u)); } return base_ptr; @@ -1576,26 +1456,25 @@ bool ValidationState_t::ContainsType( if (f(inst)) return true; switch (inst->opcode()) { - case spv::Op::OpTypeArray: - case spv::Op::OpTypeRuntimeArray: - case spv::Op::OpTypeVector: - case spv::Op::OpTypeMatrix: - case spv::Op::OpTypeImage: - case spv::Op::OpTypeSampledImage: - case spv::Op::OpTypeCooperativeMatrixNV: - case spv::Op::OpTypeCooperativeMatrixKHR: + case SpvOpTypeArray: + case SpvOpTypeRuntimeArray: + case SpvOpTypeVector: + case SpvOpTypeMatrix: + case SpvOpTypeImage: + case SpvOpTypeSampledImage: + case SpvOpTypeCooperativeMatrixNV: return ContainsType(inst->GetOperandAs(1u), f, traverse_all_types); - case spv::Op::OpTypePointer: + case SpvOpTypePointer: if (IsForwardPointer(id)) return false; if (traverse_all_types) { return ContainsType(inst->GetOperandAs(2u), f, traverse_all_types); } break; - case spv::Op::OpTypeFunction: - case spv::Op::OpTypeStruct: - if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) { + case SpvOpTypeFunction: + case SpvOpTypeStruct: + if (inst->opcode() == SpvOpTypeFunction && !traverse_all_types) { return false; } for (uint32_t i = 1; i < inst->operands().size(); ++i) { @@ -1612,9 +1491,9 @@ bool ValidationState_t::ContainsType( return false; } -bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, +bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type, uint32_t width) const { - if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false; + if (type != SpvOpTypeInt && type != SpvOpTypeFloat) return false; const auto f = [type, width](const Instruction* inst) { if (inst->opcode() == type) { @@ -1626,12 +1505,12 @@ bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, } bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { - if ((!HasCapability(spv::Capability::Int16) && - ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) || - (!HasCapability(spv::Capability::Int8) && - ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) || - (!HasCapability(spv::Capability::Float16) && - ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) { + if ((!HasCapability(SpvCapabilityInt16) && + ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 16)) || + (!HasCapability(SpvCapabilityInt8) && + ContainsSizedIntOrFloatType(id, SpvOpTypeInt, 8)) || + (!HasCapability(SpvCapabilityFloat16) && + ContainsSizedIntOrFloatType(id, SpvOpTypeFloat, 16))) { return true; } return false; @@ -1639,35 +1518,33 @@ bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const { const auto f = [](const Instruction* inst) { - return inst->opcode() == spv::Op::OpTypeRuntimeArray; + return inst->opcode() == SpvOpTypeRuntimeArray; }; return ContainsType(id, f, /* traverse_all_types = */ false); } bool ValidationState_t::IsValidStorageClass( - spv::StorageClass storage_class) const { + SpvStorageClass storage_class) const { if (spvIsVulkanEnv(context()->target_env)) { switch (storage_class) { - case spv::StorageClass::UniformConstant: - case spv::StorageClass::Uniform: - case spv::StorageClass::StorageBuffer: - case spv::StorageClass::Input: - case spv::StorageClass::Output: - case spv::StorageClass::Image: - case spv::StorageClass::Workgroup: - case spv::StorageClass::Private: - case spv::StorageClass::Function: - case spv::StorageClass::PushConstant: - case spv::StorageClass::PhysicalStorageBuffer: - case spv::StorageClass::RayPayloadKHR: - case spv::StorageClass::IncomingRayPayloadKHR: - case spv::StorageClass::HitAttributeKHR: - case spv::StorageClass::CallableDataKHR: - case spv::StorageClass::IncomingCallableDataKHR: - case spv::StorageClass::ShaderRecordBufferKHR: - case spv::StorageClass::TaskPayloadWorkgroupEXT: - case spv::StorageClass::HitObjectAttributeNV: - case spv::StorageClass::TileImageEXT: + case SpvStorageClassUniformConstant: + case SpvStorageClassUniform: + case SpvStorageClassStorageBuffer: + case SpvStorageClassInput: + case SpvStorageClassOutput: + case SpvStorageClassImage: + case SpvStorageClassWorkgroup: + case SpvStorageClassPrivate: + case SpvStorageClassFunction: + case SpvStorageClassPushConstant: + case SpvStorageClassPhysicalStorageBuffer: + case SpvStorageClassRayPayloadKHR: + case SpvStorageClassIncomingRayPayloadKHR: + case SpvStorageClassHitAttributeKHR: + case SpvStorageClassCallableDataKHR: + case SpvStorageClassIncomingCallableDataKHR: + case SpvStorageClassShaderRecordBufferKHR: + case SpvStorageClassTaskPayloadWorkgroupEXT: return true; default: return false; @@ -2143,6 +2020,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658); case 4659: return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659); + case 4662: + return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662); case 4663: return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663); case 4664: @@ -2215,16 +2094,6 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-Location-04918); case 4919: return VUID_WRAP(VUID-StandaloneSpirv-Location-04919); - case 4920: - return VUID_WRAP(VUID-StandaloneSpirv-Component-04920); - case 4921: - return VUID_WRAP(VUID-StandaloneSpirv-Component-04921); - case 4922: - return VUID_WRAP(VUID-StandaloneSpirv-Component-04922); - case 4923: - return VUID_WRAP(VUID-StandaloneSpirv-Component-04923); - case 4924: - return VUID_WRAP(VUID-StandaloneSpirv-Component-04924); case 6201: return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201); case 6202: @@ -2257,28 +2126,14 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808); case 6925: return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925); + case 6997: + return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-06997); case 7102: return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102); case 7320: return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320); case 7290: return VUID_WRAP(VUID-StandaloneSpirv-Input-07290); - case 7650: - return VUID_WRAP(VUID-StandaloneSpirv-Base-07650); - case 7651: - return VUID_WRAP(VUID-StandaloneSpirv-Base-07651); - case 7652: - return VUID_WRAP(VUID-StandaloneSpirv-Base-07652); - case 7703: - return VUID_WRAP(VUID-StandaloneSpirv-Component-07703); - case 7951: - return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-07951); - case 8721: - return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08721); - case 8722: - return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08722); - case 8973: - return VUID_WRAP(VUID-StandaloneSpirv-Pointer-08973); default: return ""; // unknown id } diff --git a/source/val/validation_state.h b/source/val/validation_state.h index 0cd6c789..1b599ff3 100644 --- a/source/val/validation_state.h +++ b/source/val/validation_state.h @@ -185,10 +185,10 @@ class ValidationState_t { void ProgressToNextLayoutSectionOrder(); /// Determines if the op instruction is in a previous layout section - bool IsOpcodeInPreviousLayoutSection(spv::Op op); + bool IsOpcodeInPreviousLayoutSection(SpvOp op); /// Determines if the op instruction is part of the current section - bool IsOpcodeInCurrentLayoutSection(spv::Op op); + bool IsOpcodeInCurrentLayoutSection(SpvOp op); DiagnosticStream diag(spv_result_t error_code, const Instruction* inst); @@ -217,8 +217,7 @@ class ValidationState_t { }; /// Registers |id| as an entry point with |execution_model| and |interfaces|. - void RegisterEntryPoint(const uint32_t id, - spv::ExecutionModel execution_model, + void RegisterEntryPoint(const uint32_t id, SpvExecutionModel execution_model, EntryPointDescription&& desc) { entry_points_.push_back(id); entry_point_to_execution_models_[id].insert(execution_model); @@ -236,7 +235,7 @@ class ValidationState_t { /// Registers execution mode for the given entry point. void RegisterExecutionModeForEntryPoint(uint32_t entry_point, - spv::ExecutionMode execution_mode) { + SpvExecutionMode execution_mode) { entry_point_to_execution_modes_[entry_point].insert(execution_mode); } @@ -248,7 +247,7 @@ class ValidationState_t { /// Returns Execution Models for the given Entry Point. /// Returns nullptr if none found (would trigger assertion). - const std::set* GetExecutionModels( + const std::set* GetExecutionModels( uint32_t entry_point) const { const auto it = entry_point_to_execution_models_.find(entry_point); if (it == entry_point_to_execution_models_.end()) { @@ -260,7 +259,7 @@ class ValidationState_t { /// Returns Execution Modes for the given Entry Point. /// Returns nullptr if none found. - const std::set* GetExecutionModes( + const std::set* GetExecutionModes( uint32_t entry_point) const { const auto it = entry_point_to_execution_modes_.find(entry_point); if (it == entry_point_to_execution_modes_.end()) { @@ -301,7 +300,7 @@ class ValidationState_t { return (id_to_function_.find(id) != id_to_function_.end()); } /// Registers the capability and its dependent capabilities - void RegisterCapability(spv::Capability cap); + void RegisterCapability(SpvCapability cap); /// Registers the extension. void RegisterExtension(Extension ext); @@ -309,15 +308,15 @@ class ValidationState_t { /// Registers the function in the module. Subsequent instructions will be /// called against this function spv_result_t RegisterFunction(uint32_t id, uint32_t ret_type_id, - spv::FunctionControlMask function_control, + SpvFunctionControlMask function_control, uint32_t function_type_id); /// Register a function end instruction spv_result_t RegisterFunctionEnd(); /// Returns true if the capability is enabled in the module. - bool HasCapability(spv::Capability cap) const { - return module_capabilities_.contains(cap); + bool HasCapability(SpvCapability cap) const { + return module_capabilities_.Contains(cap); } /// Returns a reference to the set of capabilities in the module. @@ -328,7 +327,7 @@ class ValidationState_t { /// Returns true if the extension is enabled in the module. bool HasExtension(Extension ext) const { - return module_extensions_.contains(ext); + return module_extensions_.Contains(ext); } /// Returns true if any of the capabilities is enabled, or if |capabilities| @@ -340,16 +339,16 @@ class ValidationState_t { bool HasAnyOfExtensions(const ExtensionSet& extensions) const; /// Sets the addressing model of this module (logical/physical). - void set_addressing_model(spv::AddressingModel am); + void set_addressing_model(SpvAddressingModel am); /// Returns true if the OpMemoryModel was found. bool has_memory_model_specified() const { - return addressing_model_ != spv::AddressingModel::Max && - memory_model_ != spv::MemoryModel::Max; + return addressing_model_ != SpvAddressingModelMax && + memory_model_ != SpvMemoryModelMax; } /// Returns the addressing model of this module, or Logical if uninitialized. - spv::AddressingModel addressing_model() const; + SpvAddressingModel addressing_model() const; /// Returns the addressing model of this module, or Logical if uninitialized. uint32_t pointer_size_and_alignment() const { @@ -357,10 +356,10 @@ class ValidationState_t { } /// Sets the memory model of this module. - void set_memory_model(spv::MemoryModel mm); + void set_memory_model(SpvMemoryModel mm); /// Returns the memory model of this module, or Simple if uninitialized. - spv::MemoryModel memory_model() const; + SpvMemoryModel memory_model() const; /// Sets the bit width for sampler/image type variables. If not set, they are /// considered opaque @@ -433,8 +432,8 @@ class ValidationState_t { // The decorations are sorted by member_index, so this look up will give the // exact range of decorations for this member index. - Decoration min_decoration((spv::Decoration)0, {}, member_index); - Decoration max_decoration(spv::Decoration::Max, {}, member_index); + Decoration min_decoration((SpvDecoration)0, {}, member_index); + Decoration max_decoration(SpvDecorationMax, {}, member_index); FieldDecorationsIter result; result.begin = decorations.lower_bound(min_decoration); @@ -450,7 +449,7 @@ class ValidationState_t { /// Returns true if the given id has the given decoration , /// otherwise returns false. - bool HasDecoration(uint32_t id, spv::Decoration dec) { + bool HasDecoration(uint32_t id, SpvDecoration dec) { const auto& decorations = id_decorations_.find(id); if (decorations == id_decorations_.end()) return false; @@ -485,15 +484,8 @@ class ValidationState_t { void RegisterSampledImageConsumer(uint32_t sampled_image_id, Instruction* consumer); - // Record a cons_id as a consumer of texture_id - // if texture 'texture_id' has a QCOM image processing decoration - // and consumer is a load or a sampled image instruction - void RegisterQCOMImageProcessingTextureConsumer(uint32_t texture_id, - const Instruction* consumer0, - const Instruction* consumer1); - // Record a function's storage class consumer instruction - void RegisterStorageClassConsumer(spv::StorageClass storage_class, + void RegisterStorageClassConsumer(SpvStorageClass storage_class, Instruction* consumer); /// Returns the set of Global Variables. @@ -609,7 +601,6 @@ class ValidationState_t { bool IsIntScalarOrVectorType(uint32_t id) const; bool IsUnsignedIntScalarType(uint32_t id) const; bool IsUnsignedIntVectorType(uint32_t id) const; - bool IsUnsignedIntScalarOrVectorType(uint32_t id) const; bool IsSignedIntScalarType(uint32_t id) const; bool IsSignedIntVectorType(uint32_t id) const; bool IsBoolScalarType(uint32_t id) const; @@ -618,11 +609,6 @@ class ValidationState_t { bool IsPointerType(uint32_t id) const; bool IsAccelerationStructureType(uint32_t id) const; bool IsCooperativeMatrixType(uint32_t id) const; - bool IsCooperativeMatrixNVType(uint32_t id) const; - bool IsCooperativeMatrixKHRType(uint32_t id) const; - bool IsCooperativeMatrixAType(uint32_t id) const; - bool IsCooperativeMatrixBType(uint32_t id) const; - bool IsCooperativeMatrixAccType(uint32_t id) const; bool IsFloatCooperativeMatrixType(uint32_t id) const; bool IsIntCooperativeMatrixType(uint32_t id) const; bool IsUnsignedIntCooperativeMatrixType(uint32_t id) const; @@ -630,7 +616,7 @@ class ValidationState_t { // Returns true if |id| is a type id that contains |type| (or integer or // floating point type) of |width| bits. - bool ContainsSizedIntOrFloatType(uint32_t id, spv::Op type, + bool ContainsSizedIntOrFloatType(uint32_t id, SpvOp type, uint32_t width) const; // Returns true if |id| is a type id that contains a 8- or 16-bit int or // 16-bit float that is not generally enabled for use. @@ -656,7 +642,7 @@ class ValidationState_t { // Returns opcode of the instruction which issued the id or OpNop if the // instruction is not registered. - spv::Op GetIdOpcode(uint32_t id) const; + SpvOp GetIdOpcode(uint32_t id) const; // Returns type_id for given id operand if it has a type or zero otherwise. // |operand_index| is expected to be pointing towards an operand which is an @@ -666,7 +652,7 @@ class ValidationState_t { // Provides information on pointer type. Returns false iff not pointer type. bool GetPointerTypeInfo(uint32_t id, uint32_t* data_type, - spv::StorageClass* storage_class) const; + uint32_t* storage_class) const; // Is the ID the type of a pointer to a uniform block: Block-decorated struct // in uniform storage class? The result is only valid after internal method @@ -746,9 +732,6 @@ class ValidationState_t { } return std::string(desc->name); } - std::string SpvDecorationString(spv::Decoration decoration) { - return SpvDecorationString(uint32_t(decoration)); - } // Returns whether type m1 and type m2 are cooperative matrices with // the same "shape" (matching scope, rows, cols). If any are specialization @@ -781,7 +764,7 @@ class ValidationState_t { const Instruction* TracePointer(const Instruction* inst) const; // Validates the storage class for the target environment. - bool IsValidStorageClass(spv::StorageClass storage_class) const; + bool IsValidStorageClass(SpvStorageClass storage_class) const; // Takes a Vulkan Valid Usage ID (VUID) as |id| and optional |reference| and // will return a non-empty string only if ID is known and targeting Vulkan. @@ -799,13 +782,6 @@ class ValidationState_t { current_layout_section_ = section; } - // Check if instruction 'id' is a consumer of a texture decorated - // with a QCOM image processing decoration - bool IsQCOMImageProcessingTextureConsumer(uint32_t id) { - return qcom_image_processing_consumers_.find(id) != - qcom_image_processing_consumers_.end(); - } - private: ValidationState_t(const ValidationState_t&); @@ -840,10 +816,6 @@ class ValidationState_t { std::unordered_map> sampled_image_consumers_; - /// Stores load instructions that load textures used - // in QCOM image processing functions - std::unordered_set qcom_image_processing_consumers_; - /// A map of operand IDs and their names defined by the OpName instruction std::unordered_map operand_names_; @@ -911,8 +883,8 @@ class ValidationState_t { AssemblyGrammar grammar_; - spv::AddressingModel addressing_model_; - spv::MemoryModel memory_model_; + SpvAddressingModel addressing_model_; + SpvMemoryModel memory_model_; // pointer size derived from addressing model. Assumes all storage classes // have the same pointer size (for physical pointer types). uint32_t pointer_size_and_alignment_; @@ -933,11 +905,11 @@ class ValidationState_t { /// Mapping entry point -> execution models. It is presumed that the same /// function could theoretically be used as 'main' by multiple OpEntryPoint /// instructions. - std::unordered_map> + std::unordered_map> entry_point_to_execution_models_; /// Mapping entry point -> execution modes. - std::unordered_map> + std::unordered_map> entry_point_to_execution_modes_; /// Mapping function -> array of entry points inside this diff --git a/source/wasm/build.sh b/source/wasm/build.sh index 69468c9c..f02ae525 100755 --- a/source/wasm/build.sh +++ b/source/wasm/build.sh @@ -16,11 +16,6 @@ set -e -# This is required to run any git command in the docker since owner will -# have changed between the clone environment, and the docker container. -# Marking the root of the repo as safe for ownership changes. -git config --global --add safe.directory /app - NUM_CORES=$(nproc) echo "Detected $NUM_CORES cores for building" @@ -45,7 +40,7 @@ build() { emcc \ --bind \ -I../../include \ - -std=c++17 \ + -std=c++11 \ ../../source/wasm/spirv-tools.cpp \ source/libSPIRV-Tools.a \ -o spirv-tools.js \ diff --git a/source/wasm/docker-compose.yml b/source/wasm/docker-compose.yml deleted file mode 100755 index 2340fdb0..00000000 --- a/source/wasm/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3" -services: - build: - image: emscripten/emsdk:3.1.28 - environment: - GITHUB_RUN_NUMBER: ${GITHUB_RUN_NUMBER:-} - working_dir: /app - command: ./source/wasm/build.sh - volumes: - - ./:/app diff --git a/test.txt b/test.txt old mode 100755 new mode 100644 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 662c0bf4..4ca8ef8f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,7 +31,7 @@ endif() function(add_spvtools_unittest) if (NOT "${SPIRV_SKIP_TESTS}" AND TARGET gmock_main) set(one_value_args TARGET PCH_FILE) - set(multi_value_args SRCS LIBS ENVIRONMENT DEFINES) + set(multi_value_args SRCS LIBS ENVIRONMENT) cmake_parse_arguments( ARG "" "${one_value_args}" "${multi_value_args}" ${ARGN}) set(target test_${ARG_TARGET}) @@ -40,7 +40,6 @@ function(add_spvtools_unittest) spvtools_pch(SRC_COPY ${ARG_PCH_FILE}) endif() add_executable(${target} ${SRC_COPY}) - target_compile_definitions(${target} PUBLIC ${ARG_DEFINES}) spvtools_default_compile_options(${target}) if(${COMPILER_IS_LIKE_GNU}) target_compile_options(${target} PRIVATE -Wno-undef) @@ -111,6 +110,7 @@ set(TEST_SOURCES hex_float_test.cpp immediate_int_test.cpp libspirv_macros_test.cpp + log_test.cpp named_id_test.cpp name_mapper_test.cpp opcode_make_test.cpp diff --git a/test/binary_header_get_test.cpp b/test/binary_header_get_test.cpp index aca09b03..f94f0c1a 100644 --- a/test/binary_header_get_test.cpp +++ b/test/binary_header_get_test.cpp @@ -23,8 +23,8 @@ class BinaryHeaderGet : public ::testing::Test { BinaryHeaderGet() { memset(code, 0, sizeof(code)); } virtual void SetUp() { - code[0] = static_cast(spv::MagicNumber); - code[1] = static_cast(spv::Version); + code[0] = SpvMagicNumber; + code[1] = SpvVersion; code[2] = SPV_GENERATOR_CODEPLAY; code[3] = 1; // NOTE: Bound code[4] = 0; // NOTE: Schema; reserved @@ -50,7 +50,7 @@ TEST_F(BinaryHeaderGet, Default) { spv_header_t header; ASSERT_EQ(SPV_SUCCESS, spvBinaryHeaderGet(&const_bin, endian, &header)); - ASSERT_EQ(static_cast(spv::MagicNumber), header.magic); + ASSERT_EQ(static_cast(SpvMagicNumber), header.magic); // Expect SPIRV-Headers updated to SPIR-V 1.6. ASSERT_EQ(0x00010600u, header.version); ASSERT_EQ(static_cast(SPV_GENERATOR_CODEPLAY), header.generator); diff --git a/test/binary_parse_test.cpp b/test/binary_parse_test.cpp index 1a868dba..f0810a35 100644 --- a/test/binary_parse_test.cpp +++ b/test/binary_parse_test.cpp @@ -54,14 +54,14 @@ using ::testing::Return; struct ParsedInstruction { explicit ParsedInstruction(const spv_parsed_instruction_t& inst) : words(inst.words, inst.words + inst.num_words), - opcode(static_cast(inst.opcode)), + opcode(static_cast(inst.opcode)), ext_inst_type(inst.ext_inst_type), type_id(inst.type_id), result_id(inst.result_id), operands(inst.operands, inst.operands + inst.num_operands) {} std::vector words; - spv::Op opcode; + SpvOp opcode; spv_ext_inst_type_t ext_inst_type; uint32_t type_id; uint32_t result_id; @@ -127,14 +127,14 @@ spv_result_t invoke_instruction( // The SPIR-V module header words for the Khronos Assembler generator, // for a module with an ID bound of 1. const uint32_t kHeaderForBound1[] = { - spv::MagicNumber, spv::Version, + SpvMagicNumber, SpvVersion, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 0), 1 /*bound*/, 0 /*schema*/}; // Returns the expected SPIR-V module header words for the Khronos // Assembler generator, and with a given Id bound. std::vector ExpectedHeaderForBound(uint32_t bound) { - return {spv::MagicNumber, 0x10000, + return {SpvMagicNumber, 0x10000, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 0), bound, 0}; } @@ -162,13 +162,13 @@ spv_parsed_operand_t MakeLiteralStringOperand(uint16_t offset, // Returns a ParsedInstruction for an OpTypeVoid instruction that would // generate the given result Id. ParsedInstruction MakeParsedVoidTypeInstruction(uint32_t result_id) { - const auto void_inst = MakeInstruction(spv::Op::OpTypeVoid, {result_id}); + const auto void_inst = MakeInstruction(SpvOpTypeVoid, {result_id}); const auto void_operands = std::vector{ MakeSimpleOperand(1, SPV_OPERAND_TYPE_RESULT_ID)}; const spv_parsed_instruction_t parsed_void_inst = { void_inst.data(), static_cast(void_inst.size()), - uint16_t(spv::Op::OpTypeVoid), + SpvOpTypeVoid, SPV_EXT_INST_TYPE_NONE, 0, // type id result_id, @@ -180,14 +180,14 @@ ParsedInstruction MakeParsedVoidTypeInstruction(uint32_t result_id) { // Returns a ParsedInstruction for an OpTypeInt instruction that generates // the given result Id for a 32-bit signed integer scalar type. ParsedInstruction MakeParsedInt32TypeInstruction(uint32_t result_id) { - const auto i32_inst = MakeInstruction(spv::Op::OpTypeInt, {result_id, 32, 1}); + const auto i32_inst = MakeInstruction(SpvOpTypeInt, {result_id, 32, 1}); const auto i32_operands = std::vector{ MakeSimpleOperand(1, SPV_OPERAND_TYPE_RESULT_ID), MakeLiteralNumberOperand(2), MakeLiteralNumberOperand(3)}; spv_parsed_instruction_t parsed_i32_inst = { i32_inst.data(), static_cast(i32_inst.size()), - uint16_t(spv::Op::OpTypeInt), + SpvOpTypeInt, SPV_EXT_INST_TYPE_NONE, 0, // type id result_id, @@ -214,48 +214,14 @@ class BinaryParseTest : public spvtest::TextToBinaryTestBase<::testing::Test> { MockParseClient client_; }; -class CxxBinaryParseTest - : public spvtest::TextToBinaryTestBase<::testing::Test> { - protected: - CxxBinaryParseTest() { - header_parser_ = [this](const spv_endianness_t endianness, - const spv_parsed_header_t& header) { - return this->client_.Header(endianness, header.magic, header.version, - header.generator, header.bound, - header.reserved); - }; - - instruction_parser_ = [this](const spv_parsed_instruction_t& instruction) { - return this->client_.Instruction(ParsedInstruction(instruction)); - }; - } - - ~CxxBinaryParseTest() override { spvDiagnosticDestroy(diagnostic_); } - - void Parse(const SpirvVector& words, bool expected_result, - bool flip_words = false, - spv_target_env env = SPV_ENV_UNIVERSAL_1_0) { - SpirvVector flipped_words(words); - MaybeFlipWords(flip_words, flipped_words.begin(), flipped_words.end()); - spvtools::SpirvTools tools(env); - EXPECT_EQ(expected_result, tools.Parse(flipped_words, header_parser_, - instruction_parser_, &diagnostic_)); - } - - spv_diagnostic diagnostic_ = nullptr; - MockParseClient client_; - HeaderParser header_parser_; - InstructionParser instruction_parser_; -}; - // Adds an EXPECT_CALL to client_->Header() with appropriate parameters, // including bound. Returns the EXPECT_CALL result. -#define EXPECT_HEADER(bound) \ - EXPECT_CALL(client_, \ - Header(AnyOf(SPV_ENDIANNESS_LITTLE, SPV_ENDIANNESS_BIG), \ - spv::MagicNumber, 0x10000, \ - SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 0), \ - bound, 0 /*reserved*/)) +#define EXPECT_HEADER(bound) \ + EXPECT_CALL( \ + client_, \ + Header(AnyOf(SPV_ENDIANNESS_LITTLE, SPV_ENDIANNESS_BIG), SpvMagicNumber, \ + 0x10000, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 0), \ + bound, 0 /*reserved*/)) static const bool kSwapEndians[] = {false, true}; @@ -269,16 +235,6 @@ TEST_F(BinaryParseTest, EmptyModuleHasValidHeaderAndNoInstructionCallbacks) { } } -TEST_F(CxxBinaryParseTest, EmptyModuleHasValidHeaderAndNoInstructionCallbacks) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully(""); - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - Parse(words, true, endian_swap); - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, NullDiagnosticsIsOkForGoodParse) { const auto words = CompileSuccessfully(""); EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); @@ -289,15 +245,6 @@ TEST_F(BinaryParseTest, NullDiagnosticsIsOkForGoodParse) { words.size(), invoke_header, invoke_instruction, nullptr)); } -TEST_F(CxxBinaryParseTest, NullDiagnosticsIsOkForGoodParse) { - const auto words = CompileSuccessfully(""); - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); - EXPECT_EQ(true, - tools.Parse(words, header_parser_, instruction_parser_, nullptr)); -} - TEST_F(BinaryParseTest, NullDiagnosticsIsOkForBadParse) { auto words = CompileSuccessfully(""); words.push_back(0xffffffff); // Certainly invalid instruction header. @@ -309,16 +256,6 @@ TEST_F(BinaryParseTest, NullDiagnosticsIsOkForBadParse) { words.size(), invoke_header, invoke_instruction, nullptr)); } -TEST_F(CxxBinaryParseTest, NullDiagnosticsIsOkForBadParse) { - auto words = CompileSuccessfully(""); - words.push_back(0xffffffff); // Certainly invalid instruction header. - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); - EXPECT_EQ(false, - tools.Parse(words, header_parser_, instruction_parser_, nullptr)); -} - // Make sure that we don't blow up when both the consumer and the diagnostic are // null. TEST_F(BinaryParseTest, NullConsumerNullDiagnosticsForBadParse) { @@ -335,18 +272,6 @@ TEST_F(BinaryParseTest, NullConsumerNullDiagnosticsForBadParse) { invoke_header, invoke_instruction, nullptr)); } -TEST_F(CxxBinaryParseTest, NullConsumerNullDiagnosticsForBadParse) { - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); - tools.SetMessageConsumer(nullptr); - - auto words = CompileSuccessfully(""); - words.push_back(0xffffffff); // Certainly invalid instruction header. - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - EXPECT_EQ(false, - tools.Parse(words, header_parser_, instruction_parser_, nullptr)); -} - TEST_F(BinaryParseTest, SpecifyConsumerNullDiagnosticsForGoodParse) { const auto words = CompileSuccessfully(""); @@ -364,21 +289,6 @@ TEST_F(BinaryParseTest, SpecifyConsumerNullDiagnosticsForGoodParse) { EXPECT_EQ(0, invocation); } -TEST_F(CxxBinaryParseTest, SpecifyConsumerNullDiagnosticsForGoodParse) { - const auto words = CompileSuccessfully(""); - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); - int invocation = 0; - tools.SetMessageConsumer([&invocation](spv_message_level_t, const char*, - const spv_position_t&, - const char*) { ++invocation; }); - - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - EXPECT_EQ(true, - tools.Parse(words, header_parser_, instruction_parser_, nullptr)); - EXPECT_EQ(0, invocation); -} - TEST_F(BinaryParseTest, SpecifyConsumerNullDiagnosticsForBadParse) { auto words = CompileSuccessfully(""); @@ -405,30 +315,6 @@ TEST_F(BinaryParseTest, SpecifyConsumerNullDiagnosticsForBadParse) { EXPECT_EQ(1, invocation); } -TEST_F(CxxBinaryParseTest, SpecifyConsumerNullDiagnosticsForBadParse) { - auto words = CompileSuccessfully(""); - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); - int invocation = 0; - tools.SetMessageConsumer( - [&invocation](spv_message_level_t level, const char* source, - const spv_position_t& position, const char* message) { - ++invocation; - EXPECT_EQ(SPV_MSG_ERROR, level); - EXPECT_STREQ("input", source); - EXPECT_EQ(0u, position.line); - EXPECT_EQ(0u, position.column); - EXPECT_EQ(1u, position.index); - EXPECT_STREQ("Invalid opcode: 65535", message); - }); - - words.push_back(0xffffffff); // Certainly invalid instruction header. - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - EXPECT_EQ(false, - tools.Parse(words, header_parser_, instruction_parser_, nullptr)); - EXPECT_EQ(1, invocation); -} - TEST_F(BinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForGoodParse) { const auto words = CompileSuccessfully(""); @@ -447,22 +333,6 @@ TEST_F(BinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForGoodParse) { EXPECT_EQ(nullptr, diagnostic_); } -TEST_F(CxxBinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForGoodParse) { - const auto words = CompileSuccessfully(""); - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); - int invocation = 0; - tools.SetMessageConsumer([&invocation](spv_message_level_t, const char*, - const spv_position_t&, - const char*) { ++invocation; }); - - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - EXPECT_EQ(true, tools.Parse(words, header_parser_, instruction_parser_, - &diagnostic_)); - EXPECT_EQ(0, invocation); - EXPECT_EQ(nullptr, diagnostic_); -} - TEST_F(BinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForBadParse) { auto words = CompileSuccessfully(""); @@ -482,23 +352,6 @@ TEST_F(BinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForBadParse) { EXPECT_STREQ("Invalid opcode: 65535", diagnostic_->error); } -TEST_F(CxxBinaryParseTest, SpecifyConsumerSpecifyDiagnosticsForBadParse) { - auto words = CompileSuccessfully(""); - spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); - int invocation = 0; - tools.SetMessageConsumer([&invocation](spv_message_level_t, const char*, - const spv_position_t&, - const char*) { ++invocation; }); - - words.push_back(0xffffffff); // Certainly invalid instruction header. - EXPECT_HEADER(1).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).Times(0); // No instruction callback. - EXPECT_EQ(false, tools.Parse(words, header_parser_, instruction_parser_, - &diagnostic_)); - EXPECT_EQ(0, invocation); - EXPECT_STREQ("Invalid opcode: 65535", diagnostic_->error); -} - TEST_F(BinaryParseTest, ModuleWithSingleInstructionHasValidHeaderAndInstructionCallback) { for (bool endian_swap : kSwapEndians) { @@ -512,19 +365,6 @@ TEST_F(BinaryParseTest, } } -TEST_F(CxxBinaryParseTest, - ModuleWithSingleInstructionHasValidHeaderAndInstructionCallback) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully("%1 = OpTypeVoid"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(2).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedVoidTypeInstruction(1))) - .WillOnce(Return(SPV_SUCCESS)); - Parse(words, true, endian_swap); - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, NullHeaderCallbackIsIgnored) { const auto words = CompileSuccessfully("%1 = OpTypeVoid"); EXPECT_CALL(client_, Header(_, _, _, _, _, _)) @@ -568,22 +408,6 @@ TEST_F(BinaryParseTest, TwoScalarTypesGenerateTwoInstructionCallbacks) { } } -TEST_F(CxxBinaryParseTest, TwoScalarTypesGenerateTwoInstructionCallbacks) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully( - "%1 = OpTypeVoid " - "%2 = OpTypeInt 32 1"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(3).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedVoidTypeInstruction(1))) - .WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedInt32TypeInstruction(2))) - .WillOnce(Return(SPV_SUCCESS)); - Parse(words, true, endian_swap); - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, EarlyReturnWithZeroPassingCallbacks) { for (bool endian_swap : kSwapEndians) { const auto words = CompileSuccessfully( @@ -599,21 +423,6 @@ TEST_F(BinaryParseTest, EarlyReturnWithZeroPassingCallbacks) { } } -TEST_F(CxxBinaryParseTest, EarlyReturnWithZeroPassingCallbacks) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully( - "%1 = OpTypeVoid " - "%2 = OpTypeInt 32 1"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(3).WillOnce(Return(SPV_ERROR_INVALID_BINARY)); - // Early exit means no calls to Instruction(). - EXPECT_CALL(client_, Instruction(_)).Times(0); - Parse(words, false, endian_swap); - // On error, the binary parser doesn't generate its own diagnostics. - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, EarlyReturnWithZeroPassingCallbacksAndSpecifiedResultCode) { for (bool endian_swap : kSwapEndians) { @@ -631,23 +440,6 @@ TEST_F(BinaryParseTest, } } -TEST_F(CxxBinaryParseTest, - EarlyReturnWithZeroPassingCallbacksAndSpecifiedResultCode) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully( - "%1 = OpTypeVoid " - "%2 = OpTypeInt 32 1"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(3).WillOnce(Return(SPV_REQUESTED_TERMINATION)); - // Early exit means no calls to Instruction(). - EXPECT_CALL(client_, Instruction(_)).Times(0); - Parse(words, false, endian_swap); - // On early termination, the binary parser doesn't generate its own - // diagnostics. - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, EarlyReturnWithOnePassingCallback) { for (bool endian_swap : kSwapEndians) { const auto words = CompileSuccessfully( @@ -665,23 +457,6 @@ TEST_F(BinaryParseTest, EarlyReturnWithOnePassingCallback) { } } -TEST_F(CxxBinaryParseTest, EarlyReturnWithOnePassingCallback) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully( - "%1 = OpTypeVoid " - "%2 = OpTypeInt 32 1 " - "%3 = OpTypeFloat 32"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(4).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedVoidTypeInstruction(1))) - .WillOnce(Return(SPV_REQUESTED_TERMINATION)); - Parse(words, false, endian_swap); - // On early termination, the binary parser doesn't generate its own - // diagnostics. - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, EarlyReturnWithTwoPassingCallbacks) { for (bool endian_swap : kSwapEndians) { const auto words = CompileSuccessfully( @@ -701,75 +476,30 @@ TEST_F(BinaryParseTest, EarlyReturnWithTwoPassingCallbacks) { } } -TEST_F(CxxBinaryParseTest, EarlyReturnWithTwoPassingCallbacks) { - for (bool endian_swap : kSwapEndians) { - const auto words = CompileSuccessfully( - "%1 = OpTypeVoid " - "%2 = OpTypeInt 32 1 " - "%3 = OpTypeFloat 32"); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(4).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedVoidTypeInstruction(1))) - .WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(MakeParsedInt32TypeInstruction(2))) - .WillOnce(Return(SPV_REQUESTED_TERMINATION)); - Parse(words, false, endian_swap); - // On early termination, the binary parser doesn't generate its own - // diagnostics. - EXPECT_EQ(nullptr, diagnostic_); - } -} - TEST_F(BinaryParseTest, InstructionWithStringOperand) { for (bool endian_swap : kSwapEndians) { const std::string str = "the future is already here, it's just not evenly distributed"; const auto str_words = MakeVector(str); - const auto instruction = MakeInstruction(spv::Op::OpName, {99}, str_words); + const auto instruction = MakeInstruction(SpvOpName, {99}, str_words); const auto words = Concatenate({ExpectedHeaderForBound(100), instruction}); InSequence calls_expected_in_specific_order; EXPECT_HEADER(100).WillOnce(Return(SPV_SUCCESS)); const auto operands = std::vector{ MakeSimpleOperand(1, SPV_OPERAND_TYPE_ID), MakeLiteralStringOperand(2, static_cast(str_words.size()))}; - EXPECT_CALL( - client_, - Instruction(ParsedInstruction(spv_parsed_instruction_t{ - instruction.data(), static_cast(instruction.size()), - uint16_t(spv::Op::OpName), SPV_EXT_INST_TYPE_NONE, 0 /*type id*/, - 0 /* No result id for OpName*/, operands.data(), - static_cast(operands.size())}))) + EXPECT_CALL(client_, Instruction(ParsedInstruction(spv_parsed_instruction_t{ + instruction.data(), + static_cast(instruction.size()), + SpvOpName, SPV_EXT_INST_TYPE_NONE, 0 /*type id*/, + 0 /* No result id for OpName*/, operands.data(), + static_cast(operands.size())}))) .WillOnce(Return(SPV_SUCCESS)); Parse(words, SPV_SUCCESS, endian_swap); EXPECT_EQ(nullptr, diagnostic_); } } -TEST_F(CxxBinaryParseTest, InstructionWithStringOperand) { - for (bool endian_swap : kSwapEndians) { - const std::string str = - "the future is already here, it's just not evenly distributed"; - const auto str_words = MakeVector(str); - const auto instruction = MakeInstruction(spv::Op::OpName, {99}, str_words); - const auto words = Concatenate({ExpectedHeaderForBound(100), instruction}); - InSequence calls_expected_in_specific_order; - EXPECT_HEADER(100).WillOnce(Return(SPV_SUCCESS)); - const auto operands = std::vector{ - MakeSimpleOperand(1, SPV_OPERAND_TYPE_ID), - MakeLiteralStringOperand(2, static_cast(str_words.size()))}; - EXPECT_CALL( - client_, - Instruction(ParsedInstruction(spv_parsed_instruction_t{ - instruction.data(), static_cast(instruction.size()), - uint16_t(spv::Op::OpName), SPV_EXT_INST_TYPE_NONE, 0 /*type id*/, - 0 /* No result id for OpName*/, operands.data(), - static_cast(operands.size())}))) - .WillOnce(Return(SPV_SUCCESS)); - Parse(words, true, endian_swap); - EXPECT_EQ(nullptr, diagnostic_); - } -} - // Checks for non-zero values for the result_id and ext_inst_type members // spv_parsed_instruction_t. TEST_F(BinaryParseTest, ExtendedInstruction) { @@ -788,13 +518,13 @@ TEST_F(BinaryParseTest, ExtendedInstruction) { MakeSimpleOperand(5, SPV_OPERAND_TYPE_ID), // Id of the argument }; const auto instruction = MakeInstruction( - spv::Op::OpExtInst, + SpvOpExtInst, {2, 3, 1, static_cast(OpenCLLIB::Entrypoints::Sqrt), 4}); EXPECT_CALL(client_, Instruction(ParsedInstruction(spv_parsed_instruction_t{ instruction.data(), static_cast(instruction.size()), - uint16_t(spv::Op::OpExtInst), SPV_EXT_INST_TYPE_OPENCL_STD, - 2 /*type id*/, 3 /*result id*/, operands.data(), + SpvOpExtInst, SPV_EXT_INST_TYPE_OPENCL_STD, 2 /*type id*/, + 3 /*result id*/, operands.data(), static_cast(operands.size())}))) .WillOnce(Return(SPV_SUCCESS)); // Since we are actually checking the output, don't test the @@ -803,37 +533,6 @@ TEST_F(BinaryParseTest, ExtendedInstruction) { EXPECT_EQ(nullptr, diagnostic_); } -TEST_F(CxxBinaryParseTest, ExtendedInstruction) { - const auto words = CompileSuccessfully( - "%extcl = OpExtInstImport \"OpenCL.std\" " - "%result = OpExtInst %float %extcl sqrt %x"); - EXPECT_HEADER(5).WillOnce(Return(SPV_SUCCESS)); - EXPECT_CALL(client_, Instruction(_)).WillOnce(Return(SPV_SUCCESS)); - // We're only interested in the second call to Instruction(): - const auto operands = std::vector{ - MakeSimpleOperand(1, SPV_OPERAND_TYPE_TYPE_ID), - MakeSimpleOperand(2, SPV_OPERAND_TYPE_RESULT_ID), - MakeSimpleOperand(3, - SPV_OPERAND_TYPE_ID), // Extended instruction set Id - MakeSimpleOperand(4, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER), - MakeSimpleOperand(5, SPV_OPERAND_TYPE_ID), // Id of the argument - }; - const auto instruction = MakeInstruction( - spv::Op::OpExtInst, - {2, 3, 1, static_cast(OpenCLLIB::Entrypoints::Sqrt), 4}); - EXPECT_CALL(client_, - Instruction(ParsedInstruction(spv_parsed_instruction_t{ - instruction.data(), static_cast(instruction.size()), - uint16_t(spv::Op::OpExtInst), SPV_EXT_INST_TYPE_OPENCL_STD, - 2 /*type id*/, 3 /*result id*/, operands.data(), - static_cast(operands.size())}))) - .WillOnce(Return(SPV_SUCCESS)); - // Since we are actually checking the output, don't test the - // endian-swapped version. - Parse(words, true, false); - EXPECT_EQ(nullptr, diagnostic_); -} - // A binary parser diagnostic test case where we provide the words array // pointer and word count explicitly. struct WordsAndCountDiagnosticCase { @@ -894,38 +593,36 @@ TEST_P(BinaryParseWordVectorDiagnosticTest, WordVectorCases) { INSTANTIATE_TEST_SUITE_P( BinaryParseDiagnostic, BinaryParseWordVectorDiagnosticTest, ::testing::ValuesIn(std::vector{ - {Concatenate({ExpectedHeaderForBound(1), - {spvOpcodeMake(0, spv::Op::OpNop)}}), + {Concatenate({ExpectedHeaderForBound(1), {spvOpcodeMake(0, SpvOpNop)}}), "Invalid instruction word count: 0"}, {Concatenate( {ExpectedHeaderForBound(1), - {spvOpcodeMake(1, static_cast( + {spvOpcodeMake(1, static_cast( std::numeric_limits::max()))}}), "Invalid opcode: 65535"}, {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpNop, {42})}), + MakeInstruction(SpvOpNop, {42})}), "Invalid instruction OpNop starting at word 5: expected " "no more operands after 1 words, but stated word count is 2."}, // Supply several more unexpected words. {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpNop, - {42, 43, 44, 45, 46, 47})}), + MakeInstruction(SpvOpNop, {42, 43, 44, 45, 46, 47})}), "Invalid instruction OpNop starting at word 5: expected " "no more operands after 1 words, but stated word count is 7."}, {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpTypeVoid, {1, 2})}), + MakeInstruction(SpvOpTypeVoid, {1, 2})}), "Invalid instruction OpTypeVoid starting at word 5: expected " "no more operands after 2 words, but stated word count is 3."}, {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpTypeVoid, {1, 2, 5, 9, 10})}), + MakeInstruction(SpvOpTypeVoid, {1, 2, 5, 9, 10})}), "Invalid instruction OpTypeVoid starting at word 5: expected " "no more operands after 2 words, but stated word count is 6."}, {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1, 9})}), + MakeInstruction(SpvOpTypeInt, {1, 32, 1, 9})}), "Invalid instruction OpTypeInt starting at word 5: expected " "no more operands after 4 words, but stated word count is 5."}, {Concatenate({ExpectedHeaderForBound(1), - MakeInstruction(spv::Op::OpTypeInt, {1})}), + MakeInstruction(SpvOpTypeInt, {1})}), "End of input reached while decoding OpTypeInt starting at word 5:" " expected more operands after 2 words."}, @@ -933,7 +630,7 @@ INSTANTIATE_TEST_SUITE_P( // Detect a missing single word operand. {Concatenate({ExpectedHeaderForBound(1), - {spvOpcodeMake(2, spv::Op::OpTypeStruct)}}), + {spvOpcodeMake(2, SpvOpTypeStruct)}}), "End of input reached while decoding OpTypeStruct starting at word" " 5: missing result ID operand at word offset 1."}, // Detect this a missing a multi-word operand to OpConstant. @@ -942,29 +639,29 @@ INSTANTIATE_TEST_SUITE_P( // %1 = OpTypeInt 64 0 // %2 = OpConstant %1 {Concatenate({ExpectedHeaderForBound(3), - {MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0})}, - {spvOpcodeMake(5, spv::Op::OpConstant), 1, 2}}), + {MakeInstruction(SpvOpTypeInt, {1, 64, 0})}, + {spvOpcodeMake(5, SpvOpConstant), 1, 2}}), "End of input reached while decoding OpConstant starting at word" " 9: missing possibly multi-word literal number operand at word " "offset 3."}, // Detect when we provide only one word from the 64-bit literal, // and again lie about the number of words in the instruction. {Concatenate({ExpectedHeaderForBound(3), - {MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0})}, - {spvOpcodeMake(5, spv::Op::OpConstant), 1, 2, 42}}), + {MakeInstruction(SpvOpTypeInt, {1, 64, 0})}, + {spvOpcodeMake(5, SpvOpConstant), 1, 2, 42}}), "End of input reached while decoding OpConstant starting at word" " 9: truncated possibly multi-word literal number operand at word " "offset 3."}, // Detect when a required string operand is missing. // Also, lie about the length of the instruction. {Concatenate({ExpectedHeaderForBound(3), - {spvOpcodeMake(3, spv::Op::OpString), 1}}), + {spvOpcodeMake(3, SpvOpString), 1}}), "End of input reached while decoding OpString starting at word" " 5: missing literal string operand at word offset 2."}, // Detect when a required string operand is truncated: it's missing // a null terminator. Catching the error avoids a buffer overrun. {Concatenate({ExpectedHeaderForBound(3), - {spvOpcodeMake(4, spv::Op::OpString), 1, 0x41414141, + {spvOpcodeMake(4, SpvOpString), 1, 0x41414141, 0x41414141}}), "End of input reached while decoding OpString starting at word" " 5: truncated literal string operand at word offset 2."}, @@ -972,9 +669,9 @@ INSTANTIATE_TEST_SUITE_P( // a null terminator. Catching the error avoids a buffer overrun. // (It is valid for an optional string operand to be absent.) {Concatenate({ExpectedHeaderForBound(3), - {spvOpcodeMake(6, spv::Op::OpSource), - static_cast(spv::SourceLanguage::OpenCL_C), - 210, 1 /* file id */, + {spvOpcodeMake(6, SpvOpSource), + static_cast(SpvSourceLanguageOpenCL_C), 210, + 1 /* file id */, /*start of string*/ 0x41414141, 0x41414141}}), "End of input reached while decoding OpSource starting at word" " 5: truncated literal string operand at word offset 4."}, @@ -984,19 +681,19 @@ INSTANTIATE_TEST_SUITE_P( // In this case the instruction word count is too small, where // it would truncate a multi-word operand to OpConstant. {Concatenate({ExpectedHeaderForBound(3), - {MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0})}, - {spvOpcodeMake(4, spv::Op::OpConstant), 1, 2, 44, 44}}), + {MakeInstruction(SpvOpTypeInt, {1, 64, 0})}, + {spvOpcodeMake(4, SpvOpConstant), 1, 2, 44, 44}}), "Invalid word count: OpConstant starting at word 9 says it has 4" " words, but found 5 words instead."}, // Word count is to small, where it would truncate a literal string. {Concatenate({ExpectedHeaderForBound(2), - {spvOpcodeMake(3, spv::Op::OpString), 1, 0x41414141, 0}}), + {spvOpcodeMake(3, SpvOpString), 1, 0x41414141, 0}}), "Invalid word count: OpString starting at word 5 says it has 3" " words, but found 4 words instead."}, // Word count is too large. The string terminates before the last // word. {Concatenate({ExpectedHeaderForBound(2), - {spvOpcodeMake(4, spv::Op::OpString), 1 /* result id */}, + {spvOpcodeMake(4, SpvOpString), 1 /* result id */}, MakeVector("abc"), {0 /* this word does not belong*/}}), "Invalid instruction OpString starting at word 5: expected no more" @@ -1004,116 +701,111 @@ INSTANTIATE_TEST_SUITE_P( // Word count is too large. There are too many words after the string // literal. A linkage attribute decoration is the only case in SPIR-V // where a string operand is followed by another operand. - {Concatenate( - {ExpectedHeaderForBound(2), - {spvOpcodeMake(6, spv::Op::OpDecorate), 1 /* target id */, - static_cast(spv::Decoration::LinkageAttributes)}, - MakeVector("abc"), - {static_cast(spv::LinkageType::Import), - 0 /* does not belong */}}), + {Concatenate({ExpectedHeaderForBound(2), + {spvOpcodeMake(6, SpvOpDecorate), 1 /* target id */, + static_cast(SpvDecorationLinkageAttributes)}, + MakeVector("abc"), + {static_cast(SpvLinkageTypeImport), + 0 /* does not belong */}}), "Invalid instruction OpDecorate starting at word 5: expected no more" " operands after 5 words, but stated word count is 6."}, // Like the previous case, but with 5 extra words. - {Concatenate( - {ExpectedHeaderForBound(2), - {spvOpcodeMake(10, spv::Op::OpDecorate), 1 /* target id */, - static_cast(spv::Decoration::LinkageAttributes)}, - MakeVector("abc"), - {static_cast(spv::LinkageType::Import), - /* don't belong */ 0, 1, 2, 3, 4}}), + {Concatenate({ExpectedHeaderForBound(2), + {spvOpcodeMake(10, SpvOpDecorate), 1 /* target id */, + static_cast(SpvDecorationLinkageAttributes)}, + MakeVector("abc"), + {static_cast(SpvLinkageTypeImport), + /* don't belong */ 0, 1, 2, 3, 4}}), "Invalid instruction OpDecorate starting at word 5: expected no more" " operands after 5 words, but stated word count is 10."}, // Like the previous two cases, but with OpMemberDecorate. - {Concatenate( - {ExpectedHeaderForBound(2), - {spvOpcodeMake(7, spv::Op::OpMemberDecorate), 1 /* target id */, - 42 /* member index */, - static_cast(spv::Decoration::LinkageAttributes)}, - MakeVector("abc"), - {static_cast(spv::LinkageType::Import), - 0 /* does not belong */}}), + {Concatenate({ExpectedHeaderForBound(2), + {spvOpcodeMake(7, SpvOpMemberDecorate), 1 /* target id */, + 42 /* member index */, + static_cast(SpvDecorationLinkageAttributes)}, + MakeVector("abc"), + {static_cast(SpvLinkageTypeImport), + 0 /* does not belong */}}), "Invalid instruction OpMemberDecorate starting at word 5: expected no" " more operands after 6 words, but stated word count is 7."}, - {Concatenate( - {ExpectedHeaderForBound(2), - {spvOpcodeMake(11, spv::Op::OpMemberDecorate), 1 /* target id */, - 42 /* member index */, - static_cast(spv::Decoration::LinkageAttributes)}, - MakeVector("abc"), - {static_cast(spv::LinkageType::Import), - /* don't belong */ 0, 1, 2, 3, 4}}), + {Concatenate({ExpectedHeaderForBound(2), + {spvOpcodeMake(11, SpvOpMemberDecorate), + 1 /* target id */, 42 /* member index */, + static_cast(SpvDecorationLinkageAttributes)}, + MakeVector("abc"), + {static_cast(SpvLinkageTypeImport), + /* don't belong */ 0, 1, 2, 3, 4}}), "Invalid instruction OpMemberDecorate starting at word 5: expected no" " more operands after 6 words, but stated word count is 11."}, // Word count is too large. There should be no more words // after the RelaxedPrecision decoration. {Concatenate({ExpectedHeaderForBound(2), - {spvOpcodeMake(4, spv::Op::OpDecorate), 1 /* target id */, - static_cast(spv::Decoration::RelaxedPrecision), + {spvOpcodeMake(4, SpvOpDecorate), 1 /* target id */, + static_cast(SpvDecorationRelaxedPrecision), 0 /* does not belong */}}), "Invalid instruction OpDecorate starting at word 5: expected no" " more operands after 3 words, but stated word count is 4."}, // Word count is too large. There should be only one word after // the SpecId decoration enum word. {Concatenate({ExpectedHeaderForBound(2), - {spvOpcodeMake(5, spv::Op::OpDecorate), 1 /* target id */, - static_cast(spv::Decoration::SpecId), + {spvOpcodeMake(5, SpvOpDecorate), 1 /* target id */, + static_cast(SpvDecorationSpecId), 42 /* the spec id */, 0 /* does not belong */}}), "Invalid instruction OpDecorate starting at word 5: expected no" " more operands after 4 words, but stated word count is 5."}, {Concatenate({ExpectedHeaderForBound(2), - {spvOpcodeMake(2, spv::Op::OpTypeVoid), 0}}), + {spvOpcodeMake(2, SpvOpTypeVoid), 0}}), "Error: Result Id is 0"}, {Concatenate({ ExpectedHeaderForBound(2), - {spvOpcodeMake(2, spv::Op::OpTypeVoid), 1}, - {spvOpcodeMake(2, spv::Op::OpTypeBool), 1}, + {spvOpcodeMake(2, SpvOpTypeVoid), 1}, + {spvOpcodeMake(2, SpvOpTypeBool), 1}, }), "Id 1 is defined more than once"}, {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 100, 4, 5})}), + MakeInstruction(SpvOpExtInst, {2, 3, 100, 4, 5})}), "OpExtInst set Id 100 does not reference an OpExtInstImport result " "Id"}, {Concatenate({ExpectedHeaderForBound(101), - MakeInstruction(spv::Op::OpExtInstImport, {100}, + MakeInstruction(SpvOpExtInstImport, {100}, MakeVector("OpenCL.std")), // OpenCL cos is #14 - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 100, 14, 5, 999})}), + MakeInstruction(SpvOpExtInst, {2, 3, 100, 14, 5, 999})}), "Invalid instruction OpExtInst starting at word 10: expected no " "more operands after 6 words, but stated word count is 7."}, // In this case, the OpSwitch selector refers to an invalid ID. {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpSwitch, {1, 2, 42, 3})}), + MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}), "Invalid OpSwitch: selector id 1 has no type"}, // In this case, the OpSwitch selector refers to an ID that has // no type. {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpLabel, {1}), - MakeInstruction(spv::Op::OpSwitch, {1, 2, 42, 3})}), + MakeInstruction(SpvOpLabel, {1}), + MakeInstruction(SpvOpSwitch, {1, 2, 42, 3})}), "Invalid OpSwitch: selector id 1 has no type"}, {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpSwitch, {1, 3, 42, 3})}), + MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpSwitch, {1, 3, 42, 3})}), "Invalid OpSwitch: selector id 1 is a type, not a value"}, {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x78f00000}), - MakeInstruction(spv::Op::OpSwitch, {2, 3, 42, 3})}), + MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0x78f00000}), + MakeInstruction(SpvOpSwitch, {2, 3, 42, 3})}), "Invalid OpSwitch: selector id 2 is not a scalar integer"}, {Concatenate({ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpExtInstImport, {1}, + MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("invalid-import"))}), "Invalid extended instruction import 'invalid-import'"}, {Concatenate({ ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpConstant, {2, 2, 42}), + MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpConstant, {2, 2, 42}), }), "Type Id 2 is not a type"}, {Concatenate({ ExpectedHeaderForBound(3), - MakeInstruction(spv::Op::OpTypeBool, {1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 42}), + MakeInstruction(SpvOpTypeBool, {1}), + MakeInstruction(SpvOpConstant, {1, 2, 42}), }), "Type Id 1 is not a scalar numeric type"}, })); @@ -1154,10 +846,7 @@ INSTANTIATE_TEST_SUITE_P( {"%2 = OpSpecConstantOp %1 !1000 %2", "Invalid OpSpecConstantOp opcode: 1000"}, {"OpCapability !9999", "Invalid capability operand: 9999"}, - {"OpSource !9999 100", - "Invalid source language operand: 9999, if you are creating a new " - "source language please use value 0 (Unknown) and when ready, add " - "your source language to SPRIV-Headers"}, + {"OpSource !9999 100", "Invalid source language operand: 9999"}, {"OpEntryPoint !9999", "Invalid execution model operand: 9999"}, {"OpMemoryModel !9999", "Invalid addressing model operand: 9999"}, {"OpMemoryModel Logical !9999", "Invalid memory model operand: 9999"}, diff --git a/test/binary_to_text_test.cpp b/test/binary_to_text_test.cpp index 85d5bd1d..44705f2a 100644 --- a/test/binary_to_text_test.cpp +++ b/test/binary_to_text_test.cpp @@ -185,43 +185,43 @@ TEST_P(BinaryToTextFail, EncodeSuccessfullyDecodeFailed) { INSTANTIATE_TEST_SUITE_P( InvalidIds, BinaryToTextFail, ::testing::ValuesIn(std::vector{ - {"", spvtest::MakeInstruction(spv::Op::OpTypeVoid, {0}), + {"", spvtest::MakeInstruction(SpvOpTypeVoid, {0}), "Error: Result Id is 0"}, - {"", spvtest::MakeInstruction(spv::Op::OpConstant, {0, 1, 42}), + {"", spvtest::MakeInstruction(SpvOpConstant, {0, 1, 42}), "Error: Type Id is 0"}, - {"%1 = OpTypeVoid", spvtest::MakeInstruction(spv::Op::OpTypeVoid, {1}), + {"%1 = OpTypeVoid", spvtest::MakeInstruction(SpvOpTypeVoid, {1}), "Id 1 is defined more than once"}, {"%1 = OpTypeVoid\n" "%2 = OpNot %1 %foo", - spvtest::MakeInstruction(spv::Op::OpNot, {1, 2, 3}), + spvtest::MakeInstruction(SpvOpNot, {1, 2, 3}), "Id 2 is defined more than once"}, {"%1 = OpTypeVoid\n" "%2 = OpNot %1 %foo", - spvtest::MakeInstruction(spv::Op::OpNot, {1, 1, 3}), + spvtest::MakeInstruction(SpvOpNot, {1, 1, 3}), "Id 1 is defined more than once"}, // The following are the two failure cases for // Parser::setNumericTypeInfoForType. - {"", spvtest::MakeInstruction(spv::Op::OpConstant, {500, 1, 42}), + {"", spvtest::MakeInstruction(SpvOpConstant, {500, 1, 42}), "Type Id 500 is not a type"}, {"%1 = OpTypeInt 32 0\n" "%2 = OpTypeVector %1 4", - spvtest::MakeInstruction(spv::Op::OpConstant, {2, 3, 999}), + spvtest::MakeInstruction(SpvOpConstant, {2, 3, 999}), "Type Id 2 is not a scalar numeric type"}, })); INSTANTIATE_TEST_SUITE_P( InvalidIdsCheckedDuringLiteralCaseParsing, BinaryToTextFail, ::testing::ValuesIn(std::vector{ - {"", spvtest::MakeInstruction(spv::Op::OpSwitch, {1, 2, 3, 4}), + {"", spvtest::MakeInstruction(SpvOpSwitch, {1, 2, 3, 4}), "Invalid OpSwitch: selector id 1 has no type"}, {"%1 = OpTypeVoid\n", - spvtest::MakeInstruction(spv::Op::OpSwitch, {1, 2, 3, 4}), + spvtest::MakeInstruction(SpvOpSwitch, {1, 2, 3, 4}), "Invalid OpSwitch: selector id 1 is a type, not a value"}, {"%1 = OpConstantTrue !500", - spvtest::MakeInstruction(spv::Op::OpSwitch, {1, 2, 3, 4}), + spvtest::MakeInstruction(SpvOpSwitch, {1, 2, 3, 4}), "Type Id 500 is not a type"}, {"%1 = OpTypeFloat 32\n%2 = OpConstant %1 1.5", - spvtest::MakeInstruction(spv::Op::OpSwitch, {2, 3, 4, 5}), + spvtest::MakeInstruction(SpvOpSwitch, {2, 3, 4, 5}), "Invalid OpSwitch: selector id 2 is not a scalar integer"}, })); diff --git a/test/comment_test.cpp b/test/comment_test.cpp index 5cc9b1d7..49f8df65 100644 --- a/test/comment_test.cpp +++ b/test/comment_test.cpp @@ -40,10 +40,10 @@ TEST_F(TextToBinaryTest, Whitespace) { EXPECT_THAT( CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpMemoryModel, - {uint32_t(spv::AddressingModel::Logical), - uint32_t(spv::MemoryModel::Simple)}), - MakeInstruction(spv::Op::OpExtInstImport, {1}, + Eq(Concatenate({MakeInstruction(SpvOpMemoryModel, + {uint32_t(SpvAddressingModelLogical), + uint32_t(SpvMemoryModelSimple)}), + MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("GLSL.std.450"))}))); } diff --git a/test/cpp_interface_test.cpp b/test/cpp_interface_test.cpp index 222f44f6..4cab4dfd 100644 --- a/test/cpp_interface_test.cpp +++ b/test/cpp_interface_test.cpp @@ -19,7 +19,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "spirv-tools/optimizer.hpp" -#include "spirv/unified1/spirv.hpp11" +#include "spirv/1.1/spirv.h" namespace spvtools { namespace { @@ -47,7 +47,7 @@ TEST(CppInterface, SuccessfulRoundTrip) { std::vector binary; EXPECT_TRUE(t.Assemble(input_text, &binary)); EXPECT_TRUE(binary.size() > 5u); - EXPECT_EQ(spv::MagicNumber, binary[0]); + EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(kExpectedSpvVersion, binary[1]); // This cannot pass validation since %1 is not defined. @@ -74,7 +74,7 @@ TEST(CppInterface, AssembleEmptyModule) { EXPECT_TRUE(t.Assemble("", &binary)); // We only have the header. EXPECT_EQ(5u, binary.size()); - EXPECT_EQ(spv::MagicNumber, binary[0]); + EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(kExpectedSpvVersion, binary[1]); } @@ -85,21 +85,21 @@ TEST(CppInterface, AssembleOverloads) { std::vector binary; EXPECT_TRUE(t.Assemble(input_text, &binary)); EXPECT_TRUE(binary.size() > 5u); - EXPECT_EQ(spv::MagicNumber, binary[0]); + EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(kExpectedSpvVersion, binary[1]); } { std::vector binary; EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size(), &binary)); EXPECT_TRUE(binary.size() > 5u); - EXPECT_EQ(spv::MagicNumber, binary[0]); + EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(kExpectedSpvVersion, binary[1]); } { // Ignore the last newline. std::vector binary; EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size() - 1, &binary)); EXPECT_TRUE(binary.size() > 5u); - EXPECT_EQ(spv::MagicNumber, binary[0]); + EXPECT_EQ(SpvMagicNumber, binary[0]); EXPECT_EQ(kExpectedSpvVersion, binary[1]); } } @@ -322,36 +322,6 @@ TEST(CppInterface, OptimizeSameAddressForOriginalOptimizedBinary) { EXPECT_EQ(Header(), optimized_text); } -TEST(SpirvHeadersCpp, BitwiseOrMemoryAccessMask) { - EXPECT_EQ(spv::MemoryAccessMask(6), spv::MemoryAccessMask::Aligned | - spv::MemoryAccessMask::Nontemporal); -} - -TEST(SpirvHeadersCpp, BitwiseAndMemoryAccessMask) { - EXPECT_EQ(spv::MemoryAccessMask::Aligned, - spv::MemoryAccessMask::Aligned & spv::MemoryAccessMask(6)); - EXPECT_EQ(spv::MemoryAccessMask::Nontemporal, - spv::MemoryAccessMask::Nontemporal & spv::MemoryAccessMask(6)); - EXPECT_EQ(spv::MemoryAccessMask(0), spv::MemoryAccessMask::Nontemporal & - spv::MemoryAccessMask::Aligned); -} - -TEST(SpirvHeadersCpp, BitwiseXorMemoryAccessMask) { - EXPECT_EQ(spv::MemoryAccessMask::Nontemporal, - spv::MemoryAccessMask::Aligned ^ spv::MemoryAccessMask(6)); - EXPECT_EQ(spv::MemoryAccessMask::Aligned, - spv::MemoryAccessMask::Nontemporal ^ spv::MemoryAccessMask(6)); - EXPECT_EQ(spv::MemoryAccessMask(6), spv::MemoryAccessMask::Nontemporal ^ - spv::MemoryAccessMask::Aligned); - EXPECT_EQ(spv::MemoryAccessMask(0), spv::MemoryAccessMask::Nontemporal ^ - spv::MemoryAccessMask::Nontemporal); -} - -TEST(SpirvHeadersCpp, BitwiseNegateMemoryAccessMask) { - EXPECT_EQ(spv::MemoryAccessMask(~(uint32_t(4))), - ~spv::MemoryAccessMask::Nontemporal); -} - // TODO(antiagainst): tests for SetMessageConsumer(). } // namespace diff --git a/test/diff/diff_files/.gitignore b/test/diff/diff_files/.gitignore old mode 100755 new mode 100644 diff --git a/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp b/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp index bd5a7d58..9944c2cf 100644 --- a/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp +++ b/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp @@ -95,7 +95,8 @@ TEST(DiffTest, OpextinstInSrcOnly) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 15 +-; Bound: 15 ++; Bound: 16 ; Schema: 0 OpCapability Shader -%1 = OpExtInstImport "GLSL.std.450" @@ -198,7 +199,8 @@ TEST(DiffTest, OpextinstInSrcOnlyNoDebug) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 15 +-; Bound: 15 ++; Bound: 16 ; Schema: 0 OpCapability Shader -%1 = OpExtInstImport "GLSL.std.450" diff --git a/test/diff/diff_files/basic_autogen.cpp b/test/diff/diff_files/basic_autogen.cpp index d4b6846b..f3afc701 100644 --- a/test/diff/diff_files/basic_autogen.cpp +++ b/test/diff/diff_files/basic_autogen.cpp @@ -129,7 +129,7 @@ TEST(DiffTest, Basic) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 30 ++; Bound: 36 ; Schema: 0 OpCapability Shader +%27 = OpExtInstImport "GLSL.std.450" @@ -272,7 +272,7 @@ OpFunctionEnd ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 30 ++; Bound: 36 ; Schema: 0 OpCapability Shader +%27 = OpExtInstImport "GLSL.std.450" @@ -324,7 +324,7 @@ TEST(DiffTest, BasicDumpIds) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 30 ++; Bound: 36 ; Schema: 0 OpCapability Shader +%27 = OpExtInstImport "GLSL.std.450" @@ -384,8 +384,8 @@ TEST(DiffTest, BasicDumpIds) { 6 -> 14 [TypeInt] 13 -> 19 [TypePointer] 14 -> 27 [Variable] - 15 -> 28 [Constant] - 16 -> 29 [TypeArray] + 15 -> 34 [Constant] + 16 -> 35 [TypeArray] 17 -> 11 [TypeStruct] 18 -> 12 [TypePointer] 19 -> 13 [Variable] diff --git a/test/diff/diff_files/constant_array_size_autogen.cpp b/test/diff/diff_files/constant_array_size_autogen.cpp index 2b6d7d80..16975ff4 100644 --- a/test/diff/diff_files/constant_array_size_autogen.cpp +++ b/test/diff/diff_files/constant_array_size_autogen.cpp @@ -125,7 +125,7 @@ TEST(DiffTest, ConstantArraySize) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 28 ++; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -259,7 +259,7 @@ OpFunctionEnd ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 28 ++; Bound: 34 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 diff --git a/test/diff/diff_files/diff_test_files_autogen.cmake b/test/diff/diff_files/diff_test_files_autogen.cmake index 51cb62fa..6440d0b9 100644 --- a/test/diff/diff_files/diff_test_files_autogen.cmake +++ b/test/diff/diff_files/diff_test_files_autogen.cmake @@ -36,7 +36,6 @@ list(APPEND DIFF_TEST_FILES "diff_files/large_functions_small_diffs_autogen.cpp" "diff_files/multiple_different_entry_points_autogen.cpp" "diff_files/multiple_same_entry_points_autogen.cpp" -"diff_files/ray_query_types_autogen.cpp" "diff_files/reordered_if_blocks_autogen.cpp" "diff_files/reordered_switch_blocks_autogen.cpp" "diff_files/small_functions_small_diffs_autogen.cpp" diff --git a/test/diff/diff_files/different_decorations_fragment_autogen.cpp b/test/diff/diff_files/different_decorations_fragment_autogen.cpp index ec9074c6..0d34654f 100644 --- a/test/diff/diff_files/different_decorations_fragment_autogen.cpp +++ b/test/diff/diff_files/different_decorations_fragment_autogen.cpp @@ -977,7 +977,7 @@ OpFunctionEnd ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 82 -+; Bound: 89 ++; Bound: 92 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -1030,7 +1030,8 @@ OpFunctionEnd +OpDecorate %83 DescriptorSet 0 +OpDecorate %83 Binding 0 OpDecorate %32 RelaxedPrecision - OpDecorate %33 RelaxedPrecision +-OpDecorate %33 RelaxedPrecision ++OpDecorate %84 RelaxedPrecision OpDecorate %36 RelaxedPrecision OpDecorate %37 RelaxedPrecision OpDecorate %38 RelaxedPrecision @@ -1039,8 +1040,10 @@ OpFunctionEnd OpDecorate %42 RelaxedPrecision OpDecorate %43 RelaxedPrecision OpDecorate %48 RelaxedPrecision - OpDecorate %49 RelaxedPrecision - OpDecorate %50 RelaxedPrecision +-OpDecorate %49 RelaxedPrecision +-OpDecorate %50 RelaxedPrecision ++OpDecorate %85 RelaxedPrecision ++OpDecorate %86 RelaxedPrecision OpDecorate %52 RelaxedPrecision OpDecorate %53 RelaxedPrecision OpDecorate %54 RelaxedPrecision @@ -1079,13 +1082,13 @@ OpFunctionEnd %61 = OpTypeVoid %69 = OpConstant %16 0 %78 = OpConstant %16 1 -+%85 = OpTypePointer Private %2 ++%88 = OpTypePointer Private %2 %3 = OpTypePointer Input %2 %7 = OpTypePointer UniformConstant %6 %10 = OpTypePointer UniformConstant %9 %13 = OpTypePointer Uniform %12 %19 = OpTypePointer Uniform %18 -+%86 = OpTypePointer Private %2 ++%89 = OpTypePointer Private %2 %21 = OpTypePointer Output %2 %28 = OpTypePointer Uniform %27 %30 = OpTypePointer Function %2 @@ -1103,16 +1106,19 @@ OpFunctionEnd %22 = OpVariable %21 Output -%29 = OpVariable %28 Uniform +%83 = OpVariable %28 Uniform -+%87 = OpConstant %23 0 -+%88 = OpConstant %1 0.5 ++%90 = OpConstant %23 0 ++%91 = OpConstant %1 0.5 %32 = OpFunction %2 None %31 - %33 = OpFunctionParameter %30 +-%33 = OpFunctionParameter %30 ++%84 = OpFunctionParameter %30 %34 = OpLabel %36 = OpLoad %6 %8 - %37 = OpLoad %2 %33 +-%37 = OpLoad %2 %33 ++%37 = OpLoad %2 %84 %38 = OpVectorShuffle %35 %37 %37 0 1 %39 = OpImageSampleImplicitLod %2 %36 %38 - %41 = OpLoad %2 %33 +-%41 = OpLoad %2 %33 ++%41 = OpLoad %2 %84 %42 = OpVectorShuffle %35 %41 %41 2 3 %43 = OpConvertFToS %40 %42 %44 = OpLoad %9 %11 @@ -1121,12 +1127,16 @@ OpFunctionEnd OpReturnValue %46 OpFunctionEnd %48 = OpFunction %2 None %47 - %49 = OpFunctionParameter %30 - %50 = OpFunctionParameter %30 +-%49 = OpFunctionParameter %30 +-%50 = OpFunctionParameter %30 ++%85 = OpFunctionParameter %30 ++%86 = OpFunctionParameter %30 %51 = OpLabel - %52 = OpLoad %2 %49 +-%52 = OpLoad %2 %49 ++%52 = OpLoad %2 %85 %53 = OpVectorShuffle %35 %52 %52 0 1 - %54 = OpLoad %2 %50 +-%54 = OpLoad %2 %50 ++%54 = OpLoad %2 %86 %55 = OpVectorShuffle %35 %54 %54 2 3 %56 = OpCompositeExtract %1 %53 0 %57 = OpCompositeExtract %1 %53 1 @@ -1144,9 +1154,9 @@ OpFunctionEnd OpStore %65 %66 %67 = OpFunctionCall %2 %32 %65 -%71 = OpAccessChain %70 %14 %69 -+%84 = OpAccessChain %70 %82 %69 ++%87 = OpAccessChain %70 %82 %69 -%72 = OpLoad %2 %71 -+%72 = OpLoad %2 %84 ++%72 = OpLoad %2 %87 OpStore %68 %72 -%74 = OpAccessChain %70 %20 %69 %69 +%74 = OpAccessChain %70 %14 %69 %69 diff --git a/test/diff/diff_files/different_decorations_vertex_autogen.cpp b/test/diff/diff_files/different_decorations_vertex_autogen.cpp index 134ebb4a..f65ee5a1 100644 --- a/test/diff/diff_files/different_decorations_vertex_autogen.cpp +++ b/test/diff/diff_files/different_decorations_vertex_autogen.cpp @@ -777,7 +777,7 @@ OpFunctionEnd ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 58 -+; Bound: 77 ++; Bound: 79 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -817,10 +817,12 @@ OpFunctionEnd -OpMemberDecorate %23 3 BuiltIn CullDistance OpDecorate %23 Block OpDecorate %28 RelaxedPrecision - OpDecorate %29 RelaxedPrecision +-OpDecorate %29 RelaxedPrecision ++OpDecorate %59 RelaxedPrecision OpDecorate %31 RelaxedPrecision OpDecorate %32 RelaxedPrecision - OpDecorate %33 RelaxedPrecision +-OpDecorate %33 RelaxedPrecision ++OpDecorate %60 RelaxedPrecision OpDecorate %35 RelaxedPrecision OpDecorate %36 RelaxedPrecision OpDecorate %37 RelaxedPrecision @@ -843,9 +845,9 @@ OpFunctionEnd +%23 = OpTypeStruct %2 %38 = OpTypeVoid %45 = OpConstant %12 0 -+%63 = OpTypePointer Private %2 ++%65 = OpTypePointer Private %2 %3 = OpTypePointer Input %2 -+%64 = OpTypePointer Private %2 ++%66 = OpTypePointer Private %2 %7 = OpTypePointer Output %2 %10 = OpTypePointer Uniform %9 %18 = OpTypePointer Uniform %17 @@ -863,21 +865,26 @@ OpFunctionEnd -%19 = OpVariable %18 Uniform +%19 = OpVariable %10 Uniform %20 = OpVariable %7 Output -+%58 = OpVariable %64 Private ++%58 = OpVariable %66 Private %25 = OpVariable %24 Output -+%65 = OpConstant %13 0 -+%66 = OpConstant %1 0.5 ++%67 = OpConstant %13 0 ++%68 = OpConstant %1 0.5 %28 = OpFunction %2 None %27 - %29 = OpFunctionParameter %26 +-%29 = OpFunctionParameter %26 ++%59 = OpFunctionParameter %26 %30 = OpLabel - %31 = OpLoad %2 %29 +-%31 = OpLoad %2 %29 ++%31 = OpLoad %2 %59 OpReturnValue %31 OpFunctionEnd %32 = OpFunction %2 None %27 - %33 = OpFunctionParameter %26 +-%33 = OpFunctionParameter %26 ++%60 = OpFunctionParameter %26 %34 = OpLabel - %35 = OpLoad %2 %33 - %36 = OpLoad %2 %33 +-%35 = OpLoad %2 %33 ++%35 = OpLoad %2 %60 +-%36 = OpLoad %2 %33 ++%36 = OpLoad %2 %60 %37 = OpFAdd %2 %35 %36 OpReturnValue %37 OpFunctionEnd @@ -887,41 +894,41 @@ OpFunctionEnd %50 = OpVariable %26 Function %53 = OpVariable %26 Function -%43 = OpLoad %2 %4 -+%59 = OpLoad %2 %5 ++%61 = OpLoad %2 %5 -OpStore %42 %43 -+OpStore %42 %59 ++OpStore %42 %61 %44 = OpFunctionCall %2 %28 %42 -%47 = OpAccessChain %46 %11 %45 -+%60 = OpAccessChain %46 %19 %45 ++%62 = OpAccessChain %46 %19 %45 -%48 = OpLoad %2 %47 -+%48 = OpLoad %2 %60 ++%48 = OpLoad %2 %62 %49 = OpFAdd %2 %44 %48 -OpStore %8 %49 +OpStore %20 %49 -%51 = OpLoad %2 %5 -+%61 = OpLoad %2 %6 ++%63 = OpLoad %2 %6 -OpStore %50 %51 -+OpStore %50 %61 ++OpStore %50 %63 %52 = OpFunctionCall %2 %32 %50 -%54 = OpLoad %2 %6 -+%62 = OpLoad %2 %4 ++%64 = OpLoad %2 %4 -OpStore %53 %54 -+OpStore %53 %62 ++OpStore %53 %64 %55 = OpFunctionCall %2 %28 %53 %56 = OpFAdd %2 %52 %55 %57 = OpAccessChain %7 %25 %45 OpStore %57 %56 -+%67 = OpAccessChain %7 %25 %65 -+%68 = OpLoad %2 %67 -+%69 = OpCompositeExtract %1 %68 0 -+%70 = OpCompositeExtract %1 %68 1 -+%71 = OpCompositeExtract %1 %68 2 -+%72 = OpCompositeExtract %1 %68 3 -+%74 = OpFNegate %1 %69 -+%75 = OpFAdd %1 %71 %72 -+%76 = OpFMul %1 %75 %66 -+%73 = OpCompositeConstruct %2 %70 %74 %76 %72 -+OpStore %67 %73 ++%69 = OpAccessChain %7 %25 %67 ++%70 = OpLoad %2 %69 ++%71 = OpCompositeExtract %1 %70 0 ++%72 = OpCompositeExtract %1 %70 1 ++%73 = OpCompositeExtract %1 %70 2 ++%74 = OpCompositeExtract %1 %70 3 ++%76 = OpFNegate %1 %71 ++%77 = OpFAdd %1 %73 %74 ++%78 = OpFMul %1 %77 %68 ++%75 = OpCompositeConstruct %2 %72 %76 %78 %74 ++OpStore %69 %75 OpReturn OpFunctionEnd )"; diff --git a/test/diff/diff_files/different_function_parameter_count_autogen.cpp b/test/diff/diff_files/different_function_parameter_count_autogen.cpp index e31a4a89..3a077fb0 100644 --- a/test/diff/diff_files/different_function_parameter_count_autogen.cpp +++ b/test/diff/diff_files/different_function_parameter_count_autogen.cpp @@ -128,7 +128,7 @@ TEST(DiffTest, DifferentFunctionParameterCount) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 25 -+; Bound: 31 ++; Bound: 33 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -143,7 +143,7 @@ TEST(DiffTest, DifferentFunctionParameterCount) { +OpName %26 "v2" OpName %20 "o" OpName %23 "param" -+OpName %29 "param" ++OpName %31 "param" OpDecorate %20 RelaxedPrecision OpDecorate %20 Location 0 %2 = OpTypeVoid @@ -162,13 +162,13 @@ TEST(DiffTest, DifferentFunctionParameterCount) { %4 = OpFunction %2 None %3 %5 = OpLabel %23 = OpVariable %8 Function -+%29 = OpVariable %8 Function ++%31 = OpVariable %8 Function OpStore %23 %22 -%24 = OpFunctionCall %7 %11 %23 -+OpStore %29 %15 -+%30 = OpFunctionCall %7 %11 %23 %29 ++OpStore %31 %15 ++%32 = OpFunctionCall %7 %11 %23 %31 -OpStore %20 %24 -+OpStore %20 %30 ++OpStore %20 %32 OpReturn OpFunctionEnd -%11 = OpFunction %7 None %9 @@ -280,7 +280,7 @@ TEST(DiffTest, DifferentFunctionParameterCountNoDebug) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 25 -+; Bound: 31 ++; Bound: 34 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -306,26 +306,28 @@ TEST(DiffTest, DifferentFunctionParameterCountNoDebug) { %4 = OpFunction %2 None %3 %5 = OpLabel %23 = OpVariable %8 Function -+%29 = OpVariable %8 Function ++%32 = OpVariable %8 Function OpStore %23 %22 -%24 = OpFunctionCall %7 %11 %23 -+OpStore %29 %15 -+%30 = OpFunctionCall %7 %11 %23 %29 ++OpStore %32 %15 ++%33 = OpFunctionCall %7 %11 %23 %32 -OpStore %20 %24 -+OpStore %20 %30 ++OpStore %20 %33 OpReturn OpFunctionEnd -%11 = OpFunction %7 None %9 +%11 = OpFunction %7 None %25 - %10 = OpFunctionParameter %8 +-%10 = OpFunctionParameter %8 +%26 = OpFunctionParameter %8 ++%27 = OpFunctionParameter %8 %12 = OpLabel - %13 = OpLoad %7 %10 +-%13 = OpLoad %7 %10 ++%13 = OpLoad %7 %26 -%16 = OpFAdd %7 %13 %15 -+%27 = OpLoad %7 %26 -+%28 = OpFAdd %7 %13 %27 ++%28 = OpLoad %7 %27 ++%29 = OpFAdd %7 %13 %28 -OpReturnValue %16 -+OpReturnValue %28 ++OpReturnValue %29 OpFunctionEnd )"; Options options; diff --git a/test/diff/diff_files/extra_if_block_autogen.cpp b/test/diff/diff_files/extra_if_block_autogen.cpp index fee34aea..4f913198 100644 --- a/test/diff/diff_files/extra_if_block_autogen.cpp +++ b/test/diff/diff_files/extra_if_block_autogen.cpp @@ -303,7 +303,7 @@ TEST(DiffTest, ExtraIfBlock) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 69 -+; Bound: 77 ++; Bound: 81 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -352,10 +352,10 @@ TEST(DiffTest, ExtraIfBlock) { OpDecorate %54 RelaxedPrecision OpDecorate %55 RelaxedPrecision OpDecorate %56 RelaxedPrecision -+OpDecorate %70 RelaxedPrecision ++OpDecorate %72 RelaxedPrecision OpDecorate %57 RelaxedPrecision -+OpDecorate %75 RelaxedPrecision -+OpDecorate %76 RelaxedPrecision ++OpDecorate %77 RelaxedPrecision ++OpDecorate %78 RelaxedPrecision OpDecorate %58 RelaxedPrecision OpDecorate %63 RelaxedPrecision OpDecorate %63 Location 0 @@ -383,7 +383,7 @@ TEST(DiffTest, ExtraIfBlock) { %32 = OpConstant %19 1 %49 = OpConstant %6 10 %52 = OpConstant %6 0.5 -+%74 = OpConstant %6 0.100000001 ++%76 = OpConstant %6 0.100000001 %53 = OpConstant %6 0.699999988 %61 = OpTypeVector %6 4 %62 = OpTypePointer Output %61 @@ -439,20 +439,20 @@ TEST(DiffTest, ExtraIfBlock) { %55 = OpLoad %6 %45 %56 = OpFMul %6 %55 %54 OpStore %45 %56 -+%69 = OpAccessChain %21 %18 %32 -+%70 = OpLoad %15 %69 -+%71 = OpINotEqual %25 %70 %24 -+OpSelectionMerge %73 None -+OpBranchConditional %71 %72 %73 -+%72 = OpLabel ++%71 = OpAccessChain %21 %18 %32 ++%72 = OpLoad %15 %71 ++%73 = OpINotEqual %25 %72 %24 ++OpSelectionMerge %75 None ++OpBranchConditional %73 %74 %75 ++%74 = OpLabel %57 = OpLoad %6 %45 -+%75 = OpFSub %6 %57 %74 -+OpStore %45 %75 -+OpBranch %73 -+%73 = OpLabel -+%76 = OpLoad %6 %45 ++%77 = OpFSub %6 %57 %76 ++OpStore %45 %77 ++OpBranch %75 ++%75 = OpLabel ++%78 = OpLoad %6 %45 -%58 = OpExtInst %6 %1 Exp %57 -+%58 = OpExtInst %6 %1 Exp %76 ++%58 = OpExtInst %6 %1 Exp %78 OpReturnValue %58 OpFunctionEnd )"; @@ -716,7 +716,7 @@ TEST(DiffTest, ExtraIfBlockNoDebug) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 69 -+; Bound: 77 ++; Bound: 81 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -754,10 +754,10 @@ TEST(DiffTest, ExtraIfBlockNoDebug) { OpDecorate %54 RelaxedPrecision OpDecorate %55 RelaxedPrecision OpDecorate %56 RelaxedPrecision -+OpDecorate %70 RelaxedPrecision ++OpDecorate %72 RelaxedPrecision OpDecorate %57 RelaxedPrecision -+OpDecorate %75 RelaxedPrecision -+OpDecorate %76 RelaxedPrecision ++OpDecorate %77 RelaxedPrecision ++OpDecorate %78 RelaxedPrecision OpDecorate %58 RelaxedPrecision OpDecorate %63 RelaxedPrecision OpDecorate %63 Location 0 @@ -785,7 +785,7 @@ TEST(DiffTest, ExtraIfBlockNoDebug) { %32 = OpConstant %19 1 %49 = OpConstant %6 10 %52 = OpConstant %6 0.5 -+%74 = OpConstant %6 0.100000001 ++%76 = OpConstant %6 0.100000001 %53 = OpConstant %6 0.699999988 %61 = OpTypeVector %6 4 %62 = OpTypePointer Output %61 @@ -841,20 +841,20 @@ TEST(DiffTest, ExtraIfBlockNoDebug) { %55 = OpLoad %6 %45 %56 = OpFMul %6 %55 %54 OpStore %45 %56 -+%69 = OpAccessChain %21 %18 %32 -+%70 = OpLoad %15 %69 -+%71 = OpINotEqual %25 %70 %24 -+OpSelectionMerge %73 None -+OpBranchConditional %71 %72 %73 -+%72 = OpLabel ++%71 = OpAccessChain %21 %18 %32 ++%72 = OpLoad %15 %71 ++%73 = OpINotEqual %25 %72 %24 ++OpSelectionMerge %75 None ++OpBranchConditional %73 %74 %75 ++%74 = OpLabel %57 = OpLoad %6 %45 -+%75 = OpFSub %6 %57 %74 -+OpStore %45 %75 -+OpBranch %73 -+%73 = OpLabel -+%76 = OpLoad %6 %45 ++%77 = OpFSub %6 %57 %76 ++OpStore %45 %77 ++OpBranch %75 ++%75 = OpLabel ++%78 = OpLoad %6 %45 -%58 = OpExtInst %6 %1 Exp %57 -+%58 = OpExtInst %6 %1 Exp %76 ++%58 = OpExtInst %6 %1 Exp %78 OpReturnValue %58 OpFunctionEnd )"; diff --git a/test/diff/diff_files/int_vs_uint_constants_autogen.cpp b/test/diff/diff_files/int_vs_uint_constants_autogen.cpp index 11bb8117..187722e8 100644 --- a/test/diff/diff_files/int_vs_uint_constants_autogen.cpp +++ b/test/diff/diff_files/int_vs_uint_constants_autogen.cpp @@ -371,10 +371,10 @@ TEST(DiffTest, IntVsUintConstantsDumpIds) { 3 -> 16 [TypePointer] 4 -> 17 [Variable] 5 -> 8 [TypeInt] - 8 -> 21 [TypeVector] + 8 -> 23 [TypeVector] 13 -> 19 [TypePointer] - 15 -> 22 [Constant] - 16 -> 23 [TypeArray] + 15 -> 29 [Constant] + 16 -> 30 [TypeArray] 17 -> 11 [TypeStruct] 18 -> 12 [TypePointer] 19 -> 13 [Variable] diff --git a/test/diff/diff_files/multiple_same_entry_points_autogen.cpp b/test/diff/diff_files/multiple_same_entry_points_autogen.cpp index 00bee6be..9d011661 100644 --- a/test/diff/diff_files/multiple_same_entry_points_autogen.cpp +++ b/test/diff/diff_files/multiple_same_entry_points_autogen.cpp @@ -125,8 +125,9 @@ TEST(DiffTest, MultipleSameEntryPoints) { OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 ++OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpEntryPoint Vertex %4 "main1" %8 %10 - OpEntryPoint Vertex %12 "main2" %13 %14 %15 +-OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpSource ESSL 310 OpName %4 "main1" OpName %12 "main2" @@ -256,8 +257,9 @@ TEST(DiffTest, MultipleSameEntryPointsNoDebug) { OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 ++OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpEntryPoint Vertex %4 "main1" %8 %10 - OpEntryPoint Vertex %12 "main2" %13 %14 %15 +-OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpSource ESSL 310 OpDecorate %8 Location 0 OpDecorate %10 Location 0 @@ -302,8 +304,9 @@ TEST(DiffTest, MultipleSameEntryPointsDumpIds) { OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 ++OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpEntryPoint Vertex %4 "main1" %8 %10 - OpEntryPoint Vertex %12 "main2" %13 %14 %15 +-OpEntryPoint Vertex %12 "main2" %13 %14 %15 OpSource ESSL 310 OpName %4 "main1" OpName %12 "main2" diff --git a/test/diff/diff_files/ray_query_types_autogen.cpp b/test/diff/diff_files/ray_query_types_autogen.cpp deleted file mode 100755 index 5507def6..00000000 --- a/test/diff/diff_files/ray_query_types_autogen.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// GENERATED FILE - DO NOT EDIT. -// Generated by generate_tests.py -// -// Copyright (c) 2022 Google LLC. -// -// 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 "../diff_test_utils.h" - -#include "gtest/gtest.h" - -namespace spvtools { -namespace diff { -namespace { - -// Test that OpTypeAccelerationStructureNV and OpTypeRayQueryKHR are -// matched. -constexpr char kSrc[] = R"(OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd)"; -constexpr char kDst[] = R"(; SPIR-V -; Version: 1.4 -; Generator: rspirv -; Bound: 95 -OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd -)"; - -TEST(DiffTest, RayQueryTypes) { - constexpr char kDiff[] = R"( ; SPIR-V - ; Version: 1.6 - ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 45 - ; Schema: 0 - OpCapability RayQueryKHR - OpCapability Shader - OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %43 "main" - OpExecutionMode %43 LocalSize 1 1 1 - %2 = OpTypeVoid - %3 = OpTypeAccelerationStructureKHR - %13 = OpTypeRayQueryKHR - %44 = OpTypeFunction %2 - %43 = OpFunction %2 None %44 - %42 = OpLabel - OpReturn - OpFunctionEnd -)"; - Options options; - DoStringDiffTest(kSrc, kDst, kDiff, options); -} - -TEST(DiffTest, RayQueryTypesNoDebug) { - constexpr char kSrcNoDebug[] = R"(OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd -)"; - constexpr char kDstNoDebug[] = R"(; SPIR-V -; Version: 1.4 -; Generator: rspirv -; Bound: 95 -OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd -)"; - constexpr char kDiff[] = R"( ; SPIR-V - ; Version: 1.6 - ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 45 - ; Schema: 0 - OpCapability RayQueryKHR - OpCapability Shader - OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %43 "main" - OpExecutionMode %43 LocalSize 1 1 1 - %2 = OpTypeVoid - %3 = OpTypeAccelerationStructureKHR - %13 = OpTypeRayQueryKHR - %44 = OpTypeFunction %2 - %43 = OpFunction %2 None %44 - %42 = OpLabel - OpReturn - OpFunctionEnd -)"; - Options options; - DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options); -} - -} // namespace -} // namespace diff -} // namespace spvtools diff --git a/test/diff/diff_files/ray_query_types_dst.spvasm b/test/diff/diff_files/ray_query_types_dst.spvasm deleted file mode 100755 index 5f8be53d..00000000 --- a/test/diff/diff_files/ray_query_types_dst.spvasm +++ /dev/null @@ -1,18 +0,0 @@ -; SPIR-V -; Version: 1.4 -; Generator: rspirv -; Bound: 95 -OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd diff --git a/test/diff/diff_files/ray_query_types_src.spvasm b/test/diff/diff_files/ray_query_types_src.spvasm deleted file mode 100755 index 0b64015b..00000000 --- a/test/diff/diff_files/ray_query_types_src.spvasm +++ /dev/null @@ -1,16 +0,0 @@ -;; Test that OpTypeAccelerationStructureNV and OpTypeRayQueryKHR are -;; matched. -OpCapability RayQueryKHR -OpCapability Shader -OpExtension "SPV_KHR_ray_query" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %43 "main" -OpExecutionMode %43 LocalSize 1 1 1 -%2 = OpTypeVoid -%3 = OpTypeAccelerationStructureNV -%13 = OpTypeRayQueryKHR -%44 = OpTypeFunction %2 -%43 = OpFunction %2 None %44 -%42 = OpLabel -OpReturn -OpFunctionEnd diff --git a/test/diff/diff_files/reordered_if_blocks_autogen.cpp b/test/diff/diff_files/reordered_if_blocks_autogen.cpp index 3abaf40d..0788199f 100644 --- a/test/diff/diff_files/reordered_if_blocks_autogen.cpp +++ b/test/diff/diff_files/reordered_if_blocks_autogen.cpp @@ -203,7 +203,8 @@ TEST(DiffTest, ReorderedIfBlocks) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 46 +-; Bound: 46 ++; Bound: 47 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -470,7 +471,8 @@ TEST(DiffTest, ReorderedIfBlocksNoDebug) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 46 +-; Bound: 46 ++; Bound: 47 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" diff --git a/test/diff/diff_files/reordered_switch_blocks_autogen.cpp b/test/diff/diff_files/reordered_switch_blocks_autogen.cpp index ade5350e..c0ba48d1 100644 --- a/test/diff/diff_files/reordered_switch_blocks_autogen.cpp +++ b/test/diff/diff_files/reordered_switch_blocks_autogen.cpp @@ -212,7 +212,8 @@ TEST(DiffTest, ReorderedSwitchBlocks) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 58 +-; Bound: 58 ++; Bound: 62 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -484,7 +485,8 @@ TEST(DiffTest, ReorderedSwitchBlocksNoDebug) { constexpr char kDiff[] = R"( ; SPIR-V ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 - ; Bound: 58 +-; Bound: 58 ++; Bound: 62 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" diff --git a/test/diff/diff_files/spec_constant_array_size_autogen.cpp b/test/diff/diff_files/spec_constant_array_size_autogen.cpp index 98ad0727..1962d27e 100644 --- a/test/diff/diff_files/spec_constant_array_size_autogen.cpp +++ b/test/diff/diff_files/spec_constant_array_size_autogen.cpp @@ -125,7 +125,7 @@ TEST(DiffTest, SpecConstantArraySize) { ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 29 ++; Bound: 36 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -140,7 +140,7 @@ TEST(DiffTest, SpecConstantArraySize) { OpName %19 "" OpName %22 "main" OpDecorate %4 Location 0 -+OpDecorate %27 SpecId 4 ++OpDecorate %34 SpecId 4 OpMemberDecorate %17 1 RelaxedPrecision OpMemberDecorate %17 0 BuiltIn Position OpMemberDecorate %17 1 BuiltIn PointSize @@ -153,10 +153,10 @@ TEST(DiffTest, SpecConstantArraySize) { %8 = OpTypeVector %5 4 -%15 = OpConstant %5 8 -%16 = OpTypeArray %1 %15 -+%27 = OpSpecConstant %5 8 -+%28 = OpTypeArray %1 %27 ++%34 = OpSpecConstant %5 8 ++%35 = OpTypeArray %1 %34 -%17 = OpTypeStruct %2 %1 %16 %16 -+%17 = OpTypeStruct %2 %1 %28 %28 ++%17 = OpTypeStruct %2 %1 %35 %35 %20 = OpTypeVoid %25 = OpConstant %5 0 %3 = OpTypePointer Input %2 @@ -261,14 +261,14 @@ OpFunctionEnd ; Version: 1.6 ; Generator: Khronos SPIR-V Tools Assembler; 0 -; Bound: 27 -+; Bound: 29 ++; Bound: 36 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %22 "main" %4 %19 OpSource GLSL 450 OpDecorate %4 Location 0 -+OpDecorate %27 SpecId 4 ++OpDecorate %34 SpecId 4 OpMemberDecorate %17 1 RelaxedPrecision OpMemberDecorate %17 0 BuiltIn Position OpMemberDecorate %17 1 BuiltIn PointSize @@ -281,10 +281,10 @@ OpFunctionEnd %8 = OpTypeVector %5 4 -%15 = OpConstant %5 8 -%16 = OpTypeArray %1 %15 -+%27 = OpSpecConstant %5 8 -+%28 = OpTypeArray %1 %27 ++%34 = OpSpecConstant %5 8 ++%35 = OpTypeArray %1 %34 -%17 = OpTypeStruct %2 %1 %16 %16 -+%17 = OpTypeStruct %2 %1 %28 %28 ++%17 = OpTypeStruct %2 %1 %35 %35 %20 = OpTypeVoid %25 = OpConstant %5 0 %3 = OpTypePointer Input %2 diff --git a/test/diff/diff_test.cpp b/test/diff/diff_test.cpp index 3b63c69c..5b11d0eb 100644 --- a/test/diff/diff_test.cpp +++ b/test/diff/diff_test.cpp @@ -195,14 +195,14 @@ TEST(DiffHeaderTest, Diff) { // Differentiate them in the header. const spvtools::opt::ModuleHeader src_header = { - spv::MagicNumber, + SpvMagicNumber, SPV_SPIRV_VERSION_WORD(1, 3), SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 3), src->module()->IdBound(), src->module()->schema(), }; const spvtools::opt::ModuleHeader dst_header = { - spv::MagicNumber, + SpvMagicNumber, SPV_SPIRV_VERSION_WORD(1, 2), SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_GLSLANG, 10), dst->module()->IdBound(), diff --git a/test/enum_set_test.cpp b/test/enum_set_test.cpp index 11105f99..047d6427 100644 --- a/test/enum_set_test.cpp +++ b/test/enum_set_test.cpp @@ -12,15 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/enum_set.h" - #include -#include -#include #include #include #include "gmock/gmock.h" +#include "source/enum_set.h" #include "test/unit_spirv.h" namespace spvtools { @@ -28,806 +25,214 @@ namespace { using spvtest::ElementsIn; using ::testing::Eq; -using ::testing::Values; using ::testing::ValuesIn; -enum class TestEnum : uint32_t { - ZERO = 0, - ONE = 1, - TWO = 2, - THREE = 3, - FOUR = 4, - FIVE = 5, - EIGHT = 8, - TWENTY = 20, - TWENTY_FOUR = 24, - THIRTY = 30, - ONE_HUNDRED = 100, - ONE_HUNDRED_FIFTY = 150, - TWO_HUNDRED = 200, - THREE_HUNDRED = 300, - FOUR_HUNDRED = 400, - FIVE_HUNDRED = 500, - SIX_HUNDRED = 600, -}; - -constexpr std::array kCapabilities{ - spv::Capability::Matrix, - spv::Capability::Shader, - spv::Capability::Geometry, - spv::Capability::Tessellation, - spv::Capability::Addresses, - spv::Capability::Linkage, - spv::Capability::Kernel, - spv::Capability::Vector16, - spv::Capability::Float16Buffer, - spv::Capability::Float16, - spv::Capability::Float64, - spv::Capability::Int64, - spv::Capability::Int64Atomics, - spv::Capability::ImageBasic, - spv::Capability::ImageReadWrite, - spv::Capability::ImageMipmap, - spv::Capability::Pipes, - spv::Capability::Groups, - spv::Capability::DeviceEnqueue, - spv::Capability::LiteralSampler, - spv::Capability::AtomicStorage, - spv::Capability::Int16, - spv::Capability::TessellationPointSize, - spv::Capability::GeometryPointSize, - spv::Capability::ImageGatherExtended, - spv::Capability::StorageImageMultisample, - spv::Capability::UniformBufferArrayDynamicIndexing, - spv::Capability::SampledImageArrayDynamicIndexing, - spv::Capability::StorageBufferArrayDynamicIndexing, - spv::Capability::StorageImageArrayDynamicIndexing, - spv::Capability::ClipDistance, - spv::Capability::CullDistance, - spv::Capability::ImageCubeArray, - spv::Capability::SampleRateShading, - spv::Capability::ImageRect, - spv::Capability::SampledRect, - spv::Capability::GenericPointer, - spv::Capability::Int8, - spv::Capability::InputAttachment, - spv::Capability::SparseResidency, - spv::Capability::MinLod, - spv::Capability::Sampled1D, - spv::Capability::Image1D, - spv::Capability::SampledCubeArray, - spv::Capability::SampledBuffer, - spv::Capability::ImageBuffer, - spv::Capability::ImageMSArray, - spv::Capability::StorageImageExtendedFormats, - spv::Capability::ImageQuery, - spv::Capability::DerivativeControl, - spv::Capability::InterpolationFunction, - spv::Capability::TransformFeedback, - spv::Capability::GeometryStreams, - spv::Capability::StorageImageReadWithoutFormat, - spv::Capability::StorageImageWriteWithoutFormat, - spv::Capability::MultiViewport, - spv::Capability::SubgroupDispatch, - spv::Capability::NamedBarrier, - spv::Capability::PipeStorage, - spv::Capability::GroupNonUniform, - spv::Capability::GroupNonUniformVote, - spv::Capability::GroupNonUniformArithmetic, - spv::Capability::GroupNonUniformBallot, - spv::Capability::GroupNonUniformShuffle, - spv::Capability::GroupNonUniformShuffleRelative, - spv::Capability::GroupNonUniformClustered, - spv::Capability::GroupNonUniformQuad, - spv::Capability::ShaderLayer, - spv::Capability::ShaderViewportIndex, - spv::Capability::UniformDecoration, - spv::Capability::CoreBuiltinsARM, - spv::Capability::FragmentShadingRateKHR, - spv::Capability::SubgroupBallotKHR, - spv::Capability::DrawParameters, - spv::Capability::WorkgroupMemoryExplicitLayoutKHR, - spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR, - spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR, - spv::Capability::SubgroupVoteKHR, - spv::Capability::StorageBuffer16BitAccess, - spv::Capability::StorageUniformBufferBlock16, - spv::Capability::StorageUniform16, - spv::Capability::UniformAndStorageBuffer16BitAccess, - spv::Capability::StoragePushConstant16, - spv::Capability::StorageInputOutput16, - spv::Capability::DeviceGroup, - spv::Capability::MultiView, - spv::Capability::VariablePointersStorageBuffer, - spv::Capability::VariablePointers, - spv::Capability::AtomicStorageOps, - spv::Capability::SampleMaskPostDepthCoverage, - spv::Capability::StorageBuffer8BitAccess, - spv::Capability::UniformAndStorageBuffer8BitAccess, - spv::Capability::StoragePushConstant8, - spv::Capability::DenormPreserve, - spv::Capability::DenormFlushToZero, - spv::Capability::SignedZeroInfNanPreserve, - spv::Capability::RoundingModeRTE, - spv::Capability::RoundingModeRTZ, - spv::Capability::RayQueryProvisionalKHR, - spv::Capability::RayQueryKHR, - spv::Capability::RayTraversalPrimitiveCullingKHR, - spv::Capability::RayTracingKHR, - spv::Capability::Float16ImageAMD, - spv::Capability::ImageGatherBiasLodAMD, - spv::Capability::FragmentMaskAMD, - spv::Capability::StencilExportEXT, - spv::Capability::ImageReadWriteLodAMD, - spv::Capability::Int64ImageEXT, - spv::Capability::ShaderClockKHR, - spv::Capability::SampleMaskOverrideCoverageNV, - spv::Capability::GeometryShaderPassthroughNV, - spv::Capability::ShaderViewportIndexLayerEXT, - spv::Capability::ShaderViewportIndexLayerNV, - spv::Capability::ShaderViewportMaskNV, - spv::Capability::ShaderStereoViewNV, - spv::Capability::PerViewAttributesNV, - spv::Capability::FragmentFullyCoveredEXT, - spv::Capability::MeshShadingNV, - spv::Capability::ImageFootprintNV, - spv::Capability::MeshShadingEXT, - spv::Capability::FragmentBarycentricKHR, - spv::Capability::FragmentBarycentricNV, - spv::Capability::ComputeDerivativeGroupQuadsNV, - spv::Capability::FragmentDensityEXT, - spv::Capability::ShadingRateNV, - spv::Capability::GroupNonUniformPartitionedNV, - spv::Capability::ShaderNonUniform, - spv::Capability::ShaderNonUniformEXT, - spv::Capability::RuntimeDescriptorArray, - spv::Capability::RuntimeDescriptorArrayEXT, - spv::Capability::InputAttachmentArrayDynamicIndexing, - spv::Capability::InputAttachmentArrayDynamicIndexingEXT, - spv::Capability::UniformTexelBufferArrayDynamicIndexing, - spv::Capability::UniformTexelBufferArrayDynamicIndexingEXT, - spv::Capability::StorageTexelBufferArrayDynamicIndexing, - spv::Capability::StorageTexelBufferArrayDynamicIndexingEXT, - spv::Capability::UniformBufferArrayNonUniformIndexing, - spv::Capability::UniformBufferArrayNonUniformIndexingEXT, - spv::Capability::SampledImageArrayNonUniformIndexing, - spv::Capability::SampledImageArrayNonUniformIndexingEXT, - spv::Capability::StorageBufferArrayNonUniformIndexing, - spv::Capability::StorageBufferArrayNonUniformIndexingEXT, - spv::Capability::StorageImageArrayNonUniformIndexing, - spv::Capability::StorageImageArrayNonUniformIndexingEXT, - spv::Capability::InputAttachmentArrayNonUniformIndexing, - spv::Capability::InputAttachmentArrayNonUniformIndexingEXT, - spv::Capability::UniformTexelBufferArrayNonUniformIndexing, - spv::Capability::UniformTexelBufferArrayNonUniformIndexingEXT, - spv::Capability::StorageTexelBufferArrayNonUniformIndexing, - spv::Capability::StorageTexelBufferArrayNonUniformIndexingEXT, - spv::Capability::RayTracingNV, - spv::Capability::RayTracingMotionBlurNV, - spv::Capability::VulkanMemoryModel, - spv::Capability::VulkanMemoryModelKHR, - spv::Capability::VulkanMemoryModelDeviceScope, - spv::Capability::VulkanMemoryModelDeviceScopeKHR, - spv::Capability::PhysicalStorageBufferAddresses, - spv::Capability::PhysicalStorageBufferAddressesEXT, - spv::Capability::ComputeDerivativeGroupLinearNV, - spv::Capability::RayTracingProvisionalKHR, - spv::Capability::CooperativeMatrixNV, - spv::Capability::FragmentShaderSampleInterlockEXT, - spv::Capability::FragmentShaderShadingRateInterlockEXT, - spv::Capability::ShaderSMBuiltinsNV, - spv::Capability::FragmentShaderPixelInterlockEXT, - spv::Capability::DemoteToHelperInvocation, - spv::Capability::DemoteToHelperInvocationEXT, - spv::Capability::RayTracingOpacityMicromapEXT, - spv::Capability::ShaderInvocationReorderNV, - spv::Capability::BindlessTextureNV, - spv::Capability::SubgroupShuffleINTEL, - spv::Capability::SubgroupBufferBlockIOINTEL, - spv::Capability::SubgroupImageBlockIOINTEL, - spv::Capability::SubgroupImageMediaBlockIOINTEL, - spv::Capability::RoundToInfinityINTEL, - spv::Capability::FloatingPointModeINTEL, - spv::Capability::IntegerFunctions2INTEL, - spv::Capability::FunctionPointersINTEL, - spv::Capability::IndirectReferencesINTEL, - spv::Capability::AsmINTEL, - spv::Capability::AtomicFloat32MinMaxEXT, - spv::Capability::AtomicFloat64MinMaxEXT, - spv::Capability::AtomicFloat16MinMaxEXT, - spv::Capability::VectorComputeINTEL, - spv::Capability::VectorAnyINTEL, - spv::Capability::ExpectAssumeKHR, - spv::Capability::SubgroupAvcMotionEstimationINTEL, - spv::Capability::SubgroupAvcMotionEstimationIntraINTEL, - spv::Capability::SubgroupAvcMotionEstimationChromaINTEL, - spv::Capability::VariableLengthArrayINTEL, - spv::Capability::FunctionFloatControlINTEL, - spv::Capability::FPGAMemoryAttributesINTEL, - spv::Capability::FPFastMathModeINTEL, - spv::Capability::ArbitraryPrecisionIntegersINTEL, - spv::Capability::ArbitraryPrecisionFloatingPointINTEL, - spv::Capability::UnstructuredLoopControlsINTEL, - spv::Capability::FPGALoopControlsINTEL, - spv::Capability::KernelAttributesINTEL, - spv::Capability::FPGAKernelAttributesINTEL, - spv::Capability::FPGAMemoryAccessesINTEL, - spv::Capability::FPGAClusterAttributesINTEL, - spv::Capability::LoopFuseINTEL, - spv::Capability::FPGADSPControlINTEL, - spv::Capability::MemoryAccessAliasingINTEL, - spv::Capability::FPGAInvocationPipeliningAttributesINTEL, - spv::Capability::FPGABufferLocationINTEL, - spv::Capability::ArbitraryPrecisionFixedPointINTEL, - spv::Capability::USMStorageClassesINTEL, - spv::Capability::RuntimeAlignedAttributeINTEL, - spv::Capability::IOPipesINTEL, - spv::Capability::BlockingPipesINTEL, - spv::Capability::FPGARegINTEL, - spv::Capability::DotProductInputAll, - spv::Capability::DotProductInputAllKHR, - spv::Capability::DotProductInput4x8Bit, - spv::Capability::DotProductInput4x8BitKHR, - spv::Capability::DotProductInput4x8BitPacked, - spv::Capability::DotProductInput4x8BitPackedKHR, - spv::Capability::DotProduct, - spv::Capability::DotProductKHR, - spv::Capability::RayCullMaskKHR, - spv::Capability::BitInstructions, - spv::Capability::GroupNonUniformRotateKHR, - spv::Capability::AtomicFloat32AddEXT, - spv::Capability::AtomicFloat64AddEXT, - spv::Capability::LongCompositesINTEL, - spv::Capability::OptNoneINTEL, - spv::Capability::AtomicFloat16AddEXT, - spv::Capability::DebugInfoModuleINTEL, - spv::Capability::SplitBarrierINTEL, - spv::Capability::GroupUniformArithmeticKHR, - spv::Capability::Max, -}; - -namespace { -std::vector enumerateValuesFromToWithStep(size_t start, size_t end, - size_t step) { - assert(end > start && "end > start"); - std::vector orderedValues; - for (size_t i = start; i < end; i += step) { - orderedValues.push_back(static_cast(i)); - } - return orderedValues; -} - -EnumSet createSetUnorderedInsertion( - const std::vector& values) { - std::vector shuffledValues(values.cbegin(), values.cend()); - std::mt19937 rng(0); - std::shuffle(shuffledValues.begin(), shuffledValues.end(), rng); - EnumSet set; - for (auto value : shuffledValues) { - set.insert(value); - } - return set; -} -} // namespace - TEST(EnumSet, IsEmpty1) { - EnumSet set; - EXPECT_TRUE(set.empty()); - set.insert(TestEnum::ZERO); - EXPECT_FALSE(set.empty()); + EnumSet set; + EXPECT_TRUE(set.IsEmpty()); + set.Add(0); + EXPECT_FALSE(set.IsEmpty()); } TEST(EnumSet, IsEmpty2) { - EnumSet set; - EXPECT_TRUE(set.empty()); - set.insert(TestEnum::ONE_HUNDRED_FIFTY); - EXPECT_FALSE(set.empty()); + EnumSet set; + EXPECT_TRUE(set.IsEmpty()); + set.Add(150); + EXPECT_FALSE(set.IsEmpty()); } TEST(EnumSet, IsEmpty3) { - EnumSet set(TestEnum::FOUR); - EXPECT_FALSE(set.empty()); + EnumSet set(4); + EXPECT_FALSE(set.IsEmpty()); } TEST(EnumSet, IsEmpty4) { - EnumSet set(TestEnum::THREE_HUNDRED); - EXPECT_FALSE(set.empty()); + EnumSet set(300); + EXPECT_FALSE(set.IsEmpty()); } TEST(EnumSetHasAnyOf, EmptySetEmptyQuery) { - const EnumSet set; - const EnumSet empty; + const EnumSet set; + const EnumSet empty; EXPECT_TRUE(set.HasAnyOf(empty)); - EXPECT_TRUE(EnumSet().HasAnyOf(EnumSet())); + EXPECT_TRUE(EnumSet().HasAnyOf(EnumSet())); } TEST(EnumSetHasAnyOf, MaskSetEmptyQuery) { - EnumSet set; - const EnumSet empty; - set.insert(TestEnum::FIVE); - set.insert(TestEnum::EIGHT); + EnumSet set; + const EnumSet empty; + set.Add(5); + set.Add(8); EXPECT_TRUE(set.HasAnyOf(empty)); } TEST(EnumSetHasAnyOf, OverflowSetEmptyQuery) { - EnumSet set; - const EnumSet empty; - set.insert(TestEnum::TWO_HUNDRED); - set.insert(TestEnum::THREE_HUNDRED); + EnumSet set; + const EnumSet empty; + set.Add(200); + set.Add(300); EXPECT_TRUE(set.HasAnyOf(empty)); } TEST(EnumSetHasAnyOf, EmptyQuery) { - EnumSet set; - const EnumSet empty; - set.insert(TestEnum::FIVE); - set.insert(TestEnum::EIGHT); - set.insert(TestEnum::TWO_HUNDRED); - set.insert(TestEnum::THREE_HUNDRED); + EnumSet set; + const EnumSet empty; + set.Add(5); + set.Add(8); + set.Add(200); + set.Add(300); EXPECT_TRUE(set.HasAnyOf(empty)); } TEST(EnumSetHasAnyOf, EmptyQueryAlwaysTrue) { - EnumSet set; - const EnumSet empty; + EnumSet set; + const EnumSet empty; EXPECT_TRUE(set.HasAnyOf(empty)); - set.insert(TestEnum::FIVE); + set.Add(5); EXPECT_TRUE(set.HasAnyOf(empty)); - EXPECT_TRUE( - EnumSet(TestEnum::ONE_HUNDRED).HasAnyOf(EnumSet())); + EXPECT_TRUE(EnumSet(100).HasAnyOf(EnumSet())); } TEST(EnumSetHasAnyOf, ReflexiveMask) { - EnumSet set(TestEnum::THREE); - set.insert(TestEnum::TWENTY_FOUR); - set.insert(TestEnum::THIRTY); + EnumSet set(3); + set.Add(24); + set.Add(30); EXPECT_TRUE(set.HasAnyOf(set)); } TEST(EnumSetHasAnyOf, ReflexiveOverflow) { - EnumSet set(TestEnum::TWO_HUNDRED); - set.insert(TestEnum::TWO_HUNDRED); - set.insert(TestEnum::FOUR_HUNDRED); + EnumSet set(200); + set.Add(300); + set.Add(400); EXPECT_TRUE(set.HasAnyOf(set)); } TEST(EnumSetHasAnyOf, Reflexive) { - EnumSet set(TestEnum::THREE); - set.insert(TestEnum::TWENTY_FOUR); - set.insert(TestEnum::THREE_HUNDRED); - set.insert(TestEnum::FOUR_HUNDRED); + EnumSet set(3); + set.Add(24); + set.Add(300); + set.Add(400); EXPECT_TRUE(set.HasAnyOf(set)); } TEST(EnumSetHasAnyOf, EmptySetHasNone) { - EnumSet set; - EnumSet items; + EnumSet set; + EnumSet items; for (uint32_t i = 0; i < 200; ++i) { - TestEnum enumValue = static_cast(i); - items.insert(enumValue); + items.Add(i); EXPECT_FALSE(set.HasAnyOf(items)); - EXPECT_FALSE(set.HasAnyOf(EnumSet(enumValue))); + EXPECT_FALSE(set.HasAnyOf(EnumSet(i))); } } TEST(EnumSetHasAnyOf, MaskSetMaskQuery) { - EnumSet set(TestEnum::ZERO); - EnumSet items(TestEnum::ONE); + EnumSet set(0); + EnumSet items(1); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::TWO); - items.insert(TestEnum::THREE); + set.Add(2); + items.Add(3); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::THREE); + set.Add(3); EXPECT_TRUE(set.HasAnyOf(items)); - set.insert(TestEnum::FOUR); + set.Add(4); EXPECT_TRUE(set.HasAnyOf(items)); } TEST(EnumSetHasAnyOf, OverflowSetOverflowQuery) { - EnumSet set(TestEnum::ONE_HUNDRED); - EnumSet items(TestEnum::TWO_HUNDRED); + EnumSet set(100); + EnumSet items(200); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::THREE_HUNDRED); - items.insert(TestEnum::FOUR_HUNDRED); + set.Add(300); + items.Add(400); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::TWO_HUNDRED); + set.Add(200); EXPECT_TRUE(set.HasAnyOf(items)); - set.insert(TestEnum::FIVE_HUNDRED); + set.Add(500); EXPECT_TRUE(set.HasAnyOf(items)); } TEST(EnumSetHasAnyOf, GeneralCase) { - EnumSet set(TestEnum::ZERO); - EnumSet items(TestEnum::ONE_HUNDRED); + EnumSet set(0); + EnumSet items(100); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::THREE_HUNDRED); - items.insert(TestEnum::FOUR); + set.Add(300); + items.Add(4); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::FIVE); - items.insert(TestEnum::FIVE_HUNDRED); + set.Add(5); + items.Add(500); EXPECT_FALSE(set.HasAnyOf(items)); - set.insert(TestEnum::FIVE_HUNDRED); + set.Add(500); EXPECT_TRUE(set.HasAnyOf(items)); - EXPECT_FALSE(set.HasAnyOf(EnumSet(TestEnum::TWENTY))); - EXPECT_FALSE(set.HasAnyOf(EnumSet(TestEnum::SIX_HUNDRED))); - EXPECT_TRUE(set.HasAnyOf(EnumSet(TestEnum::FIVE))); - EXPECT_TRUE(set.HasAnyOf(EnumSet(TestEnum::THREE_HUNDRED))); - EXPECT_TRUE(set.HasAnyOf(EnumSet(TestEnum::ZERO))); + EXPECT_FALSE(set.HasAnyOf(EnumSet(20))); + EXPECT_FALSE(set.HasAnyOf(EnumSet(600))); + EXPECT_TRUE(set.HasAnyOf(EnumSet(5))); + EXPECT_TRUE(set.HasAnyOf(EnumSet(300))); + EXPECT_TRUE(set.HasAnyOf(EnumSet(0))); } TEST(EnumSet, DefaultIsEmpty) { - EnumSet set; + EnumSet set; for (uint32_t i = 0; i < 1000; ++i) { - EXPECT_FALSE(set.contains(static_cast(i))); - } -} - -TEST(EnumSet, EqualityCompareEmpty) { - EnumSet set1; - EnumSet set2; - - EXPECT_TRUE(set1 == set2); - EXPECT_FALSE(set1 != set2); -} - -TEST(EnumSet, EqualityCompareSame) { - EnumSet set1; - EnumSet set2; - - set1.insert(TestEnum::ONE); - set1.insert(TestEnum::TWENTY); - set2.insert(TestEnum::TWENTY); - set2.insert(TestEnum::ONE); - - EXPECT_TRUE(set1 == set2); - EXPECT_FALSE(set1 != set2); -} - -TEST(EnumSet, EqualityCompareDifferent) { - EnumSet set1; - EnumSet set2; - - set1.insert(TestEnum::ONE); - set1.insert(TestEnum::TWENTY); - set2.insert(TestEnum::FIVE); - set2.insert(TestEnum::ONE); - - EXPECT_FALSE(set1 == set2); - EXPECT_TRUE(set1 != set2); -} - -TEST(EnumSet, ConstructFromIterators) { - auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1); - EnumSet set1 = createSetUnorderedInsertion(orderedValues); - - EnumSet set2(orderedValues.cbegin(), orderedValues.cend()); - - EXPECT_EQ(set1, set2); -} - -TEST(EnumSet, InsertUsingIteratorRange) { - auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1); - EnumSet set1 = createSetUnorderedInsertion(orderedValues); - - EnumSet set2; - set2.insert(orderedValues.cbegin(), orderedValues.cend()); - - EXPECT_EQ(set1, set2); -} - -TEST(CapabilitySet, RangeBasedLoopOrderIsEnumOrder) { - auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1); - auto set = createSetUnorderedInsertion(orderedValues); - - size_t index = 0; - for (auto value : set) { - ASSERT_THAT(value, Eq(orderedValues[index])); - index++; + EXPECT_FALSE(set.Contains(i)); } } TEST(CapabilitySet, ConstructSingleMemberMatrix) { - CapabilitySet s(spv::Capability::Matrix); - EXPECT_TRUE(s.contains(spv::Capability::Matrix)); - EXPECT_FALSE(s.contains(spv::Capability::Shader)); - EXPECT_FALSE(s.contains(static_cast(1000))); + CapabilitySet s(SpvCapabilityMatrix); + EXPECT_TRUE(s.Contains(SpvCapabilityMatrix)); + EXPECT_FALSE(s.Contains(SpvCapabilityShader)); + EXPECT_FALSE(s.Contains(static_cast(1000))); } TEST(CapabilitySet, ConstructSingleMemberMaxInMask) { - CapabilitySet s(static_cast(63)); - EXPECT_FALSE(s.contains(spv::Capability::Matrix)); - EXPECT_FALSE(s.contains(spv::Capability::Shader)); - EXPECT_TRUE(s.contains(static_cast(63))); - EXPECT_FALSE(s.contains(static_cast(64))); - EXPECT_FALSE(s.contains(static_cast(1000))); + CapabilitySet s(static_cast(63)); + EXPECT_FALSE(s.Contains(SpvCapabilityMatrix)); + EXPECT_FALSE(s.Contains(SpvCapabilityShader)); + EXPECT_TRUE(s.Contains(static_cast(63))); + EXPECT_FALSE(s.Contains(static_cast(64))); + EXPECT_FALSE(s.Contains(static_cast(1000))); } TEST(CapabilitySet, ConstructSingleMemberMinOverflow) { // Check the first one that forces overflow beyond the mask. - CapabilitySet s(static_cast(64)); - EXPECT_FALSE(s.contains(spv::Capability::Matrix)); - EXPECT_FALSE(s.contains(spv::Capability::Shader)); - EXPECT_FALSE(s.contains(static_cast(63))); - EXPECT_TRUE(s.contains(static_cast(64))); - EXPECT_FALSE(s.contains(static_cast(1000))); + CapabilitySet s(static_cast(64)); + EXPECT_FALSE(s.Contains(SpvCapabilityMatrix)); + EXPECT_FALSE(s.Contains(SpvCapabilityShader)); + EXPECT_FALSE(s.Contains(static_cast(63))); + EXPECT_TRUE(s.Contains(static_cast(64))); + EXPECT_FALSE(s.Contains(static_cast(1000))); } TEST(CapabilitySet, ConstructSingleMemberMaxOverflow) { // Check the max 32-bit signed int. - CapabilitySet s(static_cast(0x7fffffffu)); - EXPECT_FALSE(s.contains(spv::Capability::Matrix)); - EXPECT_FALSE(s.contains(spv::Capability::Shader)); - EXPECT_FALSE(s.contains(static_cast(1000))); - EXPECT_TRUE(s.contains(static_cast(0x7fffffffu))); + CapabilitySet s(static_cast(0x7fffffffu)); + EXPECT_FALSE(s.Contains(SpvCapabilityMatrix)); + EXPECT_FALSE(s.Contains(SpvCapabilityShader)); + EXPECT_FALSE(s.Contains(static_cast(1000))); + EXPECT_TRUE(s.Contains(static_cast(0x7fffffffu))); } TEST(CapabilitySet, AddEnum) { - CapabilitySet s(spv::Capability::Shader); - s.insert(spv::Capability::Kernel); - s.insert(static_cast(42)); - EXPECT_FALSE(s.contains(spv::Capability::Matrix)); - EXPECT_TRUE(s.contains(spv::Capability::Shader)); - EXPECT_TRUE(s.contains(spv::Capability::Kernel)); - EXPECT_TRUE(s.contains(static_cast(42))); -} - -TEST(CapabilitySet, InsertReturnsIteratorToInserted) { - CapabilitySet set; - - auto[it, inserted] = set.insert(spv::Capability::Kernel); - - EXPECT_TRUE(inserted); - EXPECT_EQ(*it, spv::Capability::Kernel); -} - -TEST(CapabilitySet, InsertReturnsIteratorToElementOnDoubleInsertion) { - CapabilitySet set; - EXPECT_FALSE(set.contains(spv::Capability::Shader)); - { - auto[it, inserted] = set.insert(spv::Capability::Shader); - EXPECT_TRUE(inserted); - EXPECT_EQ(*it, spv::Capability::Shader); - } - EXPECT_TRUE(set.contains(spv::Capability::Shader)); - - auto[it, inserted] = set.insert(spv::Capability::Shader); - - EXPECT_FALSE(inserted); - EXPECT_EQ(*it, spv::Capability::Shader); - EXPECT_TRUE(set.contains(spv::Capability::Shader)); -} - -TEST(CapabilitySet, InsertWithHintWorks) { - CapabilitySet set; - EXPECT_FALSE(set.contains(spv::Capability::Shader)); - - auto it = set.insert(set.begin(), spv::Capability::Shader); - - EXPECT_EQ(*it, spv::Capability::Shader); - EXPECT_TRUE(set.contains(spv::Capability::Shader)); -} - -TEST(CapabilitySet, InsertWithEndHintWorks) { - CapabilitySet set; - EXPECT_FALSE(set.contains(spv::Capability::Shader)); - - auto it = set.insert(set.end(), spv::Capability::Shader); - - EXPECT_EQ(*it, spv::Capability::Shader); - EXPECT_TRUE(set.contains(spv::Capability::Shader)); -} - -TEST(CapabilitySet, IteratorCanBeCopied) { - CapabilitySet set; - set.insert(spv::Capability::Matrix); - set.insert(spv::Capability::Shader); - set.insert(spv::Capability::Geometry); - set.insert(spv::Capability::Float64); - set.insert(spv::Capability::Float16); - - auto a = set.begin(); - ++a; - auto b = a; - - EXPECT_EQ(*b, *a); - ++b; - EXPECT_NE(*b, *a); - - ++a; - EXPECT_EQ(*b, *a); - - ++a; - EXPECT_NE(*b, *a); -} - -TEST(CapabilitySet, IteratorBeginToEndPostfix) { - auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1); - auto set = createSetUnorderedInsertion(orderedValues); - - size_t index = 0; - for (auto it = set.cbegin(); it != set.cend(); it++, index++) { - EXPECT_EQ(*it, orderedValues[index]); - } -} - -TEST(CapabilitySet, IteratorBeginToEndPrefix) { - auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1); - auto set = createSetUnorderedInsertion(orderedValues); - - size_t index = 0; - for (auto it = set.cbegin(); it != set.cend(); ++it, index++) { - EXPECT_EQ(*it, orderedValues[index]); - } -} - -TEST(CapabilitySet, IteratorBeginToEndPrefixStep) { - auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 8); - auto set = createSetUnorderedInsertion(orderedValues); - - size_t index = 0; - for (auto it = set.cbegin(); it != set.cend(); ++it, index++) { - ASSERT_EQ(*it, orderedValues[index]); - } -} - -TEST(CapabilitySet, IteratorBeginOnEmpty) { - CapabilitySet set; - - auto begin = set.begin(); - auto end = set.end(); - ASSERT_EQ(begin, end); -} - -TEST(CapabilitySet, IteratorBeginOnSingleNonZeroValue) { - CapabilitySet set; - set.insert(spv::Capability::Shader); - - auto begin = set.begin(); - auto end = set.end(); - - ASSERT_NE(begin, end); - ASSERT_EQ(*begin, spv::Capability::Shader); -} - -TEST(CapabilitySet, IteratorForLoopNonZeroValue) { - CapabilitySet set; - set.insert(spv::Capability::Shader); - set.insert(spv::Capability::Tessellation); - - auto begin = set.begin(); - auto end = set.end(); - - ASSERT_NE(begin, end); - ASSERT_EQ(*begin, spv::Capability::Shader); - - begin++; - ASSERT_NE(begin, end); - ASSERT_EQ(*begin, spv::Capability::Tessellation); - - begin++; - ASSERT_EQ(begin, end); -} - -TEST(CapabilitySet, IteratorPastEnd) { - CapabilitySet set; - set.insert(spv::Capability::Shader); - - auto begin = set.begin(); - auto end = set.end(); - - ASSERT_NE(begin, end); - ASSERT_EQ(*begin, spv::Capability::Shader); - - begin++; - ASSERT_EQ(begin, end); - - begin++; - ASSERT_EQ(begin, end); -} - -TEST(CapabilitySet, CompatibleWithSTLFind) { - CapabilitySet set; - set.insert(spv::Capability::Matrix); - set.insert(spv::Capability::Shader); - set.insert(spv::Capability::Geometry); - set.insert(spv::Capability::Tessellation); - set.insert(spv::Capability::Addresses); - set.insert(spv::Capability::Linkage); - set.insert(spv::Capability::Kernel); - set.insert(spv::Capability::Vector16); - set.insert(spv::Capability::Float16Buffer); - set.insert(spv::Capability::Float64); - - { - auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Vector16); - ASSERT_NE(it, set.end()); - ASSERT_EQ(*it, spv::Capability::Vector16); - } - - { - auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Float16); - ASSERT_EQ(it, set.end()); - } -} - -TEST(CapabilitySet, CompatibleWithSTLForEach) { - auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 15); - auto set = createSetUnorderedInsertion(orderedValues); - - size_t index = 0; - std::for_each(set.cbegin(), set.cend(), [&](auto item) { - ASSERT_EQ(item, orderedValues[index]); - index++; - }); + CapabilitySet s(SpvCapabilityShader); + s.Add(SpvCapabilityKernel); + s.Add(static_cast(42)); + EXPECT_FALSE(s.Contains(SpvCapabilityMatrix)); + EXPECT_TRUE(s.Contains(SpvCapabilityShader)); + EXPECT_TRUE(s.Contains(SpvCapabilityKernel)); + EXPECT_TRUE(s.Contains(static_cast(42))); } TEST(CapabilitySet, InitializerListEmpty) { CapabilitySet s{}; for (uint32_t i = 0; i < 1000; i++) { - EXPECT_FALSE(s.contains(static_cast(i))); - } -} - -TEST(CapabilitySet, LargeSetHasInsertedElements) { - CapabilitySet set; - for (auto c : kCapabilities) { - EXPECT_FALSE(set.contains(c)); - } - - for (auto c : kCapabilities) { - set.insert(c); - EXPECT_TRUE(set.contains(c)); - } - - for (auto c : kCapabilities) { - EXPECT_TRUE(set.contains(c)); - } -} - -TEST(CapabilitySet, LargeSetHasUnsortedInsertedElements) { - std::vector shuffledCapabilities(kCapabilities.cbegin(), - kCapabilities.cend()); - std::mt19937 rng(0); - std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng); - CapabilitySet set; - for (auto c : shuffledCapabilities) { - EXPECT_FALSE(set.contains(c)); - } - - for (auto c : shuffledCapabilities) { - set.insert(c); - EXPECT_TRUE(set.contains(c)); - } - - for (auto c : shuffledCapabilities) { - EXPECT_TRUE(set.contains(c)); - } -} - -TEST(CapabilitySet, LargeSetHasUnsortedRemovedElement) { - std::vector shuffledCapabilities(kCapabilities.cbegin(), - kCapabilities.cend()); - std::mt19937 rng(0); - std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng); - CapabilitySet set; - for (auto c : shuffledCapabilities) { - set.insert(c); - EXPECT_TRUE(set.contains(c)); - } - - for (auto c : kCapabilities) { - set.erase(c); - } - - for (auto c : shuffledCapabilities) { - EXPECT_FALSE(set.contains(c)); + EXPECT_FALSE(s.Contains(static_cast(i))); } } struct ForEachCase { CapabilitySet capabilities; - std::vector expected; + std::vector expected; }; using CapabilitySetForEachTest = ::testing::TestWithParam; @@ -848,7 +253,7 @@ TEST_P(CapabilitySetForEachTest, MoveConstructor) { EXPECT_THAT(ElementsIn(moved), Eq(GetParam().expected)); // The moved-from set is empty. - EXPECT_THAT(ElementsIn(copy), Eq(std::vector{})); + EXPECT_THAT(ElementsIn(copy), Eq(std::vector{})); } TEST_P(CapabilitySetForEachTest, OperatorEquals) { @@ -862,40 +267,24 @@ TEST_P(CapabilitySetForEachTest, OperatorEqualsSelfAssign) { EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected)); } -INSTANTIATE_TEST_SUITE_P( - Samples, CapabilitySetForEachTest, - ValuesIn(std::vector{ - {{}, {}}, - {{spv::Capability::Matrix}, {spv::Capability::Matrix}}, - {{spv::Capability::Kernel, spv::Capability::Shader}, - {spv::Capability::Shader, spv::Capability::Kernel}}, - {{static_cast(999)}, - {static_cast(999)}}, - {{static_cast(0x7fffffff)}, - {static_cast(0x7fffffff)}}, - // Mixture and out of order - {{static_cast(0x7fffffff), - static_cast(100), spv::Capability::Shader, - spv::Capability::Matrix}, - {spv::Capability::Matrix, spv::Capability::Shader, - static_cast(100), - static_cast(0x7fffffff)}}, - })); - -using BoundaryTestWithParam = ::testing::TestWithParam; - -TEST_P(BoundaryTestWithParam, InsertedContains) { - CapabilitySet set; - set.insert(GetParam()); - EXPECT_TRUE(set.contains(GetParam())); -} - -INSTANTIATE_TEST_SUITE_P( - Samples, BoundaryTestWithParam, - Values(static_cast(0), static_cast(63), - static_cast(64), static_cast(65), - static_cast(127), static_cast(128), - static_cast(129))); +INSTANTIATE_TEST_SUITE_P(Samples, CapabilitySetForEachTest, + ValuesIn(std::vector{ + {{}, {}}, + {{SpvCapabilityMatrix}, {SpvCapabilityMatrix}}, + {{SpvCapabilityKernel, SpvCapabilityShader}, + {SpvCapabilityShader, SpvCapabilityKernel}}, + {{static_cast(999)}, + {static_cast(999)}}, + {{static_cast(0x7fffffff)}, + {static_cast(0x7fffffff)}}, + // Mixture and out of order + {{static_cast(0x7fffffff), + static_cast(100), + SpvCapabilityShader, SpvCapabilityMatrix}, + {SpvCapabilityMatrix, SpvCapabilityShader, + static_cast(100), + static_cast(0x7fffffff)}}, + })); } // namespace } // namespace spvtools diff --git a/test/enum_string_mapping_test.cpp b/test/enum_string_mapping_test.cpp index 01dede74..52aa653e 100644 --- a/test/enum_string_mapping_test.cpp +++ b/test/enum_string_mapping_test.cpp @@ -34,7 +34,7 @@ using ExtensionTest = ::testing::TestWithParam>; using UnknownExtensionTest = ::testing::TestWithParam; using CapabilityTest = - ::testing::TestWithParam>; + ::testing::TestWithParam>; TEST_P(ExtensionTest, TestExtensionFromString) { const std::pair& param = GetParam(); @@ -59,8 +59,8 @@ TEST_P(UnknownExtensionTest, TestExtensionFromStringFails) { } TEST_P(CapabilityTest, TestCapabilityToString) { - const std::pair& param = GetParam(); - const spv::Capability capability = param.first; + const std::pair& param = GetParam(); + const SpvCapability capability = param.first; const std::string capability_str = param.second; const std::string result_str = CapabilityToString(capability); EXPECT_EQ(capability_str, result_str); @@ -99,105 +99,104 @@ INSTANTIATE_TEST_SUITE_P(UnknownExtensions, UnknownExtensionTest, INSTANTIATE_TEST_SUITE_P( AllCapabilities, CapabilityTest, - ValuesIn(std::vector>( - {{spv::Capability::Matrix, "Matrix"}, - {spv::Capability::Shader, "Shader"}, - {spv::Capability::Geometry, "Geometry"}, - {spv::Capability::Tessellation, "Tessellation"}, - {spv::Capability::Addresses, "Addresses"}, - {spv::Capability::Linkage, "Linkage"}, - {spv::Capability::Kernel, "Kernel"}, - {spv::Capability::Vector16, "Vector16"}, - {spv::Capability::Float16Buffer, "Float16Buffer"}, - {spv::Capability::Float16, "Float16"}, - {spv::Capability::Float64, "Float64"}, - {spv::Capability::Int64, "Int64"}, - {spv::Capability::Int64Atomics, "Int64Atomics"}, - {spv::Capability::ImageBasic, "ImageBasic"}, - {spv::Capability::ImageReadWrite, "ImageReadWrite"}, - {spv::Capability::ImageMipmap, "ImageMipmap"}, - {spv::Capability::Pipes, "Pipes"}, - {spv::Capability::Groups, "Groups"}, - {spv::Capability::DeviceEnqueue, "DeviceEnqueue"}, - {spv::Capability::LiteralSampler, "LiteralSampler"}, - {spv::Capability::AtomicStorage, "AtomicStorage"}, - {spv::Capability::Int16, "Int16"}, - {spv::Capability::TessellationPointSize, "TessellationPointSize"}, - {spv::Capability::GeometryPointSize, "GeometryPointSize"}, - {spv::Capability::ImageGatherExtended, "ImageGatherExtended"}, - {spv::Capability::StorageImageMultisample, "StorageImageMultisample"}, - {spv::Capability::UniformBufferArrayDynamicIndexing, + ValuesIn(std::vector>( + {{SpvCapabilityMatrix, "Matrix"}, + {SpvCapabilityShader, "Shader"}, + {SpvCapabilityGeometry, "Geometry"}, + {SpvCapabilityTessellation, "Tessellation"}, + {SpvCapabilityAddresses, "Addresses"}, + {SpvCapabilityLinkage, "Linkage"}, + {SpvCapabilityKernel, "Kernel"}, + {SpvCapabilityVector16, "Vector16"}, + {SpvCapabilityFloat16Buffer, "Float16Buffer"}, + {SpvCapabilityFloat16, "Float16"}, + {SpvCapabilityFloat64, "Float64"}, + {SpvCapabilityInt64, "Int64"}, + {SpvCapabilityInt64Atomics, "Int64Atomics"}, + {SpvCapabilityImageBasic, "ImageBasic"}, + {SpvCapabilityImageReadWrite, "ImageReadWrite"}, + {SpvCapabilityImageMipmap, "ImageMipmap"}, + {SpvCapabilityPipes, "Pipes"}, + {SpvCapabilityGroups, "Groups"}, + {SpvCapabilityDeviceEnqueue, "DeviceEnqueue"}, + {SpvCapabilityLiteralSampler, "LiteralSampler"}, + {SpvCapabilityAtomicStorage, "AtomicStorage"}, + {SpvCapabilityInt16, "Int16"}, + {SpvCapabilityTessellationPointSize, "TessellationPointSize"}, + {SpvCapabilityGeometryPointSize, "GeometryPointSize"}, + {SpvCapabilityImageGatherExtended, "ImageGatherExtended"}, + {SpvCapabilityStorageImageMultisample, "StorageImageMultisample"}, + {SpvCapabilityUniformBufferArrayDynamicIndexing, "UniformBufferArrayDynamicIndexing"}, - {spv::Capability::SampledImageArrayDynamicIndexing, + {SpvCapabilitySampledImageArrayDynamicIndexing, "SampledImageArrayDynamicIndexing"}, - {spv::Capability::StorageBufferArrayDynamicIndexing, + {SpvCapabilityStorageBufferArrayDynamicIndexing, "StorageBufferArrayDynamicIndexing"}, - {spv::Capability::StorageImageArrayDynamicIndexing, + {SpvCapabilityStorageImageArrayDynamicIndexing, "StorageImageArrayDynamicIndexing"}, - {spv::Capability::ClipDistance, "ClipDistance"}, - {spv::Capability::CullDistance, "CullDistance"}, - {spv::Capability::ImageCubeArray, "ImageCubeArray"}, - {spv::Capability::SampleRateShading, "SampleRateShading"}, - {spv::Capability::ImageRect, "ImageRect"}, - {spv::Capability::SampledRect, "SampledRect"}, - {spv::Capability::GenericPointer, "GenericPointer"}, - {spv::Capability::Int8, "Int8"}, - {spv::Capability::InputAttachment, "InputAttachment"}, - {spv::Capability::SparseResidency, "SparseResidency"}, - {spv::Capability::MinLod, "MinLod"}, - {spv::Capability::Sampled1D, "Sampled1D"}, - {spv::Capability::Image1D, "Image1D"}, - {spv::Capability::SampledCubeArray, "SampledCubeArray"}, - {spv::Capability::SampledBuffer, "SampledBuffer"}, - {spv::Capability::ImageBuffer, "ImageBuffer"}, - {spv::Capability::ImageMSArray, "ImageMSArray"}, - {spv::Capability::StorageImageExtendedFormats, + {SpvCapabilityClipDistance, "ClipDistance"}, + {SpvCapabilityCullDistance, "CullDistance"}, + {SpvCapabilityImageCubeArray, "ImageCubeArray"}, + {SpvCapabilitySampleRateShading, "SampleRateShading"}, + {SpvCapabilityImageRect, "ImageRect"}, + {SpvCapabilitySampledRect, "SampledRect"}, + {SpvCapabilityGenericPointer, "GenericPointer"}, + {SpvCapabilityInt8, "Int8"}, + {SpvCapabilityInputAttachment, "InputAttachment"}, + {SpvCapabilitySparseResidency, "SparseResidency"}, + {SpvCapabilityMinLod, "MinLod"}, + {SpvCapabilitySampled1D, "Sampled1D"}, + {SpvCapabilityImage1D, "Image1D"}, + {SpvCapabilitySampledCubeArray, "SampledCubeArray"}, + {SpvCapabilitySampledBuffer, "SampledBuffer"}, + {SpvCapabilityImageBuffer, "ImageBuffer"}, + {SpvCapabilityImageMSArray, "ImageMSArray"}, + {SpvCapabilityStorageImageExtendedFormats, "StorageImageExtendedFormats"}, - {spv::Capability::ImageQuery, "ImageQuery"}, - {spv::Capability::DerivativeControl, "DerivativeControl"}, - {spv::Capability::InterpolationFunction, "InterpolationFunction"}, - {spv::Capability::TransformFeedback, "TransformFeedback"}, - {spv::Capability::GeometryStreams, "GeometryStreams"}, - {spv::Capability::StorageImageReadWithoutFormat, + {SpvCapabilityImageQuery, "ImageQuery"}, + {SpvCapabilityDerivativeControl, "DerivativeControl"}, + {SpvCapabilityInterpolationFunction, "InterpolationFunction"}, + {SpvCapabilityTransformFeedback, "TransformFeedback"}, + {SpvCapabilityGeometryStreams, "GeometryStreams"}, + {SpvCapabilityStorageImageReadWithoutFormat, "StorageImageReadWithoutFormat"}, - {spv::Capability::StorageImageWriteWithoutFormat, + {SpvCapabilityStorageImageWriteWithoutFormat, "StorageImageWriteWithoutFormat"}, - {spv::Capability::MultiViewport, "MultiViewport"}, - {spv::Capability::SubgroupDispatch, "SubgroupDispatch"}, - {spv::Capability::NamedBarrier, "NamedBarrier"}, - {spv::Capability::PipeStorage, "PipeStorage"}, - {spv::Capability::SubgroupBallotKHR, "SubgroupBallotKHR"}, - {spv::Capability::DrawParameters, "DrawParameters"}, - {spv::Capability::SubgroupVoteKHR, "SubgroupVoteKHR"}, - {spv::Capability::StorageBuffer16BitAccess, - "StorageBuffer16BitAccess"}, - {spv::Capability::StorageUniformBufferBlock16, + {SpvCapabilityMultiViewport, "MultiViewport"}, + {SpvCapabilitySubgroupDispatch, "SubgroupDispatch"}, + {SpvCapabilityNamedBarrier, "NamedBarrier"}, + {SpvCapabilityPipeStorage, "PipeStorage"}, + {SpvCapabilitySubgroupBallotKHR, "SubgroupBallotKHR"}, + {SpvCapabilityDrawParameters, "DrawParameters"}, + {SpvCapabilitySubgroupVoteKHR, "SubgroupVoteKHR"}, + {SpvCapabilityStorageBuffer16BitAccess, "StorageBuffer16BitAccess"}, + {SpvCapabilityStorageUniformBufferBlock16, "StorageBuffer16BitAccess"}, // Preferred name - {spv::Capability::UniformAndStorageBuffer16BitAccess, + {SpvCapabilityUniformAndStorageBuffer16BitAccess, "UniformAndStorageBuffer16BitAccess"}, - {spv::Capability::StorageUniform16, + {SpvCapabilityStorageUniform16, "UniformAndStorageBuffer16BitAccess"}, // Preferred name - {spv::Capability::StoragePushConstant16, "StoragePushConstant16"}, - {spv::Capability::StorageInputOutput16, "StorageInputOutput16"}, - {spv::Capability::DeviceGroup, "DeviceGroup"}, - {spv::Capability::AtomicFloat32AddEXT, "AtomicFloat32AddEXT"}, - {spv::Capability::AtomicFloat64AddEXT, "AtomicFloat64AddEXT"}, - {spv::Capability::AtomicFloat32MinMaxEXT, "AtomicFloat32MinMaxEXT"}, - {spv::Capability::AtomicFloat64MinMaxEXT, "AtomicFloat64MinMaxEXT"}, - {spv::Capability::MultiView, "MultiView"}, - {spv::Capability::Int64ImageEXT, "Int64ImageEXT"}, - {spv::Capability::SampleMaskOverrideCoverageNV, + {SpvCapabilityStoragePushConstant16, "StoragePushConstant16"}, + {SpvCapabilityStorageInputOutput16, "StorageInputOutput16"}, + {SpvCapabilityDeviceGroup, "DeviceGroup"}, + {SpvCapabilityAtomicFloat32AddEXT, "AtomicFloat32AddEXT"}, + {SpvCapabilityAtomicFloat64AddEXT, "AtomicFloat64AddEXT"}, + {SpvCapabilityAtomicFloat32MinMaxEXT, "AtomicFloat32MinMaxEXT"}, + {SpvCapabilityAtomicFloat64MinMaxEXT, "AtomicFloat64MinMaxEXT"}, + {SpvCapabilityMultiView, "MultiView"}, + {SpvCapabilityInt64ImageEXT, "Int64ImageEXT"}, + {SpvCapabilitySampleMaskOverrideCoverageNV, "SampleMaskOverrideCoverageNV"}, - {spv::Capability::GeometryShaderPassthroughNV, + {SpvCapabilityGeometryShaderPassthroughNV, "GeometryShaderPassthroughNV"}, // The next two are different names for the same token. - {spv::Capability::ShaderViewportIndexLayerNV, + {SpvCapabilityShaderViewportIndexLayerNV, "ShaderViewportIndexLayerEXT"}, - {spv::Capability::ShaderViewportIndexLayerEXT, + {SpvCapabilityShaderViewportIndexLayerEXT, "ShaderViewportIndexLayerEXT"}, - {spv::Capability::ShaderViewportMaskNV, "ShaderViewportMaskNV"}, - {spv::Capability::ShaderStereoViewNV, "ShaderStereoViewNV"}, - {spv::Capability::PerViewAttributesNV, "PerViewAttributesNV"}}))); + {SpvCapabilityShaderViewportMaskNV, "ShaderViewportMaskNV"}, + {SpvCapabilityShaderStereoViewNV, "ShaderStereoViewNV"}, + {SpvCapabilityPerViewAttributesNV, "PerViewAttributesNV"}}))); } // namespace } // namespace spvtools diff --git a/test/ext_inst.cldebug100_test.cpp b/test/ext_inst.cldebug100_test.cpp index cfc68e87..0bbdd3a9 100644 --- a/test/ext_inst.cldebug100_test.cpp +++ b/test/ext_inst.cldebug100_test.cpp @@ -18,6 +18,7 @@ #include "OpenCLDebugInfo100.h" #include "gmock/gmock.h" #include "source/util/string_utils.h" +#include "spirv/unified1/spirv.h" #include "test/test_fixture.h" #include "test/unit_spirv.h" @@ -157,13 +158,12 @@ TEST_P(ExtInstCLDebugInfo100RoundTripTest, ParameterizedExtInst) { GetParam().name + GetParam().operands + "\n"; // First make sure it assembles correctly. std::cout << input << std::endl; - EXPECT_THAT( - CompiledInstructions(input), - Eq(Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("OpenCL.DebugInfo.100")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, GetParam().opcode}, - GetParam().expected_operands)}))) + EXPECT_THAT(CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, + MakeVector("OpenCL.DebugInfo.100")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode}, + GetParam().expected_operands)}))) << input; // Now check the round trip through the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input; @@ -297,7 +297,7 @@ TEST_P(ExtInstCLDebugInfo100RoundTripTest, ParameterizedExtInst) { { \ uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ " %4 " #S0 " " Fstr, { \ - 4, uint32_t(spv::StorageClass::S0), Fnum \ + 4, uint32_t(SpvStorageClass##S0), Fnum \ } \ } @@ -313,7 +313,7 @@ TEST_P(ExtInstCLDebugInfo100RoundTripTest, ParameterizedExtInst) { { \ uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ " " #L0 " " #L1 " %4 " RawEnumName, { \ - L0, L1, 4, (uint32_t)RawEnumValue \ + L0, L1, 4, RawEnumValue \ } \ } @@ -574,7 +574,7 @@ INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInfoNone, INSTANTIATE_TEST_SUITE_P( OpenCLDebugInfo100DebugCompilationUnit, ExtInstCLDebugInfo100RoundTripTest, ::testing::ValuesIn(std::vector({ - CASE_LLIe(CompilationUnit, 100, 42, "HLSL", spv::SourceLanguage::HLSL), + CASE_LLIe(CompilationUnit, 100, 42, "HLSL", SpvSourceLanguageHLSL), }))); INSTANTIATE_TEST_SUITE_P( @@ -612,14 +612,14 @@ TEST_F(ExtInstCLDebugInfo100RoundTripTestExplicit, FlagIsPublic) { const std::string input = prefix + "FlagIsPublic\n"; const std::string expected = prefix + "FlagIsProtected|FlagIsPrivate\n"; // First make sure it assembles correctly. - EXPECT_THAT(CompiledInstructions(input), - Eq(Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("DebugInfo")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, OpenCLDebugInfo100DebugTypePointer, - 4, uint32_t(spv::StorageClass::Private), - OpenCLDebugInfo100FlagIsPublic})}))) + EXPECT_THAT( + CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")), + MakeInstruction(SpvOpExtInst, + {2, 3, 1, OpenCLDebugInfo100DebugTypePointer, 4, + uint32_t(SpvStorageClassPrivate), + OpenCLDebugInfo100FlagIsPublic})}))) << input; // Now check the round trip through the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input; diff --git a/test/ext_inst.debuginfo_test.cpp b/test/ext_inst.debuginfo_test.cpp index 5ccbde6d..9090c247 100644 --- a/test/ext_inst.debuginfo_test.cpp +++ b/test/ext_inst.debuginfo_test.cpp @@ -52,12 +52,12 @@ TEST_P(ExtInstDebugInfoRoundTripTest, ParameterizedExtInst) { "%3 = OpExtInst %2 %1 " + GetParam().name + GetParam().operands + "\n"; // First make sure it assembles correctly. - EXPECT_THAT(CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("DebugInfo")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, GetParam().opcode}, - GetParam().expected_operands)}))) + EXPECT_THAT( + CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode}, + GetParam().expected_operands)}))) << input; // Now check the round trip through the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input; @@ -156,7 +156,7 @@ TEST_P(ExtInstDebugInfoRoundTripTest, ParameterizedExtInst) { #define CASE_ISF(Enum, S0, Fstr, Fnum) \ { \ uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #S0 " " Fstr, { \ - 4, uint32_t(spv::StorageClass::S0), Fnum \ + 4, uint32_t(SpvStorageClass##S0), Fnum \ } \ } @@ -408,12 +408,11 @@ TEST_F(ExtInstDebugInfoRoundTripTestExplicit, FlagIsPublic) { // First make sure it assembles correctly. EXPECT_THAT( CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("DebugInfo")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, DebugInfoDebugTypePointer, 4, - uint32_t(spv::StorageClass::Private), - DebugInfoFlagIsPublic})}))) + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, DebugInfoDebugTypePointer, 4, + uint32_t(SpvStorageClassPrivate), + DebugInfoFlagIsPublic})}))) << input; // Now check the round trip through the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input; diff --git a/test/ext_inst.opencl_test.cpp b/test/ext_inst.opencl_test.cpp index 51c2b01f..d80a9bd7 100644 --- a/test/ext_inst.opencl_test.cpp +++ b/test/ext_inst.opencl_test.cpp @@ -47,12 +47,12 @@ TEST_P(ExtInstOpenCLStdRoundTripTest, ParameterizedExtInst) { "%3 = OpExtInst %2 %1 " + GetParam().name + " " + GetParam().operands + "\n"; // First make sure it assembles correctly. - EXPECT_THAT(CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("OpenCL.std")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, GetParam().opcode}, - GetParam().expected_operands)}))) + EXPECT_THAT( + CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("OpenCL.std")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode}, + GetParam().expected_operands)}))) << input; // Now check the round trip through the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input; @@ -85,7 +85,7 @@ TEST_P(ExtInstOpenCLStdRoundTripTest, ParameterizedExtInst) { #define CASE3Round(Enum, Name, Mode) \ { \ uint32_t(OpenCLLIB::Entrypoints::Enum), #Name, "%4 %5 %6 " #Mode, { \ - 4, 5, 6, uint32_t(spv::FPRoundingMode::Mode) \ + 4, 5, 6, uint32_t(SpvFPRoundingMode##Mode) \ } \ } diff --git a/test/fuzz/available_instructions_test.cpp b/test/fuzz/available_instructions_test.cpp index bbe524a9..dc8a3b5a 100644 --- a/test/fuzz/available_instructions_test.cpp +++ b/test/fuzz/available_instructions_test.cpp @@ -176,41 +176,41 @@ TEST(AvailableInstructionsTest, BasicTest) { auto available = all_instructions.GetAvailableBeforeInstruction(i1); ASSERT_FALSE(available.empty()); ASSERT_EQ(30, available.size()); - ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); + ASSERT_EQ(SpvOpTypeVoid, available[0]->opcode()); + ASSERT_EQ(SpvOpVariable, available[15]->opcode()); } { auto available = all_instructions.GetAvailableBeforeInstruction(i2); ASSERT_FALSE(available.empty()); ASSERT_EQ(46, available.size()); - ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpTypePointer, available[3]->opcode()); - ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); - ASSERT_EQ(spv::Op::OpFunctionCall, available[40]->opcode()); - ASSERT_EQ(spv::Op::OpStore, available[45]->opcode()); + ASSERT_EQ(SpvOpTypeVoid, available[0]->opcode()); + ASSERT_EQ(SpvOpTypePointer, available[3]->opcode()); + ASSERT_EQ(SpvOpVariable, available[15]->opcode()); + ASSERT_EQ(SpvOpFunctionCall, available[40]->opcode()); + ASSERT_EQ(SpvOpStore, available[45]->opcode()); } { auto available = all_instructions.GetAvailableBeforeInstruction(i3); ASSERT_FALSE(available.empty()); ASSERT_EQ(45, available.size()); - ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpTypePointer, available[3]->opcode()); - ASSERT_EQ(spv::Op::OpVariable, available[15]->opcode()); - ASSERT_EQ(spv::Op::OpFunctionCall, available[40]->opcode()); - ASSERT_EQ(spv::Op::OpBranchConditional, available[44]->opcode()); + ASSERT_EQ(SpvOpTypeVoid, available[0]->opcode()); + ASSERT_EQ(SpvOpTypePointer, available[3]->opcode()); + ASSERT_EQ(SpvOpVariable, available[15]->opcode()); + ASSERT_EQ(SpvOpFunctionCall, available[40]->opcode()); + ASSERT_EQ(SpvOpBranchConditional, available[44]->opcode()); } { auto available = all_instructions.GetAvailableBeforeInstruction(i6); ASSERT_FALSE(available.empty()); ASSERT_EQ(33, available.size()); - ASSERT_EQ(spv::Op::OpTypeVoid, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpTypeFloat, available[4]->opcode()); - ASSERT_EQ(spv::Op::OpTypePointer, available[8]->opcode()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[12]->opcode()); - ASSERT_EQ(spv::Op::OpConstant, available[16]->opcode()); - ASSERT_EQ(spv::Op::OpFunctionParameter, available[30]->opcode()); - ASSERT_EQ(spv::Op::OpFunctionParameter, available[31]->opcode()); - ASSERT_EQ(spv::Op::OpVariable, available[32]->opcode()); + ASSERT_EQ(SpvOpTypeVoid, available[0]->opcode()); + ASSERT_EQ(SpvOpTypeFloat, available[4]->opcode()); + ASSERT_EQ(SpvOpTypePointer, available[8]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[12]->opcode()); + ASSERT_EQ(SpvOpConstant, available[16]->opcode()); + ASSERT_EQ(SpvOpFunctionParameter, available[30]->opcode()); + ASSERT_EQ(SpvOpFunctionParameter, available[31]->opcode()); + ASSERT_EQ(SpvOpVariable, available[32]->opcode()); } } { @@ -225,51 +225,51 @@ TEST(AvailableInstructionsTest, BasicTest) { auto available = vector_instructions.GetAvailableBeforeInstruction(i4); ASSERT_FALSE(available.empty()); ASSERT_EQ(3, available.size()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); - ASSERT_EQ(spv::Op::OpCopyObject, available[2]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[0]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[1]->opcode()); + ASSERT_EQ(SpvOpCopyObject, available[2]->opcode()); } { auto available = vector_instructions.GetAvailableBeforeInstruction(i5); ASSERT_FALSE(available.empty()); ASSERT_EQ(3, available.size()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); - ASSERT_EQ(spv::Op::OpCopyObject, available[2]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[0]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[1]->opcode()); + ASSERT_EQ(SpvOpCopyObject, available[2]->opcode()); } { auto available = vector_instructions.GetAvailableBeforeInstruction(i6); ASSERT_FALSE(available.empty()); ASSERT_EQ(2, available.size()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[0]->opcode()); - ASSERT_EQ(spv::Op::OpConstantComposite, available[1]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[0]->opcode()); + ASSERT_EQ(SpvOpConstantComposite, available[1]->opcode()); } } { AvailableInstructions integer_add_instructions( context.get(), [](opt::IRContext*, opt::Instruction* inst) -> bool { - return inst->opcode() == spv::Op::OpIAdd; + return inst->opcode() == SpvOpIAdd; }); { auto available = integer_add_instructions.GetAvailableBeforeInstruction(i7); ASSERT_FALSE(available.empty()); ASSERT_EQ(1, available.size()); - ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); + ASSERT_EQ(SpvOpIAdd, available[0]->opcode()); } { auto available = integer_add_instructions.GetAvailableBeforeInstruction(i8); ASSERT_FALSE(available.empty()); ASSERT_EQ(1, available.size()); - ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); + ASSERT_EQ(SpvOpIAdd, available[0]->opcode()); } { auto available = integer_add_instructions.GetAvailableBeforeInstruction(i9); ASSERT_FALSE(available.empty()); ASSERT_EQ(1, available.size()); - ASSERT_EQ(spv::Op::OpIAdd, available[0]->opcode()); + ASSERT_EQ(SpvOpIAdd, available[0]->opcode()); } } } diff --git a/test/fuzz/data_synonym_transformation_test.cpp b/test/fuzz/data_synonym_transformation_test.cpp index 3ba80931..7e93f291 100644 --- a/test/fuzz/data_synonym_transformation_test.cpp +++ b/test/fuzz/data_synonym_transformation_test.cpp @@ -146,12 +146,12 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12' auto instruction_descriptor_1 = - MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0); + MakeInstructionDescriptor(25, SpvOpAccessChain, 0); auto good_extract_1 = TransformationCompositeExtract(instruction_descriptor_1, 102, 100, {0}); // Bad: id already in use auto bad_extract_1 = TransformationCompositeExtract( - MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0), 25, 100, {0}); + MakeInstructionDescriptor(25, SpvOpAccessChain, 0), 25, 100, {0}); ASSERT_TRUE( good_extract_1.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( @@ -166,8 +166,7 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %13 with %100[1] in 'OpStore %15 %13' - auto instruction_descriptor_2 = - MakeInstructionDescriptor(100, spv::Op::OpStore, 0); + auto instruction_descriptor_2 = MakeInstructionDescriptor(100, SpvOpStore, 0); auto good_extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 103, 100, {1}); // No bad example provided here. @@ -184,7 +183,7 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Replace %22 with %100[2] in '%23 = OpConvertSToF %16 %22' auto instruction_descriptor_3 = - MakeInstructionDescriptor(23, spv::Op::OpConvertSToF, 0); + MakeInstructionDescriptor(23, SpvOpConvertSToF, 0); auto good_extract_3 = TransformationCompositeExtract(instruction_descriptor_3, 104, 100, {2}); ASSERT_TRUE( @@ -204,13 +203,12 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %28 with %101[0] in 'OpStore %33 %28' - auto instruction_descriptor_4 = - MakeInstructionDescriptor(33, spv::Op::OpStore, 0); + auto instruction_descriptor_4 = MakeInstructionDescriptor(33, SpvOpStore, 0); auto good_extract_4 = TransformationCompositeExtract(instruction_descriptor_4, 105, 101, {0}); // Bad: instruction descriptor does not identify an appropriate instruction auto bad_extract_4 = TransformationCompositeExtract( - MakeInstructionDescriptor(33, spv::Op::OpCopyObject, 0), 105, 101, {0}); + MakeInstructionDescriptor(33, SpvOpCopyObject, 0), 105, 101, {0}); ASSERT_TRUE( good_extract_4.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( @@ -226,7 +224,7 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Replace %23 with %101[1] in '%50 = OpCopyObject %16 %23' auto instruction_descriptor_5 = - MakeInstructionDescriptor(50, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(50, SpvOpCopyObject, 0); auto good_extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 106, 101, {1}); ASSERT_TRUE( @@ -246,8 +244,7 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %32 with %101[2] in 'OpStore %33 %32' - auto instruction_descriptor_6 = - MakeInstructionDescriptor(33, spv::Op::OpStore, 1); + auto instruction_descriptor_6 = MakeInstructionDescriptor(33, SpvOpStore, 1); auto good_extract_6 = TransformationCompositeExtract(instruction_descriptor_6, 107, 101, {2}); // Bad: id 1001 does not exist @@ -268,7 +265,7 @@ TEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { // Replace %23 with %101[3] in '%51 = OpCopyObject %16 %23' auto instruction_descriptor_7 = - MakeInstructionDescriptor(51, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(51, SpvOpCopyObject, 0); auto good_extract_7 = TransformationCompositeExtract(instruction_descriptor_7, 108, 101, {3}); ASSERT_TRUE( @@ -434,8 +431,7 @@ TEST(DataSynonymTransformationTest, MatrixCompositeSynonyms) { MakeSynonymFact(50, {}, 100, {2})); // Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25' - auto instruction_descriptor_1 = - MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0); + auto instruction_descriptor_1 = MakeInstructionDescriptor(26, SpvOpFAdd, 0); auto extract_1 = TransformationCompositeExtract(instruction_descriptor_1, 101, 100, {0}); ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); @@ -449,8 +445,7 @@ TEST(DataSynonymTransformationTest, MatrixCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %25 with %100[1] in '%26 = OpFAdd %7 %23 %25' - auto instruction_descriptor_2 = - MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0); + auto instruction_descriptor_2 = MakeInstructionDescriptor(26, SpvOpFAdd, 0); auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 102, 100, {1}); ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); @@ -616,7 +611,7 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { // Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45' auto instruction_descriptor_1 = - MakeInstructionDescriptor(46, spv::Op::OpCompositeConstruct, 0); + MakeInstructionDescriptor(46, SpvOpCompositeConstruct, 0); auto extract_1 = TransformationCompositeExtract(instruction_descriptor_1, 201, 100, {1}); ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); @@ -632,7 +627,7 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { // Replace second occurrence of %27 with %101[0] in '%28 = // OpCompositeConstruct %8 %27 %27' auto instruction_descriptor_2 = - MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0); + MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0); auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 202, 101, {0}); ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); @@ -647,7 +642,7 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { // Replace %36 with %101[1] in '%45 = OpCompositeConstruct %31 %36 %41 %44' auto instruction_descriptor_3 = - MakeInstructionDescriptor(45, spv::Op::OpCompositeConstruct, 0); + MakeInstructionDescriptor(45, SpvOpCompositeConstruct, 0); auto extract_3 = TransformationCompositeExtract(instruction_descriptor_3, 203, 101, {1}); ASSERT_TRUE(extract_3.IsApplicable(context.get(), transformation_context)); @@ -663,7 +658,7 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { // Replace first occurrence of %27 with %101[2] in '%28 = OpCompositeConstruct // %8 %27 %27' auto instruction_descriptor_4 = - MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0); + MakeInstructionDescriptor(28, SpvOpCompositeConstruct, 0); auto extract_4 = TransformationCompositeExtract(instruction_descriptor_4, 204, 101, {2}); ASSERT_TRUE(extract_4.IsApplicable(context.get(), transformation_context)); @@ -677,8 +672,7 @@ TEST(DataSynonymTransformationTest, StructCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %22 with %102[0] in 'OpStore %23 %22' - auto instruction_descriptor_5 = - MakeInstructionDescriptor(23, spv::Op::OpStore, 0); + auto instruction_descriptor_5 = MakeInstructionDescriptor(23, SpvOpStore, 0); auto extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 205, 102, {0}); ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context)); @@ -937,7 +931,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20' auto instruction_descriptor_1 = - MakeInstructionDescriptor(80, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(80, SpvOpCopyObject, 0); auto shuffle_1 = TransformationVectorShuffle(instruction_descriptor_1, 200, 100, 100, {0, 1, 2}); ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context)); @@ -954,7 +948,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %54 with %100[3] in '%56 = OpFOrdNotEqual %30 %54 %55' auto instruction_descriptor_2 = - MakeInstructionDescriptor(56, spv::Op::OpFOrdNotEqual, 0); + MakeInstructionDescriptor(56, SpvOpFOrdNotEqual, 0); auto extract_2 = TransformationCompositeExtract(instruction_descriptor_2, 201, 100, {3}); @@ -969,8 +963,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %15 with %101[0:1] in 'OpStore %12 %15' - auto instruction_descriptor_3 = - MakeInstructionDescriptor(64, spv::Op::OpStore, 0); + auto instruction_descriptor_3 = MakeInstructionDescriptor(64, SpvOpStore, 0); auto shuffle_3 = TransformationVectorShuffle(instruction_descriptor_3, 202, 101, 101, {0, 1}); ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context)); @@ -987,7 +980,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %19 with %101[2:3] in '%81 = OpVectorShuffle %16 %19 %19 0 0 1' auto instruction_descriptor_4 = - MakeInstructionDescriptor(81, spv::Op::OpVectorShuffle, 0); + MakeInstructionDescriptor(81, SpvOpVectorShuffle, 0); auto shuffle_4 = TransformationVectorShuffle(instruction_descriptor_4, 203, 101, 101, {2, 3}); ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context)); @@ -1005,7 +998,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %27 with %102[0] in '%82 = OpCompositeConstruct %21 %26 %27 %28 // %25' auto instruction_descriptor_5 = - MakeInstructionDescriptor(82, spv::Op::OpCompositeConstruct, 0); + MakeInstructionDescriptor(82, SpvOpCompositeConstruct, 0); auto extract_5 = TransformationCompositeExtract(instruction_descriptor_5, 204, 102, {0}); @@ -1021,7 +1014,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %15 with %102[1:2] in '%83 = OpCopyObject %10 %15' auto instruction_descriptor_6 = - MakeInstructionDescriptor(83, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(83, SpvOpCopyObject, 0); auto shuffle_6 = TransformationVectorShuffle(instruction_descriptor_6, 205, 102, 102, {1, 2}); ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context)); @@ -1038,7 +1031,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %33 with %103[0] in '%86 = OpCopyObject %30 %33' auto instruction_descriptor_7 = - MakeInstructionDescriptor(86, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(86, SpvOpCopyObject, 0); auto extract_7 = TransformationCompositeExtract(instruction_descriptor_7, 206, 103, {0}); ASSERT_TRUE(extract_7.IsApplicable(context.get(), transformation_context)); @@ -1053,7 +1046,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %47 with %103[1:3] in '%84 = OpCopyObject %39 %47' auto instruction_descriptor_8 = - MakeInstructionDescriptor(84, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(84, SpvOpCopyObject, 0); auto shuffle_8 = TransformationVectorShuffle(instruction_descriptor_8, 207, 103, 103, {1, 2, 3}); ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context)); @@ -1070,7 +1063,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %42 with %104[0] in '%85 = OpCopyObject %30 %42' auto instruction_descriptor_9 = - MakeInstructionDescriptor(85, spv::Op::OpCopyObject, 0); + MakeInstructionDescriptor(85, SpvOpCopyObject, 0); auto extract_9 = TransformationCompositeExtract(instruction_descriptor_9, 208, 104, {0}); ASSERT_TRUE(extract_9.IsApplicable(context.get(), transformation_context)); @@ -1085,7 +1078,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %45 with %104[1] in '%63 = OpLogicalOr %30 %45 %46' auto instruction_descriptor_10 = - MakeInstructionDescriptor(63, spv::Op::OpLogicalOr, 0); + MakeInstructionDescriptor(63, SpvOpLogicalOr, 0); auto extract_10 = TransformationCompositeExtract(instruction_descriptor_10, 209, 104, {1}); ASSERT_TRUE(extract_10.IsApplicable(context.get(), transformation_context)); @@ -1099,8 +1092,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { kConsoleMessageConsumer)); // Replace %38 with %105[0:1] in 'OpStore %36 %38' - auto instruction_descriptor_11 = - MakeInstructionDescriptor(85, spv::Op::OpStore, 0); + auto instruction_descriptor_11 = MakeInstructionDescriptor(85, SpvOpStore, 0); auto shuffle_11 = TransformationVectorShuffle(instruction_descriptor_11, 210, 105, 105, {0, 1}); ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context)); @@ -1117,7 +1109,7 @@ TEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { // Replace %46 with %105[2] in '%62 = OpLogicalAnd %30 %45 %46' auto instruction_descriptor_12 = - MakeInstructionDescriptor(62, spv::Op::OpLogicalAnd, 0); + MakeInstructionDescriptor(62, SpvOpLogicalAnd, 0); auto extract_12 = TransformationCompositeExtract(instruction_descriptor_12, 211, 105, {2}); ASSERT_TRUE(extract_12.IsApplicable(context.get(), transformation_context)); diff --git a/test/fuzz/fact_manager/constant_uniform_facts_test.cpp b/test/fuzz/fact_manager/constant_uniform_facts_test.cpp index b267e3dc..4d80f0a8 100644 --- a/test/fuzz/fact_manager/constant_uniform_facts_test.cpp +++ b/test/fuzz/fact_manager/constant_uniform_facts_test.cpp @@ -366,41 +366,41 @@ TEST(ConstantUniformFactsTest, ConstantsAvailableViaUniforms) { opt::Instruction::OperandList operands = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_int32_id, 50, operands)); + context.get(), SpvOpConstant, type_int32_id, 50, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int32_min[0]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_int32_id, 51, operands)); + context.get(), SpvOpConstant, type_int32_id, 51, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_int64_id, 52, operands)); + context.get(), SpvOpConstant, type_int64_id, 52, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_uint32_id, 53, operands)); + context.get(), SpvOpConstant, type_uint32_id, 53, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_uint64_id, 54, operands)); + context.get(), SpvOpConstant, type_uint64_id, 54, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_uint64_id, 55, operands)); + context.get(), SpvOpConstant, type_uint64_id, 55, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_float_10[0]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_float_id, 56, operands)); + context.get(), SpvOpConstant, type_float_id, 56, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_double_id, 57, operands)); + context.get(), SpvOpConstant, type_double_id, 57, operands)); operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_double_id, 58, operands)); + context.get(), SpvOpConstant, type_double_id, 58, operands)); // A duplicate of the constant with id 59. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, type_int32_id, 59, operands)); + context.get(), SpvOpConstant, type_int32_id, 59, operands)); context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone); diff --git a/test/fuzz/fact_manager/data_synonym_and_id_equation_facts_test.cpp b/test/fuzz/fact_manager/data_synonym_and_id_equation_facts_test.cpp index c3b47a46..689d2e7d 100644 --- a/test/fuzz/fact_manager/data_synonym_and_id_equation_facts_test.cpp +++ b/test/fuzz/fact_manager/data_synonym_and_id_equation_facts_test.cpp @@ -136,15 +136,15 @@ TEST(DataSynonymAndIdEquationFactsTest, CorollaryConversionFacts) { FactManager fact_manager(context.get()); // Add equation facts - fact_manager.AddFactIdEquation(24, spv::Op::OpConvertSToF, {15}); - fact_manager.AddFactIdEquation(25, spv::Op::OpConvertSToF, {16}); - fact_manager.AddFactIdEquation(26, spv::Op::OpConvertUToF, {17}); - fact_manager.AddFactIdEquation(27, spv::Op::OpConvertSToF, {18}); - fact_manager.AddFactIdEquation(28, spv::Op::OpConvertUToF, {19}); - fact_manager.AddFactIdEquation(29, spv::Op::OpConvertUToF, {20}); - fact_manager.AddFactIdEquation(30, spv::Op::OpConvertSToF, {21}); - fact_manager.AddFactIdEquation(31, spv::Op::OpConvertUToF, {22}); - fact_manager.AddFactIdEquation(32, spv::Op::OpConvertUToF, {23}); + fact_manager.AddFactIdEquation(24, SpvOpConvertSToF, {15}); + fact_manager.AddFactIdEquation(25, SpvOpConvertSToF, {16}); + fact_manager.AddFactIdEquation(26, SpvOpConvertUToF, {17}); + fact_manager.AddFactIdEquation(27, SpvOpConvertSToF, {18}); + fact_manager.AddFactIdEquation(28, SpvOpConvertUToF, {19}); + fact_manager.AddFactIdEquation(29, SpvOpConvertUToF, {20}); + fact_manager.AddFactIdEquation(30, SpvOpConvertSToF, {21}); + fact_manager.AddFactIdEquation(31, SpvOpConvertUToF, {22}); + fact_manager.AddFactIdEquation(32, SpvOpConvertUToF, {23}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(15, {}), MakeDataDescriptor(16, {})); @@ -212,7 +212,7 @@ TEST(DataSynonymAndIdEquationFactsTest, HandlesCorollariesWithInvalidIds) { // Add required facts. transformation_context.GetFactManager()->AddFactIdEquation( - 14, spv::Op::OpConvertSToF, {9}); + 14, SpvOpConvertSToF, {9}); transformation_context.GetFactManager()->AddFactDataSynonym( MakeDataDescriptor(14, {}), MakeDataDescriptor(17, {})); @@ -232,7 +232,7 @@ TEST(DataSynonymAndIdEquationFactsTest, HandlesCorollariesWithInvalidIds) { // Add another equation. transformation_context.GetFactManager()->AddFactIdEquation( - 15, spv::Op::OpConvertSToF, {9}); + 15, SpvOpConvertSToF, {9}); // Check that two ids are synonymous even though one of them doesn't exist in // the module (%17). @@ -249,7 +249,7 @@ TEST(DataSynonymAndIdEquationFactsTest, HandlesCorollariesWithInvalidIds) { ASSERT_TRUE(context->KillDef(15)); transformation_context.GetFactManager()->AddFactIdEquation( - 18, spv::Op::OpConvertSToF, {9}); + 18, SpvOpConvertSToF, {9}); CheckConsistencyOfSynonymFacts(context.get(), transformation_context); @@ -294,8 +294,8 @@ TEST(DataSynonymAndIdEquationFactsTest, LogicalNotEquationFacts) { MakeDataDescriptor(7, {})); fact_manager.AddFactDataSynonym(MakeDataDescriptor(16, {}), MakeDataDescriptor(14, {})); - fact_manager.AddFactIdEquation(14, spv::Op::OpLogicalNot, {7}); - fact_manager.AddFactIdEquation(17, spv::Op::OpLogicalNot, {16}); + fact_manager.AddFactIdEquation(14, SpvOpLogicalNot, {7}); + fact_manager.AddFactIdEquation(17, SpvOpLogicalNot, {16}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}))); @@ -336,8 +336,8 @@ TEST(DataSynonymAndIdEquationFactsTest, SignedNegateEquationFacts) { FactManager fact_manager(context.get()); - fact_manager.AddFactIdEquation(14, spv::Op::OpSNegate, {7}); - fact_manager.AddFactIdEquation(15, spv::Op::OpSNegate, {14}); + fact_manager.AddFactIdEquation(14, SpvOpSNegate, {7}); + fact_manager.AddFactIdEquation(15, SpvOpSNegate, {14}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(7, {}), MakeDataDescriptor(15, {}))); @@ -380,19 +380,19 @@ TEST(DataSynonymAndIdEquationFactsTest, AddSubNegateFacts1) { FactManager fact_manager(context.get()); - fact_manager.AddFactIdEquation(14, spv::Op::OpIAdd, {15, 16}); + fact_manager.AddFactIdEquation(14, SpvOpIAdd, {15, 16}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {})); fact_manager.AddFactDataSynonym(MakeDataDescriptor(18, {}), MakeDataDescriptor(16, {})); - fact_manager.AddFactIdEquation(19, spv::Op::OpISub, {14, 18}); - fact_manager.AddFactIdEquation(20, spv::Op::OpISub, {14, 17}); + fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 18}); + fact_manager.AddFactIdEquation(20, SpvOpISub, {14, 17}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {}), MakeDataDescriptor(14, {})); - fact_manager.AddFactIdEquation(22, spv::Op::OpISub, {16, 21}); + fact_manager.AddFactIdEquation(22, SpvOpISub, {16, 21}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(23, {}), MakeDataDescriptor(22, {})); - fact_manager.AddFactIdEquation(24, spv::Op::OpSNegate, {23}); + fact_manager.AddFactIdEquation(24, SpvOpSNegate, {23}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(19, {}), MakeDataDescriptor(15, {}))); @@ -438,31 +438,31 @@ TEST(DataSynonymAndIdEquationFactsTest, AddSubNegateFacts2) { FactManager fact_manager(context.get()); - fact_manager.AddFactIdEquation(14, spv::Op::OpISub, {15, 16}); - fact_manager.AddFactIdEquation(17, spv::Op::OpIAdd, {14, 16}); + fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}); + fact_manager.AddFactIdEquation(17, SpvOpIAdd, {14, 16}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}))); - fact_manager.AddFactIdEquation(18, spv::Op::OpIAdd, {16, 14}); + fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 14}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}))); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}))); - fact_manager.AddFactIdEquation(19, spv::Op::OpISub, {14, 15}); - fact_manager.AddFactIdEquation(20, spv::Op::OpSNegate, {19}); + fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}); + fact_manager.AddFactIdEquation(20, SpvOpSNegate, {19}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); - fact_manager.AddFactIdEquation(21, spv::Op::OpISub, {14, 19}); + fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}))); - fact_manager.AddFactIdEquation(22, spv::Op::OpISub, {14, 18}); - fact_manager.AddFactIdEquation(23, spv::Op::OpSNegate, {22}); + fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}); + fact_manager.AddFactIdEquation(23, SpvOpSNegate, {22}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}))); } @@ -525,31 +525,31 @@ TEST(DataSynonymAndIdEquationFactsTest, ConversionEquations) { fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}), MakeDataDescriptor(23, {})); - fact_manager.AddFactIdEquation(25, spv::Op::OpConvertUToF, {16}); - fact_manager.AddFactIdEquation(26, spv::Op::OpConvertUToF, {17}); + fact_manager.AddFactIdEquation(25, SpvOpConvertUToF, {16}); + fact_manager.AddFactIdEquation(26, SpvOpConvertUToF, {17}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(25, {}), MakeDataDescriptor(26, {}))); - fact_manager.AddFactIdEquation(27, spv::Op::OpConvertSToF, {20}); - fact_manager.AddFactIdEquation(28, spv::Op::OpConvertUToF, {21}); + fact_manager.AddFactIdEquation(27, SpvOpConvertSToF, {20}); + fact_manager.AddFactIdEquation(28, SpvOpConvertUToF, {21}); ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {}), MakeDataDescriptor(28, {}))); - fact_manager.AddFactIdEquation(29, spv::Op::OpConvertSToF, {18}); - fact_manager.AddFactIdEquation(30, spv::Op::OpConvertUToF, {19}); + fact_manager.AddFactIdEquation(29, SpvOpConvertSToF, {18}); + fact_manager.AddFactIdEquation(30, SpvOpConvertUToF, {19}); ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(29, {}), MakeDataDescriptor(30, {}))); - fact_manager.AddFactIdEquation(31, spv::Op::OpConvertSToF, {22}); - fact_manager.AddFactIdEquation(32, spv::Op::OpConvertSToF, {23}); + fact_manager.AddFactIdEquation(31, SpvOpConvertSToF, {22}); + fact_manager.AddFactIdEquation(32, SpvOpConvertSToF, {23}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(31, {}), MakeDataDescriptor(32, {}))); - fact_manager.AddFactIdEquation(33, spv::Op::OpConvertUToF, {17}); + fact_manager.AddFactIdEquation(33, SpvOpConvertUToF, {17}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {}), MakeDataDescriptor(26, {}))); - fact_manager.AddFactIdEquation(34, spv::Op::OpConvertSToF, {23}); + fact_manager.AddFactIdEquation(34, SpvOpConvertSToF, {23}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(32, {}), MakeDataDescriptor(34, {}))); } @@ -605,7 +605,7 @@ TEST(DataSynonymAndIdEquationFactsTest, BitcastEquationFacts) { uint32_t lhs_id = 30; for (uint32_t rhs_id : {6, 6, 7, 7, 19, 19, 20, 20, 21, 21, 22, 22}) { - fact_manager.AddFactIdEquation(lhs_id, spv::Op::OpBitcast, {rhs_id}); + fact_manager.AddFactIdEquation(lhs_id, SpvOpBitcast, {rhs_id}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(lhs_id, {}), MakeDataDescriptor(rhs_id, {}))); ++lhs_id; @@ -651,37 +651,37 @@ TEST(DataSynonymAndIdEquationFactsTest, EquationAndEquivalenceFacts) { FactManager fact_manager(context.get()); - fact_manager.AddFactIdEquation(14, spv::Op::OpISub, {15, 16}); + fact_manager.AddFactIdEquation(14, SpvOpISub, {15, 16}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(114, {}), MakeDataDescriptor(14, {})); - fact_manager.AddFactIdEquation(17, spv::Op::OpIAdd, {114, 16}); + fact_manager.AddFactIdEquation(17, SpvOpIAdd, {114, 16}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}))); - fact_manager.AddFactIdEquation(18, spv::Op::OpIAdd, {16, 114}); + fact_manager.AddFactIdEquation(18, SpvOpIAdd, {16, 114}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}))); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}))); - fact_manager.AddFactIdEquation(19, spv::Op::OpISub, {14, 15}); + fact_manager.AddFactIdEquation(19, SpvOpISub, {14, 15}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(119, {}), MakeDataDescriptor(19, {})); - fact_manager.AddFactIdEquation(20, spv::Op::OpSNegate, {119}); + fact_manager.AddFactIdEquation(20, SpvOpSNegate, {119}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); - fact_manager.AddFactIdEquation(21, spv::Op::OpISub, {14, 19}); + fact_manager.AddFactIdEquation(21, SpvOpISub, {14, 19}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}))); - fact_manager.AddFactIdEquation(22, spv::Op::OpISub, {14, 18}); + fact_manager.AddFactIdEquation(22, SpvOpISub, {14, 18}); fact_manager.AddFactDataSynonym(MakeDataDescriptor(22, {}), MakeDataDescriptor(220, {})); - fact_manager.AddFactIdEquation(23, spv::Op::OpSNegate, {220}); + fact_manager.AddFactIdEquation(23, SpvOpSNegate, {220}); ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}))); } diff --git a/test/fuzz/fuzzer_pass_donate_modules_test.cpp b/test/fuzz/fuzzer_pass_donate_modules_test.cpp index 81687ac3..fe8e671d 100644 --- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp +++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp @@ -2025,9 +2025,9 @@ TEST(FuzzerPassDonateModulesTest, HandlesCapabilities) { &transformation_sequence, false, {}); ASSERT_TRUE(donor_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); ASSERT_FALSE(recipient_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); fuzzer_pass.DonateSingleModule(donor_context.get(), false); @@ -2040,12 +2040,12 @@ TEST(FuzzerPassDonateModulesTest, HandlesCapabilities) { // have different OpCapability instructions but the same capabilities. In our // example, VariablePointers implicitly declares // VariablePointersStorageBuffer. Thus, two modules must be compatible. - recipient_context->AddCapability(spv::Capability::VariablePointers); + recipient_context->AddCapability(SpvCapabilityVariablePointers); ASSERT_TRUE(donor_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); ASSERT_TRUE(recipient_context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); fuzzer_pass.DonateSingleModule(donor_context.get(), false); diff --git a/test/fuzz/fuzzerutil_test.cpp b/test/fuzz/fuzzerutil_test.cpp index 65553367..1286d38d 100644 --- a/test/fuzz/fuzzerutil_test.cpp +++ b/test/fuzz/fuzzerutil_test.cpp @@ -939,9 +939,9 @@ TEST(FuzzerutilTest, FuzzerUtilMaybeGetPointerTypeTest) { kConsoleMessageConsumer)); opt::IRContext* ir_context = context.get(); - auto private_storage_class = spv::StorageClass::Private; - auto function_storage_class = spv::StorageClass::Function; - auto input_storage_class = spv::StorageClass::Input; + auto private_storage_class = SpvStorageClassPrivate; + auto function_storage_class = SpvStorageClassFunction; + auto input_storage_class = SpvStorageClassInput; // A valid pointer must have the correct |pointee_type_id| and |storageClass|. // A function type pointer with id = 9 and pointee type id 8 should be found. @@ -1610,206 +1610,196 @@ TEST(FuzzerutilTest, TypesAreCompatible) { // OpAtomicLoad #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicLoad, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicLoad, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicLoad, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicLoad, 2, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicLoad, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicLoad, 2, + int_type, uint_type)); // OpAtomicExchange +#ifndef NDEBUG + ASSERT_DEATH(fuzzerutil::TypesAreCompatible( + context.get(), SpvOpAtomicExchange, 0, int_type, uint_type), + "Signedness check should not occur on a pointer operand."); +#endif + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicExchange, + 1, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicExchange, + 2, int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible( + context.get(), SpvOpAtomicExchange, 3, int_type, uint_type)); + + // OpAtomicStore +#ifndef NDEBUG + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, + 0, int_type, uint_type), + "Signedness check should not occur on a pointer operand."); +#endif + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, + 3, int_type, uint_type)); + + // OpAtomicCompareExchange #ifndef NDEBUG ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicExchange, + fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicCompareExchange, 0, int_type, uint_type), "Signedness check should not occur on a pointer operand."); #endif ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicExchange, 1, int_type, uint_type)); + context.get(), SpvOpAtomicCompareExchange, 1, int_type, uint_type)); ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicExchange, 2, int_type, uint_type)); + context.get(), SpvOpAtomicCompareExchange, 2, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible( + context.get(), SpvOpAtomicCompareExchange, 3, int_type, uint_type)); ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicExchange, 3, int_type, uint_type)); - - // OpAtomicStore -#ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); -#endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicStore, 3, int_type, uint_type)); - - // OpAtomicCompareExchange -#ifndef NDEBUG - ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), - spv::Op::OpAtomicCompareExchange, - 0, int_type, uint_type), - "Signedness check should not occur on a pointer operand."); -#endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicCompareExchange, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicCompareExchange, 2, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicCompareExchange, 3, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicCompareExchange, 4, int_type, uint_type)); + context.get(), SpvOpAtomicCompareExchange, 4, int_type, uint_type)); // OpAtomicIIncrement #ifndef NDEBUG ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIIncrement, - 0, int_type, uint_type), + fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicIIncrement, 0, + int_type, uint_type), "Signedness check should not occur on a pointer operand."); #endif ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicIIncrement, 1, int_type, uint_type)); + context.get(), SpvOpAtomicIIncrement, 1, int_type, uint_type)); ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicIIncrement, 2, int_type, uint_type)); + context.get(), SpvOpAtomicIIncrement, 2, int_type, uint_type)); // OpAtomicIDecrement #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, + 0, int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicStore, 2, + int_type, uint_type)); // OpAtomicIAdd #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIAdd, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicIAdd, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicIAdd, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicIAdd, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicIAdd, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicIAdd, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicIAdd, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicIAdd, 3, + int_type, uint_type)); // OpAtomicISub #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicISub, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicISub, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicISub, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicISub, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicISub, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicISub, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicISub, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicISub, 3, + int_type, uint_type)); // OpAtomicSMin #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMin, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMin, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMin, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMin, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMin, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMin, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMin, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMin, 3, + int_type, uint_type)); // OpAtomicUMin #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMin, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMin, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMin, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMin, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMin, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMin, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMin, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMin, 3, + int_type, uint_type)); // OpAtomicSMax #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMax, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMax, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMax, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMax, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicSMax, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMax, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMax, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicSMax, 3, + int_type, uint_type)); // OpAtomicUMax #ifndef NDEBUG - ASSERT_DEATH( - fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMax, 0, - int_type, uint_type), - "Signedness check should not occur on a pointer operand."); + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMax, 0, + int_type, uint_type), + "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMax, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMax, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicUMax, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMax, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMax, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicUMax, 3, + int_type, uint_type)); // OpAtomicAnd #ifndef NDEBUG - ASSERT_DEATH(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicAnd, 0, int_type, uint_type), + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicAnd, 0, + int_type, uint_type), "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicAnd, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicAnd, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicAnd, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicAnd, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicAnd, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicAnd, 3, + int_type, uint_type)); // OpAtomicOr #ifndef NDEBUG - ASSERT_DEATH(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicOr, 0, int_type, uint_type), + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicOr, 0, + int_type, uint_type), "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr, - 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr, - 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicOr, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicOr, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicOr, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicOr, 3, + int_type, uint_type)); // OpAtomicXor #ifndef NDEBUG - ASSERT_DEATH(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicXor, 0, int_type, uint_type), + ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicXor, 0, + int_type, uint_type), "Signedness check should not occur on a pointer operand."); #endif - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicXor, 1, int_type, uint_type)); - ASSERT_TRUE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicXor, 2, int_type, uint_type)); - ASSERT_FALSE(fuzzerutil::TypesAreCompatible( - context.get(), spv::Op::OpAtomicXor, 3, int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicXor, 1, + int_type, uint_type)); + ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicXor, 2, + int_type, uint_type)); + ASSERT_FALSE(fuzzerutil::TypesAreCompatible(context.get(), SpvOpAtomicXor, 3, + int_type, uint_type)); } } // namespace diff --git a/test/fuzz/replayer_test.cpp b/test/fuzz/replayer_test.cpp index b87d4f8e..151f2632 100644 --- a/test/fuzz/replayer_test.cpp +++ b/test/fuzz/replayer_test.cpp @@ -90,8 +90,8 @@ TEST(ReplayerTest, PartialReplay) { protobufs::TransformationSequence transformations; for (uint32_t id = 12; id <= 22; id++) { *transformations.add_transformation() = - TransformationSplitBlock( - MakeInstructionDescriptor(id, spv::Op::OpLoad, 0), id + 100) + TransformationSplitBlock(MakeInstructionDescriptor(id, SpvOpLoad, 0), + id + 100) .ToMessage(); } @@ -335,7 +335,7 @@ TEST(ReplayerTest, CheckFactsAfterReplay) { *transformations.add_transformation() = TransformationAddConstantScalar(100, 8, {42}, true).ToMessage(); *transformations.add_transformation() = - TransformationAddGlobalVariable(101, 50, spv::StorageClass::Private, 100, + TransformationAddGlobalVariable(101, 50, SpvStorageClassPrivate, 100, true) .ToMessage(); *transformations.add_transformation() = @@ -345,7 +345,7 @@ TEST(ReplayerTest, CheckFactsAfterReplay) { 11, protobufs::TransformationAddSynonym::SynonymType:: TransformationAddSynonym_SynonymType_COPY_OBJECT, - 104, MakeInstructionDescriptor(12, spv::Op::OpFunctionCall, 0)) + 104, MakeInstructionDescriptor(12, SpvOpFunctionCall, 0)) .ToMessage(); // Full replay @@ -455,8 +455,7 @@ TEST(ReplayerTest, ReplayWithOverflowIds) { *transformations.add_transformation() = TransformationFlattenConditionalBranch(5, true, 0, 0, 0, {}).ToMessage(); *transformations.add_transformation() = - TransformationAddGlobalVariable(101, 50, spv::StorageClass::Private, 11, - true) + TransformationAddGlobalVariable(101, 50, SpvStorageClassPrivate, 11, true) .ToMessage(); protobufs::FactSequence empty_facts; diff --git a/test/fuzz/shrinker_test.cpp b/test/fuzz/shrinker_test.cpp index 699730c3..942de29a 100644 --- a/test/fuzz/shrinker_test.cpp +++ b/test/fuzz/shrinker_test.cpp @@ -186,9 +186,9 @@ TEST(ShrinkerTest, ReduceAddedFunctions) { for (auto& function : *temp_ir_context->module()) { for (auto& block : function) { for (auto& inst : block) { - if (inst.opcode() == spv::Op::OpNot) { + if (inst.opcode() == SpvOpNot) { found_op_not = true; - } else if (inst.opcode() == spv::Op::OpFunctionCall) { + } else if (inst.opcode() == SpvOpFunctionCall) { op_call_count++; } } @@ -221,21 +221,21 @@ TEST(ShrinkerTest, ReduceAddedFunctions) { for (auto& inst : block) { switch (counter) { case 0: - ASSERT_EQ(spv::Op::OpVariable, inst.opcode()); + ASSERT_EQ(SpvOpVariable, inst.opcode()); ASSERT_EQ(11, inst.result_id()); break; case 1: - ASSERT_EQ(spv::Op::OpStore, inst.opcode()); + ASSERT_EQ(SpvOpStore, inst.opcode()); break; case 2: - ASSERT_EQ(spv::Op::OpLoad, inst.opcode()); + ASSERT_EQ(SpvOpLoad, inst.opcode()); ASSERT_EQ(12, inst.result_id()); break; case 3: - ASSERT_EQ(spv::Op::OpStore, inst.opcode()); + ASSERT_EQ(SpvOpStore, inst.opcode()); break; case 4: - ASSERT_EQ(spv::Op::OpReturn, inst.opcode()); + ASSERT_EQ(SpvOpReturn, inst.opcode()); break; default: FAIL(); @@ -250,11 +250,11 @@ TEST(ShrinkerTest, ReduceAddedFunctions) { first_block = false; for (auto& inst : block) { switch (inst.opcode()) { - case spv::Op::OpVariable: - case spv::Op::OpNot: - case spv::Op::OpReturn: - case spv::Op::OpReturnValue: - case spv::Op::OpFunctionCall: + case SpvOpVariable: + case SpvOpNot: + case SpvOpReturn: + case SpvOpReturnValue: + case SpvOpFunctionCall: // These are the only instructions we expect to see. break; default: @@ -362,7 +362,7 @@ TEST(ShrinkerTest, HitStepLimitWhenReducingAddedFunctions) { uint32_t copy_object_count = 0; temp_ir_context->module()->ForEachInst( [©_object_count](opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpCopyObject) { + if (inst->opcode() == SpvOpCopyObject) { copy_object_count++; } }); diff --git a/test/fuzz/transformation_access_chain_test.cpp b/test/fuzz/transformation_access_chain_test.cpp index fa19aa50..bddcf5fe 100644 --- a/test/fuzz/transformation_access_chain_test.cpp +++ b/test/fuzz/transformation_access_chain_test.cpp @@ -129,7 +129,7 @@ TEST(TransformationAccessChainTest, BasicTest) { // Check the case where the index type is not a 32-bit integer. TransformationAccessChain invalid_index_example1( - 101, 28, {29}, MakeInstructionDescriptor(42, spv::Op::OpReturn, 0)); + 101, 28, {29}, MakeInstructionDescriptor(42, SpvOpReturn, 0)); // Since the index is not a 32-bit integer type but a 32-bit float type, // ValidIndexComposite should return false and thus the transformation is not @@ -138,95 +138,86 @@ TEST(TransformationAccessChainTest, BasicTest) { transformation_context)); // Bad: id is not fresh - ASSERT_FALSE( - TransformationAccessChain( - 43, 43, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 43, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist - ASSERT_FALSE( - TransformationAccessChain( - 100, 1000, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 1000, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id is not a type - ASSERT_FALSE( - TransformationAccessChain( - 100, 5, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 5, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id is not a pointer - ASSERT_FALSE( - TransformationAccessChain( - 100, 23, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 23, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: index id does not exist - ASSERT_FALSE( - TransformationAccessChain( - 100, 43, {1000}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 43, {1000}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: index id is not a constant and the pointer refers to a struct - ASSERT_FALSE( - TransformationAccessChain( - 100, 43, {24}, MakeInstructionDescriptor(25, spv::Op::OpIAdd, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 43, {24}, MakeInstructionDescriptor(25, SpvOpIAdd, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: too many indices - ASSERT_FALSE(TransformationAccessChain( - 100, 43, {80, 80, 80}, - MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAccessChain(100, 43, {80, 80, 80}, + MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: index id is out of bounds when accessing a struct ASSERT_FALSE( - TransformationAccessChain( - 100, 43, {83, 80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) + TransformationAccessChain(100, 43, {83, 80}, + MakeInstructionDescriptor(24, SpvOpLoad, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before variable - ASSERT_FALSE( - TransformationAccessChain( - 100, 34, {}, MakeInstructionDescriptor(36, spv::Op::OpVariable, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 34, {}, MakeInstructionDescriptor(36, SpvOpVariable, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: OpTypeBool must be present in the module to clamp an index ASSERT_FALSE( - TransformationAccessChain( - 100, 36, {80, 81}, MakeInstructionDescriptor(37, spv::Op::OpStore, 0)) + TransformationAccessChain(100, 36, {80, 81}, + MakeInstructionDescriptor(37, SpvOpStore, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: pointer not available - ASSERT_FALSE(TransformationAccessChain( - 100, 43, {80}, - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); - - // Bad: instruction descriptor does not identify anything ASSERT_FALSE( TransformationAccessChain( - 100, 43, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 100)) + 100, 43, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0)) .IsApplicable(context.get(), transformation_context)); + // Bad: instruction descriptor does not identify anything + ASSERT_FALSE(TransformationAccessChain( + 100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 100)) + .IsApplicable(context.get(), transformation_context)); + #ifndef NDEBUG // Bad: pointer is null ASSERT_DEATH( - TransformationAccessChain( - 100, 46, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) + TransformationAccessChain(100, 46, {80}, + MakeInstructionDescriptor(24, SpvOpLoad, 0)) .IsApplicable(context.get(), transformation_context), "Access chains should not be created from null/undefined pointers"); #endif // Bad: pointer to result type does not exist - ASSERT_FALSE( - TransformationAccessChain( - 100, 52, {0}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 52, {0}, MakeInstructionDescriptor(24, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); { TransformationAccessChain transformation( - 100, 43, {80}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)); + 100, 43, {80}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -239,7 +230,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 101, 28, {81}, MakeInstructionDescriptor(42, spv::Op::OpReturn, 0)); + 101, 28, {81}, MakeInstructionDescriptor(42, SpvOpReturn, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -252,7 +243,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 102, 44, {}, MakeInstructionDescriptor(44, spv::Op::OpStore, 0)); + 102, 44, {}, MakeInstructionDescriptor(44, SpvOpStore, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -265,8 +256,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 103, 13, {80}, - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0)); + 103, 13, {80}, MakeInstructionDescriptor(21, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -279,7 +269,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 104, 34, {}, MakeInstructionDescriptor(44, spv::Op::OpStore, 1)); + 104, 34, {}, MakeInstructionDescriptor(44, SpvOpStore, 1)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -292,7 +282,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 105, 38, {}, MakeInstructionDescriptor(40, spv::Op::OpFunctionCall, 0)); + 105, 38, {}, MakeInstructionDescriptor(40, SpvOpFunctionCall, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -305,7 +295,7 @@ TEST(TransformationAccessChainTest, BasicTest) { { TransformationAccessChain transformation( - 106, 14, {}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)); + 106, 14, {}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -319,7 +309,7 @@ TEST(TransformationAccessChainTest, BasicTest) { // Check the case where the access chain's base pointer has the irrelevant // pointee fact; the resulting access chain should inherit this fact. TransformationAccessChain transformation( - 107, 54, {}, MakeInstructionDescriptor(24, spv::Op::OpLoad, 0)); + 107, 54, {}, MakeInstructionDescriptor(24, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -450,10 +440,9 @@ TEST(TransformationAccessChainTest, StructIndexMustBeConstant) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Bad: %9 is a pointer to a struct, but %20 is not a constant. - ASSERT_FALSE( - TransformationAccessChain( - 100, 9, {20}, MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 9, {20}, MakeInstructionDescriptor(9, SpvOpReturn, 0)) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAccessChainTest, IsomorphicStructs) { @@ -489,7 +478,7 @@ TEST(TransformationAccessChainTest, IsomorphicStructs) { MakeUnique(context.get()), validator_options); { TransformationAccessChain transformation( - 100, 11, {}, MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); + 100, 11, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -499,7 +488,7 @@ TEST(TransformationAccessChainTest, IsomorphicStructs) { } { TransformationAccessChain transformation( - 101, 12, {}, MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); + 101, 12, {}, MakeInstructionDescriptor(5, SpvOpReturn, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -598,56 +587,51 @@ TEST(TransformationAccessChainTest, ClampingVariables) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Bad: no ids given for clamping - ASSERT_FALSE( - TransformationAccessChain( - 100, 29, {17}, MakeInstructionDescriptor(36, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAccessChain( + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: an id given for clamping is not fresh ASSERT_FALSE(TransformationAccessChain( - 100, 29, {17}, - MakeInstructionDescriptor(36, spv::Op::OpLoad, 0), + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0), {{46, 201}}) .IsApplicable(context.get(), transformation_context)); // Bad: an id given for clamping is not fresh ASSERT_FALSE(TransformationAccessChain( - 100, 29, {17}, - MakeInstructionDescriptor(36, spv::Op::OpLoad, 0), + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0), {{200, 46}}) .IsApplicable(context.get(), transformation_context)); // Bad: an id given for clamping is the same as the id for the access chain ASSERT_FALSE(TransformationAccessChain( - 100, 29, {17}, - MakeInstructionDescriptor(36, spv::Op::OpLoad, 0), + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0), {{100, 201}}) .IsApplicable(context.get(), transformation_context)); // Bad: the fresh ids given are not distinct ASSERT_FALSE(TransformationAccessChain( - 100, 29, {17}, - MakeInstructionDescriptor(36, spv::Op::OpLoad, 0), + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0), {{200, 200}}) .IsApplicable(context.get(), transformation_context)); // Bad: not enough ids given for clamping (2 pairs needed) - ASSERT_FALSE(TransformationAccessChain( - 104, 34, {45, 10, 46}, - MakeInstructionDescriptor(46, spv::Op::OpReturn, 0), - {{208, 209}, {209, 211}}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAccessChain(104, 34, {45, 10, 46}, + MakeInstructionDescriptor(46, SpvOpReturn, 0), + {{208, 209}, {209, 211}}) + .IsApplicable(context.get(), transformation_context)); // Bad: the fresh ids given are not distinct - ASSERT_FALSE(TransformationAccessChain( - 104, 34, {45, 10, 46}, - MakeInstructionDescriptor(46, spv::Op::OpReturn, 0), - {{208, 209}, {209, 211}}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAccessChain(104, 34, {45, 10, 46}, + MakeInstructionDescriptor(46, SpvOpReturn, 0), + {{208, 209}, {209, 211}}) + .IsApplicable(context.get(), transformation_context)); { TransformationAccessChain transformation( - 100, 29, {17}, MakeInstructionDescriptor(36, spv::Op::OpLoad, 0), + 100, 29, {17}, MakeInstructionDescriptor(36, SpvOpLoad, 0), {{200, 201}}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -659,7 +643,7 @@ TEST(TransformationAccessChainTest, ClampingVariables) { { TransformationAccessChain transformation( - 101, 29, {36}, MakeInstructionDescriptor(38, spv::Op::OpLoad, 0), + 101, 29, {36}, MakeInstructionDescriptor(38, SpvOpLoad, 0), {{202, 203}}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -671,7 +655,7 @@ TEST(TransformationAccessChainTest, ClampingVariables) { { TransformationAccessChain transformation( - 102, 32, {10, 40}, MakeInstructionDescriptor(42, spv::Op::OpLoad, 0), + 102, 32, {10, 40}, MakeInstructionDescriptor(42, SpvOpLoad, 0), {{204, 205}}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -683,7 +667,7 @@ TEST(TransformationAccessChainTest, ClampingVariables) { { TransformationAccessChain transformation( - 103, 34, {11}, MakeInstructionDescriptor(45, spv::Op::OpLoad, 0), + 103, 34, {11}, MakeInstructionDescriptor(45, SpvOpLoad, 0), {{206, 207}}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -695,8 +679,7 @@ TEST(TransformationAccessChainTest, ClampingVariables) { { TransformationAccessChain transformation( - 104, 34, {45, 10, 46}, - MakeInstructionDescriptor(46, spv::Op::OpReturn, 0), + 104, 34, {45, 10, 46}, MakeInstructionDescriptor(46, SpvOpReturn, 0), {{208, 209}, {210, 211}}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); diff --git a/test/fuzz/transformation_add_constant_boolean_test.cpp b/test/fuzz/transformation_add_constant_boolean_test.cpp index bb8817e9..bd8d91c9 100644 --- a/test/fuzz/transformation_add_constant_boolean_test.cpp +++ b/test/fuzz/transformation_add_constant_boolean_test.cpp @@ -72,8 +72,7 @@ TEST(TransformationAddConstantBooleanTest, NeitherPresentInitiallyAddBoth) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(7)); ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(7)); ApplyAndCheckFreshIds(add_true, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpConstantTrue, - context->get_def_use_mgr()->GetDef(7)->opcode()); + ASSERT_EQ(SpvOpConstantTrue, context->get_def_use_mgr()->GetDef(7)->opcode()); ASSERT_TRUE(context->get_constant_mgr() ->FindDeclaredConstant(7) ->AsBoolConstant() diff --git a/test/fuzz/transformation_add_constant_composite_test.cpp b/test/fuzz/transformation_add_constant_composite_test.cpp index 193aa0ad..e5cbeec2 100644 --- a/test/fuzz/transformation_add_constant_composite_test.cpp +++ b/test/fuzz/transformation_add_constant_composite_test.cpp @@ -91,7 +91,7 @@ TEST(TransformationAddConstantCompositeTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpConstantComposite, + ASSERT_EQ(SpvOpConstantComposite, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_EQ(0.0F, context->get_constant_mgr() ->FindDeclaredConstant(100) diff --git a/test/fuzz/transformation_add_constant_null_test.cpp b/test/fuzz/transformation_add_constant_null_test.cpp index 44e92f85..1553e9f9 100644 --- a/test/fuzz/transformation_add_constant_null_test.cpp +++ b/test/fuzz/transformation_add_constant_null_test.cpp @@ -87,7 +87,7 @@ TEST(TransformationAddConstantNullTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpConstantNull, + ASSERT_EQ(SpvOpConstantNull, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_EQ( 0.0F, diff --git a/test/fuzz/transformation_add_constant_scalar_test.cpp b/test/fuzz/transformation_add_constant_scalar_test.cpp index 8c742a4c..00c05416 100644 --- a/test/fuzz/transformation_add_constant_scalar_test.cpp +++ b/test/fuzz/transformation_add_constant_scalar_test.cpp @@ -179,8 +179,7 @@ TEST(TransformationAddConstantScalarTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(19)); ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(19)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpConstant, - context->get_def_use_mgr()->GetDef(19)->opcode()); + ASSERT_EQ(SpvOpConstant, context->get_def_use_mgr()->GetDef(19)->opcode()); ASSERT_EQ(4, context->get_constant_mgr()->FindDeclaredConstant(19)->GetU32()); auto* constant_instruction = context->get_def_use_mgr()->GetDef(19); EXPECT_EQ(constant_instruction->NumInOperands(), 1); diff --git a/test/fuzz/transformation_add_copy_memory_test.cpp b/test/fuzz/transformation_add_copy_memory_test.cpp index 29a936c1..ff8ac72e 100644 --- a/test/fuzz/transformation_add_copy_memory_test.cpp +++ b/test/fuzz/transformation_add_copy_memory_test.cpp @@ -148,89 +148,89 @@ TEST(TransformationAddCopyMemoryTest, BasicTest) { MakeUnique(context.get()), validator_options); // Target id is not fresh (59). ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 59, 19, spv::StorageClass::Private, 20) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 59, 19, + SpvStorageClassPrivate, 20) .IsApplicable(context.get(), transformation_context)); // Instruction descriptor is invalid (id 90 is undefined). ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(90, spv::Op::OpVariable, 0), 90, - 19, spv::StorageClass::Private, 20) + MakeInstructionDescriptor(90, SpvOpVariable, 0), 90, 19, + SpvStorageClassPrivate, 20) .IsApplicable(context.get(), transformation_context)); // Cannot insert OpCopyMemory before OpPhi. - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(75, spv::Op::OpPhi, 0), 90, 19, - spv::StorageClass::Private, 20) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(75, SpvOpPhi, 0), + 90, 19, SpvStorageClassPrivate, 20) + .IsApplicable(context.get(), transformation_context)); // Source instruction is invalid. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 90, 76, spv::StorageClass::Private, 0) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 90, 76, + SpvStorageClassPrivate, 0) .IsApplicable(context.get(), transformation_context)); // Source instruction's type doesn't exist. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 90, 5, spv::StorageClass::Private, 0) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 90, 5, + SpvStorageClassPrivate, 0) .IsApplicable(context.get(), transformation_context)); // Source instruction's type is invalid. - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(41, spv::Op::OpLoad, 0), 90, 40, - spv::StorageClass::Private, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(41, SpvOpLoad, 0), + 90, 40, SpvStorageClassPrivate, 0) + .IsApplicable(context.get(), transformation_context)); // Source instruction is OpConstantNull. - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(41, spv::Op::OpLoad, 0), 90, 88, - spv::StorageClass::Private, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(41, SpvOpLoad, 0), + 90, 88, SpvStorageClassPrivate, 0) + .IsApplicable(context.get(), transformation_context)); // Storage class is invalid. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 90, 19, spv::StorageClass::Workgroup, 20) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 90, 19, + SpvStorageClassWorkgroup, 20) .IsApplicable(context.get(), transformation_context)); // Initializer is 0. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 90, 19, spv::StorageClass::Private, 0) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 90, 19, + SpvStorageClassPrivate, 0) .IsApplicable(context.get(), transformation_context)); // Initializer has wrong type. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0), - 90, 19, spv::StorageClass::Private, 25) + MakeInstructionDescriptor(27, SpvOpFunctionCall, 0), 90, 19, + SpvStorageClassPrivate, 25) .IsApplicable(context.get(), transformation_context)); // Source and target instructions are in different functions. - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(13, spv::Op::OpLoad, 0), 90, 19, - spv::StorageClass::Private, 20) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(13, SpvOpLoad, 0), + 90, 19, SpvStorageClassPrivate, 20) + .IsApplicable(context.get(), transformation_context)); // Source instruction doesn't dominate the target instruction. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(77, spv::Op::OpLogicalEqual, 0), - 90, 89, spv::StorageClass::Private, 20) + MakeInstructionDescriptor(77, SpvOpLogicalEqual, 0), 90, 89, + SpvStorageClassPrivate, 20) .IsApplicable(context.get(), transformation_context)); // Source and target instructions are the same. ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(19, spv::Op::OpVariable, 0), 90, - 19, spv::StorageClass::Private, 20) + MakeInstructionDescriptor(19, SpvOpVariable, 0), 90, 19, + SpvStorageClassPrivate, 20) .IsApplicable(context.get(), transformation_context)); // Correct transformations. uint32_t fresh_id = 90; - auto descriptor = MakeInstructionDescriptor(27, spv::Op::OpFunctionCall, 0); + auto descriptor = MakeInstructionDescriptor(27, SpvOpFunctionCall, 0); std::vector source_ids = {19, 23, 26, 30, 35, 39, 68, 86}; std::vector initializers = {20, 24, 25, 25, 36, 84, 85, 20}; - std::vector storage_classes = { - spv::StorageClass::Private, spv::StorageClass::Function}; + std::vector storage_classes = {SpvStorageClassPrivate, + SpvStorageClassFunction}; for (size_t i = 0, n = source_ids.size(); i < n; ++i) { TransformationAddCopyMemory transformation( descriptor, fresh_id, source_ids[i], @@ -420,10 +420,10 @@ TEST(TransformationAddCopyMemoryTest, DisallowBufferBlockDecoration) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(5, spv::Op::OpReturn, 0), 100, 9, - spv::StorageClass::Private, 50) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(5, SpvOpReturn, 0), + 100, 9, SpvStorageClassPrivate, 50) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddCopyMemoryTest, DisallowBlockDecoration) { @@ -466,12 +466,12 @@ TEST(TransformationAddCopyMemoryTest, DisallowBlockDecoration) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE(TransformationAddCopyMemory( - MakeInstructionDescriptor(5, spv::Op::OpReturn, 0), 100, 9, - spv::StorageClass::Private, 50) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddCopyMemory(MakeInstructionDescriptor(5, SpvOpReturn, 0), + 100, 9, SpvStorageClassPrivate, 50) + .IsApplicable(context.get(), transformation_context)); } } // namespace } // namespace fuzz -} // namespace spvtools +} // namespace spvtools \ No newline at end of file diff --git a/test/fuzz/transformation_add_dead_block_test.cpp b/test/fuzz/transformation_add_dead_block_test.cpp index 534ad693..3c9e6b43 100644 --- a/test/fuzz/transformation_add_dead_block_test.cpp +++ b/test/fuzz/transformation_add_dead_block_test.cpp @@ -295,16 +295,11 @@ TEST(TransformationAddDeadBlockTest, TargetBlockMustNotBeLoopMergeOrContinue) { OpBranch %8 %8 = OpLabel OpLoopMerge %12 %11 None - OpBranch %13 - %13 = OpLabel - OpSelectionMerge %14 None OpBranchConditional %5 %9 %10 %9 = OpLabel OpBranch %11 %10 = OpLabel OpBranch %12 - %14 = OpLabel - OpUnreachable %11 = OpLabel OpBranch %8 %12 = OpLabel diff --git a/test/fuzz/transformation_add_dead_break_test.cpp b/test/fuzz/transformation_add_dead_break_test.cpp index fd46c96a..5302d8a6 100644 --- a/test/fuzz/transformation_add_dead_break_test.cpp +++ b/test/fuzz/transformation_add_dead_break_test.cpp @@ -2743,9 +2743,6 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) { OpBranch %100 %100 = OpLabel OpLoopMerge %101 %104 None - OpBranch %105 - %105 = OpLabel - OpSelectionMerge %106 None OpBranchConditional %11 %102 %103 %103 = OpLabel %200 = OpCopyObject %10 %11 @@ -2755,8 +2752,6 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) { OpReturn %102 = OpLabel OpBranch %103 - %106 = OpLabel - OpUnreachable %104 = OpLabel OpBranch %100 OpFunctionEnd @@ -2796,17 +2791,12 @@ TEST(TransformationAddDeadBreakTest, RespectDominanceRules8) { OpBranch %100 %100 = OpLabel OpLoopMerge %101 %104 None - OpBranch %105 - %105 = OpLabel - OpSelectionMerge %106 None OpBranchConditional %11 %102 %103 %103 = OpLabel %200 = OpCopyObject %10 %11 OpBranch %101 %102 = OpLabel OpBranch %103 - %106 = OpLabel - OpUnreachable %101 = OpLabel %201 = OpCopyObject %10 %200 OpReturn diff --git a/test/fuzz/transformation_add_early_terminator_wrapper_test.cpp b/test/fuzz/transformation_add_early_terminator_wrapper_test.cpp index 8cb04a93..8239e217 100644 --- a/test/fuzz/transformation_add_early_terminator_wrapper_test.cpp +++ b/test/fuzz/transformation_add_early_terminator_wrapper_test.cpp @@ -40,9 +40,8 @@ TEST(TransformationAddEarlyTerminatorWrapperTest, NoVoidType) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE( - TransformationAddEarlyTerminatorWrapper(100, 101, spv::Op::OpKill) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(100, 101, SpvOpKill) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddEarlyTerminatorWrapperTest, NoVoidFunctionType) { @@ -64,9 +63,8 @@ TEST(TransformationAddEarlyTerminatorWrapperTest, NoVoidFunctionType) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE( - TransformationAddEarlyTerminatorWrapper(100, 101, spv::Op::OpKill) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(100, 101, SpvOpKill) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddEarlyTerminatorWrapperTest, BasicTest) { @@ -95,27 +93,25 @@ TEST(TransformationAddEarlyTerminatorWrapperTest, BasicTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(2, 101, spv::Op::OpKill) + ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(2, 101, SpvOpKill) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(100, 4, spv::Op::OpKill) + ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(100, 4, SpvOpKill) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddEarlyTerminatorWrapper(100, 100, SpvOpKill) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE( - TransformationAddEarlyTerminatorWrapper(100, 100, spv::Op::OpKill) - .IsApplicable(context.get(), transformation_context)); #ifndef NDEBUG - ASSERT_DEATH( - TransformationAddEarlyTerminatorWrapper(100, 101, spv::Op::OpReturn) - .IsApplicable(context.get(), transformation_context), - "Invalid opcode."); + ASSERT_DEATH(TransformationAddEarlyTerminatorWrapper(100, 101, SpvOpReturn) + .IsApplicable(context.get(), transformation_context), + "Invalid opcode."); #endif auto transformation1 = - TransformationAddEarlyTerminatorWrapper(100, 101, spv::Op::OpKill); + TransformationAddEarlyTerminatorWrapper(100, 101, SpvOpKill); auto transformation2 = - TransformationAddEarlyTerminatorWrapper(102, 103, spv::Op::OpUnreachable); + TransformationAddEarlyTerminatorWrapper(102, 103, SpvOpUnreachable); auto transformation3 = TransformationAddEarlyTerminatorWrapper( - 104, 105, spv::Op::OpTerminateInvocation); + 104, 105, SpvOpTerminateInvocation); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); diff --git a/test/fuzz/transformation_add_function_test.cpp b/test/fuzz/transformation_add_function_test.cpp index 65ae2f2d..d55fb931 100644 --- a/test/fuzz/transformation_add_function_test.cpp +++ b/test/fuzz/transformation_add_function_test.cpp @@ -84,7 +84,7 @@ bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( &found_non_irrelevant_parameter]( opt::Instruction* inst) { if (context->get_def_use_mgr()->GetDef(inst->type_id())->opcode() == - spv::Op::OpTypePointer && + SpvOpTypePointer && !transformation_context.GetFactManager()->PointeeValueIsIrrelevant( inst->result_id())) { found_non_irrelevant_parameter = true; @@ -96,7 +96,7 @@ bool AllVariablesAndParametersExceptLoopLimiterAreIrrelevant( } // Look through the instructions in the function's first block. for (auto& inst : *function.begin()) { - if (inst.opcode() != spv::Op::OpVariable) { + if (inst.opcode() != SpvOpVariable) { // We have found a non-variable instruction; this means we have gotten // past all variables, so we are done. return true; @@ -154,84 +154,73 @@ TEST(TransformationAddFunctionTest, BasicTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); TransformationAddFunction transformation1(std::vector( - {MakeInstructionMessage(spv::Op::OpFunction, 8, 13, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_ID, {10}}}), - MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 11, {}), - MakeInstructionMessage(spv::Op::OpFunctionParameter, 9, 12, {}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 14, {}), - MakeInstructionMessage(spv::Op::OpVariable, 9, 17, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), - MakeInstructionMessage(spv::Op::OpVariable, 7, 19, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), + {MakeInstructionMessage( + SpvOpFunction, 8, 13, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_ID, {10}}}), + MakeInstructionMessage(SpvOpFunctionParameter, 7, 11, {}), + MakeInstructionMessage(SpvOpFunctionParameter, 9, 12, {}), + MakeInstructionMessage(SpvOpLabel, 0, 14, {}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpVariable, 9, 17, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpVariable, 7, 19, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {17}}, {SPV_OPERAND_TYPE_ID, {18}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {19}}, {SPV_OPERAND_TYPE_ID, {20}}}), - MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {21}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 21, {}), - MakeInstructionMessage(spv::Op::OpLoopMerge, 0, 0, - {{SPV_OPERAND_TYPE_ID, {23}}, - {SPV_OPERAND_TYPE_ID, {24}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}}), - MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {25}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 25, {}), - MakeInstructionMessage(spv::Op::OpLoad, 6, 26, - {{SPV_OPERAND_TYPE_ID, {19}}}), - MakeInstructionMessage(spv::Op::OpLoad, 6, 27, - {{SPV_OPERAND_TYPE_ID, {11}}}), + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {21}}}), + MakeInstructionMessage(SpvOpLabel, 0, 21, {}), MakeInstructionMessage( - spv::Op::OpSLessThan, 28, 29, + SpvOpLoopMerge, 0, 0, + {{SPV_OPERAND_TYPE_ID, {23}}, + {SPV_OPERAND_TYPE_ID, {24}}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}}), + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {25}}}), + MakeInstructionMessage(SpvOpLabel, 0, 25, {}), + MakeInstructionMessage(SpvOpLoad, 6, 26, {{SPV_OPERAND_TYPE_ID, {19}}}), + MakeInstructionMessage(SpvOpLoad, 6, 27, {{SPV_OPERAND_TYPE_ID, {11}}}), + MakeInstructionMessage( + SpvOpSLessThan, 28, 29, {{SPV_OPERAND_TYPE_ID, {26}}, {SPV_OPERAND_TYPE_ID, {27}}}), - MakeInstructionMessage(spv::Op::OpBranchConditional, 0, 0, + MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {29}}, {SPV_OPERAND_TYPE_ID, {22}}, {SPV_OPERAND_TYPE_ID, {23}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 22, {}), - MakeInstructionMessage(spv::Op::OpLoad, 8, 30, - {{SPV_OPERAND_TYPE_ID, {12}}}), - MakeInstructionMessage(spv::Op::OpLoad, 6, 31, - {{SPV_OPERAND_TYPE_ID, {19}}}), - MakeInstructionMessage(spv::Op::OpConvertSToF, 8, 32, + MakeInstructionMessage(SpvOpLabel, 0, 22, {}), + MakeInstructionMessage(SpvOpLoad, 8, 30, {{SPV_OPERAND_TYPE_ID, {12}}}), + MakeInstructionMessage(SpvOpLoad, 6, 31, {{SPV_OPERAND_TYPE_ID, {19}}}), + MakeInstructionMessage(SpvOpConvertSToF, 8, 32, {{SPV_OPERAND_TYPE_ID, {31}}}), MakeInstructionMessage( - spv::Op::OpFMul, 8, 33, + SpvOpFMul, 8, 33, {{SPV_OPERAND_TYPE_ID, {30}}, {SPV_OPERAND_TYPE_ID, {32}}}), - MakeInstructionMessage(spv::Op::OpLoad, 8, 34, - {{SPV_OPERAND_TYPE_ID, {17}}}), + MakeInstructionMessage(SpvOpLoad, 8, 34, {{SPV_OPERAND_TYPE_ID, {17}}}), MakeInstructionMessage( - spv::Op::OpFAdd, 8, 35, + SpvOpFAdd, 8, 35, {{SPV_OPERAND_TYPE_ID, {34}}, {SPV_OPERAND_TYPE_ID, {33}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {17}}, {SPV_OPERAND_TYPE_ID, {35}}}), - MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {24}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 24, {}), - MakeInstructionMessage(spv::Op::OpLoad, 6, 36, - {{SPV_OPERAND_TYPE_ID, {19}}}), + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {24}}}), + MakeInstructionMessage(SpvOpLabel, 0, 24, {}), + MakeInstructionMessage(SpvOpLoad, 6, 36, {{SPV_OPERAND_TYPE_ID, {19}}}), MakeInstructionMessage( - spv::Op::OpIAdd, 6, 38, + SpvOpIAdd, 6, 38, {{SPV_OPERAND_TYPE_ID, {36}}, {SPV_OPERAND_TYPE_ID, {37}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {19}}, {SPV_OPERAND_TYPE_ID, {38}}}), - MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {21}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 23, {}), - MakeInstructionMessage(spv::Op::OpLoad, 8, 39, - {{SPV_OPERAND_TYPE_ID, {17}}}), - MakeInstructionMessage(spv::Op::OpReturnValue, 0, 0, + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {21}}}), + MakeInstructionMessage(SpvOpLabel, 0, 23, {}), + MakeInstructionMessage(SpvOpLoad, 8, 39, {{SPV_OPERAND_TYPE_ID, {17}}}), + MakeInstructionMessage(SpvOpReturnValue, 0, 0, {{SPV_OPERAND_TYPE_ID, {39}}}), - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})})); + MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); @@ -310,51 +299,51 @@ TEST(TransformationAddFunctionTest, BasicTest) { ASSERT_TRUE(transformation_context.GetFactManager()->BlockIsDead(25)); TransformationAddFunction transformation2(std::vector( - {MakeInstructionMessage(spv::Op::OpFunction, 2, 15, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_ID, {3}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 16, {}), - MakeInstructionMessage(spv::Op::OpVariable, 7, 44, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), - MakeInstructionMessage(spv::Op::OpVariable, 9, 45, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), - MakeInstructionMessage(spv::Op::OpVariable, 7, 48, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), - MakeInstructionMessage(spv::Op::OpVariable, 9, 49, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}}), + {MakeInstructionMessage( + SpvOpFunction, 2, 15, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_ID, {3}}}), + MakeInstructionMessage(SpvOpLabel, 0, 16, {}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpVariable, 7, 44, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpVariable, 9, 45, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpVariable, 7, 48, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpVariable, 9, 49, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}), + MakeInstructionMessage( + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {44}}, {SPV_OPERAND_TYPE_ID, {20}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {45}}, {SPV_OPERAND_TYPE_ID, {18}}}), - MakeInstructionMessage(spv::Op::OpFunctionCall, 8, 46, + MakeInstructionMessage(SpvOpFunctionCall, 8, 46, {{SPV_OPERAND_TYPE_ID, {13}}, {SPV_OPERAND_TYPE_ID, {44}}, {SPV_OPERAND_TYPE_ID, {45}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {48}}, {SPV_OPERAND_TYPE_ID, {37}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {49}}, {SPV_OPERAND_TYPE_ID, {47}}}), - MakeInstructionMessage(spv::Op::OpFunctionCall, 8, 50, + MakeInstructionMessage(SpvOpFunctionCall, 8, 50, {{SPV_OPERAND_TYPE_ID, {13}}, {SPV_OPERAND_TYPE_ID, {48}}, {SPV_OPERAND_TYPE_ID, {49}}}), MakeInstructionMessage( - spv::Op::OpFAdd, 8, 51, + SpvOpFAdd, 8, 51, {{SPV_OPERAND_TYPE_ID, {46}}, {SPV_OPERAND_TYPE_ID, {50}}}), MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {43}}, {SPV_OPERAND_TYPE_ID, {51}}}), - MakeInstructionMessage(spv::Op::OpReturn, 0, 0, {}), - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})})); + MakeInstructionMessage(SpvOpReturn, 0, 0, {}), + MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); @@ -524,46 +513,45 @@ TEST(TransformationAddFunctionTest, InapplicableTransformations) { ASSERT_FALSE( TransformationAddFunction( std::vector( - {MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 11, {}), - MakeInstructionMessage(spv::Op::OpFunctionParameter, 9, 12, {}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 14, {})})) + {MakeInstructionMessage(SpvOpFunctionParameter, 7, 11, {}), + MakeInstructionMessage(SpvOpFunctionParameter, 9, 12, {}), + MakeInstructionMessage(SpvOpLabel, 0, 14, {})})) .IsApplicable(context.get(), transformation_context)); // No OpLabel ASSERT_FALSE( TransformationAddFunction( std::vector( - {MakeInstructionMessage( - spv::Op::OpFunction, 8, 13, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_ID, {10}}}), - MakeInstructionMessage(spv::Op::OpReturnValue, 0, 0, + {MakeInstructionMessage(SpvOpFunction, 8, 13, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, + {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_ID, {10}}}), + MakeInstructionMessage(SpvOpReturnValue, 0, 0, {{SPV_OPERAND_TYPE_ID, {39}}}), - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})})) + MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})})) .IsApplicable(context.get(), transformation_context)); // Abrupt end of instructions ASSERT_FALSE(TransformationAddFunction( std::vector({MakeInstructionMessage( - spv::Op::OpFunction, 8, 13, + SpvOpFunction, 8, 13, {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, + {SpvFunctionControlMaskNone}}, {SPV_OPERAND_TYPE_ID, {10}}})})) .IsApplicable(context.get(), transformation_context)); // No function end - ASSERT_FALSE(TransformationAddFunction( - std::vector( - {MakeInstructionMessage( - spv::Op::OpFunction, 8, 13, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_ID, {10}}}), - MakeInstructionMessage(spv::Op::OpLabel, 0, 14, {}), - MakeInstructionMessage(spv::Op::OpReturnValue, 0, 0, - {{SPV_OPERAND_TYPE_ID, {39}}})})) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddFunction( + std::vector( + {MakeInstructionMessage(SpvOpFunction, 8, 13, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, + {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_ID, {10}}}), + MakeInstructionMessage(SpvOpLabel, 0, 14, {}), + MakeInstructionMessage(SpvOpReturnValue, 0, 0, + {{SPV_OPERAND_TYPE_ID, {39}}})})) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationAddFunctionTest, LoopLimiters) { @@ -593,69 +581,61 @@ TEST(TransformationAddFunctionTest, LoopLimiters) { const auto consumer = nullptr; std::vector instructions; + instructions.push_back(MakeInstructionMessage( + SpvOpFunction, 2, 30, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 31, {})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 2, 30, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 31, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {20}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 20, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpLoopMerge, 0, 0, - {{SPV_OPERAND_TYPE_ID, {21}}, - {SPV_OPERAND_TYPE_ID, {22}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranchConditional, 0, - 0, + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {20}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 20, {})); + instructions.push_back(MakeInstructionMessage( + SpvOpLoopMerge, 0, 0, + {{SPV_OPERAND_TYPE_ID, {21}}, + {SPV_OPERAND_TYPE_ID, {22}}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}})); + instructions.push_back(MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {12}}, {SPV_OPERAND_TYPE_ID, {23}}, {SPV_OPERAND_TYPE_ID, {21}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 23, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 23, {})); + instructions.push_back(MakeInstructionMessage( + SpvOpLoopMerge, 0, 0, + {{SPV_OPERAND_TYPE_ID, {25}}, + {SPV_OPERAND_TYPE_ID, {26}}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpLoopMerge, 0, 0, - {{SPV_OPERAND_TYPE_ID, {25}}, - {SPV_OPERAND_TYPE_ID, {26}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {28}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 28, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranchConditional, 0, - 0, + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {28}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 28, {})); + instructions.push_back(MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {12}}, {SPV_OPERAND_TYPE_ID, {26}}, {SPV_OPERAND_TYPE_ID, {25}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 26, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {23}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 25, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 26, {})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpLoopMerge, 0, 0, - {{SPV_OPERAND_TYPE_ID, {24}}, - {SPV_OPERAND_TYPE_ID, {27}}, - {SPV_OPERAND_TYPE_LOOP_CONTROL, - {uint32_t(spv::LoopControlMask::MaskNone)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranchConditional, 0, - 0, + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {23}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 25, {})); + instructions.push_back(MakeInstructionMessage( + SpvOpLoopMerge, 0, 0, + {{SPV_OPERAND_TYPE_ID, {24}}, + {SPV_OPERAND_TYPE_ID, {27}}, + {SPV_OPERAND_TYPE_LOOP_CONTROL, {SpvLoopControlMaskNone}}})); + instructions.push_back(MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {12}}, {SPV_OPERAND_TYPE_ID, {24}}, {SPV_OPERAND_TYPE_ID, {27}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 27, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {25}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 24, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {22}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 22, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {20}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 21, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpReturn, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 27, {})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {25}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 24, {})); + instructions.push_back( + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {22}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 22, {})); + instructions.push_back( + MakeInstructionMessage(SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {20}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 21, {})); + instructions.push_back(MakeInstructionMessage(SpvOpReturn, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; @@ -857,36 +837,31 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInVoidFunction) { std::vector instructions; - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 2, 10, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {8}}})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 9, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 11, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 12, - {{SPV_OPERAND_TYPE_ID, {9}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpIEqual, 14, 15, + SpvOpFunction, 2, 10, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {8}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpFunctionParameter, 7, 9, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 11, {})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 12, {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back(MakeInstructionMessage( + SpvOpIEqual, 14, 15, {{SPV_OPERAND_TYPE_ID, {12}}, {SPV_OPERAND_TYPE_ID, {13}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpSelectionMerge, 0, 0, + SpvOpSelectionMerge, 0, 0, {{SPV_OPERAND_TYPE_ID, {17}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranchConditional, 0, - 0, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, {SpvSelectionControlMaskNone}}})); + instructions.push_back(MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {15}}, {SPV_OPERAND_TYPE_ID, {16}}, {SPV_OPERAND_TYPE_ID, {17}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 16, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpUnreachable, 0, 0, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 17, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpKill, 0, 0, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 16, {})); + instructions.push_back(MakeInstructionMessage(SpvOpUnreachable, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 17, {})); + instructions.push_back(MakeInstructionMessage(SpvOpKill, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; @@ -1021,36 +996,31 @@ TEST(TransformationAddFunctionTest, KillAndUnreachableInNonVoidFunction) { std::vector instructions; - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 6, 10, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {50}}})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 9, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 11, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 12, - {{SPV_OPERAND_TYPE_ID, {9}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpIEqual, 14, 15, + SpvOpFunction, 6, 10, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {50}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpFunctionParameter, 7, 9, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 11, {})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 12, {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back(MakeInstructionMessage( + SpvOpIEqual, 14, 15, {{SPV_OPERAND_TYPE_ID, {12}}, {SPV_OPERAND_TYPE_ID, {13}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpSelectionMerge, 0, 0, + SpvOpSelectionMerge, 0, 0, {{SPV_OPERAND_TYPE_ID, {17}}, - {SPV_OPERAND_TYPE_SELECTION_CONTROL, - {uint32_t(spv::SelectionControlMask::MaskNone)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpBranchConditional, 0, - 0, + {SPV_OPERAND_TYPE_SELECTION_CONTROL, {SpvSelectionControlMaskNone}}})); + instructions.push_back(MakeInstructionMessage(SpvOpBranchConditional, 0, 0, {{SPV_OPERAND_TYPE_ID, {15}}, {SPV_OPERAND_TYPE_ID, {16}}, {SPV_OPERAND_TYPE_ID, {17}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 16, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpUnreachable, 0, 0, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 17, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpKill, 0, 0, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 16, {})); + instructions.push_back(MakeInstructionMessage(SpvOpUnreachable, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 17, {})); + instructions.push_back(MakeInstructionMessage(SpvOpKill, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; @@ -1219,133 +1189,129 @@ TEST(TransformationAddFunctionTest, ClampedAccessChains) { std::vector instructions; + instructions.push_back(MakeInstructionMessage( + SpvOpFunction, 2, 12, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {8}}})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 2, 12, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {8}}})); + MakeInstructionMessage(SpvOpFunctionParameter, 7, 9, {})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 9, {})); + MakeInstructionMessage(SpvOpFunctionParameter, 102, 10, {})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionParameter, 102, 10, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionParameter, 7, 11, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 13, {})); + MakeInstructionMessage(SpvOpFunctionParameter, 7, 11, {})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 13, {})); + instructions.push_back(MakeInstructionMessage( + SpvOpVariable, 7, 14, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); + instructions.push_back(MakeInstructionMessage( + SpvOpVariable, 26, 27, + {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}})); instructions.push_back( - MakeInstructionMessage(spv::Op::OpVariable, 7, 14, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpVariable, 26, 27, - {{SPV_OPERAND_TYPE_STORAGE_CLASS, - {uint32_t(spv::StorageClass::Function)}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 22, - {{SPV_OPERAND_TYPE_ID, {11}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpAccessChain, 23, 24, + MakeInstructionMessage(SpvOpLoad, 6, 22, {{SPV_OPERAND_TYPE_ID, {11}}})); + instructions.push_back(MakeInstructionMessage(SpvOpAccessChain, 23, 24, {{SPV_OPERAND_TYPE_ID, {20}}, {SPV_OPERAND_TYPE_ID, {21}}, {SPV_OPERAND_TYPE_ID, {22}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 25, - {{SPV_OPERAND_TYPE_ID, {24}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 25, {{SPV_OPERAND_TYPE_ID, {24}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {14}}, {SPV_OPERAND_TYPE_ID, {25}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 15, 28, - {{SPV_OPERAND_TYPE_ID, {10}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 15, 28, {{SPV_OPERAND_TYPE_ID, {10}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpAccessChain, 29, 30, + SpvOpAccessChain, 29, 30, {{SPV_OPERAND_TYPE_ID, {20}}, {SPV_OPERAND_TYPE_ID, {28}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 17, 31, - {{SPV_OPERAND_TYPE_ID, {30}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 17, 31, {{SPV_OPERAND_TYPE_ID, {30}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {27}}, {SPV_OPERAND_TYPE_ID, {31}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 32, - {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 32, {{SPV_OPERAND_TYPE_ID, {9}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpInBoundsAccessChain, 7, 34, + SpvOpInBoundsAccessChain, 7, 34, {{SPV_OPERAND_TYPE_ID, {27}}, {SPV_OPERAND_TYPE_ID, {32}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {34}}, {SPV_OPERAND_TYPE_ID, {33}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 39, - {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 39, {{SPV_OPERAND_TYPE_ID, {9}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpAccessChain, 23, 40, + SpvOpAccessChain, 23, 40, {{SPV_OPERAND_TYPE_ID, {38}}, {SPV_OPERAND_TYPE_ID, {33}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 41, - {{SPV_OPERAND_TYPE_ID, {40}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 41, {{SPV_OPERAND_TYPE_ID, {40}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpInBoundsAccessChain, 23, 42, + SpvOpInBoundsAccessChain, 23, 42, {{SPV_OPERAND_TYPE_ID, {38}}, {SPV_OPERAND_TYPE_ID, {39}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {42}}, {SPV_OPERAND_TYPE_ID, {41}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 15, 43, - {{SPV_OPERAND_TYPE_ID, {10}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 44, - {{SPV_OPERAND_TYPE_ID, {11}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 45, - {{SPV_OPERAND_TYPE_ID, {9}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 15, 46, - {{SPV_OPERAND_TYPE_ID, {10}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 15, 43, {{SPV_OPERAND_TYPE_ID, {10}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 44, {{SPV_OPERAND_TYPE_ID, {11}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 45, {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 15, 46, {{SPV_OPERAND_TYPE_ID, {10}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpIAdd, 6, 47, + SpvOpIAdd, 6, 47, {{SPV_OPERAND_TYPE_ID, {45}}, {SPV_OPERAND_TYPE_ID, {46}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpAccessChain, 23, 48, + SpvOpAccessChain, 23, 48, {{SPV_OPERAND_TYPE_ID, {38}}, {SPV_OPERAND_TYPE_ID, {47}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 49, - {{SPV_OPERAND_TYPE_ID, {48}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpInBoundsAccessChain, - 23, 50, + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 49, {{SPV_OPERAND_TYPE_ID, {48}}})); + instructions.push_back(MakeInstructionMessage(SpvOpInBoundsAccessChain, 23, + 50, {{SPV_OPERAND_TYPE_ID, {20}}, {SPV_OPERAND_TYPE_ID, {43}}, {SPV_OPERAND_TYPE_ID, {44}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 51, - {{SPV_OPERAND_TYPE_ID, {50}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 51, {{SPV_OPERAND_TYPE_ID, {50}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpIAdd, 6, 52, + SpvOpIAdd, 6, 52, {{SPV_OPERAND_TYPE_ID, {51}}, {SPV_OPERAND_TYPE_ID, {49}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpAccessChain, 23, 53, + instructions.push_back(MakeInstructionMessage(SpvOpAccessChain, 23, 53, {{SPV_OPERAND_TYPE_ID, {20}}, {SPV_OPERAND_TYPE_ID, {43}}, {SPV_OPERAND_TYPE_ID, {44}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {53}}, {SPV_OPERAND_TYPE_ID, {52}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 15, 58, - {{SPV_OPERAND_TYPE_ID, {10}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 63, - {{SPV_OPERAND_TYPE_ID, {11}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpAccessChain, 64, 65, + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 15, 58, {{SPV_OPERAND_TYPE_ID, {10}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 63, {{SPV_OPERAND_TYPE_ID, {11}}})); + instructions.push_back(MakeInstructionMessage(SpvOpAccessChain, 64, 65, {{SPV_OPERAND_TYPE_ID, {62}}, {SPV_OPERAND_TYPE_ID, {21}}, {SPV_OPERAND_TYPE_ID, {63}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpAccessChain, 64, 101, + instructions.push_back(MakeInstructionMessage(SpvOpAccessChain, 64, 101, {{SPV_OPERAND_TYPE_ID, {62}}, {SPV_OPERAND_TYPE_ID, {45}}, {SPV_OPERAND_TYPE_ID, {46}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 54, 66, - {{SPV_OPERAND_TYPE_ID, {65}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 54, 66, {{SPV_OPERAND_TYPE_ID, {65}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpAccessChain, 64, 67, + SpvOpAccessChain, 64, 67, {{SPV_OPERAND_TYPE_ID, {57}}, {SPV_OPERAND_TYPE_ID, {58}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {67}}, {SPV_OPERAND_TYPE_ID, {66}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLoad, 6, 68, - {{SPV_OPERAND_TYPE_ID, {9}}})); + instructions.push_back( + MakeInstructionMessage(SpvOpLoad, 6, 68, {{SPV_OPERAND_TYPE_ID, {9}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpInBoundsAccessChain, 64, 70, + SpvOpInBoundsAccessChain, 64, 70, {{SPV_OPERAND_TYPE_ID, {57}}, {SPV_OPERAND_TYPE_ID, {68}}})); instructions.push_back(MakeInstructionMessage( - spv::Op::OpStore, 0, 0, + SpvOpStore, 0, 0, {{SPV_OPERAND_TYPE_ID, {70}}, {SPV_OPERAND_TYPE_ID, {69}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpReturn, 0, 0, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpReturn, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; @@ -1668,17 +1634,15 @@ TEST(TransformationAddFunctionTest, LivesafeCanCallLivesafe) { std::vector instructions; - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 2, 8, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 9, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpFunctionCall, 2, 11, + instructions.push_back(MakeInstructionMessage( + SpvOpFunction, 2, 8, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 9, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionCall, 2, 11, {{SPV_OPERAND_TYPE_ID, {6}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpReturn, 0, 0, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpReturn, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; @@ -1774,17 +1738,15 @@ TEST(TransformationAddFunctionTest, LivesafeOnlyCallsLivesafe) { std::vector instructions; - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunction, 2, 8, - {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, - {uint32_t(spv::FunctionControlMask::MaskNone)}}, - {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpLabel, 0, 9, {})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpFunctionCall, 2, 11, + instructions.push_back(MakeInstructionMessage( + SpvOpFunction, 2, 8, + {{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}}, + {SPV_OPERAND_TYPE_TYPE_ID, {3}}})); + instructions.push_back(MakeInstructionMessage(SpvOpLabel, 0, 9, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionCall, 2, 11, {{SPV_OPERAND_TYPE_ID, {6}}})); - instructions.push_back(MakeInstructionMessage(spv::Op::OpReturn, 0, 0, {})); - instructions.push_back( - MakeInstructionMessage(spv::Op::OpFunctionEnd, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpReturn, 0, 0, {})); + instructions.push_back(MakeInstructionMessage(SpvOpFunctionEnd, 0, 0, {})); spvtools::ValidatorOptions validator_options; diff --git a/test/fuzz/transformation_add_global_undef_test.cpp b/test/fuzz/transformation_add_global_undef_test.cpp index b87970fa..03b91570 100644 --- a/test/fuzz/transformation_add_global_undef_test.cpp +++ b/test/fuzz/transformation_add_global_undef_test.cpp @@ -71,8 +71,7 @@ TEST(TransformationAddGlobalUndefTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpUndef, - context->get_def_use_mgr()->GetDef(100)->opcode()); + ASSERT_EQ(SpvOpUndef, context->get_def_use_mgr()->GetDef(100)->opcode()); } TransformationAddGlobalUndef transformations[] = { diff --git a/test/fuzz/transformation_add_global_variable_test.cpp b/test/fuzz/transformation_add_global_variable_test.cpp index fc452df3..9531ade7 100644 --- a/test/fuzz/transformation_add_global_variable_test.cpp +++ b/test/fuzz/transformation_add_global_variable_test.cpp @@ -66,95 +66,94 @@ TEST(TransformationAddGlobalVariableTest, BasicTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Id already in use - ASSERT_FALSE(TransformationAddGlobalVariable( - 4, 10, spv::StorageClass::Private, 0, true) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(4, 10, SpvStorageClassPrivate, 0, true) + .IsApplicable(context.get(), transformation_context)); // %1 is not a type - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 1, spv::StorageClass::Private, 0, false) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(100, 1, SpvStorageClassPrivate, 0, false) + .IsApplicable(context.get(), transformation_context)); // %7 is not a pointer type - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 7, spv::StorageClass::Private, 0, true) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(100, 7, SpvStorageClassPrivate, 0, true) + .IsApplicable(context.get(), transformation_context)); // %9 does not have Private storage class - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 9, spv::StorageClass::Private, 0, false) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(100, 9, SpvStorageClassPrivate, 0, false) + .IsApplicable(context.get(), transformation_context)); // %15 does not have Private storage class - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 15, spv::StorageClass::Private, 0, true) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(100, 15, SpvStorageClassPrivate, 0, true) + .IsApplicable(context.get(), transformation_context)); // %10 is a pointer to float, while %16 is an int constant - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 10, spv::StorageClass::Private, 16, false) + ASSERT_FALSE(TransformationAddGlobalVariable(100, 10, SpvStorageClassPrivate, + 16, false) .IsApplicable(context.get(), transformation_context)); // %10 is a Private pointer to float, while %15 is a variable with type // Uniform float pointer - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 10, spv::StorageClass::Private, 15, true) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(100, 10, SpvStorageClassPrivate, 15, true) + .IsApplicable(context.get(), transformation_context)); // %12 is a Private pointer to int, while %10 is a variable with type // Private float pointer - ASSERT_FALSE(TransformationAddGlobalVariable( - 100, 12, spv::StorageClass::Private, 10, false) + ASSERT_FALSE(TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, + 10, false) .IsApplicable(context.get(), transformation_context)); // %10 is pointer-to-float, and %14 has type pointer-to-float; that's not OK // since the initializer's type should be the *pointee* type. - ASSERT_FALSE(TransformationAddGlobalVariable( - 104, 10, spv::StorageClass::Private, 14, true) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddGlobalVariable(104, 10, SpvStorageClassPrivate, 14, true) + .IsApplicable(context.get(), transformation_context)); // This would work in principle, but logical addressing does not allow // a pointer to a pointer. - ASSERT_FALSE(TransformationAddGlobalVariable( - 104, 17, spv::StorageClass::Private, 14, false) + ASSERT_FALSE(TransformationAddGlobalVariable(104, 17, SpvStorageClassPrivate, + 14, false) .IsApplicable(context.get(), transformation_context)); { // %100 = OpVariable %12 Private ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100)); TransformationAddGlobalVariable transformation( - 100, 12, spv::StorageClass::Private, 16, true); + 100, 12, SpvStorageClassPrivate, 16, true); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpVariable, - context->get_def_use_mgr()->GetDef(100)->opcode()); + ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_EQ( - spv::StorageClass::Private, - static_cast( + SpvStorageClassPrivate, + static_cast( context->get_def_use_mgr()->GetDef(100)->GetSingleWordInOperand( 0))); } TransformationAddGlobalVariable transformations[] = { // %101 = OpVariable %10 Private - TransformationAddGlobalVariable(101, 10, spv::StorageClass::Private, 40, + TransformationAddGlobalVariable(101, 10, SpvStorageClassPrivate, 40, false), // %102 = OpVariable %13 Private - TransformationAddGlobalVariable(102, 13, spv::StorageClass::Private, 41, + TransformationAddGlobalVariable(102, 13, SpvStorageClassPrivate, 41, true), // %103 = OpVariable %12 Private %16 - TransformationAddGlobalVariable(103, 12, spv::StorageClass::Private, 16, + TransformationAddGlobalVariable(103, 12, SpvStorageClassPrivate, 16, false), // %104 = OpVariable %19 Private %21 - TransformationAddGlobalVariable(104, 19, spv::StorageClass::Private, 21, + TransformationAddGlobalVariable(104, 19, SpvStorageClassPrivate, 21, true), // %105 = OpVariable %19 Private %22 - TransformationAddGlobalVariable(105, 19, spv::StorageClass::Private, 22, + TransformationAddGlobalVariable(105, 19, SpvStorageClassPrivate, 22, false)}; for (auto& transformation : transformations) { @@ -270,15 +269,15 @@ TEST(TransformationAddGlobalVariableTest, TestEntryPointInterfaceEnlargement) { MakeUnique(context.get()), validator_options); TransformationAddGlobalVariable transformations[] = { // %100 = OpVariable %12 Private - TransformationAddGlobalVariable(100, 12, spv::StorageClass::Private, 16, + TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16, true), // %101 = OpVariable %12 Private %16 - TransformationAddGlobalVariable(101, 12, spv::StorageClass::Private, 16, + TransformationAddGlobalVariable(101, 12, SpvStorageClassPrivate, 16, false), // %102 = OpVariable %19 Private %21 - TransformationAddGlobalVariable(102, 19, spv::StorageClass::Private, 21, + TransformationAddGlobalVariable(102, 19, SpvStorageClassPrivate, 21, true)}; for (auto& transformation : transformations) { @@ -389,15 +388,15 @@ TEST(TransformationAddGlobalVariableTest, MakeUnique(context.get()), validator_options); TransformationAddGlobalVariable transformations[] = { // %100 = OpVariable %12 Private - TransformationAddGlobalVariable(100, 12, spv::StorageClass::Private, 16, + TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16, true), // %101 = OpVariable %12 Private %16 - TransformationAddGlobalVariable(101, 12, spv::StorageClass::Private, 16, + TransformationAddGlobalVariable(101, 12, SpvStorageClassPrivate, 16, false), // %102 = OpVariable %19 Private %21 - TransformationAddGlobalVariable(102, 19, spv::StorageClass::Private, 21, + TransformationAddGlobalVariable(102, 19, SpvStorageClassPrivate, 21, true)}; for (auto& transformation : transformations) { @@ -487,8 +486,7 @@ TEST(TransformationAddGlobalVariableTest, TestAddingWorkgroupGlobals) { MakeUnique(context.get()), validator_options); #ifndef NDEBUG ASSERT_DEATH( - TransformationAddGlobalVariable(8, 7, spv::StorageClass::Workgroup, 50, - true) + TransformationAddGlobalVariable(8, 7, SpvStorageClassWorkgroup, 50, true) .IsApplicable(context.get(), transformation_context), "By construction this transformation should not have an.*initializer " "when Workgroup storage class is used"); @@ -496,11 +494,10 @@ TEST(TransformationAddGlobalVariableTest, TestAddingWorkgroupGlobals) { TransformationAddGlobalVariable transformations[] = { // %8 = OpVariable %7 Workgroup - TransformationAddGlobalVariable(8, 7, spv::StorageClass::Workgroup, 0, - true), + TransformationAddGlobalVariable(8, 7, SpvStorageClassWorkgroup, 0, true), // %10 = OpVariable %7 Workgroup - TransformationAddGlobalVariable(10, 7, spv::StorageClass::Workgroup, 0, + TransformationAddGlobalVariable(10, 7, SpvStorageClassWorkgroup, 0, false)}; for (auto& transformation : transformations) { diff --git a/test/fuzz/transformation_add_image_sample_unused_components_test.cpp b/test/fuzz/transformation_add_image_sample_unused_components_test.cpp index 7047544b..072378ca 100644 --- a/test/fuzz/transformation_add_image_sample_unused_components_test.cpp +++ b/test/fuzz/transformation_add_image_sample_unused_components_test.cpp @@ -73,14 +73,14 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { MakeUnique(context.get()), validator_options); // Tests applicable image instruction. auto instruction_descriptor = - MakeInstructionDescriptor(25, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(25, SpvOpImageSampleImplicitLod, 0); auto transformation = TransformationAddImageSampleUnusedComponents(23, instruction_descriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(26, spv::Op::OpImageSampleExplicitLod, 0); + MakeInstructionDescriptor(26, SpvOpImageSampleExplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(24, instruction_descriptor); ASSERT_TRUE( @@ -88,27 +88,27 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { // Tests undefined image instructions. instruction_descriptor = - MakeInstructionDescriptor(27, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(27, SpvOpImageSampleImplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(23, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(28, spv::Op::OpImageSampleExplicitLod, 0); + MakeInstructionDescriptor(28, SpvOpImageSampleExplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(23, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests non-image instructions. - instruction_descriptor = MakeInstructionDescriptor(19, spv::Op::OpLabel, 0); + instruction_descriptor = MakeInstructionDescriptor(19, SpvOpLabel, 0); transformation = TransformationAddImageSampleUnusedComponents(24, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instruction_descriptor = MakeInstructionDescriptor(20, spv::Op::OpLoad, 0); + instruction_descriptor = MakeInstructionDescriptor(20, SpvOpLoad, 0); transformation = TransformationAddImageSampleUnusedComponents(24, instruction_descriptor); ASSERT_FALSE( @@ -116,7 +116,7 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { // Tests coordinate operand being a vec4. instruction_descriptor = - MakeInstructionDescriptor(27, spv::Op::OpImageSampleExplicitLod, 0); + MakeInstructionDescriptor(27, SpvOpImageSampleExplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(22, instruction_descriptor); ASSERT_FALSE( @@ -124,7 +124,7 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { // Tests undefined coordinate with unused operands. instruction_descriptor = - MakeInstructionDescriptor(25, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(25, SpvOpImageSampleImplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(27, instruction_descriptor); ASSERT_FALSE( @@ -133,7 +133,7 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { // Tests coordinate with unused operands being a non-OpCompositeConstruct // instruction. instruction_descriptor = - MakeInstructionDescriptor(25, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(25, SpvOpImageSampleImplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(21, instruction_descriptor); ASSERT_FALSE( @@ -142,7 +142,7 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, IsApplicable) { // Tests the first OpCompositeConstruct constituent not being the original // coordinate. instruction_descriptor = - MakeInstructionDescriptor(25, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(25, SpvOpImageSampleImplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(22, instruction_descriptor); ASSERT_FALSE( @@ -198,13 +198,13 @@ TEST(TransformationAddImageSampleUnusedComponentsTest, Apply) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(25, spv::Op::OpImageSampleImplicitLod, 0); + MakeInstructionDescriptor(25, SpvOpImageSampleImplicitLod, 0); auto transformation = TransformationAddImageSampleUnusedComponents(23, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(26, spv::Op::OpImageSampleExplicitLod, 0); + MakeInstructionDescriptor(26, SpvOpImageSampleExplicitLod, 0); transformation = TransformationAddImageSampleUnusedComponents(24, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_add_local_variable_test.cpp b/test/fuzz/transformation_add_local_variable_test.cpp index 2af85971..de88573a 100644 --- a/test/fuzz/transformation_add_local_variable_test.cpp +++ b/test/fuzz/transformation_add_local_variable_test.cpp @@ -104,8 +104,7 @@ TEST(TransformationAddLocalVariableTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpVariable, - context->get_def_use_mgr()->GetDef(105)->opcode()); + ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(105)->opcode()); ASSERT_EQ(5, context->get_instr_block(105)->id()); } diff --git a/test/fuzz/transformation_add_opphi_synonym_test.cpp b/test/fuzz/transformation_add_opphi_synonym_test.cpp index 03fd39a1..3501f8ed 100644 --- a/test/fuzz/transformation_add_opphi_synonym_test.cpp +++ b/test/fuzz/transformation_add_opphi_synonym_test.cpp @@ -365,7 +365,8 @@ TEST(TransformationAddOpPhiSynonymTest, VariablePointers) { MakeSynonymFact(12, 16)); // Remove the VariablePointers capability. - context.get()->RemoveCapability(spv::Capability::VariablePointers); + context.get()->get_feature_mgr()->RemoveCapability( + SpvCapabilityVariablePointers); // The VariablePointers capability is required to add an OpPhi instruction of // pointer type. @@ -373,7 +374,8 @@ TEST(TransformationAddOpPhiSynonymTest, VariablePointers) { .IsApplicable(context.get(), transformation_context)); // Add the VariablePointers capability back. - context.get()->AddCapability(spv::Capability::VariablePointers); + context.get()->get_feature_mgr()->AddCapability( + SpvCapabilityVariablePointers); // If the ids have pointer type, the storage class must be Workgroup or // StorageBuffer, but it is Function in this case. diff --git a/test/fuzz/transformation_add_synonym_test.cpp b/test/fuzz/transformation_add_synonym_test.cpp index 385590e6..ffcf1c9b 100644 --- a/test/fuzz/transformation_add_synonym_test.cpp +++ b/test/fuzz/transformation_add_synonym_test.cpp @@ -77,7 +77,7 @@ TEST(TransformationAddSynonymTest, NotApplicable) { MakeUnique(context.get()), validator_options); transformation_context.GetFactManager()->AddFactIdIsIrrelevant(24); - auto insert_before = MakeInstructionDescriptor(22, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(22, SpvOpReturn, 0); #ifndef NDEBUG ASSERT_DEATH( @@ -126,34 +126,34 @@ TEST(TransformationAddSynonymTest, NotApplicable) { .IsApplicable(context.get(), transformation_context)); // |insert_before| is invalid. - ASSERT_FALSE(TransformationAddSynonym( - 9, synonym_type, 40, - MakeInstructionDescriptor(25, spv::Op::OpStore, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddSynonym(9, synonym_type, 40, + MakeInstructionDescriptor(25, SpvOpStore, 0)) + .IsApplicable(context.get(), transformation_context)); // Can't insert before |insert_before|. + ASSERT_FALSE( + TransformationAddSynonym(9, synonym_type, 40, + MakeInstructionDescriptor(5, SpvOpLabel, 0)) + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddSynonym( 9, synonym_type, 40, - MakeInstructionDescriptor(5, spv::Op::OpLabel, 0)) + MakeInstructionDescriptor(22, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddSynonym( 9, synonym_type, 40, - MakeInstructionDescriptor(22, spv::Op::OpVariable, 0)) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationAddSynonym( - 9, synonym_type, 40, - MakeInstructionDescriptor(25, spv::Op::OpFunctionEnd, 0)) + MakeInstructionDescriptor(25, SpvOpFunctionEnd, 0)) .IsApplicable(context.get(), transformation_context)); // Domination rules are not satisfied. - ASSERT_FALSE(TransformationAddSynonym( - 27, synonym_type, 40, - MakeInstructionDescriptor(27, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationAddSynonym( - 27, synonym_type, 40, - MakeInstructionDescriptor(22, spv::Op::OpStore, 1)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddSynonym(27, synonym_type, 40, + MakeInstructionDescriptor(27, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationAddSynonym(27, synonym_type, 40, + MakeInstructionDescriptor(22, SpvOpStore, 1)) + .IsApplicable(context.get(), transformation_context)); } } @@ -212,7 +212,7 @@ TEST(TransformationAddSynonymTest, AddZeroSubZeroMulOne) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(5, SpvOpReturn, 0); uint32_t fresh_id = 50; for (auto synonym_type : {protobufs::TransformationAddSynonym::ADD_ZERO, @@ -374,7 +374,7 @@ TEST(TransformationAddSynonymTest, LogicalAndLogicalOr) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(5, SpvOpReturn, 0); uint32_t fresh_id = 50; for (auto synonym_type : {protobufs::TransformationAddSynonym::LOGICAL_AND, @@ -467,7 +467,7 @@ TEST(TransformationAddSynonymTest, LogicalAndConstantIsNotPresent) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(5, SpvOpReturn, 0); const auto synonym_type = protobufs::TransformationAddSynonym::LOGICAL_AND; // Required constant is not present in the module. @@ -505,7 +505,7 @@ TEST(TransformationAddSynonymTest, LogicalOrConstantIsNotPresent) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(5, SpvOpReturn, 0); const auto synonym_type = protobufs::TransformationAddSynonym::LOGICAL_OR; // Required constant is not present in the module. @@ -563,7 +563,7 @@ TEST(TransformationAddSynonymTest, CopyObject) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(5, SpvOpReturn, 0); const auto synonym_type = protobufs::TransformationAddSynonym::COPY_OBJECT; ASSERT_FALSE( @@ -666,7 +666,7 @@ TEST(TransformationAddSynonymTest, CopyBooleanConstants) { { TransformationAddSynonym copy_true( 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, - MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(5, SpvOpReturn, 0)); ASSERT_TRUE(copy_true.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(copy_true, context.get(), &transformation_context); @@ -687,7 +687,7 @@ TEST(TransformationAddSynonymTest, CopyBooleanConstants) { { TransformationAddSynonym copy_false( 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(100, SpvOpReturn, 0)); ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(copy_false, context.get(), &transformation_context); std::vector ids_for_which_synonyms_are_known = @@ -707,7 +707,7 @@ TEST(TransformationAddSynonymTest, CopyBooleanConstants) { { TransformationAddSynonym copy_false_again( 101, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, - MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(5, SpvOpReturn, 0)); ASSERT_TRUE( copy_false_again.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(copy_false_again, context.get(), @@ -730,7 +730,7 @@ TEST(TransformationAddSynonymTest, CopyBooleanConstants) { { TransformationAddSynonym copy_true_again( 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 103, - MakeInstructionDescriptor(102, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(102, SpvOpReturn, 0)); ASSERT_TRUE( copy_true_again.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(copy_true_again, context.get(), @@ -970,133 +970,128 @@ TEST(TransformationAddSynonymTest, CheckIllegalCases) { // Inapplicable because %18 is decorated. ASSERT_FALSE(TransformationAddSynonym( 18, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0)) + MakeInstructionDescriptor(21, SpvOpAccessChain, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because %77 is decorated. ASSERT_FALSE(TransformationAddSynonym( 77, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(77, spv::Op::OpBranch, 0)) + MakeInstructionDescriptor(77, SpvOpBranch, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because %80 is decorated. ASSERT_FALSE(TransformationAddSynonym( 80, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(77, spv::Op::OpIAdd, 0)) + MakeInstructionDescriptor(77, SpvOpIAdd, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because %84 is not available at the requested point - ASSERT_FALSE( - TransformationAddSynonym( - 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(32, spv::Op::OpCompositeExtract, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddSynonym( + 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, + MakeInstructionDescriptor(32, SpvOpCompositeExtract, 0)) + .IsApplicable(context.get(), transformation_context)); // Fine because %84 is available at the requested point - ASSERT_TRUE( - TransformationAddSynonym( - 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(32, spv::Op::OpCompositeConstruct, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationAddSynonym( + 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, + MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0)) + .IsApplicable(context.get(), transformation_context)); // Inapplicable because id %9 is already in use - ASSERT_FALSE( - TransformationAddSynonym( - 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 9, - MakeInstructionDescriptor(32, spv::Op::OpCompositeConstruct, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddSynonym( + 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 9, + MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0)) + .IsApplicable(context.get(), transformation_context)); // Inapplicable because the requested point does not exist ASSERT_FALSE(TransformationAddSynonym( 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(86, spv::Op::OpReturn, 2)) + MakeInstructionDescriptor(86, SpvOpReturn, 2)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because %9 is not in a function ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(9, spv::Op::OpTypeInt, 0)) + MakeInstructionDescriptor(9, SpvOpTypeInt, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right before, or inside, a chunk // of OpPhis ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(30, spv::Op::OpPhi, 0)) + MakeInstructionDescriptor(30, SpvOpPhi, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(99, spv::Op::OpPhi, 1)) + MakeInstructionDescriptor(99, SpvOpPhi, 1)) .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is just after a chunk of OpPhis. ASSERT_TRUE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(96, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); - - // Inapplicable because the insert point is right after an OpSelectionMerge - ASSERT_FALSE( - TransformationAddSynonym( - 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(58, spv::Op::OpBranchConditional, 0)) - .IsApplicable(context.get(), transformation_context)); - - // OK, because the insert point is right before the OpSelectionMerge - ASSERT_TRUE(TransformationAddSynonym( - 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(58, spv::Op::OpSelectionMerge, 0)) + MakeInstructionDescriptor(96, SpvOpAccessChain, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right after an OpSelectionMerge ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(43, spv::Op::OpSwitch, 0)) + MakeInstructionDescriptor(58, SpvOpBranchConditional, 0)) .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is right before the OpSelectionMerge ASSERT_TRUE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(43, spv::Op::OpSelectionMerge, 0)) + MakeInstructionDescriptor(58, SpvOpSelectionMerge, 0)) + .IsApplicable(context.get(), transformation_context)); + + // Inapplicable because the insert point is right after an OpSelectionMerge + ASSERT_FALSE(TransformationAddSynonym( + 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, + MakeInstructionDescriptor(43, SpvOpSwitch, 0)) + .IsApplicable(context.get(), transformation_context)); + + // OK, because the insert point is right before the OpSelectionMerge + ASSERT_TRUE(TransformationAddSynonym( + 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, + MakeInstructionDescriptor(43, SpvOpSelectionMerge, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because the insert point is right after an OpLoopMerge - ASSERT_FALSE( - TransformationAddSynonym( - 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(40, spv::Op::OpBranchConditional, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationAddSynonym( + 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, + MakeInstructionDescriptor(40, SpvOpBranchConditional, 0)) + .IsApplicable(context.get(), transformation_context)); // OK, because the insert point is right before the OpLoopMerge ASSERT_TRUE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(40, spv::Op::OpLoopMerge, 0)) + MakeInstructionDescriptor(40, SpvOpLoopMerge, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because id %300 does not exist ASSERT_FALSE(TransformationAddSynonym( 300, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(40, spv::Op::OpLoopMerge, 0)) + MakeInstructionDescriptor(40, SpvOpLoopMerge, 0)) .IsApplicable(context.get(), transformation_context)); // Inapplicable because the following instruction is OpVariable ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(180, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(180, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(181, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(181, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(182, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(182, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); // OK, because this is just past the group of OpVariable instructions. ASSERT_TRUE(TransformationAddSynonym( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, - MakeInstructionDescriptor(182, spv::Op::OpAccessChain, 0)) + MakeInstructionDescriptor(182, SpvOpAccessChain, 0)) .IsApplicable(context.get(), transformation_context)); } @@ -1168,25 +1163,25 @@ TEST(TransformationAddSynonymTest, MiscellaneousCopies) { std::vector transformations = { TransformationAddSynonym( 19, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, - MakeInstructionDescriptor(22, spv::Op::OpStore, 0)), + MakeInstructionDescriptor(22, SpvOpStore, 0)), TransformationAddSynonym( 22, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), + MakeInstructionDescriptor(22, SpvOpCopyObject, 0)), TransformationAddSynonym( 12, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), + MakeInstructionDescriptor(22, SpvOpCopyObject, 0)), TransformationAddSynonym( 11, protobufs::TransformationAddSynonym::COPY_OBJECT, 103, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), + MakeInstructionDescriptor(22, SpvOpCopyObject, 0)), TransformationAddSynonym( 16, protobufs::TransformationAddSynonym::COPY_OBJECT, 104, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), + MakeInstructionDescriptor(22, SpvOpCopyObject, 0)), TransformationAddSynonym( 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 105, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), + MakeInstructionDescriptor(22, SpvOpCopyObject, 0)), TransformationAddSynonym( 17, protobufs::TransformationAddSynonym::COPY_OBJECT, 106, - MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0))}; + MakeInstructionDescriptor(22, SpvOpCopyObject, 0))}; for (auto& transformation : transformations) { ASSERT_TRUE( @@ -1278,7 +1273,7 @@ TEST(TransformationAddSynonymTest, DoNotCopyNullPointers) { // Illegal to copy null. ASSERT_FALSE(TransformationAddSynonym( 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, - MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(5, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); } @@ -1317,13 +1312,13 @@ TEST(TransformationAddSynonymTest, PropagateIrrelevantPointeeFact) { TransformationAddSynonym transformation1( 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, - MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(9, SpvOpReturn, 0)); TransformationAddSynonym transformation2( 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, - MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(9, SpvOpReturn, 0)); TransformationAddSynonym transformation3( 100, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, - MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); + MakeInstructionDescriptor(9, SpvOpReturn, 0)); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); @@ -1402,7 +1397,7 @@ TEST(TransformationAddSynonymTest, DoNotCopyOpSampledImage) { ASSERT_FALSE( TransformationAddSynonym( 216, protobufs::TransformationAddSynonym::COPY_OBJECT, 500, - MakeInstructionDescriptor(217, spv::Op::OpImageSampleImplicitLod, 0)) + MakeInstructionDescriptor(217, SpvOpImageSampleImplicitLod, 0)) .IsApplicable(context.get(), transformation_context)); } @@ -1439,7 +1434,7 @@ TEST(TransformationAddSynonymTest, DoNotCopyVoidRunctionResult) { MakeUnique(context.get()), validator_options); ASSERT_FALSE(TransformationAddSynonym( 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 500, - MakeInstructionDescriptor(8, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(8, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); } @@ -1480,7 +1475,7 @@ TEST(TransformationAddSynonymTest, HandlesDeadBlocks) { transformation_context.GetFactManager()->AddFactBlockIsDead(9); - auto insert_before = MakeInstructionDescriptor(9, spv::Op::OpBranch, 0); + auto insert_before = MakeInstructionDescriptor(9, SpvOpBranch, 0); ASSERT_FALSE(TransformationAddSynonym( 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, diff --git a/test/fuzz/transformation_add_type_array_test.cpp b/test/fuzz/transformation_add_type_array_test.cpp index ab480fba..2ef8200e 100644 --- a/test/fuzz/transformation_add_type_array_test.cpp +++ b/test/fuzz/transformation_add_type_array_test.cpp @@ -99,7 +99,7 @@ TEST(TransformationAddTypeArrayTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeArray, + ASSERT_EQ(SpvOpTypeArray, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsArray()); } @@ -113,7 +113,7 @@ TEST(TransformationAddTypeArrayTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeArray, + ASSERT_EQ(SpvOpTypeArray, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsArray()); } diff --git a/test/fuzz/transformation_add_type_boolean_test.cpp b/test/fuzz/transformation_add_type_boolean_test.cpp index 388d4f65..a8e657ba 100644 --- a/test/fuzz/transformation_add_type_boolean_test.cpp +++ b/test/fuzz/transformation_add_type_boolean_test.cpp @@ -57,8 +57,7 @@ TEST(TransformationAddTypeBooleanTest, BasicTest) { ASSERT_TRUE( add_type_bool.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(add_type_bool, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeBool, - context->get_def_use_mgr()->GetDef(100)->opcode()); + ASSERT_EQ(SpvOpTypeBool, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsBool()); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, kConsoleMessageConsumer)); diff --git a/test/fuzz/transformation_add_type_float_test.cpp b/test/fuzz/transformation_add_type_float_test.cpp index 135190ac..9275bec1 100644 --- a/test/fuzz/transformation_add_type_float_test.cpp +++ b/test/fuzz/transformation_add_type_float_test.cpp @@ -74,7 +74,7 @@ TEST(TransformationAddTypeFloatTest, IsApplicable) { // By default, SPIR-V does not support 64-bit float types. // Below we add such capability, so the test should now pass. - context.get()->AddCapability(spv::Capability::Float64); + context.get()->get_feature_mgr()->AddCapability(SpvCapabilityFloat64); ASSERT_TRUE(TransformationAddTypeFloat(7, 64).IsApplicable( context.get(), transformation_context)); @@ -120,8 +120,7 @@ TEST(TransformationAddTypeFloatTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(6)); ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(6)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeFloat, - context->get_def_use_mgr()->GetDef(6)->opcode()); + ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(6)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(6)->AsFloat()); // Adds 32-bit float type. @@ -129,8 +128,7 @@ TEST(TransformationAddTypeFloatTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(7)); ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(7)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeFloat, - context->get_def_use_mgr()->GetDef(7)->opcode()); + ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(7)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(7)->AsFloat()); // Adds 64-bit float type. @@ -138,8 +136,7 @@ TEST(TransformationAddTypeFloatTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(8)); ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(8)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeFloat, - context->get_def_use_mgr()->GetDef(8)->opcode()); + ASSERT_EQ(SpvOpTypeFloat, context->get_def_use_mgr()->GetDef(8)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(8)->AsFloat()); std::string variant_shader = R"( diff --git a/test/fuzz/transformation_add_type_int_test.cpp b/test/fuzz/transformation_add_type_int_test.cpp index e31730cc..4cbfed0f 100644 --- a/test/fuzz/transformation_add_type_int_test.cpp +++ b/test/fuzz/transformation_add_type_int_test.cpp @@ -88,13 +88,13 @@ TEST(TransformationAddTypeIntTest, IsApplicable) { // By default SPIR-V does not support 16-bit integers. // Below we add such capability, so the test should now be successful. - context.get()->AddCapability(spv::Capability::Int16); + context.get()->get_feature_mgr()->AddCapability(SpvCapabilityInt16); ASSERT_TRUE(TransformationAddTypeInt(7, 16, true) .IsApplicable(context.get(), transformation_context)); // By default SPIR-V does not support 64-bit integers. // Below we add such capability, so the test should now pass. - context.get()->AddCapability(spv::Capability::Int64); + context.get()->get_feature_mgr()->AddCapability(SpvCapabilityInt64); ASSERT_TRUE(TransformationAddTypeInt(7, 64, true) .IsApplicable(context.get(), transformation_context)); @@ -147,8 +147,7 @@ TEST(TransformationAddTypeIntTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(6)); ASSERT_EQ(nullptr, context->get_type_mgr()->GetType(6)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeInt, - context->get_def_use_mgr()->GetDef(6)->opcode()); + ASSERT_EQ(SpvOpTypeInt, context->get_def_use_mgr()->GetDef(6)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(6)->AsInteger()); // Adds signed 16-bit integer type. diff --git a/test/fuzz/transformation_add_type_matrix_test.cpp b/test/fuzz/transformation_add_type_matrix_test.cpp index 9b10dbd6..df0111e2 100644 --- a/test/fuzz/transformation_add_type_matrix_test.cpp +++ b/test/fuzz/transformation_add_type_matrix_test.cpp @@ -72,7 +72,7 @@ TEST(TransformationAddTypeMatrixTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeMatrix, + ASSERT_EQ(SpvOpTypeMatrix, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsMatrix()); } diff --git a/test/fuzz/transformation_add_type_pointer_test.cpp b/test/fuzz/transformation_add_type_pointer_test.cpp index 5e25f0ef..b9072e3c 100644 --- a/test/fuzz/transformation_add_type_pointer_test.cpp +++ b/test/fuzz/transformation_add_type_pointer_test.cpp @@ -103,28 +103,28 @@ TEST(TransformationAddTypePointerTest, BasicTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto bad_type_id_does_not_exist = - TransformationAddTypePointer(100, spv::StorageClass::Function, 101); + TransformationAddTypePointer(100, SpvStorageClassFunction, 101); auto bad_type_id_is_not_type = - TransformationAddTypePointer(100, spv::StorageClass::Function, 23); + TransformationAddTypePointer(100, SpvStorageClassFunction, 23); auto bad_result_id_is_not_fresh = - TransformationAddTypePointer(17, spv::StorageClass::Function, 21); + TransformationAddTypePointer(17, SpvStorageClassFunction, 21); auto good_new_private_pointer_to_t = - TransformationAddTypePointer(101, spv::StorageClass::Private, 7); + TransformationAddTypePointer(101, SpvStorageClassPrivate, 7); auto good_new_uniform_pointer_to_t = - TransformationAddTypePointer(102, spv::StorageClass::Uniform, 7); + TransformationAddTypePointer(102, SpvStorageClassUniform, 7); auto good_another_function_pointer_to_s = - TransformationAddTypePointer(103, spv::StorageClass::Function, 8); + TransformationAddTypePointer(103, SpvStorageClassFunction, 8); auto good_new_uniform_pointer_to_s = - TransformationAddTypePointer(104, spv::StorageClass::Uniform, 8); + TransformationAddTypePointer(104, SpvStorageClassUniform, 8); auto good_another_private_pointer_to_float = - TransformationAddTypePointer(105, spv::StorageClass::Private, 21); + TransformationAddTypePointer(105, SpvStorageClassPrivate, 21); auto good_new_private_pointer_to_private_pointer_to_float = - TransformationAddTypePointer(106, spv::StorageClass::Private, 105); + TransformationAddTypePointer(106, SpvStorageClassPrivate, 105); auto good_new_uniform_pointer_to_vec2 = - TransformationAddTypePointer(107, spv::StorageClass::Uniform, 24); + TransformationAddTypePointer(107, SpvStorageClassUniform, 24); auto good_new_private_pointer_to_uniform_pointer_to_vec2 = - TransformationAddTypePointer(108, spv::StorageClass::Private, 107); + TransformationAddTypePointer(108, SpvStorageClassPrivate, 107); ASSERT_FALSE(bad_type_id_does_not_exist.IsApplicable(context.get(), transformation_context)); @@ -143,7 +143,7 @@ TEST(TransformationAddTypePointerTest, BasicTest) { &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( context.get(), validator_options, kConsoleMessageConsumer)); - ASSERT_EQ(spv::Op::OpTypePointer, + ASSERT_EQ(SpvOpTypePointer, context->get_def_use_mgr()->GetDef(101)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(101)->AsPointer()); } diff --git a/test/fuzz/transformation_add_type_struct_test.cpp b/test/fuzz/transformation_add_type_struct_test.cpp index 1440b4a4..7fb91ab4 100644 --- a/test/fuzz/transformation_add_type_struct_test.cpp +++ b/test/fuzz/transformation_add_type_struct_test.cpp @@ -72,7 +72,7 @@ TEST(TransformationAddTypeStructTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeStruct, + ASSERT_EQ(SpvOpTypeStruct, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsStruct()); } diff --git a/test/fuzz/transformation_add_type_vector_test.cpp b/test/fuzz/transformation_add_type_vector_test.cpp index b39c1c98..755bc4a8 100644 --- a/test/fuzz/transformation_add_type_vector_test.cpp +++ b/test/fuzz/transformation_add_type_vector_test.cpp @@ -66,7 +66,7 @@ TEST(TransformationAddTypeVectorTest, BasicTest) { transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpTypeVector, + ASSERT_EQ(SpvOpTypeVector, context->get_def_use_mgr()->GetDef(100)->opcode()); ASSERT_NE(nullptr, context->get_type_mgr()->GetType(100)->AsVector()); } diff --git a/test/fuzz/transformation_adjust_branch_weights_test.cpp b/test/fuzz/transformation_adjust_branch_weights_test.cpp index 2b532bf3..5984a3e9 100644 --- a/test/fuzz/transformation_adjust_branch_weights_test.cpp +++ b/test/fuzz/transformation_adjust_branch_weights_test.cpp @@ -108,7 +108,7 @@ TEST(TransformationAdjustBranchWeightsTest, IsApplicableTest) { MakeUnique(context.get()), validator_options); // Tests OpBranchConditional instruction with weights. auto instruction_descriptor = - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0); auto transformation = TransformationAdjustBranchWeights(instruction_descriptor, {0, 1}); ASSERT_TRUE( @@ -116,7 +116,7 @@ TEST(TransformationAdjustBranchWeightsTest, IsApplicableTest) { // Tests the two branch weights equal to 0. instruction_descriptor = - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {0, 0}); #ifndef NDEBUG @@ -127,14 +127,14 @@ TEST(TransformationAdjustBranchWeightsTest, IsApplicableTest) { // Tests 32-bit unsigned integer overflow. instruction_descriptor = - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {UINT32_MAX, 0}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {1, UINT32_MAX}); #ifndef NDEBUG @@ -145,26 +145,26 @@ TEST(TransformationAdjustBranchWeightsTest, IsApplicableTest) { // Tests OpBranchConditional instruction with no weights. instruction_descriptor = - MakeInstructionDescriptor(21, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(21, SpvOpBranchConditional, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {0, 1}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); // Tests non-OpBranchConditional instructions. - instruction_descriptor = MakeInstructionDescriptor(2, spv::Op::OpTypeVoid, 0); + instruction_descriptor = MakeInstructionDescriptor(2, SpvOpTypeVoid, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {5, 6}); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instruction_descriptor = MakeInstructionDescriptor(20, spv::Op::OpLabel, 0); + instruction_descriptor = MakeInstructionDescriptor(20, SpvOpLabel, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {1, 2}); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instruction_descriptor = MakeInstructionDescriptor(49, spv::Op::OpIAdd, 0); + instruction_descriptor = MakeInstructionDescriptor(49, SpvOpIAdd, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {1, 2}); ASSERT_FALSE( @@ -255,13 +255,13 @@ TEST(TransformationAdjustBranchWeightsTest, ApplyTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0); auto transformation = TransformationAdjustBranchWeights(instruction_descriptor, {5, 6}); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(21, spv::Op::OpBranchConditional, 0); + MakeInstructionDescriptor(21, SpvOpBranchConditional, 0); transformation = TransformationAdjustBranchWeights(instruction_descriptor, {7, 8}); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_composite_construct_test.cpp b/test/fuzz/transformation_composite_construct_test.cpp index c4eef872..3c5f7310 100644 --- a/test/fuzz/transformation_composite_construct_test.cpp +++ b/test/fuzz/transformation_composite_construct_test.cpp @@ -136,17 +136,16 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { MakeUnique(context.get()), validator_options); // Make a vec2[3] TransformationCompositeConstruct make_vec2_array_length_3( - 37, {41, 45, 27}, - MakeInstructionDescriptor(46, spv::Op::OpAccessChain, 0), 200); + 37, {41, 45, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), + 200); // Bad: there are too many components TransformationCompositeConstruct make_vec2_array_length_3_bad( - 37, {41, 45, 27, 27}, - MakeInstructionDescriptor(46, spv::Op::OpAccessChain, 0), 200); + 37, {41, 45, 27, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), + 200); // The first component does not correspond to an instruction with a result // type so this check should return false. TransformationCompositeConstruct make_vec2_array_length_3_nores( - 37, {2, 45, 27}, MakeInstructionDescriptor(46, spv::Op::OpAccessChain, 0), - 200); + 37, {2, 45, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 200); ASSERT_TRUE(make_vec2_array_length_3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(make_vec2_array_length_3_bad.IsApplicable( @@ -160,7 +159,7 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { uint32_t num_uses_of_27_before = context->get_def_use_mgr()->NumUses(27); ApplyAndCheckFreshIds(make_vec2_array_length_3, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpCompositeConstruct, + ASSERT_EQ(SpvOpCompositeConstruct, context->get_def_use_mgr()->GetDef(200)->opcode()); ASSERT_EQ(34, context->get_instr_block(200)->id()); ASSERT_EQ(num_uses_of_41_before + 1, context->get_def_use_mgr()->NumUses(41)); @@ -177,10 +176,10 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { // Make a float[2] TransformationCompositeConstruct make_float_array_length_2( - 9, {24, 40}, MakeInstructionDescriptor(71, spv::Op::OpStore, 0), 201); + 9, {24, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201); // Bad: %41 does not have type float TransformationCompositeConstruct make_float_array_length_2_bad( - 9, {41, 40}, MakeInstructionDescriptor(71, spv::Op::OpStore, 0), 201); + 9, {41, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201); ASSERT_TRUE(make_float_array_length_2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(make_float_array_length_2_bad.IsApplicable( @@ -196,12 +195,12 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { // Make a bool[3] TransformationCompositeConstruct make_bool_array_length_3( - 47, {33, 50, 50}, - MakeInstructionDescriptor(33, spv::Op::OpSelectionMerge, 0), 202); + 47, {33, 50, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0), + 202); // Bad: %54 is not available at the desired program point. TransformationCompositeConstruct make_bool_array_length_3_bad( - 47, {33, 54, 50}, - MakeInstructionDescriptor(33, spv::Op::OpSelectionMerge, 0), 202); + 47, {33, 54, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0), + 202); ASSERT_TRUE(make_bool_array_length_3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(make_bool_array_length_3_bad.IsApplicable( @@ -219,10 +218,10 @@ TEST(TransformationCompositeConstructTest, ConstructArrays) { // make a uvec3[2][2] TransformationCompositeConstruct make_uvec3_array_length_2_2( - 58, {69, 100}, MakeInstructionDescriptor(64, spv::Op::OpStore, 0), 203); + 58, {69, 100}, MakeInstructionDescriptor(64, SpvOpStore, 0), 203); // Bad: Skip count 100 is too large. TransformationCompositeConstruct make_uvec3_array_length_2_2_bad( - 58, {33, 54}, MakeInstructionDescriptor(64, spv::Op::OpStore, 100), 203); + 58, {33, 54}, MakeInstructionDescriptor(64, SpvOpStore, 100), 203); ASSERT_TRUE(make_uvec3_array_length_2_2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable( @@ -426,17 +425,14 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) { MakeUnique(context.get()), validator_options); // make a mat3x4 TransformationCompositeConstruct make_mat34( - 32, {25, 28, 31}, MakeInstructionDescriptor(31, spv::Op::OpReturn, 0), - 200); + 32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); // Bad: %35 is mat4x3, not mat3x4. TransformationCompositeConstruct make_mat34_bad( - 35, {25, 28, 31}, MakeInstructionDescriptor(31, spv::Op::OpReturn, 0), - 200); + 35, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); // The first component does not correspond to an instruction with a result // type so this check should return false. TransformationCompositeConstruct make_mat34_nores( - 32, {2, 28, 31}, MakeInstructionDescriptor(31, spv::Op::OpReturn, 0), - 200); + 32, {2, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); ASSERT_TRUE(make_mat34.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_mat34_bad.IsApplicable(context.get(), transformation_context)); @@ -454,12 +450,10 @@ TEST(TransformationCompositeConstructTest, ConstructMatrices) { // make a mat4x3 TransformationCompositeConstruct make_mat43( - 35, {11, 13, 16, 100}, MakeInstructionDescriptor(31, spv::Op::OpStore, 0), - 201); + 35, {11, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201); // Bad: %25 does not match the matrix's column type. TransformationCompositeConstruct make_mat43_bad( - 35, {25, 13, 16, 100}, MakeInstructionDescriptor(31, spv::Op::OpStore, 0), - 201); + 35, {25, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201); ASSERT_TRUE(make_mat43.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_mat43_bad.IsApplicable(context.get(), transformation_context)); @@ -650,16 +644,14 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) { MakeUnique(context.get()), validator_options); // make an Inner TransformationCompositeConstruct make_inner( - 9, {25, 19}, MakeInstructionDescriptor(57, spv::Op::OpAccessChain, 0), - 200); + 9, {25, 19}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200); // Bad: Too few fields to make the struct. TransformationCompositeConstruct make_inner_bad( - 9, {25}, MakeInstructionDescriptor(57, spv::Op::OpAccessChain, 0), 200); + 9, {25}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200); // The first component does not correspond to an instruction with a result // type so this check should return false. TransformationCompositeConstruct make_inner_nores( - 9, {2, 19}, MakeInstructionDescriptor(57, spv::Op::OpAccessChain, 0), - 200); + 9, {2, 19}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200); ASSERT_TRUE(make_inner.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_inner_bad.IsApplicable(context.get(), transformation_context)); @@ -675,12 +667,12 @@ TEST(TransformationCompositeConstructTest, ConstructStructs) { // make an Outer TransformationCompositeConstruct make_outer( - 33, {46, 200, 56}, - MakeInstructionDescriptor(200, spv::Op::OpAccessChain, 0), 201); + 33, {46, 200, 56}, MakeInstructionDescriptor(200, SpvOpAccessChain, 0), + 201); // Bad: %200 is not available at the desired program point. TransformationCompositeConstruct make_outer_bad( 33, {46, 200, 56}, - MakeInstructionDescriptor(200, spv::Op::OpCompositeConstruct, 0), 201); + MakeInstructionDescriptor(200, SpvOpCompositeConstruct, 0), 201); ASSERT_TRUE(make_outer.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_outer_bad.IsApplicable(context.get(), transformation_context)); @@ -981,10 +973,10 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); TransformationCompositeConstruct make_vec2( - 7, {17, 11}, MakeInstructionDescriptor(100, spv::Op::OpStore, 0), 200); + 7, {17, 11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200); // Bad: not enough data for a vec2 TransformationCompositeConstruct make_vec2_bad( - 7, {11}, MakeInstructionDescriptor(100, spv::Op::OpStore, 0), 200); + 7, {11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200); ASSERT_TRUE(make_vec2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_vec2_bad.IsApplicable(context.get(), transformation_context)); @@ -997,12 +989,12 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1}))); TransformationCompositeConstruct make_vec3( - 25, {12, 32}, - MakeInstructionDescriptor(35, spv::Op::OpCompositeConstruct, 0), 201); + 25, {12, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), + 201); // Bad: too much data for a vec3 TransformationCompositeConstruct make_vec3_bad( 25, {12, 32, 32}, - MakeInstructionDescriptor(35, spv::Op::OpCompositeConstruct, 0), 201); + MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), 201); ASSERT_TRUE(make_vec3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_vec3_bad.IsApplicable(context.get(), transformation_context)); @@ -1017,12 +1009,12 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2}))); TransformationCompositeConstruct make_vec4( - 44, {32, 32, 10, 11}, - MakeInstructionDescriptor(75, spv::Op::OpAccessChain, 0), 202); + 44, {32, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0), + 202); // Bad: id 48 is not available at the insertion points TransformationCompositeConstruct make_vec4_bad( - 44, {48, 32, 10, 11}, - MakeInstructionDescriptor(75, spv::Op::OpAccessChain, 0), 202); + 44, {48, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0), + 202); ASSERT_TRUE(make_vec4.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_vec4_bad.IsApplicable(context.get(), transformation_context)); @@ -1039,10 +1031,10 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3}))); TransformationCompositeConstruct make_ivec2( - 51, {126, 120}, MakeInstructionDescriptor(128, spv::Op::OpLoad, 0), 203); + 51, {126, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203); // Bad: if 128 is not available at the instruction that defines 128 TransformationCompositeConstruct make_ivec2_bad( - 51, {128, 120}, MakeInstructionDescriptor(128, spv::Op::OpLoad, 0), 203); + 51, {128, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203); ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_ivec2_bad.IsApplicable(context.get(), transformation_context)); @@ -1055,12 +1047,12 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(120, {}), MakeDataDescriptor(203, {1}))); TransformationCompositeConstruct make_ivec3( - 114, {56, 117, 56}, - MakeInstructionDescriptor(66, spv::Op::OpAccessChain, 0), 204); + 114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0), + 204); // Bad because 1300 is not an id TransformationCompositeConstruct make_ivec3_bad( - 114, {56, 117, 1300}, - MakeInstructionDescriptor(66, spv::Op::OpAccessChain, 0), 204); + 114, {56, 117, 1300}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0), + 204); ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_ivec3_bad.IsApplicable(context.get(), transformation_context)); @@ -1075,12 +1067,12 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2}))); TransformationCompositeConstruct make_ivec4( - 122, {56, 117, 117, 117}, - MakeInstructionDescriptor(66, spv::Op::OpIAdd, 0), 205); + 122, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0), + 205); // Bad because 86 is the wrong type. TransformationCompositeConstruct make_ivec4_bad( - 86, {56, 117, 117, 117}, - MakeInstructionDescriptor(66, spv::Op::OpIAdd, 0), 205); + 86, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0), + 205); ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_ivec4_bad.IsApplicable(context.get(), transformation_context)); @@ -1097,11 +1089,9 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(117, {}), MakeDataDescriptor(205, {3}))); TransformationCompositeConstruct make_uvec2( - 86, {18, 38}, MakeInstructionDescriptor(133, spv::Op::OpAccessChain, 0), - 206); + 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206); TransformationCompositeConstruct make_uvec2_bad( - 86, {18, 38}, MakeInstructionDescriptor(133, spv::Op::OpAccessChain, 200), - 206); + 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 200), 206); ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_uvec2_bad.IsApplicable(context.get(), transformation_context)); @@ -1114,12 +1104,10 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1}))); TransformationCompositeConstruct make_uvec3( - 59, {14, 18, 136}, MakeInstructionDescriptor(137, spv::Op::OpReturn, 0), - 207); + 59, {14, 18, 136}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207); // Bad because 1300 is not an id TransformationCompositeConstruct make_uvec3_bad( - 59, {14, 18, 1300}, MakeInstructionDescriptor(137, spv::Op::OpReturn, 0), - 207); + 59, {14, 18, 1300}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207); ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_uvec3_bad.IsApplicable(context.get(), transformation_context)); @@ -1135,11 +1123,11 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { TransformationCompositeConstruct make_uvec4( 131, {14, 18, 136, 136}, - MakeInstructionDescriptor(137, spv::Op::OpAccessChain, 0), 208); + MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208); // Bad because 86 is the wrong type. TransformationCompositeConstruct make_uvec4_bad( 86, {14, 18, 136, 136}, - MakeInstructionDescriptor(137, spv::Op::OpAccessChain, 0), 208); + MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208); ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_uvec4_bad.IsApplicable(context.get(), transformation_context)); @@ -1161,7 +1149,7 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { 111, 41, }, - MakeInstructionDescriptor(75, spv::Op::OpAccessChain, 0), 209); + MakeInstructionDescriptor(75, SpvOpAccessChain, 0), 209); // Bad because 0 is not a valid base instruction id TransformationCompositeConstruct make_bvec2_bad( 102, @@ -1169,7 +1157,7 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { 111, 41, }, - MakeInstructionDescriptor(0, spv::Op::OpExtInstImport, 0), 209); + MakeInstructionDescriptor(0, SpvOpExtInstImport, 0), 209); ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_bvec2_bad.IsApplicable(context.get(), transformation_context)); @@ -1182,10 +1170,10 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1}))); TransformationCompositeConstruct make_bvec3( - 93, {108, 73}, MakeInstructionDescriptor(108, spv::Op::OpStore, 0), 210); + 93, {108, 73}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210); // Bad because there are too many components for a bvec3 TransformationCompositeConstruct make_bvec3_bad( - 93, {108, 108}, MakeInstructionDescriptor(108, spv::Op::OpStore, 0), 210); + 93, {108, 108}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210); ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_bvec3_bad.IsApplicable(context.get(), transformation_context)); @@ -1200,11 +1188,10 @@ TEST(TransformationCompositeConstructTest, ConstructVectors) { MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2}))); TransformationCompositeConstruct make_bvec4( - 70, {108, 108}, MakeInstructionDescriptor(108, spv::Op::OpBranch, 0), - 211); + 70, {108, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211); // Bad because 21 is a type, not a result id TransformationCompositeConstruct make_bvec4_bad( - 70, {21, 108}, MakeInstructionDescriptor(108, spv::Op::OpBranch, 0), 211); + 70, {21, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211); ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( make_bvec4_bad.IsApplicable(context.get(), transformation_context)); @@ -1490,8 +1477,7 @@ TEST(TransformationCompositeConstructTest, AddSynonymsForRelevantIds) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); TransformationCompositeConstruct transformation( - 32, {25, 28, 31}, MakeInstructionDescriptor(31, spv::Op::OpReturn, 0), - 200); + 32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1576,8 +1562,7 @@ TEST(TransformationCompositeConstructTest, DontAddSynonymsForIrrelevantIds) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(25); TransformationCompositeConstruct transformation( - 32, {25, 28, 31}, MakeInstructionDescriptor(31, spv::Op::OpReturn, 0), - 200); + 32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1633,7 +1618,7 @@ TEST(TransformationCompositeConstructTest, DontAddSynonymsInDeadBlock) { transformation_context.GetFactManager()->AddFactBlockIsDead(15); TransformationCompositeConstruct transformation( - 7, {10, 11}, MakeInstructionDescriptor(15, spv::Op::OpBranch, 0), 100); + 7, {10, 11}, MakeInstructionDescriptor(15, SpvOpBranch, 0), 100); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1675,7 +1660,7 @@ TEST(TransformationCompositeConstructTest, OneIrrelevantComponent) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(8); TransformationCompositeConstruct transformation( - 7, {8, 9, 10}, MakeInstructionDescriptor(5, spv::Op::OpReturn, 0), 100); + 7, {8, 9, 10}, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1722,7 +1707,7 @@ TEST(TransformationCompositeConstructTest, IrrelevantVec2ThenFloat) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(10); TransformationCompositeConstruct transformation( - 8, {10, 9}, MakeInstructionDescriptor(5, spv::Op::OpReturn, 0), 100); + 8, {10, 9}, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_composite_extract_test.cpp b/test/fuzz/transformation_composite_extract_test.cpp index d468e41d..1df55918 100644 --- a/test/fuzz/transformation_composite_extract_test.cpp +++ b/test/fuzz/transformation_composite_extract_test.cpp @@ -102,49 +102,47 @@ TEST(TransformationCompositeExtractTest, BasicTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Instruction does not exist. - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(36, spv::Op::OpIAdd, 0), 200, 101, {0}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(36, SpvOpIAdd, 0), 200, 101, {0}) + .IsApplicable(context.get(), transformation_context)); // Id for composite is not a composite. ASSERT_FALSE( TransformationCompositeExtract( - MakeInstructionDescriptor(37, spv::Op::OpAccessChain, 0), 200, 32, {}) + MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 200, 32, {}) .IsApplicable(context.get(), transformation_context)); // Composite does not dominate instruction being inserted before. - ASSERT_FALSE(TransformationCompositeExtract( - MakeInstructionDescriptor(37, spv::Op::OpAccessChain, 0), - 200, 101, {0}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationCompositeExtract( + MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 200, 101, {0}) + .IsApplicable(context.get(), transformation_context)); // Too many indices for extraction from struct composite. - ASSERT_FALSE(TransformationCompositeExtract( - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0), - 200, 101, {0, 0}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationCompositeExtract( + MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 200, 101, {0, 0}) + .IsApplicable(context.get(), transformation_context)); // Too many indices for extraction from struct composite. - ASSERT_FALSE(TransformationCompositeExtract( - MakeInstructionDescriptor(13, spv::Op::OpIEqual, 0), 200, - 104, {0, 0, 0}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationCompositeExtract( + MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 0, 0}) + .IsApplicable(context.get(), transformation_context)); // Out of bounds index for extraction from struct composite. ASSERT_FALSE( TransformationCompositeExtract( - MakeInstructionDescriptor(13, spv::Op::OpIEqual, 0), 200, 104, {0, 3}) + MakeInstructionDescriptor(13, SpvOpIEqual, 0), 200, 104, {0, 3}) .IsApplicable(context.get(), transformation_context)); // Result id already used. - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(35, spv::Op::OpFAdd, 0), 80, 103, {0}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(35, SpvOpFAdd, 0), 80, 103, {0}) + .IsApplicable(context.get(), transformation_context)); TransformationCompositeExtract transformation_1( - MakeInstructionDescriptor(36, spv::Op::OpConvertFToS, 0), 201, 100, {2}); + MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2}); ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(201)); ASSERT_EQ(nullptr, context->get_instr_block(201)); uint32_t num_uses_of_100_before = context->get_def_use_mgr()->NumUses(100); @@ -152,7 +150,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { transformation_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_1, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpCompositeExtract, + ASSERT_EQ(SpvOpCompositeExtract, context->get_def_use_mgr()->GetDef(201)->opcode()); ASSERT_EQ(15, context->get_instr_block(201)->id()); ASSERT_EQ(num_uses_of_100_before + 1, @@ -161,8 +159,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { kConsoleMessageConsumer)); TransformationCompositeExtract transformation_2( - MakeInstructionDescriptor(37, spv::Op::OpAccessChain, 0), 202, 104, - {0, 2}); + MakeInstructionDescriptor(37, SpvOpAccessChain, 0), 202, 104, {0, 2}); ASSERT_TRUE( transformation_2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_2, context.get(), @@ -171,7 +168,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { kConsoleMessageConsumer)); TransformationCompositeExtract transformation_3( - MakeInstructionDescriptor(29, spv::Op::OpAccessChain, 0), 203, 104, {0}); + MakeInstructionDescriptor(29, SpvOpAccessChain, 0), 203, 104, {0}); ASSERT_TRUE( transformation_3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_3, context.get(), @@ -180,7 +177,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { kConsoleMessageConsumer)); TransformationCompositeExtract transformation_4( - MakeInstructionDescriptor(24, spv::Op::OpStore, 0), 204, 101, {0}); + MakeInstructionDescriptor(24, SpvOpStore, 0), 204, 101, {0}); ASSERT_TRUE( transformation_4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_4, context.get(), @@ -189,7 +186,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { kConsoleMessageConsumer)); TransformationCompositeExtract transformation_5( - MakeInstructionDescriptor(29, spv::Op::OpBranch, 0), 205, 102, {2}); + MakeInstructionDescriptor(29, SpvOpBranch, 0), 205, 102, {2}); ASSERT_TRUE( transformation_5.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_5, context.get(), @@ -198,7 +195,7 @@ TEST(TransformationCompositeExtractTest, BasicTest) { kConsoleMessageConsumer)); TransformationCompositeExtract transformation_6( - MakeInstructionDescriptor(37, spv::Op::OpReturn, 0), 206, 103, {1}); + MakeInstructionDescriptor(37, SpvOpReturn, 0), 206, 103, {1}); ASSERT_TRUE( transformation_6.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_6, context.get(), @@ -381,50 +378,45 @@ TEST(TransformationCompositeExtractTest, IllegalInsertionPoints) { // Cannot insert before the OpVariables of a function. ASSERT_FALSE( TransformationCompositeExtract( - MakeInstructionDescriptor(101, spv::Op::OpVariable, 0), 200, 14, {0}) + MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, {0}) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationCompositeExtract( - MakeInstructionDescriptor(101, spv::Op::OpVariable, 1), 200, 14, {1}) + MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, {1}) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationCompositeExtract( - MakeInstructionDescriptor(102, spv::Op::OpVariable, 0), 200, 14, {1}) + MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, {1}) .IsApplicable(context.get(), transformation_context)); // OK to insert right after the OpVariables. - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(102, spv::Op::OpBranch, 1), 200, 14, {1}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, {1}) + .IsApplicable(context.get(), transformation_context)); // Cannot insert before the OpPhis of a block. - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(60, spv::Op::OpPhi, 0), 200, 14, {2}) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(59, spv::Op::OpPhi, 0), 200, 14, {3}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(60, SpvOpPhi, 0), 200, 14, {2}) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(59, SpvOpPhi, 0), 200, 14, {3}) + .IsApplicable(context.get(), transformation_context)); // OK to insert after the OpPhis. - ASSERT_TRUE(TransformationCompositeExtract( - MakeInstructionDescriptor(59, spv::Op::OpAccessChain, 0), 200, - 14, {3}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationCompositeExtract( + MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14, {3}) + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpLoopMerge - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0), 200, - 14, {3}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0), + 200, 14, {3}) + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpSelectionMerge - ASSERT_FALSE( - TransformationCompositeExtract( - MakeInstructionDescriptor(21, spv::Op::OpBranchConditional, 0), 200, - 14, {2}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationCompositeExtract( + MakeInstructionDescriptor(21, SpvOpBranchConditional, 0), + 200, 14, {2}) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationCompositeExtractTest, AddSynonymsForRelevantIds) { @@ -506,7 +498,7 @@ TEST(TransformationCompositeExtractTest, AddSynonymsForRelevantIds) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); TransformationCompositeExtract transformation( - MakeInstructionDescriptor(36, spv::Op::OpConvertFToS, 0), 201, 100, {2}); + MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -594,7 +586,7 @@ TEST(TransformationCompositeExtractTest, DontAddSynonymsForIrrelevantIds) { MakeUnique(context.get()), validator_options); transformation_context.GetFactManager()->AddFactIdIsIrrelevant(100); TransformationCompositeExtract transformation( - MakeInstructionDescriptor(36, spv::Op::OpConvertFToS, 0), 201, 100, {2}); + MakeInstructionDescriptor(36, SpvOpConvertFToS, 0), 201, 100, {2}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -643,7 +635,7 @@ TEST(TransformationCompositeExtractTest, DontAddSynonymInDeadBlock) { MakeUnique(context.get()), validator_options); transformation_context.GetFactManager()->AddFactBlockIsDead(15); TransformationCompositeExtract transformation( - MakeInstructionDescriptor(15, spv::Op::OpBranch, 0), 100, 12, {0}); + MakeInstructionDescriptor(15, SpvOpBranch, 0), 100, 12, {0}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_composite_insert_test.cpp b/test/fuzz/transformation_composite_insert_test.cpp index e61c0fa5..3b6f34d3 100644 --- a/test/fuzz/transformation_composite_insert_test.cpp +++ b/test/fuzz/transformation_composite_insert_test.cpp @@ -103,69 +103,65 @@ TEST(TransformationCompositeInsertTest, NotApplicableScenarios) { MakeUnique(context.get()), validator_options); // Bad: |fresh_id| is not fresh. auto transformation_bad_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 20, 29, 11, - {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 20, 29, 11, {1, 0, 0}); ASSERT_FALSE( transformation_bad_1.IsApplicable(context.get(), transformation_context)); // Bad: |composite_id| does not refer to a existing instruction. auto transformation_bad_2 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 40, 11, - {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 40, 11, {1, 0, 0}); ASSERT_FALSE( transformation_bad_2.IsApplicable(context.get(), transformation_context)); // Bad: |composite_id| does not refer to a composite value. auto transformation_bad_3 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 9, 11, {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 9, 11, {1, 0, 0}); ASSERT_FALSE( transformation_bad_3.IsApplicable(context.get(), transformation_context)); // Bad: |object_id| does not refer to a defined instruction. auto transformation_bad_4 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 29, 40, - {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 29, 40, {1, 0, 0}); ASSERT_FALSE( transformation_bad_4.IsApplicable(context.get(), transformation_context)); // Bad: |object_id| cannot refer to a pointer. auto transformation_bad_5 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 29, 8, {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 29, 8, {1, 0, 0}); ASSERT_FALSE( transformation_bad_5.IsApplicable(context.get(), transformation_context)); // Bad: |index| is not a correct index. auto transformation_bad_6 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 29, 11, - {2, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 29, 11, {2, 0, 0}); ASSERT_FALSE( transformation_bad_6.IsApplicable(context.get(), transformation_context)); // Bad: Type id of the object to be inserted and the type id of the // component at |index| are not the same. auto transformation_bad_7 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 29, 11, {1, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 29, 11, {1, 0}); ASSERT_FALSE( transformation_bad_7.IsApplicable(context.get(), transformation_context)); // Bad: |instruction_to_insert_before| does not refer to a defined // instruction. auto transformation_bad_8 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpIMul, 0), 50, 29, 11, {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpIMul, 0), 50, 29, 11, {1, 0, 0}); ASSERT_FALSE( transformation_bad_8.IsApplicable(context.get(), transformation_context)); // Bad: OpCompositeInsert cannot be inserted before OpBranchConditional with // OpSelectionMerge above it. auto transformation_bad_9 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpBranchConditional, 0), 50, 29, - 11, {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpBranchConditional, 0), 50, 29, 11, + {1, 0, 0}); ASSERT_FALSE( transformation_bad_9.IsApplicable(context.get(), transformation_context)); // Bad: |composite_id| does not have a type_id. auto transformation_bad_10 = TransformationCompositeInsert( - MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 50, 1, 11, {1, 0, 0}); + MakeInstructionDescriptor(29, SpvOpStore, 0), 50, 1, 11, {1, 0, 0}); ASSERT_FALSE(transformation_bad_10.IsApplicable(context.get(), transformation_context)); } @@ -226,14 +222,14 @@ TEST(TransformationCompositeInsertTest, EmptyCompositeScenarios) { MakeUnique(context.get()), validator_options); // Bad: The composite with |composite_id| cannot be empty. auto transformation_bad_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(64, spv::Op::OpStore, 0), 50, 61, 62, {1}); + MakeInstructionDescriptor(64, SpvOpStore, 0), 50, 61, 62, {1}); ASSERT_FALSE( transformation_bad_1.IsApplicable(context.get(), transformation_context)); // Good: It is possible to insert into a composite an element which is an // empty composite. auto transformation_good_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(64, spv::Op::OpStore, 0), 50, 64, 62, {1}); + MakeInstructionDescriptor(64, SpvOpStore, 0), 50, 64, 62, {1}); ASSERT_TRUE(transformation_good_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_good_1, context.get(), @@ -372,8 +368,7 @@ TEST(TransformationCompositeInsertTest, IrrelevantCompositeNoSynonyms) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(30); auto transformation_good_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(30, spv::Op::OpStore, 0), 50, 30, 11, - {1, 0, 0}); + MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0}); ASSERT_TRUE(transformation_good_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_good_1, context.get(), @@ -478,8 +473,7 @@ TEST(TransformationCompositeInsertTest, IrrelevantObjectNoSynonyms) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(11); auto transformation_good_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(30, spv::Op::OpStore, 0), 50, 30, 11, - {1, 0, 0}); + MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0}); ASSERT_TRUE(transformation_good_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_good_1, context.get(), @@ -586,8 +580,7 @@ TEST(TransformationCompositeInsertTest, ApplicableCreatedSynonyms) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto transformation_good_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(30, spv::Op::OpStore, 0), 50, 30, 11, - {1, 0, 0}); + MakeInstructionDescriptor(30, SpvOpStore, 0), 50, 30, 11, {1, 0, 0}); ASSERT_TRUE(transformation_good_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_good_1, context.get(), @@ -616,8 +609,7 @@ TEST(TransformationCompositeInsertTest, ApplicableCreatedSynonyms) { MakeDataDescriptor(30, {1, 0, 0}), MakeDataDescriptor(50, {1, 0, 0}))); auto transformation_good_2 = TransformationCompositeInsert( - MakeInstructionDescriptor(50, spv::Op::OpStore, 0), 51, 50, 11, - {0, 1, 1}); + MakeInstructionDescriptor(50, SpvOpStore, 0), 51, 50, 11, {0, 1, 1}); ASSERT_TRUE(transformation_good_2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_good_2, context.get(), @@ -795,30 +787,30 @@ TEST(TransformationCompositeInsertTest, IdNotAvailableScenarios) { // Bad: The object with |object_id| is not available at // |instruction_to_insert_before|. auto transformation_bad_1 = TransformationCompositeInsert( - MakeInstructionDescriptor(31, spv::Op::OpIMul, 0), 50, 27, 60, {1}); + MakeInstructionDescriptor(31, SpvOpIMul, 0), 50, 27, 60, {1}); ASSERT_FALSE( transformation_bad_1.IsApplicable(context.get(), transformation_context)); // Bad: The composite with |composite_id| is not available at // |instruction_to_insert_before|. auto transformation_bad_2 = TransformationCompositeInsert( - MakeInstructionDescriptor(31, spv::Op::OpIMul, 0), 50, 61, 21, {1}); + MakeInstructionDescriptor(31, SpvOpIMul, 0), 50, 61, 21, {1}); ASSERT_FALSE( transformation_bad_2.IsApplicable(context.get(), transformation_context)); // Bad: The |instruction_to_insert_before| is the composite itself and is // available. auto transformation_bad_3 = TransformationCompositeInsert( - MakeInstructionDescriptor(61, spv::Op::OpCompositeConstruct, 0), 50, 61, - 21, {1}); + MakeInstructionDescriptor(61, SpvOpCompositeConstruct, 0), 50, 61, 21, + {1}); ASSERT_FALSE( transformation_bad_3.IsApplicable(context.get(), transformation_context)); // Bad: The |instruction_to_insert_before| is the object itself and is not // available. auto transformation_bad_4 = TransformationCompositeInsert( - MakeInstructionDescriptor(60, spv::Op::OpCompositeConstruct, 0), 50, 27, - 60, {1}); + MakeInstructionDescriptor(60, SpvOpCompositeConstruct, 0), 50, 27, 60, + {1}); ASSERT_FALSE( transformation_bad_4.IsApplicable(context.get(), transformation_context)); } @@ -871,8 +863,7 @@ TEST(TransformationCompositeInsertTest, CompositeInsertionWithIrrelevantIds) { // Leads to synonyms - nothing is irrelevant. auto transformation1 = TransformationCompositeInsert( - MakeInstructionDescriptor(13, spv::Op::OpSelectionMerge, 0), 100, 9, 17, - {0}); + MakeInstructionDescriptor(13, SpvOpSelectionMerge, 0), 100, 9, 17, {0}); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -885,8 +876,7 @@ TEST(TransformationCompositeInsertTest, CompositeInsertionWithIrrelevantIds) { // Because %16 is irrelevant, we don't get a synonym with the component to // which it has been inserted (but we do for the other component). auto transformation2 = TransformationCompositeInsert( - MakeInstructionDescriptor(13, spv::Op::OpSelectionMerge, 0), 101, 9, 16, - {0}); + MakeInstructionDescriptor(13, SpvOpSelectionMerge, 0), 101, 9, 16, {0}); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -899,8 +889,7 @@ TEST(TransformationCompositeInsertTest, CompositeInsertionWithIrrelevantIds) { // Because %18 is irrelevant we only get a synonym for the component into // which insertion has taken place. auto transformation3 = TransformationCompositeInsert( - MakeInstructionDescriptor(13, spv::Op::OpSelectionMerge, 0), 102, 18, 17, - {0}); + MakeInstructionDescriptor(13, SpvOpSelectionMerge, 0), 102, 18, 17, {0}); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -912,7 +901,7 @@ TEST(TransformationCompositeInsertTest, CompositeInsertionWithIrrelevantIds) { // Does not lead to synonyms as block %14 is dead. auto transformation4 = TransformationCompositeInsert( - MakeInstructionDescriptor(14, spv::Op::OpBranch, 0), 103, 9, 17, {0}); + MakeInstructionDescriptor(14, SpvOpBranch, 0), 103, 9, 17, {0}); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), diff --git a/test/fuzz/transformation_equation_instruction_test.cpp b/test/fuzz/transformation_equation_instruction_test.cpp index 3653fcab..5b5033d2 100644 --- a/test/fuzz/transformation_equation_instruction_test.cpp +++ b/test/fuzz/transformation_equation_instruction_test.cpp @@ -54,66 +54,65 @@ TEST(TransformationEquationInstructionTest, SignedNegate) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); // Bad: id already in use. - ASSERT_FALSE(TransformationEquationInstruction(7, spv::Op::OpSNegate, {7}, + ASSERT_FALSE(TransformationEquationInstruction(7, SpvOpSNegate, {7}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: identified instruction does not exist. - ASSERT_FALSE(TransformationEquationInstruction( - 14, spv::Op::OpSNegate, {7}, - MakeInstructionDescriptor(13, spv::Op::OpLoad, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction( + 14, SpvOpSNegate, {7}, MakeInstructionDescriptor(13, SpvOpLoad, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: id 100 does not exist - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {100}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {100}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: id 20 is an OpUndef - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {20}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {20}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: id 30 is not available right before its definition ASSERT_FALSE(TransformationEquationInstruction( - 14, spv::Op::OpSNegate, {30}, - MakeInstructionDescriptor(30, spv::Op::OpCopyObject, 0)) + 14, SpvOpSNegate, {30}, + MakeInstructionDescriptor(30, SpvOpCopyObject, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: too many arguments to OpSNegate. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {7, 7}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {7, 7}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: 40 is a type id. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {40}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {40}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: wrong type of argument to OpSNegate. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {41}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpSNegate, {41}, return_instruction) .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( - 14, spv::Op::OpSNegate, {7}, return_instruction); + 14, SpvOpSNegate, {7}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(14)); ASSERT_EQ(nullptr, context->get_instr_block(14)); ApplyAndCheckFreshIds(transformation1, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpSNegate, - context->get_def_use_mgr()->GetDef(14)->opcode()); + ASSERT_EQ(SpvOpSNegate, context->get_def_use_mgr()->GetDef(14)->opcode()); ASSERT_EQ(13, context->get_instr_block(14)->id()); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 15, spv::Op::OpSNegate, {14}, return_instruction); + 15, SpvOpSNegate, {14}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -179,25 +178,25 @@ TEST(TransformationEquationInstructionTest, LogicalNot) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); // Bad: too few arguments to OpLogicalNot. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, {}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: 6 is a type id. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, {6}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {6}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: wrong type of argument to OpLogicalNot. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, - {21}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpLogicalNot, {21}, + return_instruction) .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( - 14, spv::Op::OpLogicalNot, {7}, return_instruction); + 14, SpvOpLogicalNot, {7}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -206,7 +205,7 @@ TEST(TransformationEquationInstructionTest, LogicalNot) { kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 15, spv::Op::OpLogicalNot, {14}, return_instruction); + 15, SpvOpLogicalNot, {14}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -273,31 +272,31 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); // Bad: too many arguments to OpIAdd. - ASSERT_FALSE(TransformationEquationInstruction( - 14, spv::Op::OpIAdd, {15, 16, 16}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 16, 16}, + return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: boolean argument to OpIAdd. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {15, 32}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 32}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: type as argument to OpIAdd. - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {33, 16}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {33, 16}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: arguments of mismatched widths - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {15, 31}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {15, 31}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Bad: arguments of mismatched widths - ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {31, 15}, + ASSERT_FALSE(TransformationEquationInstruction(14, SpvOpIAdd, {31, 15}, return_instruction) .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationEquationInstruction( - 14, spv::Op::OpIAdd, {15, 16}, return_instruction); + 14, SpvOpIAdd, {15, 16}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -306,7 +305,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 19, spv::Op::OpISub, {14, 16}, return_instruction); + 19, SpvOpISub, {14, 16}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -317,7 +316,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {}))); auto transformation3 = TransformationEquationInstruction( - 20, spv::Op::OpISub, {14, 15}, return_instruction); + 20, SpvOpISub, {14, 15}, return_instruction); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -328,7 +327,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); auto transformation4 = TransformationEquationInstruction( - 22, spv::Op::OpISub, {16, 14}, return_instruction); + 22, SpvOpISub, {16, 14}, return_instruction); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), @@ -337,7 +336,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate1) { kConsoleMessageConsumer)); auto transformation5 = TransformationEquationInstruction( - 24, spv::Op::OpSNegate, {22}, return_instruction); + 24, SpvOpSNegate, {22}, return_instruction); ASSERT_TRUE( transformation5.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation5, context.get(), @@ -405,10 +404,10 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); auto transformation1 = TransformationEquationInstruction( - 14, spv::Op::OpISub, {15, 16}, return_instruction); + 14, SpvOpISub, {15, 16}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -417,7 +416,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 17, spv::Op::OpIAdd, {14, 16}, return_instruction); + 17, SpvOpIAdd, {14, 16}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -428,7 +427,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}))); auto transformation3 = TransformationEquationInstruction( - 18, spv::Op::OpIAdd, {16, 14}, return_instruction); + 18, SpvOpIAdd, {16, 14}, return_instruction); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -441,7 +440,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}))); auto transformation4 = TransformationEquationInstruction( - 19, spv::Op::OpISub, {14, 15}, return_instruction); + 19, SpvOpISub, {14, 15}, return_instruction); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), @@ -450,7 +449,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { kConsoleMessageConsumer)); auto transformation5 = TransformationEquationInstruction( - 20, spv::Op::OpSNegate, {19}, return_instruction); + 20, SpvOpSNegate, {19}, return_instruction); ASSERT_TRUE( transformation5.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation5, context.get(), @@ -461,7 +460,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); auto transformation6 = TransformationEquationInstruction( - 21, spv::Op::OpISub, {14, 19}, return_instruction); + 21, SpvOpISub, {14, 19}, return_instruction); ASSERT_TRUE( transformation6.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation6, context.get(), @@ -472,7 +471,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}))); auto transformation7 = TransformationEquationInstruction( - 22, spv::Op::OpISub, {14, 18}, return_instruction); + 22, SpvOpISub, {14, 18}, return_instruction); ASSERT_TRUE( transformation7.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation7, context.get(), @@ -481,7 +480,7 @@ TEST(TransformationEquationInstructionTest, AddSubNegate2) { kConsoleMessageConsumer)); auto transformation8 = TransformationEquationInstruction( - 23, spv::Op::OpSNegate, {22}, return_instruction); + 23, SpvOpSNegate, {22}, return_instruction); ASSERT_TRUE( transformation8.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation8, context.get(), @@ -560,51 +559,51 @@ TEST(TransformationEquationInstructionTest, Bitcast) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); // Too many operands. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, - {15, 16}, insert_before) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpBitcast, {15, 16}, + insert_before) .IsApplicable(context.get(), transformation_context)); // Too few operands. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {}, insert_before) + .IsApplicable(context.get(), transformation_context)); // Operand's id is invalid. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {50}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {50}, insert_before) + .IsApplicable(context.get(), transformation_context)); // Operand's type is invalid - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {13}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {13}, insert_before) + .IsApplicable(context.get(), transformation_context)); // Operand must be a scalar or a vector of numerical type. #ifndef NDEBUG - ASSERT_DEATH(TransformationEquationInstruction(50, spv::Op::OpBitcast, {23}, - insert_before) - .IsApplicable(context.get(), transformation_context), - "Operand is not a scalar or a vector of numerical type"); - ASSERT_DEATH(TransformationEquationInstruction(50, spv::Op::OpBitcast, {24}, - insert_before) - .IsApplicable(context.get(), transformation_context), - "Only vectors of numerical components are supported"); + ASSERT_DEATH( + TransformationEquationInstruction(50, SpvOpBitcast, {23}, insert_before) + .IsApplicable(context.get(), transformation_context), + "Operand is not a scalar or a vector of numerical type"); + ASSERT_DEATH( + TransformationEquationInstruction(50, SpvOpBitcast, {24}, insert_before) + .IsApplicable(context.get(), transformation_context), + "Only vectors of numerical components are supported"); #else - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {23}, - insert_before) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {24}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {23}, insert_before) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {24}, insert_before) + .IsApplicable(context.get(), transformation_context)); #endif for (uint32_t operand_id = 15, fresh_id = 50; operand_id <= 20; ++operand_id, ++fresh_id) { TransformationEquationInstruction transformation( - fresh_id, spv::Op::OpBitcast, {operand_id}, insert_before); + fresh_id, SpvOpBitcast, {operand_id}, insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -684,23 +683,23 @@ TEST(TransformationEquationInstructionTest, kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); // Scalar floating-point type does not exist. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {15}, - insert_before) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {16}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {15}, insert_before) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {16}, insert_before) + .IsApplicable(context.get(), transformation_context)); // Vector of floating-point components does not exist. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {18}, - insert_before) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {19}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {18}, insert_before) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {19}, insert_before) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist1) { @@ -731,17 +730,17 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist1) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); // Scalar integral type does not exist. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {17}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {17}, insert_before) + .IsApplicable(context.get(), transformation_context)); // Vector of integral components does not exist. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {20}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(50, SpvOpBitcast, {20}, insert_before) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist2) { @@ -774,19 +773,19 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist2) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, - {20}, insert_before); + TransformationEquationInstruction transformation(51, SpvOpBitcast, {20}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -849,19 +848,19 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist3) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, - {20}, insert_before); + TransformationEquationInstruction transformation(51, SpvOpBitcast, {20}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -923,20 +922,20 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist4) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } - ASSERT_FALSE(TransformationEquationInstruction(51, spv::Op::OpBitcast, {20}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(51, SpvOpBitcast, {20}, insert_before) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, kConsoleMessageConsumer)); @@ -994,20 +993,20 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist5) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } - ASSERT_FALSE(TransformationEquationInstruction(51, spv::Op::OpBitcast, {20}, - insert_before) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationEquationInstruction(51, SpvOpBitcast, {20}, insert_before) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, kConsoleMessageConsumer)); @@ -1067,19 +1066,19 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist6) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, - {20}, insert_before); + TransformationEquationInstruction transformation(51, SpvOpBitcast, {20}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -1147,19 +1146,19 @@ TEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist7) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto insert_before = MakeInstructionDescriptor(13, SpvOpReturn, 0); { - TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, - {17}, insert_before); + TransformationEquationInstruction transformation(50, SpvOpBitcast, {17}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, - {20}, insert_before); + TransformationEquationInstruction transformation(51, SpvOpBitcast, {20}, + insert_before); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -1223,10 +1222,10 @@ TEST(TransformationEquationInstructionTest, Miscellaneous1) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); auto transformation1 = TransformationEquationInstruction( - 522, spv::Op::OpISub, {113, 113}, return_instruction); + 522, SpvOpISub, {113, 113}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -1235,7 +1234,7 @@ TEST(TransformationEquationInstructionTest, Miscellaneous1) { kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 570, spv::Op::OpIAdd, {522, 113}, return_instruction); + 570, SpvOpIAdd, {522, 113}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -1295,10 +1294,10 @@ TEST(TransformationEquationInstructionTest, Miscellaneous2) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); auto transformation1 = TransformationEquationInstruction( - 522, spv::Op::OpISub, {113, 113}, return_instruction); + 522, SpvOpISub, {113, 113}, return_instruction); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -1307,7 +1306,7 @@ TEST(TransformationEquationInstructionTest, Miscellaneous2) { kConsoleMessageConsumer)); auto transformation2 = TransformationEquationInstruction( - 570, spv::Op::OpIAdd, {522, 113}, return_instruction); + 570, SpvOpIAdd, {522, 113}, return_instruction); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -1381,97 +1380,97 @@ TEST(TransformationEquationInstructionTest, ConversionInstructions) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); // Too few instruction operands. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, {}, + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertSToF, {}, return_instruction) .IsApplicable(context.get(), transformation_context)); // Too many instruction operands. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, - {15, 16}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertSToF, {15, 16}, + return_instruction) .IsApplicable(context.get(), transformation_context)); // Operand has no type id. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, - {7}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertSToF, {7}, + return_instruction) .IsApplicable(context.get(), transformation_context)); // OpConvertSToF and OpConvertUToF require an operand to have scalar or vector // of integral components type. - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, - {17}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertSToF, {17}, + return_instruction) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, - {14}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertSToF, {14}, + return_instruction) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertUToF, - {17}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertUToF, {17}, + return_instruction) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertUToF, - {14}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(50, SpvOpConvertUToF, {14}, + return_instruction) .IsApplicable(context.get(), transformation_context)); { - TransformationEquationInstruction transformation(50, spv::Op::OpConvertSToF, - {15}, return_instruction); + TransformationEquationInstruction transformation(50, SpvOpConvertSToF, {15}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(51, spv::Op::OpConvertSToF, - {10}, return_instruction); + TransformationEquationInstruction transformation(51, SpvOpConvertSToF, {10}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(52, spv::Op::OpConvertUToF, - {16}, return_instruction); + TransformationEquationInstruction transformation(52, SpvOpConvertUToF, {16}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(53, spv::Op::OpConvertUToF, - {11}, return_instruction); + TransformationEquationInstruction transformation(53, SpvOpConvertUToF, {11}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(58, spv::Op::OpConvertSToF, - {18}, return_instruction); + TransformationEquationInstruction transformation(58, SpvOpConvertSToF, {18}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(59, spv::Op::OpConvertUToF, - {19}, return_instruction); + TransformationEquationInstruction transformation(59, SpvOpConvertUToF, {19}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(60, spv::Op::OpConvertSToF, - {20}, return_instruction); + TransformationEquationInstruction transformation(60, SpvOpConvertSToF, {20}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); } { - TransformationEquationInstruction transformation(61, spv::Op::OpConvertUToF, - {21}, return_instruction); + TransformationEquationInstruction transformation(61, SpvOpConvertUToF, {21}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -1556,22 +1555,22 @@ TEST(TransformationEquationInstructionTest, FloatResultTypeDoesNotExist) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); protobufs::InstructionDescriptor return_instruction = - MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + MakeInstructionDescriptor(13, SpvOpReturn, 0); // Scalar float type doesn't exist. - ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertUToF, - {10}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(16, SpvOpConvertUToF, {10}, + return_instruction) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertSToF, - {11}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(16, SpvOpConvertSToF, {11}, + return_instruction) .IsApplicable(context.get(), transformation_context)); // Vector float type doesn't exist. - ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertUToF, - {14}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(16, SpvOpConvertUToF, {14}, + return_instruction) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertSToF, - {15}, return_instruction) + ASSERT_FALSE(TransformationEquationInstruction(16, SpvOpConvertSToF, {15}, + return_instruction) .IsApplicable(context.get(), transformation_context)); } @@ -1606,11 +1605,11 @@ TEST(TransformationEquationInstructionTest, HandlesIrrelevantIds) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto return_instruction = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); + auto return_instruction = MakeInstructionDescriptor(13, SpvOpReturn, 0); // Applicable. - TransformationEquationInstruction transformation( - 14, spv::Op::OpIAdd, {15, 16}, return_instruction); + TransformationEquationInstruction transformation(14, SpvOpIAdd, {15, 16}, + return_instruction); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -1663,12 +1662,11 @@ TEST(TransformationEquationInstructionTest, HandlesDeadBlock) { transformation_context.GetFactManager()->AddFactBlockIsDead(41); TransformationEquationInstruction transformation1( - 14, spv::Op::OpIAdd, {15, 16}, - MakeInstructionDescriptor(13, spv::Op::OpSelectionMerge, 0)); + 14, SpvOpIAdd, {15, 16}, + MakeInstructionDescriptor(13, SpvOpSelectionMerge, 0)); // No synonym is created since block is dead. TransformationEquationInstruction transformation2( - 100, spv::Op::OpISub, {14, 16}, - MakeInstructionDescriptor(41, spv::Op::OpBranch, 0)); + 100, SpvOpISub, {14, 16}, MakeInstructionDescriptor(41, SpvOpBranch, 0)); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), diff --git a/test/fuzz/transformation_flatten_conditional_branch_test.cpp b/test/fuzz/transformation_flatten_conditional_branch_test.cpp index 06318990..800af0ea 100644 --- a/test/fuzz/transformation_flatten_conditional_branch_test.cpp +++ b/test/fuzz/transformation_flatten_conditional_branch_test.cpp @@ -441,8 +441,8 @@ TEST(TransformationFlattenConditionalBranchTest, LoadStoreFunctionCall) { ASSERT_DEATH(TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 100, - 101, 102, 103, 104, 14)}}) + MakeInstructionDescriptor(6, SpvOpLoad, 0), 100, 101, + 102, 103, 104, 14)}}) .IsApplicable(context.get(), transformation_context), "Bad attempt to query whether overflow ids are available."); #endif @@ -451,55 +451,52 @@ TEST(TransformationFlattenConditionalBranchTest, LoadStoreFunctionCall) { ASSERT_FALSE(TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 100, - 101, 102, 103, 0, 0)}}) + MakeInstructionDescriptor(6, SpvOpLoad, 0), 100, 101, + 102, 103, 0, 0)}}) .IsApplicable(context.get(), transformation_context)); // Not all fresh ids given are distinct. ASSERT_FALSE(TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 100, - 100, 102, 103, 104, 0)}}) + MakeInstructionDescriptor(6, SpvOpLoad, 0), 100, 100, + 102, 103, 104, 0)}}) .IsApplicable(context.get(), transformation_context)); // %48 heads a construct containing an OpSampledImage instruction. ASSERT_FALSE(TransformationFlattenConditionalBranch( 48, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(53, spv::Op::OpLoad, 0), 100, - 101, 102, 103, 104, 0)}}) + MakeInstructionDescriptor(53, SpvOpLoad, 0), 100, 101, + 102, 103, 104, 0)}}) .IsApplicable(context.get(), transformation_context)); // %0 is not a valid id. ASSERT_FALSE( TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 104, 100, 101, - 102, 103, 0), + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(6, SpvOpLoad, 0), + 104, 100, 101, 102, 103, 0), MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpStore, 0), 106, 105)}) + MakeInstructionDescriptor(6, SpvOpStore, 0), 106, 105)}) .IsApplicable(context.get(), transformation_context)); // %17 is a float constant, while %6 has int type. ASSERT_FALSE( TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 104, 100, 101, - 102, 103, 17), + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(6, SpvOpLoad, 0), + 104, 100, 101, 102, 103, 17), MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpStore, 0), 106, 105)}) + MakeInstructionDescriptor(6, SpvOpStore, 0), 106, 105)}) .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationFlattenConditionalBranch( 31, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpLoad, 0), 104, 100, 101, 102, - 103, 70), - MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(6, spv::Op::OpStore, 0), 106, 105)}); + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(6, SpvOpLoad, 0), + 104, 100, 101, 102, 103, 70), + MakeSideEffectWrapperInfo(MakeInstructionDescriptor(6, SpvOpStore, 0), + 106, 105)}); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -517,8 +514,8 @@ TEST(TransformationFlattenConditionalBranchTest, LoadStoreFunctionCall) { auto transformation2 = TransformationFlattenConditionalBranch( 36, false, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(8, spv::Op::OpStore, 0), 114, 113)}); + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(8, SpvOpStore, 0), + 114, 113)}); ASSERT_TRUE( transformation2.IsApplicable(context.get(), new_transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -720,8 +717,7 @@ TEST(TransformationFlattenConditionalBranchTest, EdgeCases) { auto transformation1 = TransformationFlattenConditionalBranch( 7, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(10, spv::Op::OpFunctionCall, 0), 100, - 101)}}); + MakeInstructionDescriptor(10, SpvOpFunctionCall, 0), 100, 101)}}); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -733,8 +729,7 @@ TEST(TransformationFlattenConditionalBranchTest, EdgeCases) { TransformationFlattenConditionalBranch( 7, true, 0, 0, 0, {{MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(14, spv::Op::OpFunctionCall, 0), 102, - 103)}}) + MakeInstructionDescriptor(14, SpvOpFunctionCall, 0), 102, 103)}}) .IsApplicable(context.get(), transformation_context)); // Block %16 is unreachable. @@ -1131,12 +1126,10 @@ TEST(TransformationFlattenConditionalBranchTest, PhiToSelect5) { auto transformation = TransformationFlattenConditionalBranch( 7, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(522, spv::Op::OpLoad, 0), 200, 201, 202, - 203, 204, 5), - MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(466, spv::Op::OpLoad, 0), 300, 301, 302, - 303, 304, 5)}); + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(522, SpvOpLoad, 0), + 200, 201, 202, 203, 204, 5), + MakeSideEffectWrapperInfo(MakeInstructionDescriptor(466, SpvOpLoad, 0), + 300, 301, 302, 303, 304, 5)}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1238,9 +1231,8 @@ TEST(TransformationFlattenConditionalBranchTest, auto transformation = TransformationFlattenConditionalBranch( 5, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(20, spv::Op::OpLoad, 0), 100, 101, 102, 103, - 104, 21)}); + {MakeSideEffectWrapperInfo(MakeInstructionDescriptor(20, SpvOpLoad, 0), + 100, 101, 102, 103, 104, 21)}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -1307,8 +1299,8 @@ TEST(TransformationFlattenConditionalBranchTest, InapplicableSampledImageLoad) { ASSERT_FALSE(TransformationFlattenConditionalBranch( 28, true, 0, 0, 0, {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(40, spv::Op::OpLoad, 0), 100, - 101, 102, 103, 104, 200)}) + MakeInstructionDescriptor(40, SpvOpLoad, 0), 100, 101, + 102, 103, 104, 200)}) .IsApplicable(context.get(), transformation_context)); } @@ -1738,7 +1730,7 @@ TEST(TransformationFlattenConditionalBranchTest, ApplicablePhiToSelectVector3) { // Check that the in operands of any OpSelect instructions all have the // appropriate operand type. context->module()->ForEachInst([](opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpSelect) { + if (inst->opcode() == SpvOpSelect) { ASSERT_EQ(SPV_OPERAND_TYPE_ID, inst->GetInOperand(0).type); ASSERT_EQ(SPV_OPERAND_TYPE_ID, inst->GetInOperand(1).type); ASSERT_EQ(SPV_OPERAND_TYPE_ID, inst->GetInOperand(2).type); @@ -2191,15 +2183,14 @@ TEST(TransformationFlattenConditionalBranchTest, ContainsSynonymCreation) { transformation_context.GetFactManager()->AddFactDataSynonym( MakeDataDescriptor(10, {}), MakeDataDescriptor(21, {})); - ASSERT_FALSE( - TransformationFlattenConditionalBranch( - 12, true, 0, 0, 0, - {MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(30, spv::Op::OpStore, 0), 100, 101), - MakeSideEffectWrapperInfo( - MakeInstructionDescriptor(21, spv::Op::OpLoad, 0), 102, 103, 104, - 105, 106, 80)}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationFlattenConditionalBranch( + 12, true, 0, 0, 0, + {MakeSideEffectWrapperInfo( + MakeInstructionDescriptor(30, SpvOpStore, 0), 100, 101), + MakeSideEffectWrapperInfo( + MakeInstructionDescriptor(21, SpvOpLoad, 0), 102, 103, + 104, 105, 106, 80)}) + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_function_call_test.cpp b/test/fuzz/transformation_function_call_test.cpp index c963e339..b27b3ca9 100644 --- a/test/fuzz/transformation_function_call_test.cpp +++ b/test/fuzz/transformation_function_call_test.cpp @@ -174,91 +174,88 @@ TEST(TransformationFunctionCallTest, BasicTest) { // Bad transformations // Too many arguments - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {71, 72, 71}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); - // Too few arguments ASSERT_FALSE( - TransformationFunctionCall( - 100, 21, {71}, MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) + TransformationFunctionCall(100, 21, {71, 72, 71}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) .IsApplicable(context.get(), transformation_context)); + // Too few arguments + ASSERT_FALSE(TransformationFunctionCall( + 100, 21, {71}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Arguments are the wrong way around (types do not match) - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {72, 71}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 21, {72, 71}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // 21 is not an appropriate argument - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {21, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 21, {21, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // 300 does not exist - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {300, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 21, {300, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // 71 is not a function - ASSERT_FALSE(TransformationFunctionCall( - 100, 71, {71, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 71, {71, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // 500 does not exist - ASSERT_FALSE(TransformationFunctionCall( - 100, 500, {71, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 500, {71, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Id is not fresh ASSERT_FALSE( - TransformationFunctionCall( - 21, 21, {71, 72}, MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) + TransformationFunctionCall(21, 21, {71, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) .IsApplicable(context.get(), transformation_context)); // Access chain as pointer parameter - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {98, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 21, {98, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Copied object as pointer parameter - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {99, 72}, - MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall(100, 21, {99, 72}, + MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Non-livesafe called from original live block - ASSERT_FALSE(TransformationFunctionCall( - 100, 10, {71}, - MakeInstructionDescriptor(99, spv::Op::OpSelectionMerge, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall( + 100, 10, {71}, MakeInstructionDescriptor(99, SpvOpSelectionMerge, 0)) + .IsApplicable(context.get(), transformation_context)); // Non-livesafe called from livesafe function - ASSERT_FALSE(TransformationFunctionCall( - 100, 10, {19}, - MakeInstructionDescriptor(38, spv::Op::OpConvertFToS, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall( + 100, 10, {19}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0)) + .IsApplicable(context.get(), transformation_context)); // Livesafe function called with pointer to non-arbitrary local variable - ASSERT_FALSE(TransformationFunctionCall( - 100, 21, {61, 72}, - MakeInstructionDescriptor(38, spv::Op::OpConvertFToS, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationFunctionCall( + 100, 21, {61, 72}, MakeInstructionDescriptor(38, SpvOpConvertFToS, 0)) + .IsApplicable(context.get(), transformation_context)); // Direct recursion - ASSERT_FALSE( - TransformationFunctionCall( - 100, 4, {}, MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationFunctionCall( + 100, 4, {}, MakeInstructionDescriptor(59, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Indirect recursion - ASSERT_FALSE( - TransformationFunctionCall( - 100, 24, {9}, MakeInstructionDescriptor(96, spv::Op::OpBranch, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationFunctionCall( + 100, 24, {9}, MakeInstructionDescriptor(96, SpvOpBranch, 0)) + .IsApplicable(context.get(), transformation_context)); // Parameter 23 is not available at the call site ASSERT_FALSE( - TransformationFunctionCall( - 104, 10, {23}, MakeInstructionDescriptor(205, spv::Op::OpBranch, 0)) + TransformationFunctionCall(104, 10, {23}, + MakeInstructionDescriptor(205, SpvOpBranch, 0)) .IsApplicable(context.get(), transformation_context)); // Good transformations { // Livesafe called from dead block: fine TransformationFunctionCall transformation( - 100, 21, {71, 72}, MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)); + 100, 21, {71, 72}, MakeInstructionDescriptor(59, SpvOpBranch, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -269,8 +266,7 @@ TEST(TransformationFunctionCallTest, BasicTest) { { // Livesafe called from original live block: fine TransformationFunctionCall transformation( - 101, 21, {71, 72}, - MakeInstructionDescriptor(98, spv::Op::OpAccessChain, 0)); + 101, 21, {71, 72}, MakeInstructionDescriptor(98, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -281,7 +277,7 @@ TEST(TransformationFunctionCallTest, BasicTest) { { // Livesafe called from livesafe function: fine TransformationFunctionCall transformation( - 102, 200, {19, 20}, MakeInstructionDescriptor(36, spv::Op::OpLoad, 0)); + 102, 200, {19, 20}, MakeInstructionDescriptor(36, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -292,7 +288,7 @@ TEST(TransformationFunctionCallTest, BasicTest) { { // Dead called from dead block in injected function: fine TransformationFunctionCall transformation( - 103, 10, {23}, MakeInstructionDescriptor(45, spv::Op::OpLoad, 0)); + 103, 10, {23}, MakeInstructionDescriptor(45, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -303,7 +299,7 @@ TEST(TransformationFunctionCallTest, BasicTest) { { // Non-livesafe called from dead block in livesafe function: OK TransformationFunctionCall transformation( - 104, 10, {201}, MakeInstructionDescriptor(205, spv::Op::OpBranch, 0)); + 104, 10, {201}, MakeInstructionDescriptor(205, SpvOpBranch, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -314,7 +310,7 @@ TEST(TransformationFunctionCallTest, BasicTest) { { // Livesafe called from dead block with non-arbitrary parameter TransformationFunctionCall transformation( - 105, 21, {62, 65}, MakeInstructionDescriptor(59, spv::Op::OpBranch, 0)); + 105, 21, {62, 65}, MakeInstructionDescriptor(59, SpvOpBranch, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -469,10 +465,9 @@ TEST(TransformationFunctionCallTest, DoNotInvokeEntryPoint) { transformation_context.GetFactManager()->AddFactBlockIsDead(11); // 4 is an entry point, so it is not legal for it to be the target of a call. - ASSERT_FALSE( - TransformationFunctionCall( - 100, 4, {}, MakeInstructionDescriptor(11, spv::Op::OpReturn, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationFunctionCall( + 100, 4, {}, MakeInstructionDescriptor(11, SpvOpReturn, 0)) + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_load_test.cpp b/test/fuzz/transformation_load_test.cpp index 6fde49ab..370826eb 100644 --- a/test/fuzz/transformation_load_test.cpp +++ b/test/fuzz/transformation_load_test.cpp @@ -131,68 +131,67 @@ TEST(TransformationLoadTest, BasicTest) { // 60 - null // Bad: id is not fresh - ASSERT_FALSE(TransformationLoad( - 33, 33, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(33, 33, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to load from 11 from outside its function - ASSERT_FALSE(TransformationLoad( - 100, 11, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 11, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is not available - ASSERT_FALSE(TransformationLoad( - 100, 33, false, 0, 0, - MakeInstructionDescriptor(45, spv::Op::OpCopyObject, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 33, false, 0, 0, + MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before OpVariable ASSERT_FALSE( TransformationLoad(100, 27, false, 0, 0, - MakeInstructionDescriptor(27, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(27, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist - ASSERT_FALSE(TransformationLoad( - 100, 1000, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 1000, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists but does not have a type - ASSERT_FALSE(TransformationLoad( - 100, 5, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 5, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists and has a type, but is not a pointer - ASSERT_FALSE(TransformationLoad( - 100, 24, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 24, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to load from null pointer - ASSERT_FALSE(TransformationLoad( - 100, 60, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(100, 60, false, 0, 0, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: %40 is not available at the program point - ASSERT_FALSE( - TransformationLoad(100, 40, false, 0, 0, - MakeInstructionDescriptor(37, spv::Op::OpReturn, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationLoad(100, 40, false, 0, 0, + MakeInstructionDescriptor(37, SpvOpReturn, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The described instruction does not exist ASSERT_FALSE( TransformationLoad(100, 33, false, 0, 0, - MakeInstructionDescriptor(1000, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(1000, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); { TransformationLoad transformation( 100, 33, false, 0, 0, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -204,7 +203,7 @@ TEST(TransformationLoadTest, BasicTest) { { TransformationLoad transformation( 101, 46, false, 0, 0, - MakeInstructionDescriptor(16, spv::Op::OpReturnValue, 0)); + MakeInstructionDescriptor(16, SpvOpReturnValue, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -216,7 +215,7 @@ TEST(TransformationLoadTest, BasicTest) { { TransformationLoad transformation( 102, 16, false, 0, 0, - MakeInstructionDescriptor(16, spv::Op::OpReturnValue, 0)); + MakeInstructionDescriptor(16, SpvOpReturnValue, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -228,7 +227,7 @@ TEST(TransformationLoadTest, BasicTest) { { TransformationLoad transformation( 103, 40, false, 0, 0, - MakeInstructionDescriptor(43, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(43, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -345,80 +344,80 @@ TEST(TransformationLoadTest, AtomicLoadTestCase) { MakeUnique(context.get()), validator_options); // Bad: id is not fresh. - ASSERT_FALSE(TransformationLoad( - 14, 14, true, 15, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(14, 14, true, 15, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: id 100 of memory scope instruction does not exist. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 100, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 100, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: id 100 of memory semantics instruction does not exist. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 15, 100, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 15, 100, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory scope should be |OpConstant| opcode. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 5, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 5, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory semantics should be |OpConstant| opcode. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 15, 5, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 15, 5, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The memory scope instruction must have an Integer operand. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 15, 19, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 15, 19, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The memory memory semantics instruction must have an Integer operand. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 19, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 19, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Integer size of the memory scope must be equal to 32 bits. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 17, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 17, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Integer size of memory semantics must be equal to 32 bits. - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 15, 17, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 15, 17, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); - // Bad: memory scope value must be 4 (spv::Scope::Invocation). - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 16, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + // Bad: memory scope value must be 4 (SpvScopeInvocation). + ASSERT_FALSE( + TransformationLoad(21, 14, true, 16, 20, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory semantics value must be either: // 64 (SpvMemorySemanticsUniformMemoryMask) // 256 (SpvMemorySemanticsWorkgroupMemoryMask) - ASSERT_FALSE(TransformationLoad( - 21, 14, true, 15, 16, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, true, 15, 16, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The described instruction does not exist - ASSERT_FALSE(TransformationLoad( - 21, 14, false, 15, 20, - MakeInstructionDescriptor(150, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(21, 14, false, 15, 20, + MakeInstructionDescriptor(150, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Successful transformations. { TransformationLoad transformation( 21, 14, true, 15, 20, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -519,22 +518,22 @@ TEST(TransformationLoadTest, AtomicLoadTestCaseForWorkgroupMemory) { MakeUnique(context.get()), validator_options); // Bad: Can't insert OpAccessChain before the id 23 of memory scope. - ASSERT_FALSE(TransformationLoad( - 60, 38, true, 21, 23, - MakeInstructionDescriptor(23, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(60, 38, true, 21, 23, + MakeInstructionDescriptor(23, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Can't insert OpAccessChain before the id 23 of memory semantics. - ASSERT_FALSE(TransformationLoad( - 60, 38, true, 21, 23, - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationLoad(60, 38, true, 21, 23, + MakeInstructionDescriptor(21, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Successful transformations. { TransformationLoad transformation( 60, 38, true, 21, 23, - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(40, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), diff --git a/test/fuzz/transformation_merge_function_returns_test.cpp b/test/fuzz/transformation_merge_function_returns_test.cpp index dd1869f0..400d49ad 100644 --- a/test/fuzz/transformation_merge_function_returns_test.cpp +++ b/test/fuzz/transformation_merge_function_returns_test.cpp @@ -1884,7 +1884,7 @@ TEST(TransformationMergeFunctionReturnsTest, OpPhiAfterFirstBlock) { // Ensure that all input operands of OpBranchConditional instructions have // the right operand type. context->module()->ForEachInst([](opt::Instruction* inst) { - if (inst->opcode() == spv::Op::OpBranchConditional) { + if (inst->opcode() == SpvOpBranchConditional) { ASSERT_EQ(inst->GetInOperand(0).type, SPV_OPERAND_TYPE_ID); ASSERT_EQ(inst->GetInOperand(1).type, SPV_OPERAND_TYPE_ID); ASSERT_EQ(inst->GetInOperand(2).type, SPV_OPERAND_TYPE_ID); diff --git a/test/fuzz/transformation_move_instruction_down_test.cpp b/test/fuzz/transformation_move_instruction_down_test.cpp index 5ab1619b..45dde7da 100644 --- a/test/fuzz/transformation_move_instruction_down_test.cpp +++ b/test/fuzz/transformation_move_instruction_down_test.cpp @@ -73,45 +73,44 @@ TEST(TransformationMoveInstructionDownTest, BasicTest) { MakeUnique(context.get()), validator_options); // Instruction descriptor is invalid. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(30, spv::Op::OpNop, 0)) + MakeInstructionDescriptor(30, SpvOpNop, 0)) .IsApplicable(context.get(), transformation_context)); // Opcode is not supported. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(5, spv::Op::OpLabel, 0)) + MakeInstructionDescriptor(5, SpvOpLabel, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(12, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(12, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(42, spv::Op::OpFunctionCall, 0)) + MakeInstructionDescriptor(42, SpvOpFunctionCall, 0)) .IsApplicable(context.get(), transformation_context)); // Can't move the last instruction in the block. - ASSERT_FALSE( - TransformationMoveInstructionDown( - MakeInstructionDescriptor(15, spv::Op::OpBranchConditional, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationMoveInstructionDown( + MakeInstructionDescriptor(15, SpvOpBranchConditional, 0)) + .IsApplicable(context.get(), transformation_context)); // Can't move the instruction if the next instruction is the last one in the // block. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(21, spv::Op::OpIAdd, 0)) + MakeInstructionDescriptor(21, SpvOpIAdd, 0)) .IsApplicable(context.get(), transformation_context)); // Can't insert instruction's opcode after its successor. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(15, spv::Op::OpIMul, 0)) + MakeInstructionDescriptor(15, SpvOpIMul, 0)) .IsApplicable(context.get(), transformation_context)); // Instruction's successor depends on the instruction. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(10, spv::Op::OpIAdd, 0)) + MakeInstructionDescriptor(10, SpvOpIAdd, 0)) .IsApplicable(context.get(), transformation_context)); { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(11, spv::Op::OpISub, 0)); + MakeInstructionDescriptor(11, SpvOpISub, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -121,7 +120,7 @@ TEST(TransformationMoveInstructionDownTest, BasicTest) { } { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(22, spv::Op::OpIAdd, 0)); + MakeInstructionDescriptor(22, SpvOpIAdd, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -219,17 +218,17 @@ TEST(TransformationMoveInstructionDownTest, HandlesUnsupportedInstructions) { MakeUnique(context.get()), validator_options); // Swap memory instruction with an unsupported one. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(22, spv::Op::OpLoad, 0)) + MakeInstructionDescriptor(22, SpvOpLoad, 0)) .IsApplicable(context.get(), transformation_context)); // Swap memory barrier with an unsupported one. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(23, spv::Op::OpMemoryBarrier, 0)) + MakeInstructionDescriptor(23, SpvOpMemoryBarrier, 0)) .IsApplicable(context.get(), transformation_context)); // Swap simple instruction with an unsupported one. TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(8, spv::Op::OpCopyObject, 0)); + MakeInstructionDescriptor(8, SpvOpCopyObject, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -323,21 +322,21 @@ TEST(TransformationMoveInstructionDownTest, HandlesBarrierInstructions) { MakeUnique(context.get()), validator_options); // Swap two barrier instructions. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(21, spv::Op::OpMemoryBarrier, 0)) + MakeInstructionDescriptor(21, SpvOpMemoryBarrier, 0)) .IsApplicable(context.get(), transformation_context)); // Swap barrier and memory instructions. ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(21, spv::Op::OpMemoryBarrier, 2)) + MakeInstructionDescriptor(21, SpvOpMemoryBarrier, 2)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationMoveInstructionDown( - MakeInstructionDescriptor(22, spv::Op::OpLoad, 0)) + MakeInstructionDescriptor(22, SpvOpLoad, 0)) .IsApplicable(context.get(), transformation_context)); // Swap barrier and simple instructions. { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(23, spv::Op::OpCopyObject, 0)); + MakeInstructionDescriptor(23, SpvOpCopyObject, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -347,7 +346,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesBarrierInstructions) { } { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(22, spv::Op::OpMemoryBarrier, 1)); + MakeInstructionDescriptor(22, SpvOpMemoryBarrier, 1)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -407,7 +406,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesSimpleInstructions) { // Swap simple and barrier instructions. { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(40, spv::Op::OpCopyObject, 0)); + MakeInstructionDescriptor(40, SpvOpCopyObject, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -417,7 +416,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesSimpleInstructions) { } { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(21, spv::Op::OpMemoryBarrier, 0)); + MakeInstructionDescriptor(21, SpvOpMemoryBarrier, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -429,7 +428,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesSimpleInstructions) { // Swap simple and memory instructions. { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(41, spv::Op::OpCopyObject, 0)); + MakeInstructionDescriptor(41, SpvOpCopyObject, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -439,7 +438,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesSimpleInstructions) { } { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(22, spv::Op::OpLoad, 0)); + MakeInstructionDescriptor(22, SpvOpLoad, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -451,7 +450,7 @@ TEST(TransformationMoveInstructionDownTest, HandlesSimpleInstructions) { // Swap two simple instructions. { TransformationMoveInstructionDown transformation( - MakeInstructionDescriptor(23, spv::Op::OpCopyObject, 0)); + MakeInstructionDescriptor(23, SpvOpCopyObject, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -626,22 +625,22 @@ TEST(TransformationMoveInstructionDownTest, HandlesMemoryInstructions) { protobufs::InstructionDescriptor invalid_swaps[] = { // R and RW - MakeInstructionDescriptor(25, spv::Op::OpLoad, 0), + MakeInstructionDescriptor(25, SpvOpLoad, 0), // R and W - MakeInstructionDescriptor(29, spv::Op::OpLoad, 0), + MakeInstructionDescriptor(29, SpvOpLoad, 0), // RW and RW - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 0), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 2), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 4), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 0), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 2), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 4), // RW and W - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 12), - MakeInstructionDescriptor(32, spv::Op::OpStore, 1), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 12), + MakeInstructionDescriptor(32, SpvOpStore, 1), // W and W - MakeInstructionDescriptor(32, spv::Op::OpStore, 6), + MakeInstructionDescriptor(32, SpvOpStore, 6), }; for (const auto& descriptor : invalid_swaps) { @@ -652,55 +651,55 @@ TEST(TransformationMoveInstructionDownTest, HandlesMemoryInstructions) { // Valid swaps. protobufs::InstructionDescriptor valid_swaps[] = { // R and R - MakeInstructionDescriptor(23, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(24, spv::Op::OpLoad, 0), + MakeInstructionDescriptor(23, SpvOpLoad, 0), + MakeInstructionDescriptor(24, SpvOpLoad, 0), // R and RW - MakeInstructionDescriptor(26, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(25, spv::Op::OpCopyMemory, 1), + MakeInstructionDescriptor(26, SpvOpLoad, 0), + MakeInstructionDescriptor(25, SpvOpCopyMemory, 1), - MakeInstructionDescriptor(27, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(26, spv::Op::OpCopyMemory, 1), + MakeInstructionDescriptor(27, SpvOpLoad, 0), + MakeInstructionDescriptor(26, SpvOpCopyMemory, 1), - MakeInstructionDescriptor(28, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(27, spv::Op::OpCopyMemory, 1), + MakeInstructionDescriptor(28, SpvOpLoad, 0), + MakeInstructionDescriptor(27, SpvOpCopyMemory, 1), // R and W - MakeInstructionDescriptor(30, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(29, spv::Op::OpStore, 1), + MakeInstructionDescriptor(30, SpvOpLoad, 0), + MakeInstructionDescriptor(29, SpvOpStore, 1), - MakeInstructionDescriptor(31, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(30, spv::Op::OpStore, 1), + MakeInstructionDescriptor(31, SpvOpLoad, 0), + MakeInstructionDescriptor(30, SpvOpStore, 1), - MakeInstructionDescriptor(32, spv::Op::OpLoad, 0), - MakeInstructionDescriptor(31, spv::Op::OpStore, 1), + MakeInstructionDescriptor(32, SpvOpLoad, 0), + MakeInstructionDescriptor(31, SpvOpStore, 1), // RW and RW - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 6), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 6), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 6), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 6), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 8), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 8), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 8), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 8), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 10), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 10), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 10), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 10), // RW and W - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 14), - MakeInstructionDescriptor(32, spv::Op::OpStore, 3), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 14), + MakeInstructionDescriptor(32, SpvOpStore, 3), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 15), - MakeInstructionDescriptor(32, spv::Op::OpStore, 4), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 15), + MakeInstructionDescriptor(32, SpvOpStore, 4), - MakeInstructionDescriptor(32, spv::Op::OpCopyMemory, 16), - MakeInstructionDescriptor(32, spv::Op::OpStore, 5), + MakeInstructionDescriptor(32, SpvOpCopyMemory, 16), + MakeInstructionDescriptor(32, SpvOpStore, 5), // W and W - MakeInstructionDescriptor(32, spv::Op::OpStore, 8), - MakeInstructionDescriptor(32, spv::Op::OpStore, 8), + MakeInstructionDescriptor(32, SpvOpStore, 8), + MakeInstructionDescriptor(32, SpvOpStore, 8), - MakeInstructionDescriptor(32, spv::Op::OpStore, 10), - MakeInstructionDescriptor(32, spv::Op::OpStore, 10), + MakeInstructionDescriptor(32, SpvOpStore, 10), + MakeInstructionDescriptor(32, SpvOpStore, 10), }; for (const auto& descriptor : valid_swaps) { diff --git a/test/fuzz/transformation_mutate_pointer_test.cpp b/test/fuzz/transformation_mutate_pointer_test.cpp index e0cb6154..e869efa6 100644 --- a/test/fuzz/transformation_mutate_pointer_test.cpp +++ b/test/fuzz/transformation_mutate_pointer_test.cpp @@ -86,8 +86,7 @@ TEST(TransformationMutatePointerTest, BasicTest) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(35); transformation_context.GetFactManager()->AddFactIdIsIrrelevant(39); - const auto insert_before = - MakeInstructionDescriptor(26, spv::Op::OpReturn, 0); + const auto insert_before = MakeInstructionDescriptor(26, SpvOpReturn, 0); // 20 is not a fresh id. ASSERT_FALSE(TransformationMutatePointer(20, 20, insert_before) @@ -95,14 +94,13 @@ TEST(TransformationMutatePointerTest, BasicTest) { // |insert_before| instruction descriptor is invalid. ASSERT_FALSE(TransformationMutatePointer( - 20, 70, MakeInstructionDescriptor(26, spv::Op::OpStore, 0)) + 20, 70, MakeInstructionDescriptor(26, SpvOpStore, 0)) .IsApplicable(context.get(), transformation_context)); // Can't insert OpLoad before OpVariable. - ASSERT_FALSE( - TransformationMutatePointer( - 20, 70, MakeInstructionDescriptor(26, spv::Op::OpVariable, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationMutatePointer( + 20, 70, MakeInstructionDescriptor(26, SpvOpVariable, 0)) + .IsApplicable(context.get(), transformation_context)); // |pointer_id| doesn't exist in the module. ASSERT_FALSE(TransformationMutatePointer(70, 70, insert_before) @@ -133,10 +131,9 @@ TEST(TransformationMutatePointerTest, BasicTest) { .IsApplicable(context.get(), transformation_context)); // |pointer_id| is not available before |insert_before|. - ASSERT_FALSE( - TransformationMutatePointer( - 26, 70, MakeInstructionDescriptor(26, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationMutatePointer( + 26, 70, MakeInstructionDescriptor(26, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); transformation_context.GetFactManager()->AddFactIdIsIrrelevant(40); @@ -277,8 +274,7 @@ TEST(TransformationMutatePointerTest, HandlesUnreachableBlocks) { ASSERT_FALSE( context->GetDominatorAnalysis(context->GetFunction(4))->IsReachable(10)); - const auto insert_before = - MakeInstructionDescriptor(10, spv::Op::OpReturn, 0); + const auto insert_before = MakeInstructionDescriptor(10, SpvOpReturn, 0); // Can mutate a global variable in an unreachable block. TransformationMutatePointer transformation(12, 50, insert_before); diff --git a/test/fuzz/transformation_permute_phi_operands_test.cpp b/test/fuzz/transformation_permute_phi_operands_test.cpp index 320dd1d4..0774dcf3 100644 --- a/test/fuzz/transformation_permute_phi_operands_test.cpp +++ b/test/fuzz/transformation_permute_phi_operands_test.cpp @@ -128,11 +128,11 @@ TEST(TransformationPermutePhiOperandsTest, BasicTest) { context->get_def_use_mgr()->ForEachUse( 25, [&found_use_in_store, &found_use_in_add_lhs, &found_use_in_add_rhs]( opt::Instruction* inst, uint32_t operand_index) { - if (inst->opcode() == spv::Op::OpStore) { + if (inst->opcode() == SpvOpStore) { ASSERT_FALSE(found_use_in_store); found_use_in_store = true; } else { - ASSERT_EQ(spv::Op::OpIAdd, inst->opcode()); + ASSERT_EQ(SpvOpIAdd, inst->opcode()); if (operand_index == 2) { ASSERT_FALSE(found_use_in_add_lhs); found_use_in_add_lhs = true; diff --git a/test/fuzz/transformation_propagate_instruction_down_test.cpp b/test/fuzz/transformation_propagate_instruction_down_test.cpp index 8bedef2c..52974cac 100644 --- a/test/fuzz/transformation_propagate_instruction_down_test.cpp +++ b/test/fuzz/transformation_propagate_instruction_down_test.cpp @@ -499,13 +499,13 @@ TEST(TransformationPropagateInstructionDownTest, VariablePointersCapability) { TransformationPropagateInstructionDown transformation( 5, 200, {{{15, 203}, {16, 204}}}); ASSERT_FALSE(context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - context->AddCapability(spv::Capability::VariablePointers); + context->AddCapability(SpvCapabilityVariablePointers); ASSERT_TRUE(context->get_feature_mgr()->HasCapability( - spv::Capability::VariablePointersStorageBuffer)); + SpvCapabilityVariablePointersStorageBuffer)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), diff --git a/test/fuzz/transformation_propagate_instruction_up_test.cpp b/test/fuzz/transformation_propagate_instruction_up_test.cpp index 20cf4b3e..8a04270f 100644 --- a/test/fuzz/transformation_propagate_instruction_up_test.cpp +++ b/test/fuzz/transformation_propagate_instruction_up_test.cpp @@ -699,7 +699,7 @@ TEST(TransformationPropagateInstructionUpTest, ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - context->AddCapability(spv::Capability::VariablePointers); + context->AddCapability(SpvCapabilityVariablePointers); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -779,7 +779,7 @@ TEST(TransformationPropagateInstructionUpTest, ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - context->AddCapability(spv::Capability::VariablePointersStorageBuffer); + context->AddCapability(SpvCapabilityVariablePointersStorageBuffer); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); diff --git a/test/fuzz/transformation_push_id_through_variable_test.cpp b/test/fuzz/transformation_push_id_through_variable_test.cpp index 0d4850d4..b0fff588 100644 --- a/test/fuzz/transformation_push_id_through_variable_test.cpp +++ b/test/fuzz/transformation_push_id_through_variable_test.cpp @@ -110,9 +110,9 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { uint32_t value_synonym_id = 62; uint32_t variable_id = 63; uint32_t initializer_id = 23; - uint32_t variable_storage_class = (uint32_t)spv::StorageClass::Private; + uint32_t variable_storage_class = SpvStorageClassPrivate; auto instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0); auto transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -124,9 +124,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 60; variable_id = 61; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(38, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -138,9 +137,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(64, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(64, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -153,9 +151,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 24; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(27, spv::Op::OpVariable, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(27, SpvOpVariable, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -167,9 +164,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(100, spv::Op::OpUnreachable, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(100, SpvOpUnreachable, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -181,9 +177,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 23; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -195,9 +190,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Private; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassPrivate; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -209,9 +203,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 93; - variable_storage_class = (uint32_t)spv::StorageClass::Input; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassInput; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -226,9 +219,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(40, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -240,9 +232,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 95; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(40, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -254,9 +245,8 @@ TEST(TransformationPushIdThroughVariableTest, IsApplicable) { value_synonym_id = 62; variable_id = 63; initializer_id = 93; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(40, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -345,9 +335,9 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { uint32_t value_synonym_id = 100; uint32_t variable_id = 101; uint32_t initializer_id = 80; - uint32_t variable_storage_class = (uint32_t)spv::StorageClass::Function; + uint32_t variable_storage_class = SpvStorageClassFunction; auto instruction_descriptor = - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0); + MakeInstructionDescriptor(38, SpvOpAccessChain, 0); auto transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -356,18 +346,18 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(variable_id)); ASSERT_EQ(nullptr, context->get_instr_block(variable_id)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpLoad, + ASSERT_EQ(SpvOpLoad, context->get_def_use_mgr()->GetDef(value_synonym_id)->opcode()); ASSERT_EQ(36, context->get_instr_block(value_synonym_id)->id()); - ASSERT_EQ(spv::Op::OpVariable, + ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(variable_id)->opcode()); ASSERT_EQ(5, context->get_instr_block(variable_id)->id()); uint32_t variable_use_count = 0; context->get_def_use_mgr()->ForEachUse( variable_id, [&variable_use_count](opt::Instruction* inst, uint32_t /*unused*/) { - ASSERT_TRUE(inst->opcode() == spv::Op::OpLoad || - inst->opcode() == spv::Op::OpStore); + ASSERT_TRUE(inst->opcode() == SpvOpLoad || + inst->opcode() == SpvOpStore); variable_use_count++; }); ASSERT_EQ(2, variable_use_count); @@ -376,9 +366,8 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { value_synonym_id = 102; variable_id = 103; initializer_id = 21; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(38, SpvOpAccessChain, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -388,9 +377,8 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { value_synonym_id = 104; variable_id = 105; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -400,9 +388,8 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { value_synonym_id = 106; variable_id = 107; initializer_id = 80; - variable_storage_class = (uint32_t)spv::StorageClass::Function; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassFunction; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -412,9 +399,8 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { value_synonym_id = 108; variable_id = 109; initializer_id = 21; - variable_storage_class = (uint32_t)spv::StorageClass::Private; - instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + variable_storage_class = SpvStorageClassPrivate; + instruction_descriptor = MakeInstructionDescriptor(95, SpvOpReturnValue, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -424,8 +410,8 @@ TEST(TransformationPushIdThroughVariableTest, Apply) { value_synonym_id = 110; variable_id = 111; initializer_id = 21; - variable_storage_class = (uint32_t)spv::StorageClass::Private; - instruction_descriptor = MakeInstructionDescriptor(27, spv::Op::OpStore, 0); + variable_storage_class = SpvStorageClassPrivate; + instruction_descriptor = MakeInstructionDescriptor(27, SpvOpStore, 0); transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -616,9 +602,9 @@ TEST(TransformationPushIdThroughVariableTest, AddSynonymsForRelevantIds) { uint32_t value_synonym_id = 62; uint32_t variable_id = 63; uint32_t initializer_id = 23; - uint32_t variable_storage_class = (uint32_t)spv::StorageClass::Private; + uint32_t variable_storage_class = SpvStorageClassPrivate; auto instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0); auto transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -719,9 +705,9 @@ TEST(TransformationPushIdThroughVariableTest, DontAddSynonymsForIrrelevantIds) { uint32_t value_synonym_id = 62; uint32_t variable_id = 63; uint32_t initializer_id = 23; - uint32_t variable_storage_class = (uint32_t)spv::StorageClass::Private; + uint32_t variable_storage_class = SpvStorageClassPrivate; auto instruction_descriptor = - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0); auto transformation = TransformationPushIdThroughVariable( value_id, value_synonym_id, variable_id, variable_storage_class, initializer_id, instruction_descriptor); @@ -780,8 +766,8 @@ TEST(TransformationPushIdThroughVariableTest, DontAddSynonymsInDeadBlocks) { transformation_context.GetFactManager()->AddFactBlockIsDead(15); auto transformation = TransformationPushIdThroughVariable( - 14, 100, 101, uint32_t(spv::StorageClass::Function), 14, - MakeInstructionDescriptor(15, spv::Op::OpBranch, 0)); + 14, 100, 101, SpvStorageClassFunction, 14, + MakeInstructionDescriptor(15, SpvOpBranch, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp index 65cf3d43..b8c2a8ad 100644 --- a/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp +++ b/test/fuzz/transformation_replace_boolean_constant_with_constant_binary_test.cpp @@ -167,38 +167,34 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); std::vector uses_of_true = { - MakeIdUseDescriptor( - 41, MakeInstructionDescriptor(44, spv::Op::OpStore, 12), 1), - MakeIdUseDescriptor( - 41, MakeInstructionDescriptor(46, spv::Op::OpLogicalOr, 0), 0)}; + MakeIdUseDescriptor(41, MakeInstructionDescriptor(44, SpvOpStore, 12), 1), + MakeIdUseDescriptor(41, MakeInstructionDescriptor(46, SpvOpLogicalOr, 0), + 0)}; std::vector uses_of_false = { - MakeIdUseDescriptor( - 43, MakeInstructionDescriptor(44, spv::Op::OpStore, 13), 1), - MakeIdUseDescriptor( - 43, MakeInstructionDescriptor(48, spv::Op::OpLogicalAnd, 0), 1)}; + MakeIdUseDescriptor(43, MakeInstructionDescriptor(44, SpvOpStore, 13), 1), + MakeIdUseDescriptor(43, MakeInstructionDescriptor(48, SpvOpLogicalAnd, 0), + 1)}; const uint32_t fresh_id = 100; - std::vector fp_gt_opcodes = { - spv::Op::OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThanEqual, - spv::Op::OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThanEqual}; + std::vector fp_gt_opcodes = { + SpvOpFOrdGreaterThan, SpvOpFOrdGreaterThanEqual, SpvOpFUnordGreaterThan, + SpvOpFUnordGreaterThanEqual}; - std::vector fp_lt_opcodes = { - spv::Op::OpFOrdLessThan, spv::Op::OpFOrdLessThanEqual, - spv::Op::OpFUnordLessThan, spv::Op::OpFUnordLessThanEqual}; + std::vector fp_lt_opcodes = {SpvOpFOrdLessThan, SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThan, + SpvOpFUnordLessThanEqual}; - std::vector int_gt_opcodes = {spv::Op::OpSGreaterThan, - spv::Op::OpSGreaterThanEqual}; + std::vector int_gt_opcodes = {SpvOpSGreaterThan, + SpvOpSGreaterThanEqual}; - std::vector int_lt_opcodes = {spv::Op::OpSLessThan, - spv::Op::OpSLessThanEqual}; + std::vector int_lt_opcodes = {SpvOpSLessThan, SpvOpSLessThanEqual}; - std::vector uint_gt_opcodes = {spv::Op::OpUGreaterThan, - spv::Op::OpUGreaterThanEqual}; + std::vector uint_gt_opcodes = {SpvOpUGreaterThan, + SpvOpUGreaterThanEqual}; - std::vector uint_lt_opcodes = {spv::Op::OpULessThan, - spv::Op::OpULessThanEqual}; + std::vector uint_lt_opcodes = {SpvOpULessThan, SpvOpULessThanEqual}; #define CHECK_OPERATOR(USE_DESCRIPTOR, LHS_ID, RHS_ID, OPCODE, FRESH_ID) \ ASSERT_TRUE(TransformationReplaceBooleanConstantWithConstantBinary( \ @@ -257,41 +253,41 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // Target id is not fresh ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 15, 17, spv::Op::OpFOrdLessThan, 15) + uses_of_true[0], 15, 17, SpvOpFOrdLessThan, 15) .IsApplicable(context.get(), transformation_context)); // LHS id does not exist ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 300, 17, spv::Op::OpFOrdLessThan, 200) + uses_of_true[0], 300, 17, SpvOpFOrdLessThan, 200) .IsApplicable(context.get(), transformation_context)); // RHS id does not exist ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 15, 300, spv::Op::OpFOrdLessThan, 200) + uses_of_true[0], 15, 300, SpvOpFOrdLessThan, 200) .IsApplicable(context.get(), transformation_context)); // LHS and RHS ids do not match type ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 11, 17, spv::Op::OpFOrdLessThan, 200) + uses_of_true[0], 11, 17, SpvOpFOrdLessThan, 200) .IsApplicable(context.get(), transformation_context)); // Opcode not appropriate ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 15, 17, spv::Op::OpFDiv, 200) + uses_of_true[0], 15, 17, SpvOpFDiv, 200) .IsApplicable(context.get(), transformation_context)); auto replace_true_with_double_comparison = TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 11, 9, spv::Op::OpFUnordGreaterThan, 100); + uses_of_true[0], 11, 9, SpvOpFUnordGreaterThan, 100); auto replace_true_with_uint32_comparison = TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[1], 27, 29, spv::Op::OpULessThanEqual, 101); + uses_of_true[1], 27, 29, SpvOpULessThanEqual, 101); auto replace_false_with_float_comparison = TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_false[0], 17, 15, spv::Op::OpFOrdLessThan, 102); + uses_of_false[0], 17, 15, SpvOpFOrdLessThan, 102); auto replace_false_with_sint64_comparison = TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_false[1], 33, 31, spv::Op::OpSLessThan, 103); + uses_of_false[1], 33, 31, SpvOpSLessThan, 103); ASSERT_TRUE(replace_true_with_double_comparison.IsApplicable( context.get(), transformation_context)); @@ -427,13 +423,13 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, 6, 200, operands)); + context.get(), SpvOpConstant, 6, 200, operands)); fuzzerutil::UpdateModuleIdBound(context.get(), 200); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( context.get(), validator_options, kConsoleMessageConsumer)); // The transformation is not applicable because %200 is NaN. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 11, 200, spv::Op::OpFOrdLessThan, 300) + uses_of_true[0], 11, 200, SpvOpFOrdLessThan, 300) .IsApplicable(context.get(), transformation_context)); } if (std::numeric_limits::has_infinity) { @@ -444,14 +440,14 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words[0]}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words[1]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, 6, 201, operands)); + context.get(), SpvOpConstant, 6, 201, operands)); fuzzerutil::UpdateModuleIdBound(context.get(), 201); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( context.get(), validator_options, kConsoleMessageConsumer)); // Even though the double constant %11 is less than the infinity %201, the // transformation is restricted to only apply to finite values. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 11, 201, spv::Op::OpFOrdLessThan, 300) + uses_of_true[0], 11, 201, SpvOpFOrdLessThan, 300) .IsApplicable(context.get(), transformation_context)); } if (std::numeric_limits::has_infinity) { @@ -463,14 +459,13 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, memcpy(words_negative_infinity, &negative_infinity_float, sizeof(float)); opt::Instruction::OperandList operands_positive_infinity = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words_positive_infinity[0]}}}; - context->module()->AddGlobalValue( - MakeUnique(context.get(), spv::Op::OpConstant, 12, - 202, operands_positive_infinity)); + context->module()->AddGlobalValue(MakeUnique( + context.get(), SpvOpConstant, 12, 202, operands_positive_infinity)); fuzzerutil::UpdateModuleIdBound(context.get(), 202); opt::Instruction::OperandList operands = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {words_negative_infinity[0]}}}; context->module()->AddGlobalValue(MakeUnique( - context.get(), spv::Op::OpConstant, 12, 203, operands)); + context.get(), SpvOpConstant, 12, 203, operands)); fuzzerutil::UpdateModuleIdBound(context.get(), 203); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( context.get(), validator_options, kConsoleMessageConsumer)); @@ -478,7 +473,7 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, // infinity %202, the transformation is restricted to only apply to finite // values. ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( - uses_of_true[0], 203, 202, spv::Op::OpFOrdLessThan, 300) + uses_of_true[0], 203, 202, SpvOpFOrdLessThan, 300) .IsApplicable(context.get(), transformation_context)); } } @@ -552,14 +547,14 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto use_of_true_in_if = MakeIdUseDescriptor( - 13, MakeInstructionDescriptor(10, spv::Op::OpBranchConditional, 0), 0); + 13, MakeInstructionDescriptor(10, SpvOpBranchConditional, 0), 0); auto use_of_false_in_while = MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(16, spv::Op::OpBranchConditional, 0), 0); + 21, MakeInstructionDescriptor(16, SpvOpBranchConditional, 0), 0); auto replacement_1 = TransformationReplaceBooleanConstantWithConstantBinary( - use_of_true_in_if, 9, 11, spv::Op::OpSLessThan, 100); + use_of_true_in_if, 9, 11, SpvOpSLessThan, 100); auto replacement_2 = TransformationReplaceBooleanConstantWithConstantBinary( - use_of_false_in_while, 9, 11, spv::Op::OpSGreaterThanEqual, 101); + use_of_false_in_while, 9, 11, SpvOpSGreaterThanEqual, 101); ASSERT_TRUE( replacement_1.IsApplicable(context.get(), transformation_context)); @@ -667,11 +662,10 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, OpPhi) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto instruction_descriptor = - MakeInstructionDescriptor(14, spv::Op::OpPhi, 0); + auto instruction_descriptor = MakeInstructionDescriptor(14, SpvOpPhi, 0); auto id_use_descriptor = MakeIdUseDescriptor(8, instruction_descriptor, 0); auto transformation = TransformationReplaceBooleanConstantWithConstantBinary( - id_use_descriptor, 6, 7, spv::Op::OpULessThan, 15); + id_use_descriptor, 6, 7, SpvOpULessThan, 15); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -746,12 +740,11 @@ TEST(TransformationReplaceBooleanConstantWithConstantBinaryTest, kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_FALSE( - TransformationReplaceBooleanConstantWithConstantBinary( - MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(50, spv::Op::OpVariable, 0), 1), - 13, 15, spv::Op::OpSLessThan, 100) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceBooleanConstantWithConstantBinary( + MakeIdUseDescriptor( + 9, MakeInstructionDescriptor(50, SpvOpVariable, 0), 1), + 13, 15, SpvOpSLessThan, 100) + .IsApplicable(context.get(), transformation_context)); } } // namespace diff --git a/test/fuzz/transformation_replace_branch_from_dead_block_with_exit_test.cpp b/test/fuzz/transformation_replace_branch_from_dead_block_with_exit_test.cpp index 012e3172..6bba14f6 100644 --- a/test/fuzz/transformation_replace_branch_from_dead_block_with_exit_test.cpp +++ b/test/fuzz/transformation_replace_branch_from_dead_block_with_exit_test.cpp @@ -79,37 +79,35 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, BasicTest) { transformation_context.GetFactManager()->AddFactBlockIsDead(20); // Bad: 4 is not a block - ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(4, spv::Op::OpKill, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit(4, SpvOpKill, 0) + .IsApplicable(context.get(), transformation_context)); // Bad: 200 does not exist ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(200, spv::Op::OpKill, 0) + TransformationReplaceBranchFromDeadBlockWithExit(200, SpvOpKill, 0) .IsApplicable(context.get(), transformation_context)); // Bad: 21 is not a dead block ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(21, spv::Op::OpKill, 0) + TransformationReplaceBranchFromDeadBlockWithExit(21, SpvOpKill, 0) .IsApplicable(context.get(), transformation_context)); // Bad: terminator of 8 is not OpBranch - ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(8, spv::Op::OpKill, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit(8, SpvOpKill, 0) + .IsApplicable(context.get(), transformation_context)); // Bad: 10's successor only has 10 as a predecessor ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(10, spv::Op::OpKill, 0) + TransformationReplaceBranchFromDeadBlockWithExit(10, SpvOpKill, 0) .IsApplicable(context.get(), transformation_context)); #ifndef NDEBUG ASSERT_DEATH( - TransformationReplaceBranchFromDeadBlockWithExit(20, spv::Op::OpSwitch, 0) + TransformationReplaceBranchFromDeadBlockWithExit(20, SpvOpSwitch, 0) .IsApplicable(context.get(), transformation_context), "Invalid early exit opcode."); #endif auto transformation1 = - TransformationReplaceBranchFromDeadBlockWithExit(20, spv::Op::OpKill, 0); + TransformationReplaceBranchFromDeadBlockWithExit(20, SpvOpKill, 0); auto transformation2 = - TransformationReplaceBranchFromDeadBlockWithExit(16, spv::Op::OpKill, 0); + TransformationReplaceBranchFromDeadBlockWithExit(16, SpvOpKill, 0); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( @@ -283,48 +281,48 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, // Bad: OpKill not allowed in vertex shader ASSERT_FALSE( - TransformationReplaceBranchFromDeadBlockWithExit(201, spv::Op::OpKill, 0) + TransformationReplaceBranchFromDeadBlockWithExit(201, SpvOpKill, 0) .IsApplicable(context.get(), transformation_context)); // Bad: OpReturn is not allowed in function that expects a returned value. - ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 200, spv::Op::OpReturn, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationReplaceBranchFromDeadBlockWithExit(200, SpvOpReturn, 0) + .IsApplicable(context.get(), transformation_context)); // Bad: Return value id does not exist ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 201, spv::Op::OpReturnValue, 1000) + 201, SpvOpReturnValue, 1000) .IsApplicable(context.get(), transformation_context)); // Bad: Return value id does not have a type - ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 200, spv::Op::OpReturnValue, 6) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationReplaceBranchFromDeadBlockWithExit(200, SpvOpReturnValue, 6) + .IsApplicable(context.get(), transformation_context)); // Bad: Return value id does not have the right type ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 201, spv::Op::OpReturnValue, 48) + 201, SpvOpReturnValue, 48) .IsApplicable(context.get(), transformation_context)); // Bad: Return value id is not available ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 200, spv::Op::OpReturnValue, 400) + 200, SpvOpReturnValue, 400) .IsApplicable(context.get(), transformation_context)); // Bad: Early exit now allowed in continue construct - ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 101, spv::Op::OpUnreachable, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationReplaceBranchFromDeadBlockWithExit(101, SpvOpUnreachable, 0) + .IsApplicable(context.get(), transformation_context)); // Bad: Early exit now allowed in continue construct (again) ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 300, spv::Op::OpReturnValue, 14) + 300, SpvOpReturnValue, 14) .IsApplicable(context.get(), transformation_context)); auto transformation1 = TransformationReplaceBranchFromDeadBlockWithExit( - 200, spv::Op::OpUnreachable, 0); + 200, SpvOpUnreachable, 0); auto transformation2 = TransformationReplaceBranchFromDeadBlockWithExit( - 201, spv::Op::OpReturnValue, 400); + 201, SpvOpReturnValue, 400); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); @@ -341,7 +339,7 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, opt::Instruction* return_value_inst = context->get_instr_block(201)->terminator(); - ASSERT_EQ(spv::Op::OpReturnValue, return_value_inst->opcode()); + ASSERT_EQ(SpvOpReturnValue, return_value_inst->opcode()); ASSERT_EQ(SPV_OPERAND_TYPE_ID, return_value_inst->GetInOperand(0).type); ASSERT_EQ(400, return_value_inst->GetSingleWordInOperand(0)); @@ -506,9 +504,9 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, OpPhi) { transformation_context.GetFactManager()->AddFactBlockIsDead(20); auto transformation1 = - TransformationReplaceBranchFromDeadBlockWithExit(20, spv::Op::OpKill, 0); + TransformationReplaceBranchFromDeadBlockWithExit(20, SpvOpKill, 0); auto transformation2 = - TransformationReplaceBranchFromDeadBlockWithExit(16, spv::Op::OpKill, 0); + TransformationReplaceBranchFromDeadBlockWithExit(16, SpvOpKill, 0); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( @@ -611,9 +609,9 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, transformation_context.GetFactManager()->AddFactBlockIsDead(9); transformation_context.GetFactManager()->AddFactBlockIsDead(11); - ASSERT_FALSE(TransformationReplaceBranchFromDeadBlockWithExit( - 11, spv::Op::OpUnreachable, 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationReplaceBranchFromDeadBlockWithExit(11, SpvOpUnreachable, 0) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, @@ -660,7 +658,7 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, transformation_context.GetFactManager()->AddFactBlockIsDead(11); TransformationReplaceBranchFromDeadBlockWithExit transformation( - 11, spv::Op::OpUnreachable, 0); + 11, SpvOpUnreachable, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); transformation.Apply(context.get(), &transformation_context); @@ -743,7 +741,7 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, transformation_context.GetFactManager()->AddFactBlockIsDead(13); TransformationReplaceBranchFromDeadBlockWithExit transformation( - 13, spv::Op::OpUnreachable, 0); + 13, SpvOpUnreachable, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); transformation.Apply(context.get(), &transformation_context); @@ -825,7 +823,7 @@ TEST(TransformationReplaceBranchFromDeadBlockWithExitTest, transformation_context.GetFactManager()->AddFactBlockIsDead(10); TransformationReplaceBranchFromDeadBlockWithExit transformation( - 10, spv::Op::OpUnreachable, 0); + 10, SpvOpUnreachable, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); transformation.Apply(context.get(), &transformation_context); diff --git a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp index 7c6d1263..fe760680 100644 --- a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp +++ b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp @@ -121,12 +121,12 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { ASSERT_TRUE(AddFactHelper(&transformation_context, 3, blockname_c)); // The constant ids are 9, 11 and 14, for 1, 2 and 3 respectively. - protobufs::IdUseDescriptor use_of_9_in_store = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(8, spv::Op::OpStore, 0), 1); - protobufs::IdUseDescriptor use_of_11_in_add = MakeIdUseDescriptor( - 11, MakeInstructionDescriptor(12, spv::Op::OpIAdd, 0), 1); - protobufs::IdUseDescriptor use_of_14_in_add = MakeIdUseDescriptor( - 14, MakeInstructionDescriptor(15, spv::Op::OpIAdd, 0), 0); + protobufs::IdUseDescriptor use_of_9_in_store = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(8, SpvOpStore, 0), 1); + protobufs::IdUseDescriptor use_of_11_in_add = + MakeIdUseDescriptor(11, MakeInstructionDescriptor(12, SpvOpIAdd, 0), 1); + protobufs::IdUseDescriptor use_of_14_in_add = + MakeIdUseDescriptor(14, MakeInstructionDescriptor(15, SpvOpIAdd, 0), 0); // These transformations work: they match the facts. auto transformation_use_of_9_in_store = @@ -172,8 +172,8 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { // The following transformation does not apply because the id descriptor is // not sensible. - protobufs::IdUseDescriptor nonsense_id_use_descriptor = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(15, spv::Op::OpIAdd, 0), 0); + protobufs::IdUseDescriptor nonsense_id_use_descriptor = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(15, SpvOpIAdd, 0), 0); ASSERT_FALSE(TransformationReplaceConstantWithUniform( nonsense_id_use_descriptor, blockname_a, 101, 102) .IsApplicable(context.get(), transformation_context)); @@ -490,14 +490,14 @@ TEST(TransformationReplaceConstantWithUniformTest, NestedStruct) { ASSERT_TRUE(AddFactHelper(&transformation_context, 4, blockname_4)); // The constant ids are 13, 15, 17 and 20, for 1, 2, 3 and 4 respectively. - protobufs::IdUseDescriptor use_of_13_in_store = MakeIdUseDescriptor( - 13, MakeInstructionDescriptor(21, spv::Op::OpStore, 0), 1); - protobufs::IdUseDescriptor use_of_15_in_add = MakeIdUseDescriptor( - 15, MakeInstructionDescriptor(16, spv::Op::OpIAdd, 0), 1); - protobufs::IdUseDescriptor use_of_17_in_add = MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(19, spv::Op::OpIAdd, 0), 0); - protobufs::IdUseDescriptor use_of_20_in_store = MakeIdUseDescriptor( - 20, MakeInstructionDescriptor(19, spv::Op::OpStore, 1), 1); + protobufs::IdUseDescriptor use_of_13_in_store = + MakeIdUseDescriptor(13, MakeInstructionDescriptor(21, SpvOpStore, 0), 1); + protobufs::IdUseDescriptor use_of_15_in_add = + MakeIdUseDescriptor(15, MakeInstructionDescriptor(16, SpvOpIAdd, 0), 1); + protobufs::IdUseDescriptor use_of_17_in_add = + MakeIdUseDescriptor(17, MakeInstructionDescriptor(19, SpvOpIAdd, 0), 0); + protobufs::IdUseDescriptor use_of_20_in_store = + MakeIdUseDescriptor(20, MakeInstructionDescriptor(19, SpvOpStore, 1), 1); // These transformations work: they match the facts. auto transformation_use_of_13_in_store = @@ -726,8 +726,8 @@ TEST(TransformationReplaceConstantWithUniformTest, NoUniformIntPointerPresent) { ASSERT_TRUE(AddFactHelper(&transformation_context, 0, blockname_0)); // The constant id is 9 for 0. - protobufs::IdUseDescriptor use_of_9_in_store = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(8, spv::Op::OpStore, 0), 1); + protobufs::IdUseDescriptor use_of_9_in_store = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(8, SpvOpStore, 0), 1); // This transformation is not available because no uniform pointer to integer // type is present: @@ -803,8 +803,8 @@ TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) { ASSERT_TRUE(AddFactHelper(&transformation_context, 9, blockname_9)); // The constant id is 9 for 9. - protobufs::IdUseDescriptor use_of_9_in_store = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(8, spv::Op::OpStore, 0), 1); + protobufs::IdUseDescriptor use_of_9_in_store = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(8, SpvOpStore, 0), 1); // This transformation is not available because no constant is present for the // index 1 required to index into the uniform buffer: @@ -879,8 +879,8 @@ TEST(TransformationReplaceConstantWithUniformTest, AddFactHelper(&transformation_context, float_data[0], blockname_3)); // The constant id is 9 for 3.0. - protobufs::IdUseDescriptor use_of_9_in_store = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(8, spv::Op::OpStore, 0), 1); + protobufs::IdUseDescriptor use_of_9_in_store = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(8, SpvOpStore, 0), 1); // This transformation is not available because no integer type is present to // allow a constant index to be expressed: @@ -966,10 +966,10 @@ TEST(TransformationReplaceConstantWithUniformTest, ASSERT_TRUE(AddFactHelper(&transformation_context, 10, blockname_10)); // The constant ids for 9 and 10 are 9 and 11 respectively - protobufs::IdUseDescriptor use_of_9_in_store = MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(10, spv::Op::OpStore, 0), 1); - protobufs::IdUseDescriptor use_of_11_in_store = MakeIdUseDescriptor( - 11, MakeInstructionDescriptor(10, spv::Op::OpStore, 1), 1); + protobufs::IdUseDescriptor use_of_9_in_store = + MakeIdUseDescriptor(9, MakeInstructionDescriptor(10, SpvOpStore, 0), 1); + protobufs::IdUseDescriptor use_of_11_in_store = + MakeIdUseDescriptor(11, MakeInstructionDescriptor(10, SpvOpStore, 1), 1); // These are right: ASSERT_TRUE(TransformationReplaceConstantWithUniform(use_of_9_in_store, @@ -1251,73 +1251,57 @@ TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { std::vector transformations; transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 18, MakeInstructionDescriptor(20, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(18, MakeInstructionDescriptor(20, SpvOpStore, 0), 1), uniform_f_a_4, 200, 201)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 22, MakeInstructionDescriptor(23, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(22, MakeInstructionDescriptor(23, SpvOpStore, 0), 1), uniform_f_a_3, 202, 203)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 25, MakeInstructionDescriptor(26, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(25, MakeInstructionDescriptor(26, SpvOpStore, 0), 1), uniform_f_a_2, 204, 205)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 28, MakeInstructionDescriptor(29, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(28, MakeInstructionDescriptor(29, SpvOpStore, 0), 1), uniform_f_a_1, 206, 207)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 31, MakeInstructionDescriptor(32, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(31, MakeInstructionDescriptor(32, SpvOpStore, 0), 1), uniform_f_a_0, 208, 209)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 30, MakeInstructionDescriptor(35, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(30, MakeInstructionDescriptor(35, SpvOpStore, 0), 1), uniform_f_b_w, 210, 211)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 27, MakeInstructionDescriptor(37, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(27, MakeInstructionDescriptor(37, SpvOpStore, 0), 1), uniform_f_b_z, 212, 213)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 24, MakeInstructionDescriptor(39, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(24, MakeInstructionDescriptor(39, SpvOpStore, 0), 1), uniform_f_b_y, 214, 215)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(41, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(21, MakeInstructionDescriptor(41, SpvOpStore, 0), 1), uniform_f_b_x, 216, 217)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 44, MakeInstructionDescriptor(45, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(44, MakeInstructionDescriptor(45, SpvOpStore, 0), 1), uniform_f_c_z, 220, 221)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 46, MakeInstructionDescriptor(47, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(46, MakeInstructionDescriptor(47, SpvOpStore, 0), 1), uniform_f_c_y, 222, 223)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 48, MakeInstructionDescriptor(49, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(48, MakeInstructionDescriptor(49, SpvOpStore, 0), 1), uniform_f_c_x, 224, 225)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 50, MakeInstructionDescriptor(52, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(50, MakeInstructionDescriptor(52, SpvOpStore, 0), 1), uniform_f_d, 226, 227)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 53, MakeInstructionDescriptor(54, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(53, MakeInstructionDescriptor(54, SpvOpStore, 0), 1), uniform_h_x, 228, 229)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 55, MakeInstructionDescriptor(56, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(55, MakeInstructionDescriptor(56, SpvOpStore, 0), 1), uniform_h_y, 230, 231)); transformations.emplace_back(TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 42, MakeInstructionDescriptor(43, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(42, MakeInstructionDescriptor(43, SpvOpStore, 0), 1), uniform_g, 218, 219)); for (auto& transformation : transformations) { @@ -1536,12 +1520,11 @@ TEST(TransformationReplaceConstantWithUniformTest, ASSERT_TRUE(AddFactHelper(&transformation_context, 0, blockname_a)); - ASSERT_FALSE( - TransformationReplaceConstantWithUniform( - MakeIdUseDescriptor( - 50, MakeInstructionDescriptor(8, spv::Op::OpVariable, 0), 1), - blockname_a, 100, 101) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceConstantWithUniform( + MakeIdUseDescriptor( + 50, MakeInstructionDescriptor(8, SpvOpVariable, 0), 1), + blockname_a, 100, 101) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceConstantWithUniformTest, ReplaceOpPhiOperand) { @@ -1596,8 +1579,7 @@ TEST(TransformationReplaceConstantWithUniformTest, ReplaceOpPhiOperand) { { TransformationReplaceConstantWithUniform transformation( - MakeIdUseDescriptor(7, MakeInstructionDescriptor(23, spv::Op::OpPhi, 0), - 0), + MakeIdUseDescriptor(7, MakeInstructionDescriptor(23, SpvOpPhi, 0), 0), int_descriptor, 50, 51); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); diff --git a/test/fuzz/transformation_replace_copy_memory_with_load_store_test.cpp b/test/fuzz/transformation_replace_copy_memory_with_load_store_test.cpp index 689cf193..bcd04afa 100644 --- a/test/fuzz/transformation_replace_copy_memory_with_load_store_test.cpp +++ b/test/fuzz/transformation_replace_copy_memory_with_load_store_test.cpp @@ -75,11 +75,11 @@ TEST(TransformationReplaceCopyMemoryWithLoadStoreTest, BasicScenarios) { kConsoleMessageConsumer)); auto instruction_descriptor_invalid_1 = - MakeInstructionDescriptor(5, spv::Op::OpStore, 0); + MakeInstructionDescriptor(5, SpvOpStore, 0); auto instruction_descriptor_valid_1 = - MakeInstructionDescriptor(5, spv::Op::OpCopyMemory, 0); + MakeInstructionDescriptor(5, SpvOpCopyMemory, 0); auto instruction_descriptor_valid_2 = - MakeInstructionDescriptor(5, spv::Op::OpCopyMemory, 0); + MakeInstructionDescriptor(5, SpvOpCopyMemory, 0); // Invalid: |source_id| is not a fresh id. auto transformation_invalid_1 = TransformationReplaceCopyMemoryWithLoadStore( diff --git a/test/fuzz/transformation_replace_copy_object_with_store_load_test.cpp b/test/fuzz/transformation_replace_copy_object_with_store_load_test.cpp index 368e2086..fa8c068e 100644 --- a/test/fuzz/transformation_replace_copy_object_with_store_load_test.cpp +++ b/test/fuzz/transformation_replace_copy_object_with_store_load_test.cpp @@ -88,45 +88,44 @@ TEST(TransformationReplaceCopyObjectWithStoreLoad, BasicScenarios) { // Invalid: fresh_variable_id=10 is not fresh. auto transformation_invalid_1 = TransformationReplaceCopyObjectWithStoreLoad( - 27, 10, (uint32_t)spv::StorageClass::Function, 9); + 27, 10, SpvStorageClassFunction, 9); ASSERT_FALSE(transformation_invalid_1.IsApplicable(context.get(), transformation_context)); // Invalid: copy_object_result_id=26 is not a CopyObject instruction. auto transformation_invalid_2 = TransformationReplaceCopyObjectWithStoreLoad( - 26, 30, (uint32_t)spv::StorageClass::Function, 9); + 26, 30, SpvStorageClassFunction, 9); ASSERT_FALSE(transformation_invalid_2.IsApplicable(context.get(), transformation_context)); // Invalid: copy_object_result_id=40 is of type pointer. auto transformation_invalid_3 = TransformationReplaceCopyObjectWithStoreLoad( - 40, 30, (uint32_t)spv::StorageClass::Function, 9); + 40, 30, SpvStorageClassFunction, 9); ASSERT_FALSE(transformation_invalid_3.IsApplicable(context.get(), transformation_context)); // Invalid: Pointer type instruction in this storage class pointing to the // value type is not defined. auto transformation_invalid_4 = TransformationReplaceCopyObjectWithStoreLoad( - 40, 30, (uint32_t)spv::StorageClass::Private, 9); + 40, 30, SpvStorageClassPrivate, 9); ASSERT_FALSE(transformation_invalid_4.IsApplicable(context.get(), transformation_context)); // Invalid: initializer_id=15 has the wrong type relative to the OpCopyObject // instruction. auto transformation_invalid_5 = TransformationReplaceCopyObjectWithStoreLoad( - 27, 30, (uint32_t)spv::StorageClass::Function, 15); + 27, 30, SpvStorageClassFunction, 15); ASSERT_FALSE(transformation_invalid_5.IsApplicable(context.get(), transformation_context)); - // Invalid: spv::StorageClass::Uniform is not applicable to the - // transformation. + // Invalid: SpvStorageClassUniform is not applicable to the transformation. auto transformation_invalid_6 = TransformationReplaceCopyObjectWithStoreLoad( - 27, 30, (uint32_t)spv::StorageClass::Uniform, 9); + 27, 30, SpvStorageClassUniform, 9); ASSERT_FALSE(transformation_invalid_6.IsApplicable(context.get(), transformation_context)); auto transformation_valid_1 = TransformationReplaceCopyObjectWithStoreLoad( - 27, 30, (uint32_t)spv::StorageClass::Function, 9); + 27, 30, SpvStorageClassFunction, 9); ASSERT_TRUE(transformation_valid_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_valid_1, context.get(), @@ -135,7 +134,7 @@ TEST(TransformationReplaceCopyObjectWithStoreLoad, BasicScenarios) { kConsoleMessageConsumer)); auto transformation_valid_2 = TransformationReplaceCopyObjectWithStoreLoad( - 28, 32, (uint32_t)spv::StorageClass::Private, 15); + 28, 32, SpvStorageClassPrivate, 15); ASSERT_TRUE(transformation_valid_2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_valid_2, context.get(), @@ -245,7 +244,7 @@ TEST(TransformationReplaceCopyObjectWithStoreLoad, IrrelevantIdsAndDeadBlocks) { transformation_context.GetFactManager()->AddFactIdIsIrrelevant(11); auto transformation_1 = TransformationReplaceCopyObjectWithStoreLoad( - 50, 100, (uint32_t)spv::StorageClass::Function, 10); + 50, 100, SpvStorageClassFunction, 10); ASSERT_TRUE( transformation_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_1, context.get(), @@ -254,7 +253,7 @@ TEST(TransformationReplaceCopyObjectWithStoreLoad, IrrelevantIdsAndDeadBlocks) { MakeDataDescriptor(100, {}), MakeDataDescriptor(50, {}))); auto transformation_2 = TransformationReplaceCopyObjectWithStoreLoad( - 51, 101, (uint32_t)spv::StorageClass::Function, 10); + 51, 101, SpvStorageClassFunction, 10); ASSERT_TRUE( transformation_2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation_2, context.get(), diff --git a/test/fuzz/transformation_replace_id_with_synonym_test.cpp b/test/fuzz/transformation_replace_id_with_synonym_test.cpp index bd27c299..b33dd48c 100644 --- a/test/fuzz/transformation_replace_id_with_synonym_test.cpp +++ b/test/fuzz/transformation_replace_id_with_synonym_test.cpp @@ -230,8 +230,7 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { // %202 cannot replace %15 as in-operand 0 of %300, since %202 does not // dominate %300. auto synonym_does_not_dominate_use = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 15, MakeInstructionDescriptor(300, spv::Op::OpIAdd, 0), 0), + MakeIdUseDescriptor(15, MakeInstructionDescriptor(300, SpvOpIAdd, 0), 0), 202); ASSERT_FALSE(synonym_does_not_dominate_use.IsApplicable( context.get(), transformation_context)); @@ -240,8 +239,8 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { // incoming value for block %72, and %202 does not dominate %72. auto synonym_does_not_dominate_use_op_phi = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 15, MakeInstructionDescriptor(301, spv::Op::OpPhi, 0), 2), + MakeIdUseDescriptor(15, MakeInstructionDescriptor(301, SpvOpPhi, 0), + 2), 202); ASSERT_FALSE(synonym_does_not_dominate_use_op_phi.IsApplicable( context.get(), transformation_context)); @@ -249,15 +248,14 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { // %200 is not a synonym for %84 auto id_in_use_is_not_synonymous = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 84, MakeInstructionDescriptor(67, spv::Op::OpSGreaterThan, 0), 0), + 84, MakeInstructionDescriptor(67, SpvOpSGreaterThan, 0), 0), 200); ASSERT_FALSE(id_in_use_is_not_synonymous.IsApplicable( context.get(), transformation_context)); // %86 is not a synonym for anything (and in particular not for %74) auto id_has_no_synonyms = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(86, MakeInstructionDescriptor(84, spv::Op::OpPhi, 0), - 2), + MakeIdUseDescriptor(86, MakeInstructionDescriptor(84, SpvOpPhi, 0), 2), 74); ASSERT_FALSE( id_has_no_synonyms.IsApplicable(context.get(), transformation_context)); @@ -266,7 +264,7 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { auto synonym_use_is_in_synonym_definition = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 84, MakeInstructionDescriptor(207, spv::Op::OpCopyObject, 0), 0), + 84, MakeInstructionDescriptor(207, SpvOpCopyObject, 0), 0), 207); ASSERT_FALSE(synonym_use_is_in_synonym_definition.IsApplicable( context.get(), transformation_context)); @@ -275,7 +273,7 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { // definition of %207) auto bad_id_use_descriptor = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 84, MakeInstructionDescriptor(200, spv::Op::OpCopyObject, 0), 0), + 84, MakeInstructionDescriptor(200, SpvOpCopyObject, 0), 0), 207); ASSERT_FALSE(bad_id_use_descriptor.IsApplicable(context.get(), transformation_context)); @@ -284,7 +282,7 @@ TEST(TransformationReplaceIdWithSynonymTest, IllegalTransformations) { // non-constant index. auto bad_access_chain = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 12, MakeInstructionDescriptor(14, spv::Op::OpAccessChain, 0), 1), + 12, MakeInstructionDescriptor(14, SpvOpAccessChain, 0), 1), 209); ASSERT_FALSE( bad_access_chain.IsApplicable(context.get(), transformation_context)); @@ -303,8 +301,7 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { SetUpIdSynonyms(transformation_context.GetFactManager()); auto global_constant_synonym = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 19, MakeInstructionDescriptor(47, spv::Op::OpStore, 0), 1), + MakeIdUseDescriptor(19, MakeInstructionDescriptor(47, SpvOpStore, 0), 1), 210); uint32_t num_uses_of_original_id_before_replacement = context->get_def_use_mgr()->NumUses(19); @@ -323,7 +320,7 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { auto replace_vector_access_chain_index = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 54, MakeInstructionDescriptor(55, spv::Op::OpAccessChain, 0), 1), + 54, MakeInstructionDescriptor(55, SpvOpAccessChain, 0), 1), 204); ASSERT_TRUE(replace_vector_access_chain_index.IsApplicable( context.get(), transformation_context)); @@ -336,7 +333,7 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { // copied with something that is already a synonym. auto regular_replacement = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 15, MakeInstructionDescriptor(202, spv::Op::OpCopyObject, 0), 0), + 15, MakeInstructionDescriptor(202, SpvOpCopyObject, 0), 0), 201); ASSERT_TRUE( regular_replacement.IsApplicable(context.get(), transformation_context)); @@ -346,8 +343,7 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { kConsoleMessageConsumer)); auto regular_replacement2 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 55, MakeInstructionDescriptor(203, spv::Op::OpStore, 0), 0), + MakeIdUseDescriptor(55, MakeInstructionDescriptor(203, SpvOpStore, 0), 0), 203); ASSERT_TRUE( regular_replacement2.IsApplicable(context.get(), transformation_context)); @@ -357,8 +353,7 @@ TEST(TransformationReplaceIdWithSynonymTest, LegalTransformations) { kConsoleMessageConsumer)); auto good_op_phi = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(74, MakeInstructionDescriptor(86, spv::Op::OpPhi, 0), - 2), + MakeIdUseDescriptor(74, MakeInstructionDescriptor(86, SpvOpPhi, 0), 2), 205); ASSERT_TRUE(good_op_phi.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(good_op_phi, context.get(), &transformation_context); @@ -548,8 +543,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { // Replace %10 with %100 in: // %11 = OpLoad %6 %10 auto replacement1 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(10, MakeInstructionDescriptor(11, spv::Op::OpLoad, 0), - 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(11, SpvOpLoad, 0), 0), 100); ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement1, context.get(), &transformation_context); @@ -559,8 +553,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { // Replace %8 with %101 in: // OpStore %8 %11 auto replacement2 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(8, MakeInstructionDescriptor(11, spv::Op::OpStore, 0), - 0), + MakeIdUseDescriptor(8, MakeInstructionDescriptor(11, SpvOpStore, 0), 0), 101); ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement2, context.get(), &transformation_context); @@ -570,8 +563,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { // Replace %8 with %101 in: // %12 = OpLoad %6 %8 auto replacement3 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(8, MakeInstructionDescriptor(12, spv::Op::OpLoad, 0), - 0), + MakeIdUseDescriptor(8, MakeInstructionDescriptor(12, SpvOpLoad, 0), 0), 101); ASSERT_TRUE(replacement3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement3, context.get(), &transformation_context); @@ -581,8 +573,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfVariables) { // Replace %10 with %100 in: // OpStore %10 %12 auto replacement4 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(12, spv::Op::OpStore, 0), 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(12, SpvOpStore, 0), 0), 100); ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement4, context.get(), &transformation_context); @@ -687,7 +678,7 @@ TEST(TransformationReplaceIdWithSynonymTest, // %16 = OpFunctionCall %2 %10 %14 auto replacement = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 14, MakeInstructionDescriptor(16, spv::Op::OpFunctionCall, 0), 1), + 14, MakeInstructionDescriptor(16, SpvOpFunctionCall, 0), 1), 100); ASSERT_FALSE(replacement.IsApplicable(context.get(), transformation_context)); } @@ -880,7 +871,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for a cannot be replaced auto replacement1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(20, spv::Op::OpAccessChain, 0), 1), + 16, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 1), 100); ASSERT_FALSE( replacement1.IsApplicable(context.get(), transformation_context)); @@ -890,7 +881,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for f cannot be replaced auto replacement2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(39, spv::Op::OpAccessChain, 0), 1), + 16, MakeInstructionDescriptor(39, SpvOpAccessChain, 0), 1), 100); ASSERT_FALSE( replacement2.IsApplicable(context.get(), transformation_context)); @@ -900,7 +891,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for a cannot be replaced auto replacement3 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(41, spv::Op::OpAccessChain, 0), 2), + 16, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 2), 100); ASSERT_FALSE( replacement3.IsApplicable(context.get(), transformation_context)); @@ -910,7 +901,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for 0 *can* be replaced auto replacement4 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(52, spv::Op::OpAccessChain, 0), 1), + 16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 1), 100); ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement4, context.get(), &transformation_context); @@ -922,7 +913,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for f cannot be replaced auto replacement5 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(52, spv::Op::OpAccessChain, 0), 2), + 16, MakeInstructionDescriptor(52, SpvOpAccessChain, 0), 2), 100); ASSERT_FALSE( replacement5.IsApplicable(context.get(), transformation_context)); @@ -932,7 +923,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for a cannot be replaced auto replacement6 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(53, spv::Op::OpAccessChain, 0), 3), + 16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 3), 100); ASSERT_FALSE( replacement6.IsApplicable(context.get(), transformation_context)); @@ -942,7 +933,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %16 used for 0 *can* be replaced auto replacement7 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 16, MakeInstructionDescriptor(53, spv::Op::OpAccessChain, 0), 4), + 16, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 4), 100); ASSERT_TRUE(replacement7.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement7, context.get(), &transformation_context); @@ -956,7 +947,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for b cannot be replaced auto replacement8 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0), 1), + 21, MakeInstructionDescriptor(24, SpvOpAccessChain, 0), 1), 101); ASSERT_FALSE( replacement8.IsApplicable(context.get(), transformation_context)); @@ -966,7 +957,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement9 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(41, spv::Op::OpAccessChain, 0), 1), + 21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 1), 101); ASSERT_FALSE( replacement9.IsApplicable(context.get(), transformation_context)); @@ -976,7 +967,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for 1 *can* be replaced auto replacement10 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(41, spv::Op::OpAccessChain, 0), 3), + 21, MakeInstructionDescriptor(41, SpvOpAccessChain, 0), 3), 101); ASSERT_TRUE( replacement10.IsApplicable(context.get(), transformation_context)); @@ -989,7 +980,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement11 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(44, spv::Op::OpAccessChain, 0), 1), + 21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 1), 101); ASSERT_FALSE( replacement11.IsApplicable(context.get(), transformation_context)); @@ -999,7 +990,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for b cannot be replaced auto replacement12 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(44, spv::Op::OpAccessChain, 0), 2), + 21, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 2), 101); ASSERT_FALSE( replacement12.IsApplicable(context.get(), transformation_context)); @@ -1009,7 +1000,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement13 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(46, spv::Op::OpAccessChain, 0), 1), + 21, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 1), 101); ASSERT_FALSE( replacement13.IsApplicable(context.get(), transformation_context)); @@ -1019,7 +1010,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for 1 *can* be replaced auto replacement14 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(53, spv::Op::OpAccessChain, 0), 1), + 21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 1), 101); ASSERT_TRUE( replacement14.IsApplicable(context.get(), transformation_context)); @@ -1032,7 +1023,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement15 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(53, spv::Op::OpAccessChain, 0), 2), + 21, MakeInstructionDescriptor(53, SpvOpAccessChain, 0), 2), 101); ASSERT_FALSE( replacement15.IsApplicable(context.get(), transformation_context)); @@ -1042,7 +1033,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement16 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(56, spv::Op::OpAccessChain, 0), 2), + 21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 2), 101); ASSERT_FALSE( replacement16.IsApplicable(context.get(), transformation_context)); @@ -1052,7 +1043,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for b cannot be replaced auto replacement17 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(56, spv::Op::OpAccessChain, 0), 3), + 21, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 3), 101); ASSERT_FALSE( replacement17.IsApplicable(context.get(), transformation_context)); @@ -1062,8 +1053,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %24 used for g cannot be replaced auto replacement18 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 21, MakeInstructionDescriptor(58, spv::Op::OpInBoundsAccessChain, 0), - 2), + 21, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 2), 101); ASSERT_FALSE( replacement18.IsApplicable(context.get(), transformation_context)); @@ -1075,7 +1065,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %17 used for 2 *can* be replaced auto replacement19 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(20, spv::Op::OpAccessChain, 0), 2), + 17, MakeInstructionDescriptor(20, SpvOpAccessChain, 0), 2), 102); ASSERT_TRUE( replacement19.IsApplicable(context.get(), transformation_context)); @@ -1088,7 +1078,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %17 used for c cannot be replaced auto replacement20 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(27, spv::Op::OpAccessChain, 0), 1), + 17, MakeInstructionDescriptor(27, SpvOpAccessChain, 0), 1), 102); ASSERT_FALSE( replacement20.IsApplicable(context.get(), transformation_context)); @@ -1098,7 +1088,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %17 used for c cannot be replaced auto replacement21 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(46, spv::Op::OpAccessChain, 0), 2), + 17, MakeInstructionDescriptor(46, SpvOpAccessChain, 0), 2), 102); ASSERT_FALSE( replacement21.IsApplicable(context.get(), transformation_context)); @@ -1108,7 +1098,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %17 used for 2 *can* be replaced auto replacement22 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(56, spv::Op::OpAccessChain, 0), 1), + 17, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 1), 102); ASSERT_TRUE( replacement22.IsApplicable(context.get(), transformation_context)); @@ -1121,8 +1111,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %17 used for c cannot be replaced auto replacement23 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 17, MakeInstructionDescriptor(58, spv::Op::OpInBoundsAccessChain, 0), - 3), + 17, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 3), 102); ASSERT_FALSE( replacement23.IsApplicable(context.get(), transformation_context)); @@ -1134,8 +1123,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %57 used for 3 *can* be replaced auto replacement24 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 57, MakeInstructionDescriptor(58, spv::Op::OpInBoundsAccessChain, 0), - 1), + 57, MakeInstructionDescriptor(58, SpvOpInBoundsAccessChain, 0), 1), 103); ASSERT_TRUE( replacement24.IsApplicable(context.get(), transformation_context)); @@ -1150,7 +1138,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %32 used for 17 *can* be replaced auto replacement25 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 32, MakeInstructionDescriptor(34, spv::Op::OpAccessChain, 0), 1), + 32, MakeInstructionDescriptor(34, SpvOpAccessChain, 0), 1), 106); ASSERT_TRUE( replacement25.IsApplicable(context.get(), transformation_context)); @@ -1165,7 +1153,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %43 used for 0 *can* be replaced auto replacement26 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 43, MakeInstructionDescriptor(44, spv::Op::OpAccessChain, 0), 3), + 43, MakeInstructionDescriptor(44, SpvOpAccessChain, 0), 3), 107); ASSERT_TRUE( replacement26.IsApplicable(context.get(), transformation_context)); @@ -1180,7 +1168,7 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // The index %55 used for 1 *can* be replaced auto replacement27 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 55, MakeInstructionDescriptor(56, spv::Op::OpAccessChain, 0), 4), + 55, MakeInstructionDescriptor(56, SpvOpAccessChain, 0), 4), 108); ASSERT_TRUE( replacement27.IsApplicable(context.get(), transformation_context)); @@ -1194,8 +1182,8 @@ TEST(TransformationReplaceIdWithSynonymTest, SynonymsOfAccessChainIndices) { // Corresponds to d.b[*3*] // The index %8 used for 3 *can* be replaced auto replacement28 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 8, MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0), 2), + MakeIdUseDescriptor(8, MakeInstructionDescriptor(24, SpvOpAccessChain, 0), + 2), 109); ASSERT_TRUE( replacement28.IsApplicable(context.get(), transformation_context)); @@ -1368,14 +1356,14 @@ TEST(TransformationReplaceIdWithSynonymTest, RuntimeArrayTest) { ASSERT_FALSE( TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 12, MakeInstructionDescriptor(16, spv::Op::OpAccessChain, 0), 1), + 12, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 1), 50) .IsApplicable(context.get(), transformation_context)); // Fine to replace an index into a runtime array. auto replacement1 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 12, MakeInstructionDescriptor(16, spv::Op::OpAccessChain, 0), 2), + 12, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 2), 50); ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement1, context.get(), &transformation_context); @@ -1383,7 +1371,7 @@ TEST(TransformationReplaceIdWithSynonymTest, RuntimeArrayTest) { // Fine to replace an index into a vector inside the runtime array. auto replacement2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 14, MakeInstructionDescriptor(16, spv::Op::OpAccessChain, 0), 3), + 14, MakeInstructionDescriptor(16, SpvOpAccessChain, 0), 3), 51); ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement2, context.get(), &transformation_context); @@ -1478,8 +1466,7 @@ TEST(TransformationReplaceIdWithSynonymTest, ASSERT_FALSE( TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 9, MakeInstructionDescriptor(20, spv::Op::OpImageTexelPointer, 0), - 2), + 9, MakeInstructionDescriptor(20, SpvOpImageTexelPointer, 0), 2), 100) .IsApplicable(context.get(), transformation_context)); } @@ -1537,61 +1524,56 @@ TEST(TransformationReplaceIdWithSynonymTest, EquivalentIntegerConstants) { // Legal because OpSNegate always considers the integer as signed auto replacement1 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(15, spv::Op::OpSNegate, 0), 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(15, SpvOpSNegate, 0), + 0), 13); ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement1, context.get(), &transformation_context); // Legal because OpIAdd does not care about the signedness of the operands auto replacement2 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(10, MakeInstructionDescriptor(16, spv::Op::OpIAdd, 0), - 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(16, SpvOpIAdd, 0), 0), 13); ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement2, context.get(), &transformation_context); // Legal because OpSDiv does not care about the signedness of the operands auto replacement3 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(10, MakeInstructionDescriptor(17, spv::Op::OpSDiv, 0), - 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(17, SpvOpSDiv, 0), 0), 13); ASSERT_TRUE(replacement3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement3, context.get(), &transformation_context); // Not legal because OpUDiv requires unsigned integers - ASSERT_FALSE( - TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 13, MakeInstructionDescriptor(18, spv::Op::OpUDiv, 0), 0), - 10) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceIdWithSynonym( + MakeIdUseDescriptor( + 13, MakeInstructionDescriptor(18, SpvOpUDiv, 0), 0), + 10) + .IsApplicable(context.get(), transformation_context)); // Legal because OpSDiv does not care about the signedness of the operands auto replacement4 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(19, spv::Op::OpBitwiseAnd, 0), 0), + MakeIdUseDescriptor(10, MakeInstructionDescriptor(19, SpvOpBitwiseAnd, 0), + 0), 13); ASSERT_TRUE(replacement4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement4, context.get(), &transformation_context); // Not legal because OpSelect requires both operands to have the same type as // the result type - ASSERT_FALSE( - TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(20, spv::Op::OpUDiv, 0), 1), - 13) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceIdWithSynonym( + MakeIdUseDescriptor( + 10, MakeInstructionDescriptor(20, SpvOpUDiv, 0), 1), + 13) + .IsApplicable(context.get(), transformation_context)); // Not legal because OpStore requires the object to match the type pointed // to by the pointer. - ASSERT_FALSE( - TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(21, spv::Op::OpStore, 0), 1), - 13) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceIdWithSynonym( + MakeIdUseDescriptor( + 10, MakeInstructionDescriptor(21, SpvOpStore, 0), 1), + 13) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, kConsoleMessageConsumer)); @@ -1686,20 +1668,18 @@ TEST(TransformationReplaceIdWithSynonymTest, EquivalentIntegerVectorConstants) { // Legal because OpIAdd does not consider the signedness of the operands auto replacement1 = TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor(14, MakeInstructionDescriptor(18, spv::Op::OpIAdd, 0), - 0), + MakeIdUseDescriptor(14, MakeInstructionDescriptor(18, SpvOpIAdd, 0), 0), 15); ASSERT_TRUE(replacement1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement1, context.get(), &transformation_context); // Not legal because OpStore requires the object to match the type pointed // to by the pointer. - ASSERT_FALSE( - TransformationReplaceIdWithSynonym( - MakeIdUseDescriptor( - 14, MakeInstructionDescriptor(18, spv::Op::OpStore, 0), 1), - 15) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceIdWithSynonym( + MakeIdUseDescriptor( + 14, MakeInstructionDescriptor(18, SpvOpStore, 0), 1), + 15) + .IsApplicable(context.get(), transformation_context)); // Add synonym fact relating %12 and %13 (equivalent integer constants with // different signedness). @@ -1709,7 +1689,7 @@ TEST(TransformationReplaceIdWithSynonymTest, EquivalentIntegerVectorConstants) { // Legal because the indices of OpAccessChain are always treated as signed auto replacement2 = TransformationReplaceIdWithSynonym( MakeIdUseDescriptor( - 13, MakeInstructionDescriptor(19, spv::Op::OpAccessChain, 0), 1), + 13, MakeInstructionDescriptor(19, SpvOpAccessChain, 0), 1), 12); ASSERT_TRUE(replacement2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(replacement2, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_replace_irrelevant_id_test.cpp b/test/fuzz/transformation_replace_irrelevant_id_test.cpp index c5d6981c..c04a091d 100644 --- a/test/fuzz/transformation_replace_irrelevant_id_test.cpp +++ b/test/fuzz/transformation_replace_irrelevant_id_test.cpp @@ -82,9 +82,8 @@ TEST(TransformationReplaceIrrelevantIdTest, Inapplicable) { SetUpIrrelevantIdFacts(transformation_context.GetFactManager()); auto instruction_21_descriptor = - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0); - auto instruction_24_descriptor = - MakeInstructionDescriptor(24, spv::Op::OpIAdd, 0); + MakeInstructionDescriptor(21, SpvOpAccessChain, 0); + auto instruction_24_descriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0); // %20 has not been declared as irrelevant. ASSERT_FALSE(TransformationReplaceIrrelevantId( @@ -133,8 +132,7 @@ TEST(TransformationReplaceIrrelevantIdTest, Apply) { MakeUnique(context.get()), validator_options); SetUpIrrelevantIdFacts(transformation_context.GetFactManager()); - auto instruction_24_descriptor = - MakeInstructionDescriptor(24, spv::Op::OpIAdd, 0); + auto instruction_24_descriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0); // Replace the use of %23 in %24 with %22. auto transformation = TransformationReplaceIrrelevantId( @@ -231,12 +229,11 @@ TEST(TransformationReplaceIrrelevantIdTest, // We cannot replace the use of %13 in the initializer of %12 with %9 because // %9 is not a constant. - ASSERT_FALSE( - TransformationReplaceIrrelevantId( - MakeIdUseDescriptor( - 13, MakeInstructionDescriptor(12, spv::Op::OpVariable, 0), 1), - 9) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationReplaceIrrelevantId( + MakeIdUseDescriptor( + 13, MakeInstructionDescriptor(12, SpvOpVariable, 0), 1), + 9) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationReplaceIrrelevantIdTest, @@ -283,7 +280,7 @@ TEST(TransformationReplaceIrrelevantIdTest, ASSERT_FALSE( TransformationReplaceIrrelevantId( MakeIdUseDescriptor( - 20, MakeInstructionDescriptor(21, spv::Op::OpCopyObject, 0), 0), + 20, MakeInstructionDescriptor(21, SpvOpCopyObject, 0), 0), 10) .IsApplicable(context.get(), transformation_context)); } @@ -329,7 +326,7 @@ TEST(TransformationReplaceIrrelevantIdTest, OpAccessChainIrrelevantIndex) { ASSERT_FALSE( TransformationReplaceIrrelevantId( MakeIdUseDescriptor( - 10, MakeInstructionDescriptor(12, spv::Op::OpAccessChain, 0), 1), + 10, MakeInstructionDescriptor(12, SpvOpAccessChain, 0), 1), 11) .IsApplicable(context.get(), transformation_context)); } diff --git a/test/fuzz/transformation_replace_linear_algebra_instruction_test.cpp b/test/fuzz/transformation_replace_linear_algebra_instruction_test.cpp index 2dedea13..8ec5552c 100644 --- a/test/fuzz/transformation_replace_linear_algebra_instruction_test.cpp +++ b/test/fuzz/transformation_replace_linear_algebra_instruction_test.cpp @@ -76,56 +76,54 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, IsApplicable) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Tests linear algebra instructions. - auto instruction_descriptor = - MakeInstructionDescriptor(24, spv::Op::OpDot, 0); + auto instruction_descriptor = MakeInstructionDescriptor(24, SpvOpDot, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 37, 38}, instruction_descriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(27, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(27, SpvOpVectorTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36}, instruction_descriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); // Tests non-linear algebra instructions. - instruction_descriptor = - MakeInstructionDescriptor(30, spv::Op::OpCopyObject, 0); + instruction_descriptor = MakeInstructionDescriptor(30, SpvOpCopyObject, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 37, 38}, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instruction_descriptor = MakeInstructionDescriptor(31, spv::Op::OpFAdd, 0); + instruction_descriptor = MakeInstructionDescriptor(31, SpvOpFAdd, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 37}, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instruction_descriptor = MakeInstructionDescriptor(32, spv::Op::OpFMul, 0); + instruction_descriptor = MakeInstructionDescriptor(32, SpvOpFMul, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36}, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests number of fresh ids is different than necessary. - instruction_descriptor = MakeInstructionDescriptor(25, spv::Op::OpDot, 0); + instruction_descriptor = MakeInstructionDescriptor(25, SpvOpDot, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36}, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(28, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(28, SpvOpVectorTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 37, 38, 39}, instruction_descriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests non-fresh ids. - instruction_descriptor = MakeInstructionDescriptor(26, spv::Op::OpDot, 0); + instruction_descriptor = MakeInstructionDescriptor(26, SpvOpDot, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 5, 36, 37, 8, 39, 40, 1, 42, 3, 44, 45, 46}, instruction_descriptor); @@ -133,7 +131,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, IsApplicable) { transformation.IsApplicable(context.get(), transformation_context)); instruction_descriptor = - MakeInstructionDescriptor(29, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(29, SpvOpVectorTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 7, 38, 9, 40}, instruction_descriptor); ASSERT_FALSE( @@ -251,36 +249,32 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpTranspose) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(56, spv::Op::OpTranspose, 0); + MakeInstructionDescriptor(56, SpvOpTranspose, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {65, 66, 67, 68, 69, 70, 71, 72, 73, 74}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(57, spv::Op::OpTranspose, 0); + instruction_descriptor = MakeInstructionDescriptor(57, SpvOpTranspose, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(58, spv::Op::OpTranspose, 0); + instruction_descriptor = MakeInstructionDescriptor(58, SpvOpTranspose, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(59, spv::Op::OpTranspose, 0); + instruction_descriptor = MakeInstructionDescriptor(59, SpvOpTranspose, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(60, spv::Op::OpTranspose, 0); + instruction_descriptor = MakeInstructionDescriptor(60, SpvOpTranspose, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142}, @@ -512,19 +506,19 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(17, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(17, SpvOpVectorTimesScalar, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {20, 21, 22, 23}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(18, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(18, SpvOpVectorTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {24, 25, 26, 27, 28, 29}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(19, spv::Op::OpVectorTimesScalar, 0); + MakeInstructionDescriptor(19, SpvOpVectorTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {30, 31, 32, 33, 34, 35, 36, 37}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -683,20 +677,20 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(56, spv::Op::OpMatrixTimesScalar, 0); + MakeInstructionDescriptor(56, SpvOpMatrixTimesScalar, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(57, spv::Op::OpMatrixTimesScalar, 0); + MakeInstructionDescriptor(57, SpvOpMatrixTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(58, spv::Op::OpMatrixTimesScalar, 0); + MakeInstructionDescriptor(58, SpvOpMatrixTimesScalar, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118}, @@ -970,14 +964,14 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(56, spv::Op::OpVectorTimesMatrix, 0); + MakeInstructionDescriptor(56, SpvOpVectorTimesMatrix, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(57, spv::Op::OpVectorTimesMatrix, 0); + MakeInstructionDescriptor(57, SpvOpVectorTimesMatrix, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98}, @@ -985,7 +979,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(58, spv::Op::OpVectorTimesMatrix, 0); + MakeInstructionDescriptor(58, SpvOpVectorTimesMatrix, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124}, @@ -993,7 +987,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(59, spv::Op::OpVectorTimesMatrix, 0); + MakeInstructionDescriptor(59, SpvOpVectorTimesMatrix, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145}, @@ -1304,14 +1298,14 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(56, spv::Op::OpMatrixTimesVector, 0); + MakeInstructionDescriptor(56, SpvOpMatrixTimesVector, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(57, spv::Op::OpMatrixTimesVector, 0); + MakeInstructionDescriptor(57, SpvOpMatrixTimesVector, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97}, @@ -1319,7 +1313,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(58, spv::Op::OpMatrixTimesVector, 0); + MakeInstructionDescriptor(58, SpvOpMatrixTimesVector, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121}, @@ -1327,7 +1321,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(59, spv::Op::OpMatrixTimesVector, 0); + MakeInstructionDescriptor(59, SpvOpMatrixTimesVector, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}, @@ -1690,7 +1684,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(56, spv::Op::OpMatrixTimesMatrix, 0); + MakeInstructionDescriptor(56, SpvOpMatrixTimesMatrix, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, @@ -1699,7 +1693,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(57, spv::Op::OpMatrixTimesMatrix, 0); + MakeInstructionDescriptor(57, SpvOpMatrixTimesMatrix, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, @@ -1710,7 +1704,7 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instruction_descriptor = - MakeInstructionDescriptor(58, spv::Op::OpMatrixTimesMatrix, 0); + MakeInstructionDescriptor(58, SpvOpMatrixTimesMatrix, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, @@ -2163,28 +2157,25 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpOuterProduct) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instruction_descriptor = - MakeInstructionDescriptor(47, spv::Op::OpOuterProduct, 0); + MakeInstructionDescriptor(47, SpvOpOuterProduct, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(48, spv::Op::OpOuterProduct, 0); + instruction_descriptor = MakeInstructionDescriptor(48, SpvOpOuterProduct, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(49, spv::Op::OpOuterProduct, 0); + instruction_descriptor = MakeInstructionDescriptor(49, SpvOpOuterProduct, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = - MakeInstructionDescriptor(50, spv::Op::OpOuterProduct, 0); + instruction_descriptor = MakeInstructionDescriptor(50, SpvOpOuterProduct, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125}, @@ -2402,18 +2393,17 @@ TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpDot) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto instruction_descriptor = - MakeInstructionDescriptor(24, spv::Op::OpDot, 0); + auto instruction_descriptor = MakeInstructionDescriptor(24, SpvOpDot, 0); auto transformation = TransformationReplaceLinearAlgebraInstruction( {27, 28, 29, 30, 31, 32}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = MakeInstructionDescriptor(25, spv::Op::OpDot, 0); + instruction_descriptor = MakeInstructionDescriptor(25, SpvOpDot, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {33, 34, 35, 36, 37, 38, 39, 40, 41, 42}, instruction_descriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instruction_descriptor = MakeInstructionDescriptor(26, spv::Op::OpDot, 0); + instruction_descriptor = MakeInstructionDescriptor(26, SpvOpDot, 0); transformation = TransformationReplaceLinearAlgebraInstruction( {43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56}, instruction_descriptor); diff --git a/test/fuzz/transformation_replace_load_store_with_copy_memory_test.cpp b/test/fuzz/transformation_replace_load_store_with_copy_memory_test.cpp index 74da98b4..bc100990 100644 --- a/test/fuzz/transformation_replace_load_store_with_copy_memory_test.cpp +++ b/test/fuzz/transformation_replace_load_store_with_copy_memory_test.cpp @@ -118,29 +118,29 @@ TEST(TransformationReplaceLoadStoreWithCopyMemoryTest, BasicScenarios) { kConsoleMessageConsumer)); auto bad_instruction_descriptor_1 = - MakeInstructionDescriptor(11, spv::Op::OpConstant, 0); + MakeInstructionDescriptor(11, SpvOpConstant, 0); auto load_instruction_descriptor_1 = - MakeInstructionDescriptor(22, spv::Op::OpLoad, 0); + MakeInstructionDescriptor(22, SpvOpLoad, 0); auto load_instruction_descriptor_2 = - MakeInstructionDescriptor(23, spv::Op::OpLoad, 0); + MakeInstructionDescriptor(23, SpvOpLoad, 0); auto load_instruction_descriptor_3 = - MakeInstructionDescriptor(24, spv::Op::OpLoad, 0); + MakeInstructionDescriptor(24, SpvOpLoad, 0); auto load_instruction_descriptor_other_block = - MakeInstructionDescriptor(34, spv::Op::OpLoad, 0); + MakeInstructionDescriptor(34, SpvOpLoad, 0); auto load_instruction_descriptor_unsafe = - MakeInstructionDescriptor(29, spv::Op::OpLoad, 0); + MakeInstructionDescriptor(29, SpvOpLoad, 0); auto store_instruction_descriptor_1 = - MakeInstructionDescriptor(22, spv::Op::OpStore, 0); + MakeInstructionDescriptor(22, SpvOpStore, 0); auto store_instruction_descriptor_2 = - MakeInstructionDescriptor(23, spv::Op::OpStore, 0); + MakeInstructionDescriptor(23, SpvOpStore, 0); auto store_instruction_descriptor_3 = - MakeInstructionDescriptor(24, spv::Op::OpStore, 0); + MakeInstructionDescriptor(24, SpvOpStore, 0); auto store_instruction_descriptor_other_block = - MakeInstructionDescriptor(37, spv::Op::OpStore, 0); + MakeInstructionDescriptor(37, SpvOpStore, 0); auto store_instruction_descriptor_unsafe = - MakeInstructionDescriptor(29, spv::Op::OpStore, 0); + MakeInstructionDescriptor(29, SpvOpStore, 0); // Bad: |load_instruction_descriptor| is incorrect. auto transformation_bad_1 = TransformationReplaceLoadStoreWithCopyMemory( diff --git a/test/fuzz/transformation_set_function_control_test.cpp b/test/fuzz/transformation_set_function_control_test.cpp index e51e24af..85402e17 100644 --- a/test/fuzz/transformation_set_function_control_test.cpp +++ b/test/fuzz/transformation_set_function_control_test.cpp @@ -124,22 +124,19 @@ TEST(TransformationSetFunctionControlTest, VariousScenarios) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // %36 is not a function - ASSERT_FALSE(TransformationSetFunctionControl( - 36, uint32_t(spv::FunctionControlMask::MaskNone)) + ASSERT_FALSE(TransformationSetFunctionControl(36, SpvFunctionControlMaskNone) .IsApplicable(context.get(), transformation_context)); // Cannot add the Pure function control to %4 as it did not already have it - ASSERT_FALSE(TransformationSetFunctionControl( - 4, uint32_t(spv::FunctionControlMask::Pure)) + ASSERT_FALSE(TransformationSetFunctionControl(4, SpvFunctionControlPureMask) .IsApplicable(context.get(), transformation_context)); // Cannot add the Const function control to %21 as it did not already // have it - ASSERT_FALSE(TransformationSetFunctionControl( - 21, uint32_t(spv::FunctionControlMask::Const)) + ASSERT_FALSE(TransformationSetFunctionControl(21, SpvFunctionControlConstMask) .IsApplicable(context.get(), transformation_context)); // Set to None, removing Const - TransformationSetFunctionControl transformation1( - 11, uint32_t(spv::FunctionControlMask::MaskNone)); + TransformationSetFunctionControl transformation1(11, + SpvFunctionControlMaskNone); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -147,15 +144,15 @@ TEST(TransformationSetFunctionControlTest, VariousScenarios) { // Set to Inline; silly to do it on an entry point, but it is allowed TransformationSetFunctionControl transformation2( - 4, uint32_t(spv::FunctionControlMask::Inline)); + 4, SpvFunctionControlInlineMask); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), &transformation_context); // Set to Pure, removing DontInline - TransformationSetFunctionControl transformation3( - 17, uint32_t(spv::FunctionControlMask::Pure)); + TransformationSetFunctionControl transformation3(17, + SpvFunctionControlPureMask); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -163,7 +160,7 @@ TEST(TransformationSetFunctionControlTest, VariousScenarios) { // Change from Inline to DontInline TransformationSetFunctionControl transformation4( - 13, uint32_t(spv::FunctionControlMask::DontInline)); + 13, SpvFunctionControlDontInlineMask); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), diff --git a/test/fuzz/transformation_set_loop_control_test.cpp b/test/fuzz/transformation_set_loop_control_test.cpp index 94a5b366..88b4aab5 100644 --- a/test/fuzz/transformation_set_loop_control_test.cpp +++ b/test/fuzz/transformation_set_loop_control_test.cpp @@ -278,458 +278,398 @@ TEST(TransformationSetLoopControlTest, VariousScenarios) { // DependencyLength|MinIterations|MaxIterations|IterationMultiple|PeelCount|PartialCount // 2 5 90 4 7 14 - ASSERT_TRUE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(10, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::DependencyInfinite, 0, 0) + 10, SpvLoopControlDependencyInfiniteMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(10, SpvLoopControlDependencyLengthMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(10, SpvLoopControlMinIterationsMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(10, SpvLoopControlMaxIterationsMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::DependencyLength, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::MinIterations, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::MaxIterations, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::IterationMultiple, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::PeelCount, 3, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::PeelCount, 3, 3) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::PartialCount, 0, 3) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, (uint32_t)spv::LoopControlMask::PartialCount, 3, 3) + 10, SpvLoopControlIterationMultipleMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 3) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 0, 3) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 3, 3) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 10, - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 10, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 3, 3) + ASSERT_TRUE(TransformationSetLoopControl(10, + SpvLoopControlUnrollMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, + 3, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 10, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 3, 3) + ASSERT_FALSE(TransformationSetLoopControl(10, + SpvLoopControlDontUnrollMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, + 3, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 23, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 23, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 23, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 23, - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 3, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 23, (uint32_t)spv::LoopControlMask::MaxIterations, 2, 3) + ASSERT_FALSE( + TransformationSetLoopControl(23, SpvLoopControlMaxIterationsMask, 2, 3) + .IsApplicable(context.get(), transformation_context)); + + ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlMaskNone, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(33, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(33, SpvLoopControlMinIterationsMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 33, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSetLoopControl(33, + SpvLoopControlDontUnrollMask | + SpvLoopControlPartialCountMask, + 0, 10) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 33, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 33, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(43, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( - 33, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + 43, + SpvLoopControlMaskNone | SpvLoopControlDependencyInfiniteMask, + 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 33, (uint32_t)spv::LoopControlMask::MinIterations, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 33, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::PeelCount, - 5, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 33, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::PartialCount, - 0, 10) - .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 43, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 43, + SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(43, + SpvLoopControlDependencyInfiniteMask | + SpvLoopControlDependencyLengthMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 43, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0) + .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, - (uint32_t)spv::LoopControlMask::MaskNone | - (uint32_t)spv::LoopControlMask::DependencyInfinite, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::DependencyInfinite, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::DependencyInfinite, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 43, - (uint32_t)spv::LoopControlMask::DependencyInfinite | - (uint32_t)spv::LoopControlMask::DependencyLength, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 43, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::PeelCount, - 5, 0) + ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(53, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(53, SpvLoopControlMaxIterationsMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 53, SpvLoopControlMaskNone | SpvLoopControlDependencyLengthMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl( + 53, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 53, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyLengthMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(53, + SpvLoopControlDependencyInfiniteMask | + SpvLoopControlDependencyLengthMask, + 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 53, + SpvLoopControlUnrollMask | SpvLoopControlDependencyLengthMask | + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, + 5, 3) + .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + ASSERT_TRUE( + TransformationSetLoopControl(63, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationSetLoopControl(63, + SpvLoopControlUnrollMask | + SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, + 5, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 53, (uint32_t)spv::LoopControlMask::MaxIterations, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, - (uint32_t)spv::LoopControlMask::MaskNone | - (uint32_t)spv::LoopControlMask::DependencyLength, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 53, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::DependencyInfinite, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::DependencyLength, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 53, - (uint32_t)spv::LoopControlMask::DependencyInfinite | - (uint32_t)spv::LoopControlMask::DependencyLength, - 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 53, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::DependencyLength | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 5, 3) - .IsApplicable(context.get(), transformation_context)); - - ASSERT_TRUE(TransformationSetLoopControl( - 63, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 63, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 63, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 63, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 5, 3) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 63, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount, - 23, 0) + ASSERT_TRUE(TransformationSetLoopControl(63, + SpvLoopControlUnrollMask | + SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask, + 23, 0) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 63, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount, + SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask, 2, 23) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 73, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 73, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 73, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + ASSERT_TRUE( + TransformationSetLoopControl(73, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSetLoopControl( + 73, + SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, + 5, 3) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationSetLoopControl(73, + SpvLoopControlUnrollMask | + SpvLoopControlMaxIterationsMask | + SpvLoopControlPeelCountMask, + 23, 0) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 73, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 5, 3) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 73, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PeelCount, - 23, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 73, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PeelCount, + SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask | + SpvLoopControlPeelCountMask, 2, 23) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 83, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 83, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 83, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSetLoopControl( 83, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, + SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, 5, 3) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 83, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::IterationMultiple | - (uint32_t)spv::LoopControlMask::PeelCount, - 23, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 83, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::IterationMultiple | - (uint32_t)spv::LoopControlMask::PeelCount, - 2, 23) - .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(83, + SpvLoopControlUnrollMask | + SpvLoopControlIterationMultipleMask | + SpvLoopControlPeelCountMask, + 23, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(83, + SpvLoopControlUnrollMask | + SpvLoopControlIterationMultipleMask | + SpvLoopControlPeelCountMask, + 2, 23) + .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::PeelCount, 8, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::PeelCount, 8, 8) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 93, (uint32_t)spv::LoopControlMask::PartialCount, 0, 8) + ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(93, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 8) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(93, SpvLoopControlPartialCountMask, 0, 8) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE(TransformationSetLoopControl( 93, - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, 8) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 103, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 103, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 103, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 103, (uint32_t)spv::LoopControlMask::PartialCount, 0, 60) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 103, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::PartialCount, - 0, 60) + ASSERT_TRUE( + TransformationSetLoopControl(103, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSetLoopControl(103, + SpvLoopControlDontUnrollMask | + SpvLoopControlPartialCountMask, + 0, 60) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 113, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlMaskNone, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 113, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) + ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlUnrollMask, 0, 0) .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 113, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 113, (uint32_t)spv::LoopControlMask::PeelCount, 12, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 113, - (uint32_t)spv::LoopControlMask::IterationMultiple | - (uint32_t)spv::LoopControlMask::PeelCount, - 12, 0) - .IsApplicable(context.get(), transformation_context)); - - ASSERT_TRUE(TransformationSetLoopControl( - 123, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 123, (uint32_t)spv::LoopControlMask::Unroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 123, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 123, - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::IterationMultiple | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 7, 8) - .IsApplicable(context.get(), transformation_context)); - ASSERT_TRUE(TransformationSetLoopControl( - 123, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PartialCount, - 0, 9) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 123, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PartialCount, - 7, 9) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSetLoopControl( - 123, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PartialCount, - 7, 9) - .IsApplicable(context.get(), transformation_context)); - - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 10, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 3, 3), - context.get(), &transformation_context); - ApplyAndCheckFreshIds( + ASSERT_TRUE( + TransformationSetLoopControl(113, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( TransformationSetLoopControl( - 23, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0), + 113, + SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 12, + 0) + .IsApplicable(context.get(), transformation_context)); + + ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlMaskNone, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl(123, SpvLoopControlDontUnrollMask, 0, 0) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSetLoopControl( + 123, + SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask | + SpvLoopControlIterationMultipleMask | + SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, + 7, 8) + .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE(TransformationSetLoopControl(123, + SpvLoopControlUnrollMask | + SpvLoopControlMinIterationsMask | + SpvLoopControlMaxIterationsMask | + SpvLoopControlPartialCountMask, + 0, 9) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSetLoopControl( + 123, + SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlMaxIterationsMask | + SpvLoopControlPartialCountMask, + 7, 9) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetLoopControl( + 123, + SpvLoopControlDontUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, + 7, 9) + .IsApplicable(context.get(), transformation_context)); + + ApplyAndCheckFreshIds( + TransformationSetLoopControl(10, + SpvLoopControlUnrollMask | + SpvLoopControlPeelCountMask | + SpvLoopControlPartialCountMask, + 3, 3), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0), context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 33, (uint32_t)spv::LoopControlMask::Unroll, 0, 0), - context.get(), &transformation_context); ApplyAndCheckFreshIds( TransformationSetLoopControl( 43, - (uint32_t)spv::LoopControlMask::DontUnroll | - (uint32_t)spv::LoopControlMask::DependencyInfinite, + SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask, 0, 0), context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 53, (uint32_t)spv::LoopControlMask::MaskNone, 0, 0), - context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 63, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::PeelCount, - 23, 0), - context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 73, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PeelCount, - 23, 0), - context.get(), &transformation_context); ApplyAndCheckFreshIds( - TransformationSetLoopControl( - 83, (uint32_t)spv::LoopControlMask::DontUnroll, 0, 0), + TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0), context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 93, - (uint32_t)spv::LoopControlMask::PeelCount | - (uint32_t)spv::LoopControlMask::PartialCount, - 16, 8), - context.get(), &transformation_context); ApplyAndCheckFreshIds( - TransformationSetLoopControl( - 103, (uint32_t)spv::LoopControlMask::PartialCount, 0, 60), + TransformationSetLoopControl(63, + SpvLoopControlUnrollMask | + SpvLoopControlMinIterationsMask | + SpvLoopControlPeelCountMask, + 23, 0), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(73, + SpvLoopControlUnrollMask | + SpvLoopControlMaxIterationsMask | + SpvLoopControlPeelCountMask, + 23, 0), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0), context.get(), &transformation_context); ApplyAndCheckFreshIds( TransformationSetLoopControl( - 113, (uint32_t)spv::LoopControlMask::PeelCount, 12, 0), + 93, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, + 8), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0), + context.get(), &transformation_context); + ApplyAndCheckFreshIds( + TransformationSetLoopControl( + 123, + SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask | + SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask, + 0, 9), context.get(), &transformation_context); - ApplyAndCheckFreshIds(TransformationSetLoopControl( - 123, - (uint32_t)spv::LoopControlMask::Unroll | - (uint32_t)spv::LoopControlMask::MinIterations | - (uint32_t)spv::LoopControlMask::MaxIterations | - (uint32_t)spv::LoopControlMask::PartialCount, - 0, 9), - context.get(), &transformation_context); std::string after_transformation = R"( OpCapability Shader @@ -1018,10 +958,10 @@ TEST(TransformationSetLoopControlTest, CheckSPIRVVersionsRespected) { context.get(), validator_options, kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - TransformationSetLoopControl peel_count( - 10, (uint32_t)spv::LoopControlMask::PeelCount, 4, 0); + TransformationSetLoopControl peel_count(10, SpvLoopControlPeelCountMask, 4, + 0); TransformationSetLoopControl partial_count( - 10, (uint32_t)spv::LoopControlMask::PartialCount, 0, 4); + 10, SpvLoopControlPartialCountMask, 0, 4); switch (env) { case SPV_ENV_UNIVERSAL_1_0: diff --git a/test/fuzz/transformation_set_memory_operands_mask_test.cpp b/test/fuzz/transformation_set_memory_operands_mask_test.cpp index 44901f9c..29e57f42 100644 --- a/test/fuzz/transformation_set_memory_operands_mask_test.cpp +++ b/test/fuzz/transformation_set_memory_operands_mask_test.cpp @@ -106,10 +106,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { { // Not OK: multiple operands are not supported pre SPIR-V 1.4. TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 3), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 1); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 3), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 1); ASSERT_DEATH( transformation.IsApplicable(context.get(), transformation_context), "Multiple memory operand masks are not supported"); @@ -118,24 +116,21 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { // Not OK: the instruction is not a memory access. ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0), - (uint32_t)spv::MemoryAccessMask::MaskNone, 0) + MakeInstructionDescriptor(21, SpvOpAccessChain, 0), + SpvMemoryAccessMaskNone, 0) .IsApplicable(context.get(), transformation_context)); // Not OK to remove Aligned - ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(147, spv::Op::OpLoad, 0), - (uint32_t)spv::MemoryAccessMask::Volatile | - (uint32_t)spv::MemoryAccessMask::Nontemporal, - 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetMemoryOperandsMask( + MakeInstructionDescriptor(147, SpvOpLoad, 0), + SpvMemoryAccessVolatileMask | SpvMemoryAccessNontemporalMask, 0) + .IsApplicable(context.get(), transformation_context)); { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(147, spv::Op::OpLoad, 0), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Volatile, - 0); + MakeInstructionDescriptor(147, SpvOpLoad, 0), + SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -144,23 +139,22 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { // Not OK to remove Aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::MaskNone, 0) + MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), + SpvMemoryAccessMaskNone, 0) .IsApplicable(context.get(), transformation_context)); // OK: leaves the mask as is ASSERT_TRUE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Aligned, 0) + MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), + SpvMemoryAccessAlignedMask, 0) .IsApplicable(context.get(), transformation_context)); { // OK: adds Nontemporal and Volatile TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, + MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), + SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask | + SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -170,25 +164,22 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { // Not OK to remove Volatile ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Nontemporal, 0) + MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), + SpvMemoryAccessNontemporalMask, 0) .IsApplicable(context.get(), transformation_context)); // Not OK to add Aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Volatile, + MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), + SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 0) .IsApplicable(context.get(), transformation_context)); { // OK: adds Nontemporal TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 0); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -198,10 +189,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { { // OK: adds Nontemporal (creates new operand) TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 2), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 0); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 2), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -211,10 +200,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { { // OK: adds Nontemporal and Volatile TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(138, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 0); + MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -224,8 +211,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, PreSpirv14) { { // OK: removes Nontemporal, adds Volatile TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(148, spv::Op::OpStore, 0), - (uint32_t)spv::MemoryAccessMask::Volatile, 0); + MakeInstructionDescriptor(148, SpvOpStore, 0), + SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -382,14 +369,12 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { MakeUnique(context.get()), validator_options); { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Volatile, - 1); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), + SpvMemoryAccessAlignedMask | SpvMemoryAccessVolatileMask, 1); // Bad: cannot remove aligned ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Volatile, 1) + MakeInstructionDescriptor(21, SpvOpCopyMemory, 0), + SpvMemoryAccessVolatileMask, 1) .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -399,14 +384,12 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 1); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 1); // Bad: cannot remove volatile ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Nontemporal, 0) + MakeInstructionDescriptor(21, SpvOpCopyMemory, 1), + SpvMemoryAccessNontemporalMask, 0) .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); @@ -417,10 +400,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { // Creates the first operand. TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 2), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 0); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 2), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -430,10 +411,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { // Creates both operands. TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(21, spv::Op::OpCopyMemory, 3), - (uint32_t)spv::MemoryAccessMask::Nontemporal | - (uint32_t)spv::MemoryAccessMask::Volatile, - 1); + MakeInstructionDescriptor(21, SpvOpCopyMemory, 3), + SpvMemoryAccessNontemporalMask | SpvMemoryAccessVolatileMask, 1); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -442,17 +421,14 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(138, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Nontemporal, - 1); + MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), + SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask, 1); // Bad: the first mask is None, so Aligned cannot be added to it. - ASSERT_FALSE(TransformationSetMemoryOperandsMask( - MakeInstructionDescriptor(138, spv::Op::OpCopyMemory, 0), - (uint32_t)spv::MemoryAccessMask::Aligned | - (uint32_t)spv::MemoryAccessMask::Nontemporal, - 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetMemoryOperandsMask( + MakeInstructionDescriptor(138, SpvOpCopyMemory, 0), + SpvMemoryAccessAlignedMask | SpvMemoryAccessNontemporalMask, 0) + .IsApplicable(context.get(), transformation_context)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -461,8 +437,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(138, spv::Op::OpCopyMemory, 1), - (uint32_t)spv::MemoryAccessMask::Volatile, 1); + MakeInstructionDescriptor(138, SpvOpCopyMemory, 1), + SpvMemoryAccessVolatileMask, 1); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -471,10 +447,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(147, spv::Op::OpLoad, 0), - (uint32_t)spv::MemoryAccessMask::Volatile | - (uint32_t)spv::MemoryAccessMask::Aligned, - 0); + MakeInstructionDescriptor(147, SpvOpLoad, 0), + SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -483,8 +457,8 @@ TEST(TransformationSetMemoryOperandsMaskTest, Spirv14OrHigher) { { TransformationSetMemoryOperandsMask transformation( - MakeInstructionDescriptor(148, spv::Op::OpStore, 0), - (uint32_t)spv::MemoryAccessMask::MaskNone, 0); + MakeInstructionDescriptor(148, SpvOpStore, 0), + SpvMemoryAccessMaskNone, 0); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), diff --git a/test/fuzz/transformation_set_selection_control_test.cpp b/test/fuzz/transformation_set_selection_control_test.cpp index 4cecd23e..c584ff13 100644 --- a/test/fuzz/transformation_set_selection_control_test.cpp +++ b/test/fuzz/transformation_set_selection_control_test.cpp @@ -109,41 +109,41 @@ TEST(TransformationSetSelectionControlTest, VariousScenarios) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // %44 is not a block - ASSERT_FALSE(TransformationSetSelectionControl( - 44, uint32_t(spv::SelectionControlMask::Flatten)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetSelectionControl(44, SpvSelectionControlFlattenMask) + .IsApplicable(context.get(), transformation_context)); // %13 does not end with OpSelectionMerge - ASSERT_FALSE(TransformationSetSelectionControl( - 13, uint32_t(spv::SelectionControlMask::MaskNone)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetSelectionControl(13, SpvSelectionControlMaskNone) + .IsApplicable(context.get(), transformation_context)); // %10 ends in OpLoopMerge, not OpSelectionMerge - ASSERT_FALSE(TransformationSetSelectionControl( - 10, uint32_t(spv::SelectionControlMask::MaskNone)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSetSelectionControl(10, SpvSelectionControlMaskNone) + .IsApplicable(context.get(), transformation_context)); TransformationSetSelectionControl transformation1( - 11, uint32_t(spv::SelectionControlMask::DontFlatten)); + 11, SpvSelectionControlDontFlattenMask); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), &transformation_context); TransformationSetSelectionControl transformation2( - 23, uint32_t(spv::SelectionControlMask::Flatten)); + 23, SpvSelectionControlFlattenMask); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), &transformation_context); TransformationSetSelectionControl transformation3( - 31, uint32_t(spv::SelectionControlMask::MaskNone)); + 31, SpvSelectionControlMaskNone); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), &transformation_context); TransformationSetSelectionControl transformation4( - 31, uint32_t(spv::SelectionControlMask::Flatten)); + 31, SpvSelectionControlFlattenMask); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), diff --git a/test/fuzz/transformation_split_block_test.cpp b/test/fuzz/transformation_split_block_test.cpp index 1cef1823..55091ded 100644 --- a/test/fuzz/transformation_split_block_test.cpp +++ b/test/fuzz/transformation_split_block_test.cpp @@ -96,54 +96,53 @@ TEST(TransformationSplitBlockTest, NotApplicable) { MakeUnique(context.get()), validator_options); // No split before OpVariable ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(8, spv::Op::OpVariable, 0), 100) + MakeInstructionDescriptor(8, SpvOpVariable, 0), 100) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(8, spv::Op::OpVariable, 1), 100) + MakeInstructionDescriptor(8, SpvOpVariable, 1), 100) .IsApplicable(context.get(), transformation_context)); // No split before OpLabel ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(14, spv::Op::OpLabel, 0), 100) + MakeInstructionDescriptor(14, SpvOpLabel, 0), 100) .IsApplicable(context.get(), transformation_context)); // No split if base instruction is outside a function - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(1, spv::Op::OpLabel, 0), 100) - .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( - TransformationSplitBlock( - MakeInstructionDescriptor(1, spv::Op::OpExecutionMode, 0), 100) + TransformationSplitBlock(MakeInstructionDescriptor(1, SpvOpLabel, 0), 100) .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSplitBlock( + MakeInstructionDescriptor(1, SpvOpExecutionMode, 0), 100) + .IsApplicable(context.get(), transformation_context)); // No split if block is loop header - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(27, spv::Op::OpPhi, 0), 100) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(27, spv::Op::OpPhi, 1), 100) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100) + .IsApplicable(context.get(), transformation_context)); // No split if base instruction does not exist + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(88, SpvOpIAdd, 0), 100) + .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(88, spv::Op::OpIAdd, 0), 100) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(88, spv::Op::OpIMul, 22), 100) + MakeInstructionDescriptor(88, SpvOpIMul, 22), 100) .IsApplicable(context.get(), transformation_context)); // No split if too many instructions with the desired opcode are skipped ASSERT_FALSE( TransformationSplitBlock( - MakeInstructionDescriptor(18, spv::Op::OpBranchConditional, 1), 100) + MakeInstructionDescriptor(18, SpvOpBranchConditional, 1), 100) .IsApplicable(context.get(), transformation_context)); // No split if id in use ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(18, spv::Op::OpSLessThan, 0), 27) + MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 27) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(18, spv::Op::OpSLessThan, 0), 14) + MakeInstructionDescriptor(18, SpvOpSLessThan, 0), 14) .IsApplicable(context.get(), transformation_context)); } @@ -207,7 +206,7 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto split_1 = TransformationSplitBlock( - MakeInstructionDescriptor(5, spv::Op::OpStore, 0), 100); + MakeInstructionDescriptor(5, SpvOpStore, 0), 100); ASSERT_TRUE(split_1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split_1, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -256,7 +255,7 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { ASSERT_TRUE(IsEqual(env, after_split_1, context.get())); auto split_2 = TransformationSplitBlock( - MakeInstructionDescriptor(11, spv::Op::OpStore, 0), 101); + MakeInstructionDescriptor(11, SpvOpStore, 0), 101); ASSERT_TRUE(split_2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split_2, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -307,7 +306,7 @@ TEST(TransformationSplitBlockTest, SplitBlockSeveralTimes) { ASSERT_TRUE(IsEqual(env, after_split_2, context.get())); auto split_3 = TransformationSplitBlock( - MakeInstructionDescriptor(14, spv::Op::OpLoad, 0), 102); + MakeInstructionDescriptor(14, SpvOpLoad, 0), 102); ASSERT_TRUE(split_3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split_3, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -426,15 +425,15 @@ TEST(TransformationSplitBlockTest, SplitBlockBeforeSelectBranch) { // Illegal to split between the merge and the conditional branch. ASSERT_FALSE( TransformationSplitBlock( - MakeInstructionDescriptor(14, spv::Op::OpBranchConditional, 0), 100) + MakeInstructionDescriptor(14, SpvOpBranchConditional, 0), 100) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationSplitBlock( - MakeInstructionDescriptor(12, spv::Op::OpBranchConditional, 0), 100) + MakeInstructionDescriptor(12, SpvOpBranchConditional, 0), 100) .IsApplicable(context.get(), transformation_context)); auto split = TransformationSplitBlock( - MakeInstructionDescriptor(14, spv::Op::OpSelectionMerge, 0), 100); + MakeInstructionDescriptor(14, SpvOpSelectionMerge, 0), 100); ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -556,14 +555,14 @@ TEST(TransformationSplitBlockTest, SplitBlockBeforeSwitchBranch) { MakeUnique(context.get()), validator_options); // Illegal to split between the merge and the conditional branch. ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(9, spv::Op::OpSwitch, 0), 100) + MakeInstructionDescriptor(9, SpvOpSwitch, 0), 100) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(15, spv::Op::OpSwitch, 0), 100) + MakeInstructionDescriptor(15, SpvOpSwitch, 0), 100) .IsApplicable(context.get(), transformation_context)); auto split = TransformationSplitBlock( - MakeInstructionDescriptor(9, spv::Op::OpSelectionMerge, 0), 100); + MakeInstructionDescriptor(9, SpvOpSelectionMerge, 0), 100); ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -691,15 +690,15 @@ TEST(TransformationSplitBlockTest, NoSplitDuringOpPhis) { MakeUnique(context.get()), validator_options); // We cannot split before OpPhi instructions, since the number of incoming // blocks may not appropriately match after splitting. - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(26, spv::Op::OpPhi, 0), 100) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(27, spv::Op::OpPhi, 0), 100) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationSplitBlock( - MakeInstructionDescriptor(27, spv::Op::OpPhi, 1), 100) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(26, SpvOpPhi, 0), 100) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 0), 100) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationSplitBlock(MakeInstructionDescriptor(27, SpvOpPhi, 1), 100) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationSplitBlockTest, SplitOpPhiWithSinglePredecessor) { @@ -742,13 +741,13 @@ TEST(TransformationSplitBlockTest, SplitOpPhiWithSinglePredecessor) { spvtools::ValidatorOptions validator_options; TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - ASSERT_TRUE(TransformationSplitBlock( - MakeInstructionDescriptor(21, spv::Op::OpPhi, 0), 100) - .IsApplicable(context.get(), transformation_context)); + ASSERT_TRUE( + TransformationSplitBlock(MakeInstructionDescriptor(21, SpvOpPhi, 0), 100) + .IsApplicable(context.get(), transformation_context)); // An equivalent transformation to the above, just described with respect to a // different base instruction. - auto split = TransformationSplitBlock( - MakeInstructionDescriptor(20, spv::Op::OpPhi, 0), 100); + auto split = + TransformationSplitBlock(MakeInstructionDescriptor(20, SpvOpPhi, 0), 100); ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -827,7 +826,7 @@ TEST(TransformationSplitBlockTest, DeadBlockShouldSplitToTwoDeadBlocks) { transformation_context.GetFactManager()->AddFactBlockIsDead(8); auto split = TransformationSplitBlock( - MakeInstructionDescriptor(8, spv::Op::OpBranch, 0), 100); + MakeInstructionDescriptor(8, SpvOpBranch, 0), 100); ASSERT_TRUE(split.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(split, context.get(), &transformation_context); ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, @@ -913,8 +912,7 @@ TEST(TransformationSplitBlockTest, DoNotSplitUseOfOpSampledImage) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto split = TransformationSplitBlock( - MakeInstructionDescriptor(217, spv::Op::OpImageSampleImplicitLod, 0), - 500); + MakeInstructionDescriptor(217, SpvOpImageSampleImplicitLod, 0), 500); ASSERT_FALSE(split.IsApplicable(context.get(), transformation_context)); } diff --git a/test/fuzz/transformation_store_test.cpp b/test/fuzz/transformation_store_test.cpp index fe24d744..dd653e28 100644 --- a/test/fuzz/transformation_store_test.cpp +++ b/test/fuzz/transformation_store_test.cpp @@ -148,107 +148,107 @@ TEST(TransformationStoreTest, BasicTest) { // 61 - undefined // Bad: attempt to store to 11 from outside its function - ASSERT_FALSE(TransformationStore( - 11, false, 0, 0, 80, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(11, false, 0, 0, 80, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer is not available - ASSERT_FALSE(TransformationStore( - 81, false, 0, 0, 80, - MakeInstructionDescriptor(45, spv::Op::OpCopyObject, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(81, false, 0, 0, 80, + MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to insert before OpVariable ASSERT_FALSE( TransformationStore(52, false, 0, 0, 24, - MakeInstructionDescriptor(27, spv::Op::OpVariable, 0)) + MakeInstructionDescriptor(27, SpvOpVariable, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: pointer id does not exist - ASSERT_FALSE(TransformationStore( - 1000, false, 0, 0, 24, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(1000, false, 0, 0, 24, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists but does not have a type - ASSERT_FALSE(TransformationStore( - 5, false, 0, 0, 24, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(5, false, 0, 0, 24, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: pointer id exists and has a type, but is not a pointer - ASSERT_FALSE(TransformationStore( - 24, false, 0, 0, 24, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(24, false, 0, 0, 24, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to a null pointer - ASSERT_FALSE(TransformationStore( - 60, false, 0, 0, 24, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(60, false, 0, 0, 24, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to an undefined pointer - ASSERT_FALSE(TransformationStore( - 61, false, 0, 0, 21, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(61, false, 0, 0, 21, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: %82 is not available at the program point ASSERT_FALSE( TransformationStore(82, false, 0, 0, 80, - MakeInstructionDescriptor(37, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(37, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); // Bad: value id does not exist - ASSERT_FALSE(TransformationStore( - 27, false, 0, 0, 1000, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(27, false, 0, 0, 1000, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: value id exists but does not have a type - ASSERT_FALSE(TransformationStore( - 27, false, 0, 0, 15, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(27, false, 0, 0, 15, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: value id exists but has the wrong type - ASSERT_FALSE(TransformationStore( - 27, false, 0, 0, 14, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(27, false, 0, 0, 14, + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: attempt to store to read-only variable - ASSERT_FALSE(TransformationStore( - 92, false, 0, 0, 93, - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(92, false, 0, 0, 93, + MakeInstructionDescriptor(40, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: value is not available - ASSERT_FALSE(TransformationStore( - 27, false, 0, 0, 95, - MakeInstructionDescriptor(40, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(27, false, 0, 0, 95, + MakeInstructionDescriptor(40, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: variable being stored to does not have an irrelevant pointee value, // and the store is not in a dead block. - ASSERT_FALSE(TransformationStore( - 20, false, 0, 0, 95, - MakeInstructionDescriptor(45, spv::Op::OpCopyObject, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(20, false, 0, 0, 95, + MakeInstructionDescriptor(45, SpvOpCopyObject, 0)) + .IsApplicable(context.get(), transformation_context)); // The described instruction does not exist. - ASSERT_FALSE(TransformationStore( - 27, false, 0, 0, 80, - MakeInstructionDescriptor(1000, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(27, false, 0, 0, 80, + MakeInstructionDescriptor(1000, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); { // Store to irrelevant variable from dead block. TransformationStore transformation( 27, false, 0, 0, 80, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -261,7 +261,7 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 11, false, 0, 0, 95, - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0)); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -274,7 +274,7 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 46, false, 0, 0, 80, - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0)); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -287,7 +287,7 @@ TEST(TransformationStoreTest, BasicTest) { // Store to irrelevant variable from live block. TransformationStore transformation( 16, false, 0, 0, 21, - MakeInstructionDescriptor(95, spv::Op::OpReturnValue, 0)); + MakeInstructionDescriptor(95, SpvOpReturnValue, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -300,7 +300,7 @@ TEST(TransformationStoreTest, BasicTest) { // Store to non-irrelevant variable from dead block. TransformationStore transformation( 53, false, 0, 0, 21, - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0)); + MakeInstructionDescriptor(38, SpvOpAccessChain, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), @@ -436,15 +436,15 @@ TEST(TransformationStoreTest, DoNotAllowStoresToReadOnlyMemory) { ASSERT_FALSE( TransformationStore(15, false, 0, 0, 13, - MakeInstructionDescriptor(27, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(27, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationStore(19, false, 0, 0, 50, - MakeInstructionDescriptor(27, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(27, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( TransformationStore(27, false, 0, 0, 50, - MakeInstructionDescriptor(27, spv::Op::OpReturn, 0)) + MakeInstructionDescriptor(27, SpvOpReturn, 0)) .IsApplicable(context.get(), transformation_context)); } @@ -495,85 +495,84 @@ TEST(TransformationStoreTest, SupportAtomicStore) { 14); // Bad: id 100 of memory scope instruction does not exist. - ASSERT_FALSE(TransformationStore( - 14, true, 100, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 100, 20, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: id 100 of memory semantics instruction does not exist. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 100, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 100, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory scope should be |OpConstant| opcode. - ASSERT_FALSE(TransformationStore( - 14, true, 5, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 5, 20, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory semantics should be |OpConstant| opcode. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 5, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 5, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The memory scope instruction must have an Integer operand. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 19, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 19, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The memory memory semantics instruction must have an Integer operand. - ASSERT_FALSE(TransformationStore( - 14, true, 19, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 19, 20, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Integer size of the memory scope must be equal to 32 bits. - ASSERT_FALSE(TransformationStore( - 14, true, 17, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 17, 20, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Integer size of memory semantics must be equal to 32 bits. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 17, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 17, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); - // Bad: memory scope value must be 4 (spv::Scope::Invocation). - ASSERT_FALSE(TransformationStore( - 14, true, 16, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + // Bad: memory scope value must be 4 (SpvScopeInvocation). + ASSERT_FALSE( + TransformationStore(14, true, 16, 20, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: memory semantics value must be either: // 64 (SpvMemorySemanticsUniformMemoryMask) // 256 (SpvMemorySemanticsWorkgroupMemoryMask) - ASSERT_FALSE(TransformationStore( - 14, true, 15, 16, 21, - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 16, 21, + MakeInstructionDescriptor(24, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: The described instruction does not exist - ASSERT_FALSE(TransformationStore( - 14, true, 15, 20, 21, - MakeInstructionDescriptor(150, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 20, 21, + MakeInstructionDescriptor(150, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Can't insert OpAccessChain before the id 15 of memory scope. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 20, 21, - MakeInstructionDescriptor(15, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 20, 21, + MakeInstructionDescriptor(15, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Bad: Can't insert OpAccessChain before the id 20 of memory semantics. - ASSERT_FALSE(TransformationStore( - 14, true, 15, 20, 21, - MakeInstructionDescriptor(20, spv::Op::OpAccessChain, 0)) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationStore(14, true, 15, 20, 21, + MakeInstructionDescriptor(20, SpvOpAccessChain, 0)) + .IsApplicable(context.get(), transformation_context)); // Successful transformations. { TransformationStore transformation( - 14, true, 15, 20, 21, - MakeInstructionDescriptor(24, spv::Op::OpReturn, 0)); + 14, true, 15, 20, 21, MakeInstructionDescriptor(24, SpvOpReturn, 0)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), diff --git a/test/fuzz/transformation_swap_commutable_operands_test.cpp b/test/fuzz/transformation_swap_commutable_operands_test.cpp index 789dd09a..07315294 100644 --- a/test/fuzz/transformation_swap_commutable_operands_test.cpp +++ b/test/fuzz/transformation_swap_commutable_operands_test.cpp @@ -118,108 +118,103 @@ TEST(TransformationSwapCommutableOperandsTest, IsApplicableTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Tests existing commutative instructions - auto instructionDescriptor = - MakeInstructionDescriptor(22, spv::Op::OpIAdd, 0); + auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0); auto transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(28, spv::Op::OpIMul, 0); + instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(42, spv::Op::OpFAdd, 0); + instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(48, spv::Op::OpFMul, 0); + instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(66, spv::Op::OpDot, 0); + instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); // Tests existing non-commutative instructions - instructionDescriptor = - MakeInstructionDescriptor(1, spv::Op::OpExtInstImport, 0); + instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(5, spv::Op::OpLabel, 0); + instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(8, spv::Op::OpConstant, 0); + instructionDescriptor = MakeInstructionDescriptor(8, SpvOpConstant, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(11, spv::Op::OpVariable, 0); + instructionDescriptor = MakeInstructionDescriptor(11, SpvOpVariable, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(14, spv::Op::OpConstantComposite, 0); + MakeInstructionDescriptor(14, SpvOpConstantComposite, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests the base instruction id not existing - instructionDescriptor = - MakeInstructionDescriptor(67, spv::Op::OpIAddCarry, 0); + instructionDescriptor = MakeInstructionDescriptor(67, SpvOpIAddCarry, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(68, spv::Op::OpIEqual, 0); + instructionDescriptor = MakeInstructionDescriptor(68, SpvOpIEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = - MakeInstructionDescriptor(69, spv::Op::OpINotEqual, 0); + instructionDescriptor = MakeInstructionDescriptor(69, SpvOpINotEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = - MakeInstructionDescriptor(70, spv::Op::OpFOrdEqual, 0); + instructionDescriptor = MakeInstructionDescriptor(70, SpvOpFOrdEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(71, spv::Op::OpPtrEqual, 0); + instructionDescriptor = MakeInstructionDescriptor(71, SpvOpPtrEqual, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests there being no instruction with the desired opcode after the base // instruction id - instructionDescriptor = MakeInstructionDescriptor(24, spv::Op::OpIAdd, 0); + instructionDescriptor = MakeInstructionDescriptor(24, SpvOpIAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(38, spv::Op::OpIMul, 0); + instructionDescriptor = MakeInstructionDescriptor(38, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(45, spv::Op::OpFAdd, 0); + instructionDescriptor = MakeInstructionDescriptor(45, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(66, spv::Op::OpFMul, 0); + instructionDescriptor = MakeInstructionDescriptor(66, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); @@ -227,27 +222,27 @@ TEST(TransformationSwapCommutableOperandsTest, IsApplicableTest) { // Tests there being an instruction with the desired opcode after the base // instruction id, but the skip count associated with the instruction // descriptor being so high. - instructionDescriptor = MakeInstructionDescriptor(11, spv::Op::OpIAdd, 100); + instructionDescriptor = MakeInstructionDescriptor(11, SpvOpIAdd, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(16, spv::Op::OpIMul, 100); + instructionDescriptor = MakeInstructionDescriptor(16, SpvOpIMul, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(23, spv::Op::OpFAdd, 100); + instructionDescriptor = MakeInstructionDescriptor(23, SpvOpFAdd, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(32, spv::Op::OpFMul, 100); + instructionDescriptor = MakeInstructionDescriptor(32, SpvOpFMul, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(37, spv::Op::OpDot, 100); + instructionDescriptor = MakeInstructionDescriptor(37, SpvOpDot, 100); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); @@ -347,25 +342,24 @@ TEST(TransformationSwapCommutableOperandsTest, ApplyTest) { kConsoleMessageConsumer)); TransformationContext transformation_context( MakeUnique(context.get()), validator_options); - auto instructionDescriptor = - MakeInstructionDescriptor(22, spv::Op::OpIAdd, 0); + auto instructionDescriptor = MakeInstructionDescriptor(22, SpvOpIAdd, 0); auto transformation = TransformationSwapCommutableOperands(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instructionDescriptor = MakeInstructionDescriptor(28, spv::Op::OpIMul, 0); + instructionDescriptor = MakeInstructionDescriptor(28, SpvOpIMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instructionDescriptor = MakeInstructionDescriptor(42, spv::Op::OpFAdd, 0); + instructionDescriptor = MakeInstructionDescriptor(42, SpvOpFAdd, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instructionDescriptor = MakeInstructionDescriptor(48, spv::Op::OpFMul, 0); + instructionDescriptor = MakeInstructionDescriptor(48, SpvOpFMul, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instructionDescriptor = MakeInstructionDescriptor(66, spv::Op::OpDot, 0); + instructionDescriptor = MakeInstructionDescriptor(66, SpvOpDot, 0); transformation = TransformationSwapCommutableOperands(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_swap_conditional_branch_operands_test.cpp b/test/fuzz/transformation_swap_conditional_branch_operands_test.cpp index 5f7ffe40..6133a7a8 100644 --- a/test/fuzz/transformation_swap_conditional_branch_operands_test.cpp +++ b/test/fuzz/transformation_swap_conditional_branch_operands_test.cpp @@ -76,29 +76,27 @@ TEST(TransformationSwapConditionalBranchOperandsTest, BasicTest) { MakeUnique(context.get()), validator_options); // Invalid instruction descriptor. ASSERT_FALSE(TransformationSwapConditionalBranchOperands( - MakeInstructionDescriptor(26, spv::Op::OpPhi, 0), 26) + MakeInstructionDescriptor(26, SpvOpPhi, 0), 26) .IsApplicable(context.get(), transformation_context)); // Descriptor for a wrong instruction. ASSERT_FALSE(TransformationSwapConditionalBranchOperands( - MakeInstructionDescriptor(25, spv::Op::OpPhi, 0), 26) + MakeInstructionDescriptor(25, SpvOpPhi, 0), 26) .IsApplicable(context.get(), transformation_context)); // Fresh id is not fresh. - ASSERT_FALSE( - TransformationSwapConditionalBranchOperands( - MakeInstructionDescriptor(15, spv::Op::OpBranchConditional, 0), 25) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationSwapConditionalBranchOperands( + MakeInstructionDescriptor(15, SpvOpBranchConditional, 0), 25) + .IsApplicable(context.get(), transformation_context)); TransformationSwapConditionalBranchOperands transformation( - MakeInstructionDescriptor(15, spv::Op::OpBranchConditional, 0), 26); + MakeInstructionDescriptor(15, SpvOpBranchConditional, 0), 26); ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(26)); ASSERT_EQ(nullptr, context->get_instr_block(26)); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - ASSERT_EQ(spv::Op::OpLogicalNot, - context->get_def_use_mgr()->GetDef(26)->opcode()); + ASSERT_EQ(SpvOpLogicalNot, context->get_def_use_mgr()->GetDef(26)->opcode()); ASSERT_EQ(5, context->get_instr_block(26)->id()); ASSERT_EQ(1, context->get_def_use_mgr()->NumUses(26)); @@ -111,7 +109,7 @@ TEST(TransformationSwapConditionalBranchOperandsTest, BasicTest) { context->get_def_use_mgr()->WhileEachUse( entry.first, [&entry](opt::Instruction* inst, uint32_t operand_index) -> bool { - if (inst->opcode() == spv::Op::OpBranchConditional) { + if (inst->opcode() == SpvOpBranchConditional) { EXPECT_EQ(entry.second, operand_index); return false; } diff --git a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp index 94ca8044..84ed20d2 100644 --- a/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp +++ b/test/fuzz/transformation_toggle_access_chain_instruction_test.cpp @@ -119,71 +119,67 @@ TEST(TransformationToggleAccessChainInstructionTest, IsApplicableTest) { MakeUnique(context.get()), validator_options); // Tests existing access chain instructions auto instructionDescriptor = - MakeInstructionDescriptor(18, spv::Op::OpAccessChain, 0); + MakeInstructionDescriptor(18, SpvOpAccessChain, 0); auto transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(20, spv::Op::OpInBoundsAccessChain, 0); + MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0); + transformation = + TransformationToggleAccessChainInstruction(instructionDescriptor); + ASSERT_TRUE( + transformation.IsApplicable(context.get(), transformation_context)); + + instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0); - transformation = - TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_TRUE( - transformation.IsApplicable(context.get(), transformation_context)); - - instructionDescriptor = - MakeInstructionDescriptor(26, spv::Op::OpInBoundsAccessChain, 0); + MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); // Tests existing non-access chain instructions - instructionDescriptor = - MakeInstructionDescriptor(1, spv::Op::OpExtInstImport, 0); + instructionDescriptor = MakeInstructionDescriptor(1, SpvOpExtInstImport, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); - instructionDescriptor = MakeInstructionDescriptor(5, spv::Op::OpLabel, 0); + instructionDescriptor = MakeInstructionDescriptor(5, SpvOpLabel, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(14, spv::Op::OpConstantComposite, 0); + MakeInstructionDescriptor(14, SpvOpConstantComposite, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); // Tests the base instruction id not existing - instructionDescriptor = - MakeInstructionDescriptor(67, spv::Op::OpAccessChain, 0); + instructionDescriptor = MakeInstructionDescriptor(67, SpvOpAccessChain, 0); + transformation = + TransformationToggleAccessChainInstruction(instructionDescriptor); + ASSERT_FALSE( + transformation.IsApplicable(context.get(), transformation_context)); + + instructionDescriptor = MakeInstructionDescriptor(68, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(68, spv::Op::OpAccessChain, 0); - transformation = - TransformationToggleAccessChainInstruction(instructionDescriptor); - ASSERT_FALSE( - transformation.IsApplicable(context.get(), transformation_context)); - - instructionDescriptor = - MakeInstructionDescriptor(69, spv::Op::OpInBoundsAccessChain, 0); + MakeInstructionDescriptor(69, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( @@ -191,15 +187,14 @@ TEST(TransformationToggleAccessChainInstructionTest, IsApplicableTest) { // Tests there being no instruction with the desired opcode after the base // instruction id - instructionDescriptor = - MakeInstructionDescriptor(65, spv::Op::OpAccessChain, 0); + instructionDescriptor = MakeInstructionDescriptor(65, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(66, spv::Op::OpInBoundsAccessChain, 0); + MakeInstructionDescriptor(66, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( @@ -208,15 +203,14 @@ TEST(TransformationToggleAccessChainInstructionTest, IsApplicableTest) { // Tests there being an instruction with the desired opcode after the base // instruction id, but the skip count associated with the instruction // descriptor being so high. - instructionDescriptor = - MakeInstructionDescriptor(11, spv::Op::OpAccessChain, 100); + instructionDescriptor = MakeInstructionDescriptor(11, SpvOpAccessChain, 100); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( transformation.IsApplicable(context.get(), transformation_context)); instructionDescriptor = - MakeInstructionDescriptor(16, spv::Op::OpInBoundsAccessChain, 100); + MakeInstructionDescriptor(16, SpvOpInBoundsAccessChain, 100); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ASSERT_FALSE( @@ -318,31 +312,29 @@ TEST(TransformationToggleAccessChainInstructionTest, ApplyTest) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); auto instructionDescriptor = - MakeInstructionDescriptor(18, spv::Op::OpAccessChain, 0); + MakeInstructionDescriptor(18, SpvOpAccessChain, 0); auto transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instructionDescriptor = - MakeInstructionDescriptor(20, spv::Op::OpInBoundsAccessChain, 0); + MakeInstructionDescriptor(20, SpvOpInBoundsAccessChain, 0); + transformation = + TransformationToggleAccessChainInstruction(instructionDescriptor); + ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); + + instructionDescriptor = MakeInstructionDescriptor(24, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); instructionDescriptor = - MakeInstructionDescriptor(24, spv::Op::OpAccessChain, 0); + MakeInstructionDescriptor(26, SpvOpInBoundsAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - instructionDescriptor = - MakeInstructionDescriptor(26, spv::Op::OpInBoundsAccessChain, 0); - transformation = - TransformationToggleAccessChainInstruction(instructionDescriptor); - ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); - - instructionDescriptor = - MakeInstructionDescriptor(38, spv::Op::OpAccessChain, 0); + instructionDescriptor = MakeInstructionDescriptor(38, SpvOpAccessChain, 0); transformation = TransformationToggleAccessChainInstruction(instructionDescriptor); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); diff --git a/test/fuzz/transformation_vector_shuffle_test.cpp b/test/fuzz/transformation_vector_shuffle_test.cpp index 4d8f985b..e3dc0a7e 100644 --- a/test/fuzz/transformation_vector_shuffle_test.cpp +++ b/test/fuzz/transformation_vector_shuffle_test.cpp @@ -172,82 +172,80 @@ TEST(TransformationVectorShuffleTest, BasicTest) { // %103 does not dominate the return instruction. ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 103, 65, {3, 5, 7}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 103, 65, + {3, 5, 7}) .IsApplicable(context.get(), transformation_context)); // Illegal to shuffle a bvec2 and a vec3 ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 112, 61, {0, 2, 4}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 112, 61, + {0, 2, 4}) .IsApplicable(context.get(), transformation_context)); // Illegal to shuffle an ivec2 and a uvec4 ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 27, 50, {1, 3, 5}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 50, + {1, 3, 5}) .IsApplicable(context.get(), transformation_context)); // Vector 1 does not exist ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 300, 50, {1, 3, 5}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 300, 50, + {1, 3, 5}) .IsApplicable(context.get(), transformation_context)); // Vector 2 does not exist ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 27, 300, {1, 3, 5}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 27, 300, + {1, 3, 5}) .IsApplicable(context.get(), transformation_context)); // Index out of range - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 12, 112, {0, 20}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0, 20}) + .IsApplicable(context.get(), transformation_context)); // Too many indices ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 12, 112, {0, 1, 0, 1, 0, 1, 0, 1}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, + {0, 1, 0, 1, 0, 1, 0, 1}) .IsApplicable(context.get(), transformation_context)); // Too few indices - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 12, 112, {}) - .IsApplicable(context.get(), transformation_context)); - - // Too few indices again - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 12, 112, {0}) - .IsApplicable(context.get(), transformation_context)); - - // Indices define unknown type: we do not have vec2 - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, - 65, 65, {0, 1}) - .IsApplicable(context.get(), transformation_context)); - - // The instruction to insert before does not exist ASSERT_FALSE( TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpCompositeConstruct, 1), 201, - 20, 12, {0xFFFFFFFF, 3, 5}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {}) .IsApplicable(context.get(), transformation_context)); + // Too few indices again + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {0}) + .IsApplicable(context.get(), transformation_context)); + + // Indices define unknown type: we do not have vec2 + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 65, 65, {0, 1}) + .IsApplicable(context.get(), transformation_context)); + + // The instruction to insert before does not exist + ASSERT_FALSE(TransformationVectorShuffle( + MakeInstructionDescriptor(100, SpvOpCompositeConstruct, 1), + 201, 20, 12, {0xFFFFFFFF, 3, 5}) + .IsApplicable(context.get(), transformation_context)); + // The 'fresh' id is already in use ASSERT_FALSE( TransformationVectorShuffle( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 12, 12, 112, {}) + MakeInstructionDescriptor(100, SpvOpReturn, 0), 12, 12, 112, {}) .IsApplicable(context.get(), transformation_context)); protobufs::DataDescriptor temp_dd; TransformationVectorShuffle transformation1( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, 12, 112, - {1, 0}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {1, 0}); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -260,7 +258,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { MakeDataDescriptor(10, {}), temp_dd)); TransformationVectorShuffle transformation2( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 201, 20, 12, + MakeInstructionDescriptor(100, SpvOpReturn, 0), 201, 20, 12, {0xFFFFFFFF, 3, 5}); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); @@ -274,8 +272,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { MakeDataDescriptor(11, {}), temp_dd)); TransformationVectorShuffle transformation3( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 202, 27, 35, - {5, 4, 1}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 202, 27, 35, {5, 4, 1}); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -291,8 +288,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { MakeDataDescriptor(26, {}), temp_dd)); TransformationVectorShuffle transformation4( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 203, 42, 46, - {0, 1}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 203, 42, 46, {0, 1}); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), @@ -305,8 +301,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { MakeDataDescriptor(41, {}), temp_dd)); TransformationVectorShuffle transformation5( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 204, 42, 46, - {2, 3, 4}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 204, 42, 46, {2, 3, 4}); ASSERT_TRUE( transformation5.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation5, context.get(), @@ -322,7 +317,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { MakeDataDescriptor(40, {}), temp_dd)); TransformationVectorShuffle transformation6( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 205, 42, 42, + MakeInstructionDescriptor(100, SpvOpReturn, 0), 205, 42, 42, {0, 1, 2, 3}); ASSERT_TRUE( transformation6.IsApplicable(context.get(), transformation_context)); @@ -343,7 +338,7 @@ TEST(TransformationVectorShuffleTest, BasicTest) { // swizzle vec4 from vec4 and vec4 using some undefs TransformationVectorShuffle transformation7( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 206, 65, 65, + MakeInstructionDescriptor(100, SpvOpReturn, 0), 206, 65, 65, {0xFFFFFFFF, 3, 6, 0xFFFFFFFF}); ASSERT_TRUE( transformation7.IsApplicable(context.get(), transformation_context)); @@ -505,52 +500,50 @@ TEST(TransformationVectorShuffleTest, IllegalInsertionPoints) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); // Cannot insert before the OpVariables of a function. - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(101, spv::Op::OpVariable, 0), 200, - 14, 14, {0, 1}) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(101, spv::Op::OpVariable, 1), 200, - 14, 14, {1, 2}) - .IsApplicable(context.get(), transformation_context)); - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(102, spv::Op::OpVariable, 0), 200, - 14, 14, {1, 2}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(101, SpvOpVariable, 0), 200, 14, 14, {0, 1}) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(101, SpvOpVariable, 1), 200, 14, 14, {1, 2}) + .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(102, SpvOpVariable, 0), 200, 14, 14, {1, 2}) + .IsApplicable(context.get(), transformation_context)); // OK to insert right after the OpVariables. - ASSERT_FALSE(TransformationVectorShuffle( - MakeInstructionDescriptor(102, spv::Op::OpBranch, 1), 200, - 14, 14, {1, 1}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE( + TransformationVectorShuffle( + MakeInstructionDescriptor(102, SpvOpBranch, 1), 200, 14, 14, {1, 1}) + .IsApplicable(context.get(), transformation_context)); // Cannot insert before the OpPhis of a block. ASSERT_FALSE( - TransformationVectorShuffle( - MakeInstructionDescriptor(60, spv::Op::OpPhi, 0), 200, 14, 14, {2, 0}) + TransformationVectorShuffle(MakeInstructionDescriptor(60, SpvOpPhi, 0), + 200, 14, 14, {2, 0}) .IsApplicable(context.get(), transformation_context)); ASSERT_FALSE( - TransformationVectorShuffle( - MakeInstructionDescriptor(59, spv::Op::OpPhi, 0), 200, 14, 14, {3, 0}) + TransformationVectorShuffle(MakeInstructionDescriptor(59, SpvOpPhi, 0), + 200, 14, 14, {3, 0}) .IsApplicable(context.get(), transformation_context)); // OK to insert after the OpPhis. ASSERT_TRUE(TransformationVectorShuffle( - MakeInstructionDescriptor(59, spv::Op::OpAccessChain, 0), 200, - 14, 14, {3, 4}) + MakeInstructionDescriptor(59, SpvOpAccessChain, 0), 200, 14, + 14, {3, 4}) .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpLoopMerge - ASSERT_FALSE( - TransformationVectorShuffle( - MakeInstructionDescriptor(33, spv::Op::OpBranchConditional, 0), 200, - 14, 14, {3}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationVectorShuffle( + MakeInstructionDescriptor(33, SpvOpBranchConditional, 0), + 200, 14, 14, {3}) + .IsApplicable(context.get(), transformation_context)); // Cannot insert before OpSelectionMerge - ASSERT_FALSE( - TransformationVectorShuffle( - MakeInstructionDescriptor(21, spv::Op::OpBranchConditional, 0), 200, - 14, 14, {2}) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationVectorShuffle( + MakeInstructionDescriptor(21, SpvOpBranchConditional, 0), + 200, 14, 14, {2}) + .IsApplicable(context.get(), transformation_context)); } TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds1) { @@ -622,8 +615,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds1) { TransformationContext transformation_context( MakeUnique(context.get()), validator_options); TransformationVectorShuffle transformation( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, 12, 112, - {2, 0}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {2, 0}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -705,8 +697,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds2) { MakeUnique(context.get()), validator_options); transformation_context.GetFactManager()->AddFactIdIsIrrelevant(112); TransformationVectorShuffle transformation( - MakeInstructionDescriptor(100, spv::Op::OpReturn, 0), 200, 12, 112, - {2, 0}); + MakeInstructionDescriptor(100, SpvOpReturn, 0), 200, 12, 112, {2, 0}); ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); @@ -764,7 +755,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds3) { transformation_context.GetFactManager()->AddFactBlockIsDead(15); TransformationVectorShuffle transformation1( - MakeInstructionDescriptor(15, spv::Op::OpBranch, 0), 200, 12, 12, {0, 3}); + MakeInstructionDescriptor(15, SpvOpBranch, 0), 200, 12, 12, {0, 3}); ASSERT_TRUE( transformation1.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation1, context.get(), @@ -775,7 +766,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds3) { MakeDataDescriptor(200, {1}), MakeDataDescriptor(12, {1}))); TransformationVectorShuffle transformation2( - MakeInstructionDescriptor(16, spv::Op::OpReturn, 0), 201, 12, 40, {0, 1}); + MakeInstructionDescriptor(16, SpvOpReturn, 0), 201, 12, 40, {0, 1}); ASSERT_TRUE( transformation2.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation2, context.get(), @@ -786,7 +777,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds3) { MakeDataDescriptor(201, {1}), MakeDataDescriptor(12, {1}))); TransformationVectorShuffle transformation3( - MakeInstructionDescriptor(16, spv::Op::OpReturn, 0), 202, 40, 12, {2, 3}); + MakeInstructionDescriptor(16, SpvOpReturn, 0), 202, 40, 12, {2, 3}); ASSERT_TRUE( transformation3.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation3, context.get(), @@ -797,7 +788,7 @@ TEST(TransformationVectorShuffleTest, HandlesIrrelevantIds3) { MakeDataDescriptor(202, {1}), MakeDataDescriptor(12, {1}))); TransformationVectorShuffle transformation4( - MakeInstructionDescriptor(16, spv::Op::OpReturn, 0), 203, 40, 12, {0, 3}); + MakeInstructionDescriptor(16, SpvOpReturn, 0), 203, 40, 12, {0, 3}); ASSERT_TRUE( transformation4.IsApplicable(context.get(), transformation_context)); ApplyAndCheckFreshIds(transformation4, context.get(), diff --git a/test/fuzz/transformation_wrap_early_terminator_in_function_test.cpp b/test/fuzz/transformation_wrap_early_terminator_in_function_test.cpp index fbbf57b3..7b4e487c 100644 --- a/test/fuzz/transformation_wrap_early_terminator_in_function_test.cpp +++ b/test/fuzz/transformation_wrap_early_terminator_in_function_test.cpp @@ -98,50 +98,48 @@ TEST(TransformationWrapEarlyTerminatorInFunctionTest, IsApplicable) { // Bad: id is not fresh ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 61, MakeInstructionDescriptor(8, spv::Op::OpKill, 0), 0) + 61, MakeInstructionDescriptor(8, SpvOpKill, 0), 0) .IsApplicable(context.get(), transformation_context)); // Bad: early terminator instruction descriptor does not exist ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(82, spv::Op::OpKill, 0), 0) + 100, MakeInstructionDescriptor(82, SpvOpKill, 0), 0) .IsApplicable(context.get(), transformation_context)); // Bad: early terminator instruction does not identify an early terminator - ASSERT_FALSE( - TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(5, spv::Op::OpSelectionMerge, 0), 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( + 100, MakeInstructionDescriptor(5, SpvOpSelectionMerge, 0), 0) + .IsApplicable(context.get(), transformation_context)); // Bad: no wrapper function is available - ASSERT_FALSE( - TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(9, spv::Op::OpUnreachable, 0), 0) - .IsApplicable(context.get(), transformation_context)); + ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( + 100, MakeInstructionDescriptor(9, SpvOpUnreachable, 0), 0) + .IsApplicable(context.get(), transformation_context)); // Bad: returned value does not exist ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(62, spv::Op::OpKill, 0), 1000) + 100, MakeInstructionDescriptor(62, SpvOpKill, 0), 1000) .IsApplicable(context.get(), transformation_context)); // Bad: returned value does not have a type ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(62, spv::Op::OpKill, 0), 61) + 100, MakeInstructionDescriptor(62, SpvOpKill, 0), 61) .IsApplicable(context.get(), transformation_context)); // Bad: returned value type does not match ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(62, spv::Op::OpKill, 0), 91) + 100, MakeInstructionDescriptor(62, SpvOpKill, 0), 91) .IsApplicable(context.get(), transformation_context)); // Bad: returned value is not available ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(62, spv::Op::OpKill, 0), 81) + 100, MakeInstructionDescriptor(62, SpvOpKill, 0), 81) .IsApplicable(context.get(), transformation_context)); // Bad: the OpKill being targeted is in the only available wrapper; we cannot // have the wrapper call itself. ASSERT_FALSE(TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(31, spv::Op::OpKill, 0), 0) + 100, MakeInstructionDescriptor(31, SpvOpKill, 0), 0) .IsApplicable(context.get(), transformation_context)); } @@ -222,20 +220,17 @@ TEST(TransformationWrapEarlyTerminatorInFunctionTest, Apply) { for (auto& transformation : {TransformationWrapEarlyTerminatorInFunction( - 100, MakeInstructionDescriptor(8, spv::Op::OpKill, 0), 0), + 100, MakeInstructionDescriptor(8, SpvOpKill, 0), 0), TransformationWrapEarlyTerminatorInFunction( - 101, MakeInstructionDescriptor(9, spv::Op::OpUnreachable, 0), 0), + 101, MakeInstructionDescriptor(9, SpvOpUnreachable, 0), 0), TransformationWrapEarlyTerminatorInFunction( - 102, - MakeInstructionDescriptor(10, spv::Op::OpTerminateInvocation, 0), - 0), + 102, MakeInstructionDescriptor(10, SpvOpTerminateInvocation, 0), 0), TransformationWrapEarlyTerminatorInFunction( - 103, MakeInstructionDescriptor(62, spv::Op::OpKill, 0), 0), + 103, MakeInstructionDescriptor(62, SpvOpKill, 0), 0), TransformationWrapEarlyTerminatorInFunction( - 104, MakeInstructionDescriptor(71, spv::Op::OpUnreachable, 0), 7), + 104, MakeInstructionDescriptor(71, SpvOpUnreachable, 0), 7), TransformationWrapEarlyTerminatorInFunction( - 105, - MakeInstructionDescriptor(82, spv::Op::OpTerminateInvocation, 0), + 105, MakeInstructionDescriptor(82, SpvOpTerminateInvocation, 0), 0)}) { ASSERT_TRUE( transformation.IsApplicable(context.get(), transformation_context)); diff --git a/test/hex_float_test.cpp b/test/hex_float_test.cpp index a44d9ec7..25d3c707 100644 --- a/test/hex_float_test.cpp +++ b/test/hex_float_test.cpp @@ -1348,11 +1348,9 @@ std::ostream& operator<<(std::ostream& os, const StreamParseCase& fspc) { return os; } -using Float32StreamParseTest = ::testing::TestWithParam>; -using Float16StreamParseTest = - ::testing::TestWithParam>; +using FloatStreamParseTest = ::testing::TestWithParam>; -TEST_P(Float32StreamParseTest, Samples) { +TEST_P(FloatStreamParseTest, Samples) { std::stringstream input(GetParam().literal); HexFloat> parsed_value(0.0f); // Hex floats must be read with the stream input operator. @@ -1369,87 +1367,8 @@ TEST_P(Float32StreamParseTest, Samples) { } } -// Returns a Float16 constructed from its sign bit, unbiased exponent, and -// mantissa. -Float16 makeF16(int sign_bit, int unbiased_exp, int mantissa) { - EXPECT_LE(0, sign_bit); - EXPECT_LE(sign_bit, 1); - // Exponent is 5 bits, with bias of 15. - EXPECT_LE(-15, unbiased_exp); // -15 means zero or subnormal - EXPECT_LE(unbiased_exp, 16); // 16 means infinity or NaN - EXPECT_LE(0, mantissa); - EXPECT_LE(mantissa, 0x3ff); - const unsigned biased_exp = 15 + unbiased_exp; - const uint32_t as_bits = sign_bit << 15 | (biased_exp << 10) | mantissa; - EXPECT_LE(as_bits, 0xffffu); - return Float16(static_cast(as_bits)); -} - -TEST_P(Float16StreamParseTest, Samples) { - std::stringstream input(GetParam().literal); - HexFloat> parsed_value(makeF16(0, 0, 0)); - // Hex floats must be read with the stream input operator. - input >> parsed_value; - if (GetParam().expect_success) { - EXPECT_FALSE(input.fail()); - std::string suffix; - input >> suffix; - const auto got = parsed_value.value(); - const auto expected = GetParam().expected_value.value(); - EXPECT_EQ(got.data(), expected.data()) - << "got: " << got << " expected: " << expected; - } else { - EXPECT_TRUE(input.fail()); - } -} - INSTANTIATE_TEST_SUITE_P( - HexFloat32FillSignificantDigits, Float32StreamParseTest, - ::testing::ValuesIn(std::vector>{ - {"0x123456p0", true, "", ldexpf(0x123456, 0)}, - // Patterns that fill all mantissa bits - {"0x1.fffffep+23", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1f.ffffep+19", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1ff.fffep+15", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1fff.ffep+11", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1ffff.fep+7", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1fffff.ep+3", true, "", ldexpf(0x1fffffe, -1)}, - {"0x1fffffe.p-1", true, "", ldexpf(0x1fffffe, -1)}, - {"0xffffff.p+0", true, "", ldexpf(0x1fffffe, -1)}, - {"0xffffff.p+0", true, "", ldexpf(0xffffff, 0)}, - // Now drop some bits in the middle - {"0xa5a5a5.p+0", true, "", ldexpf(0xa5a5a5, 0)}, - {"0x5a5a5a.p+0", true, "", ldexpf(0x5a5a5a, 0)}})); - -INSTANTIATE_TEST_SUITE_P( - HexFloat32ExcessSignificantDigits, Float32StreamParseTest, - ::testing::ValuesIn(std::vector>{ - // Base cases - {"0x1.fffffep0", true, "", ldexpf(0xffffff, -23)}, - {"0xa5a5a5p0", true, "", ldexpf(0xa5a5a5, 0)}, - {"0xa.5a5a5p+9", true, "", ldexpf(0xa5a5a5, -11)}, - {"0x5a5a5ap0", true, "", ldexpf(0x5a5a5a, 0)}, - {"0x5.a5a5ap+9", true, "", ldexpf(0x5a5a5a, -11)}, - // Truncate extra bits: zeroes - {"0x1.fffffe0p0", true, "", ldexpf(0xffffff, -23)}, - {"0xa5a5a5000p0", true, "", ldexpf(0xa5a5a5, 12)}, - {"0xa.5a5a5000p+9", true, "", ldexpf(0xa5a5a5, -11)}, - {"0x5a5a5a000p0", true, "", ldexpf(0x5a5a5a, 12)}, - {"0x5.a5a5a000p+9", true, "", ldexpf(0x5a5a5a, -11)}, - // Truncate extra bits: ones - {"0x1.ffffffp0", // Extra bits in the last nibble - true, "", ldexpf(0xffffff, -23)}, - {"0x1.fffffffp0", true, "", ldexpf(0xffffff, -23)}, - {"0xa5a5a5fffp0", true, "", ldexpf(0xa5a5a5, 12)}, - {"0xa.5a5a5fffp+9", true, "", ldexpf(0xa5a5a5, -11)}, - {"0x5a5a5afffp0", - // The 5 nibble (0101), leads with 0, so the result can fit a leading - // 1 bit , yielding 8 (1000). - true, "", ldexpf(0x5a5a5a8, 8)}, - {"0x5.a5a5afffp+9", true, "", ldexpf(0x5a5a5a8, 8 - 32 + 9)}})); - -INSTANTIATE_TEST_SUITE_P( - HexFloat32ExponentMissingDigits, Float32StreamParseTest, + HexFloatExponentMissingDigits, FloatStreamParseTest, ::testing::ValuesIn(std::vector>{ {"0x1.0p1", true, "", 2.0f}, {"0x1.0p1a", true, "a", 2.0f}, @@ -1469,7 +1388,7 @@ INSTANTIATE_TEST_SUITE_P( {"0x1.0p--", false, "", 0.0f}})); INSTANTIATE_TEST_SUITE_P( - HexFloat32ExponentTrailingSign, Float32StreamParseTest, + HexFloatExponentTrailingSign, FloatStreamParseTest, ::testing::ValuesIn(std::vector>{ // Don't consume a sign after the binary exponent digits. {"0x1.0p1", true, "", 2.0f}, @@ -1477,7 +1396,7 @@ INSTANTIATE_TEST_SUITE_P( {"0x1.0p1-", true, "-", 2.0f}})); INSTANTIATE_TEST_SUITE_P( - HexFloat32PositiveExponentOverflow, Float32StreamParseTest, + HexFloatPositiveExponentOverflow, FloatStreamParseTest, ::testing::ValuesIn(std::vector>{ // Positive exponents {"0x1.0p1", true, "", 2.0f}, // fine, a normal number @@ -1493,7 +1412,7 @@ INSTANTIATE_TEST_SUITE_P( })); INSTANTIATE_TEST_SUITE_P( - HexFloat32NegativeExponentOverflow, Float32StreamParseTest, + HexFloatNegativeExponentOverflow, FloatStreamParseTest, ::testing::ValuesIn(std::vector>{ // Positive results, digits before '.' {"0x1.0p-126", true, "", @@ -1517,109 +1436,7 @@ INSTANTIATE_TEST_SUITE_P( {"0x0.0p-5000000000", true, "", 0.0f}, // zero mantissa, zero result })); -INSTANTIATE_TEST_SUITE_P( - HexFloat16ExcessSignificantDigits, Float16StreamParseTest, - ::testing::ValuesIn(std::vector>{ - // Zero - {"0x1.c00p0", true, "", makeF16(0, 0, 0x300)}, - {"0x0p0", true, "", makeF16(0, -15, 0x0)}, - {"0x000.0000p0", true, "", makeF16(0, -15, 0x0)}, - // All leading 1s - {"0x1p0", true, "", makeF16(0, 0, 0x0)}, - {"0x1.8p0", true, "", makeF16(0, 0, 0x200)}, - {"0x1.cp0", true, "", makeF16(0, 0, 0x300)}, - {"0x1.ep0", true, "", makeF16(0, 0, 0x380)}, - {"0x1.fp0", true, "", makeF16(0, 0, 0x3c0)}, - {"0x1.f8p0", true, "", makeF16(0, 0, 0x3e0)}, - {"0x1.fcp0", true, "", makeF16(0, 0, 0x3f0)}, - {"0x1.fep0", true, "", makeF16(0, 0, 0x3f8)}, - {"0x1.ffp0", true, "", makeF16(0, 0, 0x3fc)}, - // Fill trailing zeros to all significant places - // that might be used for significant digits. - {"0x1.ff8p0", true, "", makeF16(0, 0, 0x3fe)}, - {"0x1.ffcp0", true, "", makeF16(0, 0, 0x3ff)}, - {"0x1.800p0", true, "", makeF16(0, 0, 0x200)}, - {"0x1.c00p0", true, "", makeF16(0, 0, 0x300)}, - {"0x1.e00p0", true, "", makeF16(0, 0, 0x380)}, - {"0x1.f00p0", true, "", makeF16(0, 0, 0x3c0)}, - {"0x1.f80p0", true, "", makeF16(0, 0, 0x3e0)}, - {"0x1.fc0p0", true, "", makeF16(0, 0, 0x3f0)}, - {"0x1.fe0p0", true, "", makeF16(0, 0, 0x3f8)}, - {"0x1.ff0p0", true, "", makeF16(0, 0, 0x3fc)}, - {"0x1.ff8p0", true, "", makeF16(0, 0, 0x3fe)}, - {"0x1.ffcp0", true, "", makeF16(0, 0, 0x3ff)}, - // Add several trailing zeros - {"0x1.c00000p0", true, "", makeF16(0, 0, 0x300)}, - {"0x1.e00000p0", true, "", makeF16(0, 0, 0x380)}, - {"0x1.f00000p0", true, "", makeF16(0, 0, 0x3c0)}, - {"0x1.f80000p0", true, "", makeF16(0, 0, 0x3e0)}, - {"0x1.fc0000p0", true, "", makeF16(0, 0, 0x3f0)}, - {"0x1.fe0000p0", true, "", makeF16(0, 0, 0x3f8)}, - {"0x1.ff0000p0", true, "", makeF16(0, 0, 0x3fc)}, - {"0x1.ff8000p0", true, "", makeF16(0, 0, 0x3fe)}, - {"0x1.ffcp0000", true, "", makeF16(0, 0, 0x3ff)}, - // Samples that drop out bits in the middle. - // 5 = 0101 4 = 0100 - // a = 1010 8 = 1000 - {"0x1.5a4p0", true, "", makeF16(0, 0, 0x169)}, - {"0x1.a58p0", true, "", makeF16(0, 0, 0x296)}, - // Samples that drop out bits *and* truncate significant bits - // that can't be represented. - {"0x1.5a40000p0", true, "", makeF16(0, 0, 0x169)}, - {"0x1.5a7ffffp0", true, "", makeF16(0, 0, 0x169)}, - {"0x1.a580000p0", true, "", makeF16(0, 0, 0x296)}, - {"0x1.a5bffffp0", true, "", makeF16(0, 0, 0x296)}, - // Try some negations. - {"-0x0p0", true, "", makeF16(1, -15, 0x0)}, - {"-0x000.0000p0", true, "", makeF16(1, -15, 0x0)}, - {"-0x1.5a40000p0", true, "", makeF16(1, 0, 0x169)}, - {"-0x1.5a7ffffp0", true, "", makeF16(1, 0, 0x169)}, - {"-0x1.a580000p0", true, "", makeF16(1, 0, 0x296)}, - {"-0x1.a5bffffp0", true, "", makeF16(1, 0, 0x296)}})); - -INSTANTIATE_TEST_SUITE_P( - HexFloat16IncreasingExponentsAndMantissa, Float16StreamParseTest, - ::testing::ValuesIn(std::vector>{ - // Zero - {"0x0p0", true, "", makeF16(0, -15, 0x0)}, - {"0x0p5000000000000", true, "", makeF16(0, -15, 0x0)}, - {"-0x0p5000000000000", true, "", makeF16(1, -15, 0x0)}, - // Leading 1 - {"0x1p0", true, "", makeF16(0, 0, 0x0)}, - {"0x1p1", true, "", makeF16(0, 1, 0x0)}, - {"0x1p16", true, "", makeF16(0, 16, 0x0)}, - {"0x1p-1", true, "", makeF16(0, -1, 0x0)}, - {"0x1p-14", true, "", makeF16(0, -14, 0x0)}, - // Leading 2 - {"0x2p0", true, "", makeF16(0, 1, 0x0)}, - {"0x2p1", true, "", makeF16(0, 2, 0x0)}, - {"0x2p15", true, "", makeF16(0, 16, 0x0)}, - {"0x2p-1", true, "", makeF16(0, 0, 0x0)}, - {"0x2p-15", true, "", makeF16(0, -14, 0x0)}, - // Leading 8 - {"0x8p0", true, "", makeF16(0, 3, 0x0)}, - {"0x8p1", true, "", makeF16(0, 4, 0x0)}, - {"0x8p13", true, "", makeF16(0, 16, 0x0)}, - {"0x8p-3", true, "", makeF16(0, 0, 0x0)}, - {"0x8p-17", true, "", makeF16(0, -14, 0x0)}, - // Leading 10 - {"0x10.0p0", true, "", makeF16(0, 4, 0x0)}, - {"0x10.0p1", true, "", makeF16(0, 5, 0x0)}, - {"0x10.0p12", true, "", makeF16(0, 16, 0x0)}, - {"0x10.0p-5", true, "", makeF16(0, -1, 0x0)}, - {"0x10.0p-18", true, "", makeF16(0, -14, 0x0)}, - // Samples that drop out bits *and* truncate significant bits - // that can't be represented. - // Progressively increase the leading digit. - {"0x1.5a40000p0", true, "", makeF16(0, 0, 0x169)}, - {"0x1.5a7ffffp0", true, "", makeF16(0, 0, 0x169)}, - {"0x2.5a40000p0", true, "", makeF16(0, 1, 0x0b4)}, - {"0x2.5a7ffffp0", true, "", makeF16(0, 1, 0x0b4)}, - {"0x4.5a40000p0", true, "", makeF16(0, 2, 0x05a)}, - {"0x4.5a7ffffp0", true, "", makeF16(0, 2, 0x05a)}, - {"0x8.5a40000p0", true, "", makeF16(0, 3, 0x02d)}, - {"0x8.5a7ffffp0", true, "", makeF16(0, 3, 0x02d)}})); - +// TODO(awoloszyn): Add fp16 tests and HexFloatTraits. } // namespace } // namespace utils } // namespace spvtools diff --git a/test/immediate_int_test.cpp b/test/immediate_int_test.cpp index 8e7a8fd3..393075a4 100644 --- a/test/immediate_int_test.cpp +++ b/test/immediate_int_test.cpp @@ -57,34 +57,34 @@ using ImmediateIntTest = TextToBinaryTest; TEST_F(ImmediateIntTest, AnyWordInSimpleStatement) { EXPECT_THAT(CompiledInstructions("!0x00040018 %a %b %123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 2, 3}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 3}))); EXPECT_THAT(CompiledInstructions("!0x00040018 !1 %b %123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 1, 2}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 1, 2}))); EXPECT_THAT(CompiledInstructions("%a = OpTypeMatrix !2 %123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 2, 2}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 2}))); EXPECT_THAT(CompiledInstructions("%a = OpTypeMatrix %b !123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 2, 123}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 123}))); EXPECT_THAT(CompiledInstructions("!0x00040018 %a !2 %123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 2, 2}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 2}))); EXPECT_THAT(CompiledInstructions("!0x00040018 !1 %b !123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 1, 123}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 1, 123}))); EXPECT_THAT(CompiledInstructions("!0x00040018 !1 !2 !123"), - Eq(MakeInstruction(spv::Op::OpTypeMatrix, {1, 2, 123}))); + Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 123}))); } TEST_F(ImmediateIntTest, AnyWordAfterEqualsAndOpCode) { EXPECT_THAT(CompiledInstructions("%a = OpArrayLength !2 %c 123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {2, 1, 2, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {2, 1, 2, 123}))); EXPECT_THAT(CompiledInstructions("%a = OpArrayLength %b !3 123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {1, 2, 3, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {1, 2, 3, 123}))); EXPECT_THAT(CompiledInstructions("%a = OpArrayLength %b %c !123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {1, 2, 3, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {1, 2, 3, 123}))); EXPECT_THAT(CompiledInstructions("%a = OpArrayLength %b !3 !123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {1, 2, 3, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {1, 2, 3, 123}))); EXPECT_THAT(CompiledInstructions("%a = OpArrayLength !2 !3 123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {2, 1, 3, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {2, 1, 3, 123}))); EXPECT_THAT(CompiledInstructions("%a = OpArrayLength !2 !3 !123"), - Eq(MakeInstruction(spv::Op::OpArrayLength, {2, 1, 3, 123}))); + Eq(MakeInstruction(SpvOpArrayLength, {2, 1, 3, 123}))); } TEST_F(ImmediateIntTest, ResultIdInAssignment) { @@ -108,8 +108,8 @@ TEST_F(ImmediateIntTest, IntegerFollowingImmediate) { // With !, we can (and can only) accept 32-bit number literals, // even when we declare the return type is 64-bit. EXPECT_EQ(Concatenate({ - MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 4294967295}), + MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 4294967295}), }), CompiledInstructions("%i64 = OpTypeInt 64 0\n" "!0x0004002b %i64 !2 4294967295")); @@ -151,9 +151,9 @@ TEST_F(ImmediateIntTest, FloatFollowingImmediate) { CompiledInstructions("%1 = OpTypeFloat 32\n!0x0004002b %1 %2 -0.5")); EXPECT_EQ(Concatenate({ - MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xb, 0xa}), - MakeInstruction(spv::Op::OpSwitch, + MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0xb, 0xa}), + MakeInstruction(SpvOpSwitch, {2, 1234, BitwiseCast(2.5f), 3}), }), CompiledInstructions("%i64 = OpTypeInt 64 0\n" @@ -174,7 +174,7 @@ TEST_F(ImmediateIntTest, StringFollowingImmediate) { CompiledInstructions("OpMemberName !1 !4 \"" + name + "\"")) << name; const uint16_t wordCount = static_cast(4 + name.size() / 4); - const uint32_t firstWord = spvOpcodeMake(wordCount, spv::Op::OpMemberName); + const uint32_t firstWord = spvOpcodeMake(wordCount, SpvOpMemberName); EXPECT_EQ(original, CompiledInstructions("!" + std::to_string(firstWord) + " %10 !4 \"" + name + "\"")) << name; @@ -205,8 +205,8 @@ TEST_F(ImmediateIntTest, InvalidStatementBetweenValidOnes) { EXPECT_THAT(Subvector(CompileSuccessfully( "%10 = OpTypeFloat 32 !5 !6 !7 OpEmitVertex"), kFirstInstruction), - ElementsAre(spvOpcodeMake(3, spv::Op::OpTypeFloat), 1, 32, 5, 6, - 7, spvOpcodeMake(1, spv::Op::OpEmitVertex))); + ElementsAre(spvOpcodeMake(3, SpvOpTypeFloat), 1, 32, 5, 6, 7, + spvOpcodeMake(1, SpvOpEmitVertex))); } TEST_F(ImmediateIntTest, NextOpcodeRecognized) { diff --git a/test/link/binary_version_test.cpp b/test/link/binary_version_test.cpp index 384255a4..a56030f4 100644 --- a/test/link/binary_version_test.cpp +++ b/test/link/binary_version_test.cpp @@ -27,20 +27,20 @@ spvtest::Binary CreateBinary(uint32_t version) { return { // clang-format off // Header - static_cast(spv::MagicNumber), + SpvMagicNumber, version, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0), 1u, // NOTE: Bound 0u, // NOTE: Schema; reserved // OpCapability Shader - static_cast(spv::Op::OpCapability) | 2u << spv::WordCountShift, - static_cast(spv::Capability::Shader), + SpvOpCapability | 2u << SpvWordCountShift, + SpvCapabilityShader, // OpMemoryModel Logical Simple - static_cast(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift, - static_cast(spv::AddressingModel::Logical), - static_cast(spv::MemoryModel::Simple) + SpvOpMemoryModel | 3u << SpvWordCountShift, + SpvAddressingModelLogical, + SpvMemoryModelSimple // clang-format on }; } @@ -73,21 +73,5 @@ TEST_F(BinaryVersion, Mismatch) { "through 1) vs 1.5 (input module 2).")); } -TEST_F(BinaryVersion, UseHighest) { - // clang-format off - spvtest::Binaries binaries = { - CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)), - CreateBinary(SPV_SPIRV_VERSION_WORD(1, 5)), - }; - // clang-format on - LinkerOptions options; - options.SetUseHighestVersion(true); - spvtest::Binary linked_binary; - ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary, options)) - << GetErrorMessage(); - EXPECT_THAT(GetErrorMessage(), std::string()); - EXPECT_EQ(SPV_SPIRV_VERSION_WORD(1, 5), linked_binary[1]); -} - } // namespace } // namespace spvtools diff --git a/test/link/global_values_amount_test.cpp b/test/link/global_values_amount_test.cpp index fda55d6a..3158b7ec 100644 --- a/test/link/global_values_amount_test.cpp +++ b/test/link/global_values_amount_test.cpp @@ -34,26 +34,26 @@ class EntryPointsAmountTest : public spvtest::LinkerTest { spvtest::Binary common_binary = { // clang-format off - static_cast(spv::MagicNumber), - static_cast(spv::Version), + SpvMagicNumber, + SpvVersion, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0), 3u + global_variable_count_per_binary, // NOTE: Bound 0u, // NOTE: Schema; reserved - static_cast(spv::Op::OpCapability) | 2u << spv::WordCountShift, - static_cast(spv::Capability::Shader), + SpvOpCapability | 2u << SpvWordCountShift, + SpvCapabilityShader, - static_cast(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift, - static_cast(spv::AddressingModel::Logical), - static_cast(spv::MemoryModel::Simple), + SpvOpMemoryModel | 3u << SpvWordCountShift, + SpvAddressingModelLogical, + SpvMemoryModelSimple, - static_cast(spv::Op::OpTypeFloat) | 3u << spv::WordCountShift, + SpvOpTypeFloat | 3u << SpvWordCountShift, 1u, // NOTE: Result ID 32u, // NOTE: Width - static_cast(spv::Op::OpTypePointer) | 4u << spv::WordCountShift, + SpvOpTypePointer | 4u << SpvWordCountShift, 2u, // NOTE: Result ID - static_cast(spv::StorageClass::Input), + SpvStorageClassInput, 1u // NOTE: Type ID // clang-format on }; @@ -64,11 +64,10 @@ class EntryPointsAmountTest : public spvtest::LinkerTest { binary.insert(binary.end(), common_binary.cbegin(), common_binary.cend()); for (uint32_t i = 0u; i < global_variable_count_per_binary; ++i) { - binary.push_back(static_cast(spv::Op::OpVariable) | - 4u << spv::WordCountShift); + binary.push_back(SpvOpVariable | 4u << SpvWordCountShift); binary.push_back(2u); // NOTE: Type ID binary.push_back(3u + i); // NOTE: Result ID - binary.push_back(static_cast(spv::StorageClass::Input)); + binary.push_back(SpvStorageClassInput); } for (uint32_t i = 0u; i < binary_count - 1u; ++i) { @@ -90,37 +89,37 @@ TEST_F(EntryPointsAmountTest, UnderLimit) { TEST_F(EntryPointsAmountTest, OverLimit) { binaries.push_back({ // clang-format off - static_cast(spv::MagicNumber), - static_cast(spv::Version), + SpvMagicNumber, + SpvVersion, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0), 5u, // NOTE: Bound 0u, // NOTE: Schema; reserved - static_cast(spv::Op::OpCapability) | 2u << spv::WordCountShift, - static_cast(spv::Capability::Shader), + SpvOpCapability | 2u << SpvWordCountShift, + SpvCapabilityShader, - static_cast(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift, - static_cast(spv::AddressingModel::Logical), - static_cast(spv::MemoryModel::Simple), + SpvOpMemoryModel | 3u << SpvWordCountShift, + SpvAddressingModelLogical, + SpvMemoryModelSimple, - static_cast(spv::Op::OpTypeFloat) | 3u << spv::WordCountShift, + SpvOpTypeFloat | 3u << SpvWordCountShift, 1u, // NOTE: Result ID 32u, // NOTE: Width - static_cast(spv::Op::OpTypePointer) | 4u << spv::WordCountShift, + SpvOpTypePointer | 4u << SpvWordCountShift, 2u, // NOTE: Result ID - static_cast(spv::StorageClass::Input), + SpvStorageClassInput, 1u, // NOTE: Type ID - static_cast(spv::Op::OpVariable) | 4u << spv::WordCountShift, + SpvOpVariable | 4u << SpvWordCountShift, 2u, // NOTE: Type ID 3u, // NOTE: Result ID - static_cast(spv::StorageClass::Input), + SpvStorageClassInput, - static_cast(spv::Op::OpVariable) | 4u << spv::WordCountShift, + SpvOpVariable | 4u << SpvWordCountShift, 2u, // NOTE: Type ID 4u, // NOTE: Result ID - static_cast(spv::StorageClass::Input) + SpvStorageClassInput // clang-format on }); diff --git a/test/link/ids_limit_test.cpp b/test/link/ids_limit_test.cpp index 8182e5d6..846fbef8 100644 --- a/test/link/ids_limit_test.cpp +++ b/test/link/ids_limit_test.cpp @@ -36,20 +36,20 @@ class IdsLimit : public spvtest::LinkerTest { // running the RemoveDuplicates pass. spvtest::Binary common_binary = { // clang-format off - spv::MagicNumber, - spv::Version, + SpvMagicNumber, + SpvVersion, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0), id_bound, // NOTE: Bound 0u, // NOTE: Schema; reserved - static_cast(spv::Op::OpCapability) | 2u << spv::WordCountShift, - static_cast(spv::Capability::Shader), + SpvOpCapability | 2u << SpvWordCountShift, + SpvCapabilityShader, - static_cast(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift, - static_cast(spv::AddressingModel::Logical), - static_cast(spv::MemoryModel::Simple), + SpvOpMemoryModel | 3u << SpvWordCountShift, + SpvAddressingModelLogical, + SpvMemoryModelSimple, - static_cast(spv::Op::OpTypeBool) | 2u << spv::WordCountShift, + SpvOpTypeBool | 2u << SpvWordCountShift, 1u // NOTE: Result ID // clang-format on }; @@ -60,8 +60,7 @@ class IdsLimit : public spvtest::LinkerTest { binary.insert(binary.end(), common_binary.cbegin(), common_binary.cend()); for (uint32_t i = 0u; i < constant_count; ++i) { - binary.push_back(static_cast(spv::Op::OpConstantTrue) | - 3u << spv::WordCountShift); + binary.push_back(SpvOpConstantTrue | 3u << SpvWordCountShift); binary.push_back(1u); // NOTE: Type ID binary.push_back(2u + i); // NOTE: Result ID } @@ -75,20 +74,20 @@ spvtest::Binary CreateBinary(uint32_t id_bound) { return { // clang-format off // Header - spv::MagicNumber, - spv::Version, + SpvMagicNumber, + SpvVersion, SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0), id_bound, // NOTE: Bound 0u, // NOTE: Schema; reserved // OpCapability Shader - static_cast(spv::Op::OpCapability) | 2u << spv::WordCountShift, - static_cast(spv::Capability::Shader), + SpvOpCapability | 2u << SpvWordCountShift, + SpvCapabilityShader, // OpMemoryModel Logical Simple - static_cast(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift, - static_cast(spv::AddressingModel::Logical), - static_cast(spv::MemoryModel::Simple) + SpvOpMemoryModel | 3u << SpvWordCountShift, + SpvAddressingModelLogical, + SpvMemoryModelSimple // clang-format on }; } @@ -106,8 +105,7 @@ TEST_F(IdsLimit, DISABLED_OverLimit) { const uint32_t id_bound = binary[3]; binary[3] = id_bound + 1u; - binary.push_back(static_cast(spv::Op::OpConstantFalse) | - 3u << spv::WordCountShift); + binary.push_back(SpvOpConstantFalse | 3u << SpvWordCountShift); binary.push_back(1u); // NOTE: Type ID binary.push_back(id_bound); // NOTE: Result ID diff --git a/test/link/memory_model_test.cpp b/test/link/memory_model_test.cpp index ee63c59f..280a776a 100644 --- a/test/link/memory_model_test.cpp +++ b/test/link/memory_model_test.cpp @@ -35,10 +35,8 @@ OpMemoryModel Logical Simple ASSERT_EQ(SPV_SUCCESS, AssembleAndLink({body1, body2}, &linked_binary)); EXPECT_THAT(GetErrorMessage(), std::string()); - EXPECT_EQ(spv::AddressingModel::Logical, - static_cast(linked_binary[6])); - EXPECT_EQ(spv::MemoryModel::Simple, - static_cast(linked_binary[7])); + EXPECT_EQ(SpvAddressingModelLogical, linked_binary[6]); + EXPECT_EQ(SpvMemoryModelSimple, linked_binary[7]); } TEST_F(MemoryModel, AddressingMismatch) { diff --git a/test/log_test.cpp b/test/log_test.cpp new file mode 100644 index 00000000..ec66aa1e --- /dev/null +++ b/test/log_test.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2016 Google Inc. +// +// 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 "source/opt/log.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace spvtools { +namespace { + +using ::testing::MatchesRegex; + +TEST(Log, Unimplemented) { + int invocation = 0; + auto consumer = [&invocation](spv_message_level_t level, const char* source, + const spv_position_t&, const char* message) { + ++invocation; + EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level); + EXPECT_THAT(source, MatchesRegex(".*log_test.cpp$")); + EXPECT_STREQ("unimplemented: the-ultimite-feature", message); + }; + + SPIRV_UNIMPLEMENTED(consumer, "the-ultimite-feature"); + EXPECT_EQ(1, invocation); +} + +TEST(Log, Unreachable) { + int invocation = 0; + auto consumer = [&invocation](spv_message_level_t level, const char* source, + const spv_position_t&, const char* message) { + ++invocation; + EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level); + EXPECT_THAT(source, MatchesRegex(".*log_test.cpp$")); + EXPECT_STREQ("unreachable", message); + }; + + SPIRV_UNREACHABLE(consumer); + EXPECT_EQ(1, invocation); +} + +} // namespace +} // namespace spvtools diff --git a/test/opcode_make_test.cpp b/test/opcode_make_test.cpp index 6c1dab60..6481ef32 100644 --- a/test/opcode_make_test.cpp +++ b/test/opcode_make_test.cpp @@ -35,7 +35,7 @@ TEST(OpcodeMake, Samples) { uint32_t word = 0; word |= uint32_t(opcode); word |= uint32_t(wordCount) << 16; - EXPECT_EQ(word, spvOpcodeMake(wordCount, spv::Op(opcode))); + EXPECT_EQ(word, spvOpcodeMake(wordCount, SpvOp(opcode))); } } } diff --git a/test/opcode_require_capabilities_test.cpp b/test/opcode_require_capabilities_test.cpp index 37097c6f..07e86f87 100644 --- a/test/opcode_require_capabilities_test.cpp +++ b/test/opcode_require_capabilities_test.cpp @@ -23,7 +23,7 @@ using spvtest::ElementsIn; // Capabilities required by an Opcode. struct ExpectedOpCodeCapabilities { - spv::Op opcode; + SpvOp opcode; CapabilitySet capabilities; }; @@ -46,36 +46,33 @@ INSTANTIATE_TEST_SUITE_P( TableRowTest, OpcodeTableCapabilitiesTest, // Spot-check a few opcodes. ::testing::Values( - ExpectedOpCodeCapabilities{spv::Op::OpImageQuerySize, - CapabilitySet{spv::Capability::Kernel, - spv::Capability::ImageQuery}}, - ExpectedOpCodeCapabilities{spv::Op::OpImageQuerySizeLod, - CapabilitySet{spv::Capability::Kernel, - spv::Capability::ImageQuery}}, - ExpectedOpCodeCapabilities{spv::Op::OpImageQueryLevels, - CapabilitySet{spv::Capability::Kernel, - spv::Capability::ImageQuery}}, - ExpectedOpCodeCapabilities{spv::Op::OpImageQuerySamples, - CapabilitySet{spv::Capability::Kernel, - spv::Capability::ImageQuery}}, ExpectedOpCodeCapabilities{ - spv::Op::OpImageSparseSampleImplicitLod, - CapabilitySet{spv::Capability::SparseResidency}}, - ExpectedOpCodeCapabilities{spv::Op::OpCopyMemorySized, - CapabilitySet{spv::Capability::Addresses}}, - ExpectedOpCodeCapabilities{spv::Op::OpArrayLength, - CapabilitySet{spv::Capability::Shader}}, - ExpectedOpCodeCapabilities{spv::Op::OpFunction, CapabilitySet()}, - ExpectedOpCodeCapabilities{spv::Op::OpConvertFToS, CapabilitySet()}, + SpvOpImageQuerySize, + CapabilitySet{SpvCapabilityKernel, SpvCapabilityImageQuery}}, ExpectedOpCodeCapabilities{ - spv::Op::OpEmitStreamVertex, - CapabilitySet{spv::Capability::GeometryStreams}}, + SpvOpImageQuerySizeLod, + CapabilitySet{SpvCapabilityKernel, SpvCapabilityImageQuery}}, ExpectedOpCodeCapabilities{ - spv::Op::OpTypeNamedBarrier, - CapabilitySet{spv::Capability::NamedBarrier}}, + SpvOpImageQueryLevels, + CapabilitySet{SpvCapabilityKernel, SpvCapabilityImageQuery}}, ExpectedOpCodeCapabilities{ - spv::Op::OpGetKernelMaxNumSubgroups, - CapabilitySet{spv::Capability::SubgroupDispatch}})); + SpvOpImageQuerySamples, + CapabilitySet{SpvCapabilityKernel, SpvCapabilityImageQuery}}, + ExpectedOpCodeCapabilities{SpvOpImageSparseSampleImplicitLod, + CapabilitySet{SpvCapabilitySparseResidency}}, + ExpectedOpCodeCapabilities{SpvOpCopyMemorySized, + CapabilitySet{SpvCapabilityAddresses}}, + ExpectedOpCodeCapabilities{SpvOpArrayLength, + CapabilitySet{SpvCapabilityShader}}, + ExpectedOpCodeCapabilities{SpvOpFunction, CapabilitySet()}, + ExpectedOpCodeCapabilities{SpvOpConvertFToS, CapabilitySet()}, + ExpectedOpCodeCapabilities{SpvOpEmitStreamVertex, + CapabilitySet{SpvCapabilityGeometryStreams}}, + ExpectedOpCodeCapabilities{SpvOpTypeNamedBarrier, + CapabilitySet{SpvCapabilityNamedBarrier}}, + ExpectedOpCodeCapabilities{ + SpvOpGetKernelMaxNumSubgroups, + CapabilitySet{SpvCapabilitySubgroupDispatch}})); } // namespace } // namespace spvtools diff --git a/test/opcode_split_test.cpp b/test/opcode_split_test.cpp index e8a67b68..43fedb38 100644 --- a/test/opcode_split_test.cpp +++ b/test/opcode_split_test.cpp @@ -18,7 +18,7 @@ namespace spvtools { namespace { TEST(OpcodeSplit, Default) { - uint32_t word = spvOpcodeMake(42, (spv::Op)23); + uint32_t word = spvOpcodeMake(42, (SpvOp)23); uint16_t wordCount = 0; uint16_t opcode; spvOpcodeSplit(word, &wordCount, &opcode); diff --git a/test/operand_capabilities_test.cpp b/test/operand_capabilities_test.cpp index 48722281..60503461 100644 --- a/test/operand_capabilities_test.cpp +++ b/test/operand_capabilities_test.cpp @@ -18,9 +18,7 @@ #include #include "gmock/gmock.h" -#include "source/assembly_grammar.h" #include "source/enum_set.h" -#include "source/operand.h" #include "test/unit_spirv.h" namespace spvtools { @@ -33,39 +31,12 @@ using ::testing::TestWithParam; using ::testing::Values; using ::testing::ValuesIn; -// Emits a CapabilitySet to the given ostream, returning the ostream. -inline std::ostream& operator<<(std::ostream& out, const CapabilitySet& cs) { - out << "CapabilitySet{"; - auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_0); - spvtools::AssemblyGrammar grammar(ctx); - bool first = true; - for (auto c : cs) { - if (!first) { - out << " "; - first = false; - } - out << grammar.lookupOperandName(SPV_OPERAND_TYPE_CAPABILITY, uint32_t(c)) - << "(" << uint32_t(c) << ")"; - } - spvContextDestroy(ctx); - out << "}"; - return out; -} - // A test case for mapping an enum to a capability mask. struct EnumCapabilityCase { spv_operand_type_t type; uint32_t value; CapabilitySet expected_capabilities; }; -// Emits an EnumCapabilityCase to the ostream, returning the ostream. -inline std::ostream& operator<<(std::ostream& out, - const EnumCapabilityCase& ecc) { - out << "EnumCapabilityCase{ " << spvOperandTypeStr(ecc.type) << "(" - << unsigned(ecc.type) << "), " << ecc.value << ", " - << ecc.expected_capabilities << "}"; - return out; -} // Test fixture for testing EnumCapabilityCases. using EnumCapabilityTest = @@ -85,53 +56,53 @@ TEST_P(EnumCapabilityTest, Sample) { EXPECT_THAT(ElementsIn(cap_set), Eq(ElementsIn(std::get<1>(GetParam()).expected_capabilities))) - << " enum value " << std::get<1>(GetParam()).value; + << " capability value " << std::get<1>(GetParam()).value; spvContextDestroy(context); } #define CASE0(TYPE, VALUE) \ { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), {} \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), {} \ } #define CASE1(TYPE, VALUE, CAP) \ { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP \ } \ } #define CASE2(TYPE, VALUE, CAP1, CAP2) \ { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP1, spv::Capability::CAP2 \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2 \ } \ } -#define CASE3(TYPE, VALUE, CAP1, CAP2, CAP3) \ - { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP1, spv::Capability::CAP2, spv::Capability::CAP3 \ - } \ +#define CASE3(TYPE, VALUE, CAP1, CAP2, CAP3) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3 \ + } \ } -#define CASE4(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4) \ - { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP1, spv::Capability::CAP2, spv::Capability::CAP3, \ - spv::Capability::CAP4 \ - } \ +#define CASE4(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3, \ + SpvCapability##CAP4 \ + } \ } -#define CASE5(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5) \ - { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP1, spv::Capability::CAP2, spv::Capability::CAP3, \ - spv::Capability::CAP4, spv::Capability::CAP5 \ - } \ +#define CASE5(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3, \ + SpvCapability##CAP4, SpvCapability##CAP5 \ + } \ } -#define CASE6(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5, CAP6) \ - { \ - SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), CapabilitySet { \ - spv::Capability::CAP1, spv::Capability::CAP2, spv::Capability::CAP3, \ - spv::Capability::CAP4, spv::Capability::CAP5, spv::Capability::CAP6 \ - } \ +#define CASE6(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5, CAP6) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet { \ + SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3, \ + SpvCapability##CAP4, SpvCapability##CAP5, SpvCapability##CAP6 \ + } \ } // See SPIR-V Section 3.3 Execution Model @@ -139,15 +110,15 @@ INSTANTIATE_TEST_SUITE_P( ExecutionModel, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(EXECUTION_MODEL, ExecutionModel::Vertex, Shader), - CASE1(EXECUTION_MODEL, ExecutionModel::TessellationControl, + CASE1(EXECUTION_MODEL, ExecutionModelVertex, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelTessellationControl, Tessellation), - CASE1(EXECUTION_MODEL, ExecutionModel::TessellationEvaluation, + CASE1(EXECUTION_MODEL, ExecutionModelTessellationEvaluation, Tessellation), - CASE1(EXECUTION_MODEL, ExecutionModel::Geometry, Geometry), - CASE1(EXECUTION_MODEL, ExecutionModel::Fragment, Shader), - CASE1(EXECUTION_MODEL, ExecutionModel::GLCompute, Shader), - CASE1(EXECUTION_MODEL, ExecutionModel::Kernel, Kernel), + CASE1(EXECUTION_MODEL, ExecutionModelGeometry, Geometry), + CASE1(EXECUTION_MODEL, ExecutionModelFragment, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelGLCompute, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelKernel, Kernel), }))); // See SPIR-V Section 3.4 Addressing Model @@ -155,9 +126,9 @@ INSTANTIATE_TEST_SUITE_P( AddressingModel, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(ADDRESSING_MODEL, AddressingModel::Logical), - CASE1(ADDRESSING_MODEL, AddressingModel::Physical32, Addresses), - CASE1(ADDRESSING_MODEL, AddressingModel::Physical64, Addresses), + CASE0(ADDRESSING_MODEL, AddressingModelLogical), + CASE1(ADDRESSING_MODEL, AddressingModelPhysical32, Addresses), + CASE1(ADDRESSING_MODEL, AddressingModelPhysical64, Addresses), }))); // See SPIR-V Section 3.5 Memory Model @@ -165,9 +136,9 @@ INSTANTIATE_TEST_SUITE_P( MemoryModel, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(MEMORY_MODEL, MemoryModel::Simple, Shader), - CASE1(MEMORY_MODEL, MemoryModel::GLSL450, Shader), - CASE1(MEMORY_MODEL, MemoryModel::OpenCL, Kernel), + CASE1(MEMORY_MODEL, MemoryModelSimple, Shader), + CASE1(MEMORY_MODEL, MemoryModelGLSL450, Shader), + CASE1(MEMORY_MODEL, MemoryModelOpenCL, Kernel), }))); // See SPIR-V Section 3.6 Execution Mode @@ -176,54 +147,54 @@ INSTANTIATE_TEST_SUITE_P( Combine( Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(EXECUTION_MODE, ExecutionMode::Invocations, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::SpacingEqual, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::SpacingFractionalEven, + CASE1(EXECUTION_MODE, ExecutionModeInvocations, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeSpacingEqual, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeSpacingFractionalEven, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::SpacingFractionalOdd, + CASE1(EXECUTION_MODE, ExecutionModeSpacingFractionalOdd, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::VertexOrderCw, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::VertexOrderCcw, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::PixelCenterInteger, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::OriginUpperLeft, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::OriginLowerLeft, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::EarlyFragmentTests, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::PointMode, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::Xfb, TransformFeedback), - CASE1(EXECUTION_MODE, ExecutionMode::DepthReplacing, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::DepthGreater, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::DepthLess, Shader), - CASE1(EXECUTION_MODE, ExecutionMode::DepthUnchanged, Shader), - CASE0(EXECUTION_MODE, ExecutionMode::LocalSize), - CASE1(EXECUTION_MODE, ExecutionMode::LocalSizeHint, Kernel), - CASE1(EXECUTION_MODE, ExecutionMode::InputPoints, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::InputLines, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::InputLinesAdjacency, Geometry), - CASE2(EXECUTION_MODE, ExecutionMode::Triangles, Geometry, + CASE1(EXECUTION_MODE, ExecutionModeVertexOrderCw, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeVertexOrderCcw, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModePixelCenterInteger, Shader), + CASE1(EXECUTION_MODE, ExecutionModeOriginUpperLeft, Shader), + CASE1(EXECUTION_MODE, ExecutionModeOriginLowerLeft, Shader), + CASE1(EXECUTION_MODE, ExecutionModeEarlyFragmentTests, Shader), + CASE1(EXECUTION_MODE, ExecutionModePointMode, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeXfb, TransformFeedback), + CASE1(EXECUTION_MODE, ExecutionModeDepthReplacing, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthGreater, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthLess, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthUnchanged, Shader), + CASE0(EXECUTION_MODE, ExecutionModeLocalSize), + CASE1(EXECUTION_MODE, ExecutionModeLocalSizeHint, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeInputPoints, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeInputLines, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeInputLinesAdjacency, Geometry), + CASE2(EXECUTION_MODE, ExecutionModeTriangles, Geometry, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::InputTrianglesAdjacency, + CASE1(EXECUTION_MODE, ExecutionModeInputTrianglesAdjacency, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::Quads, Tessellation), - CASE1(EXECUTION_MODE, ExecutionMode::Isolines, Tessellation), - CASE4(EXECUTION_MODE, ExecutionMode::OutputVertices, Geometry, + CASE1(EXECUTION_MODE, ExecutionModeQuads, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeIsolines, Tessellation), + CASE4(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry, Tessellation, MeshShadingNV, MeshShadingEXT), - CASE3(EXECUTION_MODE, ExecutionMode::OutputPoints, Geometry, + CASE3(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry, MeshShadingNV, MeshShadingEXT), - CASE1(EXECUTION_MODE, ExecutionMode::OutputLineStrip, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::OutputTriangleStrip, Geometry), - CASE1(EXECUTION_MODE, ExecutionMode::VecTypeHint, Kernel), - CASE1(EXECUTION_MODE, ExecutionMode::ContractionOff, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeOutputLineStrip, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeOutputTriangleStrip, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeVecTypeHint, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeContractionOff, Kernel), }))); INSTANTIATE_TEST_SUITE_P( ExecutionModeV11, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(EXECUTION_MODE, ExecutionMode::Initializer, Kernel), - CASE1(EXECUTION_MODE, ExecutionMode::Finalizer, Kernel), - CASE1(EXECUTION_MODE, ExecutionMode::SubgroupSize, + CASE1(EXECUTION_MODE, ExecutionModeInitializer, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeFinalizer, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeSubgroupSize, SubgroupDispatch), - CASE1(EXECUTION_MODE, ExecutionMode::SubgroupsPerWorkgroup, + CASE1(EXECUTION_MODE, ExecutionModeSubgroupsPerWorkgroup, SubgroupDispatch)}))); // See SPIR-V Section 3.7 Storage Class @@ -231,20 +202,19 @@ INSTANTIATE_TEST_SUITE_P( StorageClass, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(STORAGE_CLASS, StorageClass::UniformConstant), - CASE1(STORAGE_CLASS, StorageClass::Uniform, Shader), - CASE1(STORAGE_CLASS, StorageClass::Output, Shader), - CASE0(STORAGE_CLASS, StorageClass::Workgroup), - CASE0(STORAGE_CLASS, StorageClass::CrossWorkgroup), - CASE2(STORAGE_CLASS, StorageClass::Private, Shader, + CASE0(STORAGE_CLASS, StorageClassUniformConstant), + CASE1(STORAGE_CLASS, StorageClassUniform, Shader), + CASE1(STORAGE_CLASS, StorageClassOutput, Shader), + CASE0(STORAGE_CLASS, StorageClassWorkgroup), + CASE0(STORAGE_CLASS, StorageClassCrossWorkgroup), + CASE2(STORAGE_CLASS, StorageClassPrivate, Shader, VectorComputeINTEL), - CASE0(STORAGE_CLASS, StorageClass::Function), - CASE1(STORAGE_CLASS, StorageClass::Generic, + CASE0(STORAGE_CLASS, StorageClassFunction), + CASE1(STORAGE_CLASS, StorageClassGeneric, GenericPointer), // Bug 14287 - CASE1(STORAGE_CLASS, StorageClass::PushConstant, Shader), - CASE1(STORAGE_CLASS, StorageClass::AtomicCounter, - AtomicStorage), - CASE0(STORAGE_CLASS, StorageClass::Image), + CASE1(STORAGE_CLASS, StorageClassPushConstant, Shader), + CASE1(STORAGE_CLASS, StorageClassAtomicCounter, AtomicStorage), + CASE0(STORAGE_CLASS, StorageClassImage), }))); // See SPIR-V Section 3.8 Dim @@ -252,35 +222,37 @@ INSTANTIATE_TEST_SUITE_P( Dim, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(DIMENSIONALITY, Dim::Dim1D, Sampled1D), - CASE0(DIMENSIONALITY, Dim::Dim2D), - CASE0(DIMENSIONALITY, Dim::Dim3D), - CASE1(DIMENSIONALITY, Dim::Cube, Shader), - CASE1(DIMENSIONALITY, Dim::Rect, SampledRect), - CASE1(DIMENSIONALITY, Dim::Buffer, SampledBuffer), - CASE1(DIMENSIONALITY, Dim::SubpassData, InputAttachment), + CASE2(DIMENSIONALITY, Dim1D, Sampled1D, Image1D), + CASE3(DIMENSIONALITY, Dim2D, Kernel, Shader, ImageMSArray), + CASE0(DIMENSIONALITY, Dim3D), + CASE2(DIMENSIONALITY, DimCube, Shader, ImageCubeArray), + CASE2(DIMENSIONALITY, DimRect, SampledRect, ImageRect), + CASE2(DIMENSIONALITY, DimBuffer, SampledBuffer, ImageBuffer), + CASE1(DIMENSIONALITY, DimSubpassData, InputAttachment), }))); // See SPIR-V Section 3.9 Sampler Addressing Mode INSTANTIATE_TEST_SUITE_P( SamplerAddressingMode, EnumCapabilityTest, - Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector{ - CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::None), - CASE0(SAMPLER_ADDRESSING_MODE, - SamplerAddressingMode::ClampToEdge), - CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Clamp), - CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Repeat), - CASE0(SAMPLER_ADDRESSING_MODE, - SamplerAddressingMode::RepeatMirrored)}))); + Combine( + Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), + ValuesIn(std::vector{ + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeNone, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeClampToEdge, + Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeClamp, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeRepeat, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeRepeatMirrored, + Kernel), + }))); // See SPIR-V Section 3.10 Sampler Filter Mode INSTANTIATE_TEST_SUITE_P( SamplerFilterMode, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(SAMPLER_FILTER_MODE, SamplerFilterMode::Nearest), - CASE0(SAMPLER_FILTER_MODE, SamplerFilterMode::Linear), + CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeNearest, Kernel), + CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeLinear, Kernel), }))); // See SPIR-V Section 3.11 Image Format @@ -289,76 +261,76 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE0(SAMPLER_IMAGE_FORMAT, ImageFormat::Unknown), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba32f, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba16f, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R32f, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba8, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba8Snorm, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg32f, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg16f, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R11fG11fB10f, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R16f, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba16, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgb10A2, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg16, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg8, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R16, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R8, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba16Snorm, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg16Snorm, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg8Snorm, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R16Snorm, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R8Snorm, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba32i, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba16i, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba8i, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R32i, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg32i, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg16i, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg8i, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R16i, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R8i, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba32ui, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba16ui, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba8ui, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgba8ui, Shader), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rgb10a2ui, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg32ui, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg16ui, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::Rg8ui, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R16ui, StorageImageExtendedFormats), - CASE1(SAMPLER_IMAGE_FORMAT, ImageFormat::R8ui, StorageImageExtendedFormats), + CASE0(SAMPLER_IMAGE_FORMAT, ImageFormatUnknown), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR32f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8Snorm, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32f, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16f, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR11fG11fB10f, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16f, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgb10A2, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16Snorm, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16Snorm, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8Snorm, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16Snorm, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8Snorm, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR32i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32i, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16i, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8i, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16i, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8i, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgb10a2ui, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32ui, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16ui, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8ui, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16ui, StorageImageExtendedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8ui, StorageImageExtendedFormats), // clang-format on }))); // See SPIR-V Section 3.12 Image Channel Order INSTANTIATE_TEST_SUITE_P( ImageChannelOrder, EnumCapabilityTest, - Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector{ - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::R, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::A, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RG, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RA, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGB, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBA, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::BGRA, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ARGB, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Intensity, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Luminance, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Rx, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGx, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBx, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Depth, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::DepthStencil, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGB, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBx, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBA, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sBGRA, Kernel), - CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ABGR, Kernel), - }))); + Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), + ValuesIn(std::vector{ + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderR, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRG, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGBA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderBGRA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderARGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderIntensity, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderLuminance, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGBx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderDepth, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderDepthStencil, + Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGBx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGBA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersBGRA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderABGR, Kernel), + }))); // See SPIR-V Section 3.13 Image Channel Data Type INSTANTIATE_TEST_SUITE_P( @@ -366,23 +338,23 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt8, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt16, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt8, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt16, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort565, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort555, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt8, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt16, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt32, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt8, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt16, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt32, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::HalfFloat, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::Float, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt24, Kernel), - CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010_2, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormShort565, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormShort555, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt101010, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt32, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt32, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeHalfFloat, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeFloat, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt24, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt101010_2, Kernel), // clang-format on }))); @@ -392,15 +364,15 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE0(OPTIONAL_IMAGE, ImageOperandsMask::MaskNone), - CASE1(OPTIONAL_IMAGE, ImageOperandsMask::Bias, Shader), - CASE0(OPTIONAL_IMAGE, ImageOperandsMask::Lod), - CASE0(OPTIONAL_IMAGE, ImageOperandsMask::Grad), - CASE0(OPTIONAL_IMAGE, ImageOperandsMask::ConstOffset), - CASE1(OPTIONAL_IMAGE, ImageOperandsMask::Offset, ImageGatherExtended), - CASE1(OPTIONAL_IMAGE, ImageOperandsMask::ConstOffsets, ImageGatherExtended), - CASE0(OPTIONAL_IMAGE, ImageOperandsMask::Sample), - CASE1(OPTIONAL_IMAGE, ImageOperandsMask::MinLod, MinLod), + CASE0(OPTIONAL_IMAGE, ImageOperandsMaskNone), + CASE1(OPTIONAL_IMAGE, ImageOperandsBiasMask, Shader), + CASE0(OPTIONAL_IMAGE, ImageOperandsLodMask), + CASE0(OPTIONAL_IMAGE, ImageOperandsGradMask), + CASE0(OPTIONAL_IMAGE, ImageOperandsConstOffsetMask), + CASE1(OPTIONAL_IMAGE, ImageOperandsOffsetMask, ImageGatherExtended), + CASE1(OPTIONAL_IMAGE, ImageOperandsConstOffsetsMask, ImageGatherExtended), + CASE0(OPTIONAL_IMAGE, ImageOperandsSampleMask), + CASE1(OPTIONAL_IMAGE, ImageOperandsMinLodMask, MinLod), // clang-format on }))); @@ -409,8 +381,8 @@ INSTANTIATE_TEST_SUITE_P( LinkageType, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(LINKAGE_TYPE, LinkageType::Export, Linkage), - CASE1(LINKAGE_TYPE, LinkageType::Import, Linkage), + CASE1(LINKAGE_TYPE, LinkageTypeExport, Linkage), + CASE1(LINKAGE_TYPE, LinkageTypeImport, Linkage), }))); // See SPIR-V Section 3.18 Access Qualifier @@ -418,9 +390,9 @@ INSTANTIATE_TEST_SUITE_P( AccessQualifier, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(ACCESS_QUALIFIER, AccessQualifier::ReadOnly, Kernel), - CASE1(ACCESS_QUALIFIER, AccessQualifier::WriteOnly, Kernel), - CASE1(ACCESS_QUALIFIER, AccessQualifier::ReadWrite, Kernel), + CASE1(ACCESS_QUALIFIER, AccessQualifierReadOnly, Kernel), + CASE1(ACCESS_QUALIFIER, AccessQualifierWriteOnly, Kernel), + CASE1(ACCESS_QUALIFIER, AccessQualifierReadWrite, Kernel), }))); // See SPIR-V Section 3.19 Function Parameter Attribute @@ -429,78 +401,70 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::Zext, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::Sext, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::ByVal, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::Sret, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::NoAlias, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::NoCapture, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::NoWrite, Kernel), - CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttribute::NoReadWrite, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeZext, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeSext, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeByVal, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeSret, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoAlias, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoCapture, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoWrite, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoReadWrite, Kernel), // clang-format on }))); // See SPIR-V Section 3.20 Decoration INSTANTIATE_TEST_SUITE_P( - Decoration_1_1, EnumCapabilityTest, + Decoration, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(DECORATION, Decoration::RelaxedPrecision, Shader), + CASE1(DECORATION, DecorationRelaxedPrecision, Shader), // DecorationSpecId handled below. - CASE1(DECORATION, Decoration::Block, Shader), - CASE1(DECORATION, Decoration::BufferBlock, Shader), - CASE1(DECORATION, Decoration::RowMajor, Matrix), - CASE1(DECORATION, Decoration::ColMajor, Matrix), - CASE1(DECORATION, Decoration::ArrayStride, Shader), - CASE1(DECORATION, Decoration::MatrixStride, - Matrix), // Bug 15234 - CASE1(DECORATION, Decoration::GLSLShared, Shader), - CASE1(DECORATION, Decoration::GLSLPacked, Shader), - CASE1(DECORATION, Decoration::CPacked, Kernel), - CASE0(DECORATION, Decoration::BuiltIn), // Bug 15248 + CASE1(DECORATION, DecorationBlock, Shader), + CASE1(DECORATION, DecorationBufferBlock, Shader), + CASE1(DECORATION, DecorationRowMajor, Matrix), + CASE1(DECORATION, DecorationColMajor, Matrix), + CASE1(DECORATION, DecorationArrayStride, Shader), + CASE1(DECORATION, DecorationMatrixStride, Matrix), // Bug 15234 + CASE1(DECORATION, DecorationGLSLShared, Shader), + CASE1(DECORATION, DecorationGLSLPacked, Shader), + CASE1(DECORATION, DecorationCPacked, Kernel), + CASE0(DECORATION, DecorationBuiltIn), // Bug 15248 // Value 12 placeholder - CASE1(DECORATION, Decoration::NoPerspective, Shader), - CASE1(DECORATION, Decoration::Flat, Shader), - CASE1(DECORATION, Decoration::Patch, Tessellation), - CASE1(DECORATION, Decoration::Centroid, Shader), - CASE1(DECORATION, Decoration::Sample, + CASE1(DECORATION, DecorationNoPerspective, Shader), + CASE1(DECORATION, DecorationFlat, Shader), + CASE1(DECORATION, DecorationPatch, Tessellation), + CASE1(DECORATION, DecorationCentroid, Shader), + CASE1(DECORATION, DecorationSample, SampleRateShading), // Bug 15234 - CASE1(DECORATION, Decoration::Invariant, Shader), - CASE0(DECORATION, Decoration::Restrict), - CASE0(DECORATION, Decoration::Aliased), - CASE0(DECORATION, Decoration::Volatile), - CASE1(DECORATION, Decoration::Constant, Kernel), - CASE0(DECORATION, Decoration::Coherent), - CASE0(DECORATION, Decoration::NonWritable), - CASE0(DECORATION, Decoration::NonReadable), - CASE1(DECORATION, Decoration::Uniform, Shader), + CASE1(DECORATION, DecorationInvariant, Shader), + CASE0(DECORATION, DecorationRestrict), + CASE0(DECORATION, DecorationAliased), + CASE0(DECORATION, DecorationVolatile), + CASE1(DECORATION, DecorationConstant, Kernel), + CASE0(DECORATION, DecorationCoherent), + CASE0(DECORATION, DecorationNonWritable), + CASE0(DECORATION, DecorationNonReadable), + CASE1(DECORATION, DecorationUniform, Shader), // Value 27 is an intentional gap in the spec numbering. - CASE1(DECORATION, Decoration::SaturatedConversion, Kernel), - CASE1(DECORATION, Decoration::Stream, GeometryStreams), - CASE1(DECORATION, Decoration::Location, Shader), - CASE1(DECORATION, Decoration::Component, Shader), - CASE1(DECORATION, Decoration::Index, Shader), - CASE1(DECORATION, Decoration::Binding, Shader), - CASE1(DECORATION, Decoration::DescriptorSet, Shader), - CASE1(DECORATION, Decoration::Offset, Shader), // Bug 15268 - CASE1(DECORATION, Decoration::XfbBuffer, TransformFeedback), - CASE1(DECORATION, Decoration::XfbStride, TransformFeedback), - CASE1(DECORATION, Decoration::FuncParamAttr, Kernel), - CASE1(DECORATION, Decoration::FPFastMathMode, Kernel), - CASE1(DECORATION, Decoration::LinkageAttributes, Linkage), - CASE1(DECORATION, Decoration::NoContraction, Shader), - CASE1(DECORATION, Decoration::InputAttachmentIndex, + CASE1(DECORATION, DecorationSaturatedConversion, Kernel), + CASE1(DECORATION, DecorationStream, GeometryStreams), + CASE1(DECORATION, DecorationLocation, Shader), + CASE1(DECORATION, DecorationComponent, Shader), + CASE1(DECORATION, DecorationIndex, Shader), + CASE1(DECORATION, DecorationBinding, Shader), + CASE1(DECORATION, DecorationDescriptorSet, Shader), + CASE1(DECORATION, DecorationOffset, Shader), // Bug 15268 + CASE1(DECORATION, DecorationXfbBuffer, TransformFeedback), + CASE1(DECORATION, DecorationXfbStride, TransformFeedback), + CASE1(DECORATION, DecorationFuncParamAttr, Kernel), + CASE1(DECORATION, DecorationFPFastMathMode, Kernel), + CASE1(DECORATION, DecorationLinkageAttributes, Linkage), + CASE1(DECORATION, DecorationNoContraction, Shader), + CASE1(DECORATION, DecorationInputAttachmentIndex, InputAttachment), - CASE1(DECORATION, Decoration::Alignment, Kernel), + CASE1(DECORATION, DecorationAlignment, Kernel), }))); -// See SPIR-V Section 3.20 Decoration -INSTANTIATE_TEST_SUITE_P(Decoration_1_6, EnumCapabilityTest, - Combine(Values(SPV_ENV_UNIVERSAL_1_6), - ValuesIn(std::vector{ - CASE2(DECORATION, Decoration::Uniform, - Shader, UniformDecoration)}))); - #if 0 // SpecId has different requirements in v1.0 and v1.1: INSTANTIATE_TEST_SUITE_P(DecorationSpecIdV10, EnumCapabilityTest, @@ -513,8 +477,8 @@ INSTANTIATE_TEST_SUITE_P( DecorationV11, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE2(DECORATION, Decoration::SpecId, Shader, Kernel), - CASE1(DECORATION, Decoration::MaxByteOffset, Addresses)}))); + CASE2(DECORATION, DecorationSpecId, Shader, Kernel), + CASE1(DECORATION, DecorationMaxByteOffset, Addresses)}))); // See SPIR-V Section 3.21 BuiltIn INSTANTIATE_TEST_SUITE_P( @@ -523,51 +487,51 @@ INSTANTIATE_TEST_SUITE_P( Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE1(BUILT_IN, BuiltIn::Position, Shader), - CASE1(BUILT_IN, BuiltIn::PointSize, Shader), + CASE1(BUILT_IN, BuiltInPosition, Shader), + CASE1(BUILT_IN, BuiltInPointSize, Shader), // 2 is an intentional gap in the spec numbering. - CASE1(BUILT_IN, BuiltIn::ClipDistance, ClipDistance), // Bug 1407, 15234 - CASE1(BUILT_IN, BuiltIn::CullDistance, CullDistance), // Bug 1407, 15234 - CASE1(BUILT_IN, BuiltIn::VertexId, Shader), - CASE1(BUILT_IN, BuiltIn::InstanceId, Shader), - CASE6(BUILT_IN, BuiltIn::PrimitiveId, Geometry, Tessellation, + CASE1(BUILT_IN, BuiltInClipDistance, ClipDistance), // Bug 1407, 15234 + CASE1(BUILT_IN, BuiltInCullDistance, CullDistance), // Bug 1407, 15234 + CASE1(BUILT_IN, BuiltInVertexId, Shader), + CASE1(BUILT_IN, BuiltInInstanceId, Shader), + CASE6(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation, RayTracingNV, RayTracingKHR, MeshShadingNV, MeshShadingEXT), - CASE2(BUILT_IN, BuiltIn::InvocationId, Geometry, Tessellation), - CASE4(BUILT_IN, BuiltIn::Layer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), - CASE4(BUILT_IN, BuiltIn::ViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), // Bug 15234 - CASE1(BUILT_IN, BuiltIn::TessLevelOuter, Tessellation), - CASE1(BUILT_IN, BuiltIn::TessLevelInner, Tessellation), - CASE1(BUILT_IN, BuiltIn::TessCoord, Tessellation), - CASE1(BUILT_IN, BuiltIn::PatchVertices, Tessellation), - CASE1(BUILT_IN, BuiltIn::FragCoord, Shader), - CASE1(BUILT_IN, BuiltIn::PointCoord, Shader), - CASE1(BUILT_IN, BuiltIn::FrontFacing, Shader), - CASE1(BUILT_IN, BuiltIn::SampleId, SampleRateShading), // Bug 15234 - CASE1(BUILT_IN, BuiltIn::SamplePosition, SampleRateShading), // Bug 15234 - CASE1(BUILT_IN, BuiltIn::SampleMask, Shader), // Bug 15234, Issue 182 + CASE2(BUILT_IN, BuiltInInvocationId, Geometry, Tessellation), + CASE4(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), + CASE4(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), // Bug 15234 + CASE1(BUILT_IN, BuiltInTessLevelOuter, Tessellation), + CASE1(BUILT_IN, BuiltInTessLevelInner, Tessellation), + CASE1(BUILT_IN, BuiltInTessCoord, Tessellation), + CASE1(BUILT_IN, BuiltInPatchVertices, Tessellation), + CASE1(BUILT_IN, BuiltInFragCoord, Shader), + CASE1(BUILT_IN, BuiltInPointCoord, Shader), + CASE1(BUILT_IN, BuiltInFrontFacing, Shader), + CASE1(BUILT_IN, BuiltInSampleId, SampleRateShading), // Bug 15234 + CASE1(BUILT_IN, BuiltInSamplePosition, SampleRateShading), // Bug 15234 + CASE1(BUILT_IN, BuiltInSampleMask, Shader), // Bug 15234, Issue 182 // Value 21 intentionally missing - CASE1(BUILT_IN, BuiltIn::FragDepth, Shader), - CASE1(BUILT_IN, BuiltIn::HelperInvocation, Shader), - CASE0(BUILT_IN, BuiltIn::NumWorkgroups), - CASE0(BUILT_IN, BuiltIn::WorkgroupSize), - CASE0(BUILT_IN, BuiltIn::WorkgroupId), - CASE0(BUILT_IN, BuiltIn::LocalInvocationId), - CASE0(BUILT_IN, BuiltIn::GlobalInvocationId), - CASE0(BUILT_IN, BuiltIn::LocalInvocationIndex), - CASE1(BUILT_IN, BuiltIn::WorkDim, Kernel), - CASE1(BUILT_IN, BuiltIn::GlobalSize, Kernel), - CASE1(BUILT_IN, BuiltIn::EnqueuedWorkgroupSize, Kernel), - CASE1(BUILT_IN, BuiltIn::GlobalOffset, Kernel), - CASE1(BUILT_IN, BuiltIn::GlobalLinearId, Kernel), + CASE1(BUILT_IN, BuiltInFragDepth, Shader), + CASE1(BUILT_IN, BuiltInHelperInvocation, Shader), + CASE0(BUILT_IN, BuiltInNumWorkgroups), + CASE0(BUILT_IN, BuiltInWorkgroupSize), + CASE0(BUILT_IN, BuiltInWorkgroupId), + CASE0(BUILT_IN, BuiltInLocalInvocationId), + CASE0(BUILT_IN, BuiltInGlobalInvocationId), + CASE0(BUILT_IN, BuiltInLocalInvocationIndex), + CASE1(BUILT_IN, BuiltInWorkDim, Kernel), + CASE1(BUILT_IN, BuiltInGlobalSize, Kernel), + CASE1(BUILT_IN, BuiltInEnqueuedWorkgroupSize, Kernel), + CASE1(BUILT_IN, BuiltInGlobalOffset, Kernel), + CASE1(BUILT_IN, BuiltInGlobalLinearId, Kernel), // Value 35 intentionally missing - CASE2(BUILT_IN, BuiltIn::SubgroupSize, Kernel, SubgroupBallotKHR), - CASE1(BUILT_IN, BuiltIn::SubgroupMaxSize, Kernel), - CASE1(BUILT_IN, BuiltIn::NumSubgroups, Kernel), - CASE1(BUILT_IN, BuiltIn::NumEnqueuedSubgroups, Kernel), - CASE1(BUILT_IN, BuiltIn::SubgroupId, Kernel), - CASE2(BUILT_IN, BuiltIn::SubgroupLocalInvocationId, Kernel, SubgroupBallotKHR), - CASE1(BUILT_IN, BuiltIn::VertexIndex, Shader), - CASE1(BUILT_IN, BuiltIn::InstanceIndex, Shader), + CASE2(BUILT_IN, BuiltInSubgroupSize, Kernel, SubgroupBallotKHR), + CASE1(BUILT_IN, BuiltInSubgroupMaxSize, Kernel), + CASE1(BUILT_IN, BuiltInNumSubgroups, Kernel), + CASE1(BUILT_IN, BuiltInNumEnqueuedSubgroups, Kernel), + CASE1(BUILT_IN, BuiltInSubgroupId, Kernel), + CASE2(BUILT_IN, BuiltInSubgroupLocalInvocationId, Kernel, SubgroupBallotKHR), + CASE1(BUILT_IN, BuiltInVertexIndex, Shader), + CASE1(BUILT_IN, BuiltInInstanceIndex, Shader), // clang-format on }))); @@ -577,9 +541,9 @@ INSTANTIATE_TEST_SUITE_P( Values(SPV_ENV_UNIVERSAL_1_5), ValuesIn(std::vector{ // SPIR-V 1.5 adds new capabilities to enable these two builtins. - CASE5(BUILT_IN, BuiltIn::Layer, Geometry, ShaderLayer, + CASE5(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), - CASE5(BUILT_IN, BuiltIn::ViewportIndex, MultiViewport, + CASE5(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndex, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT), }))); @@ -589,9 +553,9 @@ INSTANTIATE_TEST_SUITE_P( SelectionControl, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(SELECTION_CONTROL, SelectionControlMask::MaskNone), - CASE0(SELECTION_CONTROL, SelectionControlMask::Flatten), - CASE0(SELECTION_CONTROL, SelectionControlMask::DontFlatten), + CASE0(SELECTION_CONTROL, SelectionControlMaskNone), + CASE0(SELECTION_CONTROL, SelectionControlFlattenMask), + CASE0(SELECTION_CONTROL, SelectionControlDontFlattenMask), }))); // See SPIR-V Section 3.23 Loop Control @@ -599,17 +563,17 @@ INSTANTIATE_TEST_SUITE_P( LoopControl, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(LOOP_CONTROL, LoopControlMask::MaskNone), - CASE0(LOOP_CONTROL, LoopControlMask::Unroll), - CASE0(LOOP_CONTROL, LoopControlMask::DontUnroll), + CASE0(LOOP_CONTROL, LoopControlMaskNone), + CASE0(LOOP_CONTROL, LoopControlUnrollMask), + CASE0(LOOP_CONTROL, LoopControlDontUnrollMask), }))); INSTANTIATE_TEST_SUITE_P( LoopControlV11, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(LOOP_CONTROL, LoopControlMask::DependencyInfinite), - CASE0(LOOP_CONTROL, LoopControlMask::DependencyLength), + CASE0(LOOP_CONTROL, LoopControlDependencyInfiniteMask), + CASE0(LOOP_CONTROL, LoopControlDependencyLengthMask), }))); // See SPIR-V Section 3.24 Function Control @@ -617,11 +581,11 @@ INSTANTIATE_TEST_SUITE_P( FunctionControl, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(FUNCTION_CONTROL, FunctionControlMask::MaskNone), - CASE0(FUNCTION_CONTROL, FunctionControlMask::Inline), - CASE0(FUNCTION_CONTROL, FunctionControlMask::DontInline), - CASE0(FUNCTION_CONTROL, FunctionControlMask::Pure), - CASE0(FUNCTION_CONTROL, FunctionControlMask::Const), + CASE0(FUNCTION_CONTROL, FunctionControlMaskNone), + CASE0(FUNCTION_CONTROL, FunctionControlInlineMask), + CASE0(FUNCTION_CONTROL, FunctionControlDontInlineMask), + CASE0(FUNCTION_CONTROL, FunctionControlPureMask), + CASE0(FUNCTION_CONTROL, FunctionControlConstMask), }))); // See SPIR-V Section 3.25 Memory Semantics @@ -630,21 +594,20 @@ INSTANTIATE_TEST_SUITE_P( Combine( Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::MaskNone), - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::Acquire), - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::Release), - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::AcquireRelease), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMaskNone), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsAcquireMask), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsReleaseMask), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsAcquireReleaseMask), CASE0(MEMORY_SEMANTICS_ID, - MemorySemanticsMask::SequentiallyConsistent), - CASE1(MEMORY_SEMANTICS_ID, MemorySemanticsMask::UniformMemory, + MemorySemanticsSequentiallyConsistentMask), + CASE1(MEMORY_SEMANTICS_ID, MemorySemanticsUniformMemoryMask, Shader), - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::SubgroupMemory), - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::WorkgroupMemory), - CASE0(MEMORY_SEMANTICS_ID, - MemorySemanticsMask::CrossWorkgroupMemory), - CASE1(MEMORY_SEMANTICS_ID, MemorySemanticsMask::AtomicCounterMemory, + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsSubgroupMemoryMask), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsWorkgroupMemoryMask), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsCrossWorkgroupMemoryMask), + CASE1(MEMORY_SEMANTICS_ID, MemorySemanticsAtomicCounterMemoryMask, AtomicStorage), // Bug 15234 - CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMask::ImageMemory), + CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsImageMemoryMask), }))); // See SPIR-V Section 3.26 Memory Access @@ -652,10 +615,10 @@ INSTANTIATE_TEST_SUITE_P( MemoryAccess, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMask::MaskNone), - CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMask::Volatile), - CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMask::Aligned), - CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMask::Nontemporal), + CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMaskNone), + CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessVolatileMask), + CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessAlignedMask), + CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessNontemporalMask), }))); // See SPIR-V Section 3.27 Scope @@ -664,12 +627,12 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ValuesIn(std::vector{ - CASE0(SCOPE_ID, Scope::CrossDevice), - CASE0(SCOPE_ID, Scope::Device), - CASE0(SCOPE_ID, Scope::Workgroup), - CASE0(SCOPE_ID, Scope::Subgroup), - CASE0(SCOPE_ID, Scope::Invocation), - CASE1(SCOPE_ID, Scope::QueueFamilyKHR, VulkanMemoryModelKHR), + CASE0(SCOPE_ID, ScopeCrossDevice), + CASE0(SCOPE_ID, ScopeDevice), + CASE0(SCOPE_ID, ScopeWorkgroup), + CASE0(SCOPE_ID, ScopeSubgroup), + CASE0(SCOPE_ID, ScopeInvocation), + CASE1(SCOPE_ID, ScopeQueueFamilyKHR, VulkanMemoryModelKHR), }))); // See SPIR-V Section 3.28 Group Operation @@ -677,11 +640,11 @@ INSTANTIATE_TEST_SUITE_P( GroupOperation, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE3(GROUP_OPERATION, GroupOperation::Reduce, Kernel, + CASE3(GROUP_OPERATION, GroupOperationReduce, Kernel, GroupNonUniformArithmetic, GroupNonUniformBallot), - CASE3(GROUP_OPERATION, GroupOperation::InclusiveScan, Kernel, + CASE3(GROUP_OPERATION, GroupOperationInclusiveScan, Kernel, GroupNonUniformArithmetic, GroupNonUniformBallot), - CASE3(GROUP_OPERATION, GroupOperation::ExclusiveScan, Kernel, + CASE3(GROUP_OPERATION, GroupOperationExclusiveScan, Kernel, GroupNonUniformArithmetic, GroupNonUniformBallot), }))); @@ -690,9 +653,9 @@ INSTANTIATE_TEST_SUITE_P( KernelEnqueueFlags, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlags::NoWait, Kernel), - CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlags::WaitKernel, Kernel), - CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlags::WaitWorkGroup, + CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlagsNoWait, Kernel), + CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlagsWaitKernel, Kernel), + CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlagsWaitWorkGroup, Kernel), }))); @@ -701,9 +664,9 @@ INSTANTIATE_TEST_SUITE_P( KernelProfilingInfo, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE0(KERNEL_PROFILING_INFO, KernelProfilingInfoMask::MaskNone), - CASE1(KERNEL_PROFILING_INFO, - KernelProfilingInfoMask::CmdExecTime, Kernel), + CASE0(KERNEL_PROFILING_INFO, KernelProfilingInfoMaskNone), + CASE1(KERNEL_PROFILING_INFO, KernelProfilingInfoCmdExecTimeMask, + Kernel), }))); // See SPIR-V Section 3.31 Capability @@ -713,62 +676,62 @@ INSTANTIATE_TEST_SUITE_P( Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ // clang-format off - CASE0(CAPABILITY, Capability::Matrix), - CASE1(CAPABILITY, Capability::Shader, Matrix), - CASE1(CAPABILITY, Capability::Geometry, Shader), - CASE1(CAPABILITY, Capability::Tessellation, Shader), - CASE0(CAPABILITY, Capability::Addresses), - CASE0(CAPABILITY, Capability::Linkage), - CASE0(CAPABILITY, Capability::Kernel), - CASE1(CAPABILITY, Capability::Vector16, Kernel), - CASE1(CAPABILITY, Capability::Float16Buffer, Kernel), - CASE0(CAPABILITY, Capability::Float16), // Bug 15234 - CASE0(CAPABILITY, Capability::Float64), - CASE0(CAPABILITY, Capability::Int64), - CASE1(CAPABILITY, Capability::Int64Atomics, Int64), - CASE1(CAPABILITY, Capability::ImageBasic, Kernel), - CASE1(CAPABILITY, Capability::ImageReadWrite, ImageBasic), - CASE1(CAPABILITY, Capability::ImageMipmap, ImageBasic), + CASE0(CAPABILITY, CapabilityMatrix), + CASE1(CAPABILITY, CapabilityShader, Matrix), + CASE1(CAPABILITY, CapabilityGeometry, Shader), + CASE1(CAPABILITY, CapabilityTessellation, Shader), + CASE0(CAPABILITY, CapabilityAddresses), + CASE0(CAPABILITY, CapabilityLinkage), + CASE0(CAPABILITY, CapabilityKernel), + CASE1(CAPABILITY, CapabilityVector16, Kernel), + CASE1(CAPABILITY, CapabilityFloat16Buffer, Kernel), + CASE0(CAPABILITY, CapabilityFloat16), // Bug 15234 + CASE0(CAPABILITY, CapabilityFloat64), + CASE0(CAPABILITY, CapabilityInt64), + CASE1(CAPABILITY, CapabilityInt64Atomics, Int64), + CASE1(CAPABILITY, CapabilityImageBasic, Kernel), + CASE1(CAPABILITY, CapabilityImageReadWrite, ImageBasic), + CASE1(CAPABILITY, CapabilityImageMipmap, ImageBasic), // Value 16 intentionally missing. - CASE1(CAPABILITY, Capability::Pipes, Kernel), - CASE0(CAPABILITY, Capability::Groups), - CASE1(CAPABILITY, Capability::DeviceEnqueue, Kernel), - CASE1(CAPABILITY, Capability::LiteralSampler, Kernel), - CASE1(CAPABILITY, Capability::AtomicStorage, Shader), - CASE0(CAPABILITY, Capability::Int16), - CASE1(CAPABILITY, Capability::TessellationPointSize, Tessellation), - CASE1(CAPABILITY, Capability::GeometryPointSize, Geometry), - CASE1(CAPABILITY, Capability::ImageGatherExtended, Shader), + CASE1(CAPABILITY, CapabilityPipes, Kernel), + CASE0(CAPABILITY, CapabilityGroups), + CASE1(CAPABILITY, CapabilityDeviceEnqueue, Kernel), + CASE1(CAPABILITY, CapabilityLiteralSampler, Kernel), + CASE1(CAPABILITY, CapabilityAtomicStorage, Shader), + CASE0(CAPABILITY, CapabilityInt16), + CASE1(CAPABILITY, CapabilityTessellationPointSize, Tessellation), + CASE1(CAPABILITY, CapabilityGeometryPointSize, Geometry), + CASE1(CAPABILITY, CapabilityImageGatherExtended, Shader), // Value 26 intentionally missing. - CASE1(CAPABILITY, Capability::StorageImageMultisample, Shader), - CASE1(CAPABILITY, Capability::UniformBufferArrayDynamicIndexing, Shader), - CASE1(CAPABILITY, Capability::SampledImageArrayDynamicIndexing, Shader), - CASE1(CAPABILITY, Capability::StorageBufferArrayDynamicIndexing, Shader), - CASE1(CAPABILITY, Capability::StorageImageArrayDynamicIndexing, Shader), - CASE1(CAPABILITY, Capability::ClipDistance, Shader), - CASE1(CAPABILITY, Capability::CullDistance, Shader), - CASE1(CAPABILITY, Capability::ImageCubeArray, SampledCubeArray), - CASE1(CAPABILITY, Capability::SampleRateShading, Shader), - CASE1(CAPABILITY, Capability::ImageRect, SampledRect), - CASE1(CAPABILITY, Capability::SampledRect, Shader), - CASE1(CAPABILITY, Capability::GenericPointer, Addresses), - CASE0(CAPABILITY, Capability::Int8), - CASE1(CAPABILITY, Capability::InputAttachment, Shader), - CASE1(CAPABILITY, Capability::SparseResidency, Shader), - CASE1(CAPABILITY, Capability::MinLod, Shader), - CASE1(CAPABILITY, Capability::Image1D, Sampled1D), - CASE1(CAPABILITY, Capability::SampledCubeArray, Shader), - CASE1(CAPABILITY, Capability::ImageBuffer, SampledBuffer), - CASE1(CAPABILITY, Capability::ImageMSArray, Shader), - CASE1(CAPABILITY, Capability::StorageImageExtendedFormats, Shader), - CASE1(CAPABILITY, Capability::ImageQuery, Shader), - CASE1(CAPABILITY, Capability::DerivativeControl, Shader), - CASE1(CAPABILITY, Capability::InterpolationFunction, Shader), - CASE1(CAPABILITY, Capability::TransformFeedback, Shader), - CASE1(CAPABILITY, Capability::GeometryStreams, Geometry), - CASE1(CAPABILITY, Capability::StorageImageReadWithoutFormat, Shader), - CASE1(CAPABILITY, Capability::StorageImageWriteWithoutFormat, Shader), - CASE1(CAPABILITY, Capability::MultiViewport, Geometry), + CASE1(CAPABILITY, CapabilityStorageImageMultisample, Shader), + CASE1(CAPABILITY, CapabilityUniformBufferArrayDynamicIndexing, Shader), + CASE1(CAPABILITY, CapabilitySampledImageArrayDynamicIndexing, Shader), + CASE1(CAPABILITY, CapabilityStorageBufferArrayDynamicIndexing, Shader), + CASE1(CAPABILITY, CapabilityStorageImageArrayDynamicIndexing, Shader), + CASE1(CAPABILITY, CapabilityClipDistance, Shader), + CASE1(CAPABILITY, CapabilityCullDistance, Shader), + CASE1(CAPABILITY, CapabilityImageCubeArray, SampledCubeArray), + CASE1(CAPABILITY, CapabilitySampleRateShading, Shader), + CASE1(CAPABILITY, CapabilityImageRect, SampledRect), + CASE1(CAPABILITY, CapabilitySampledRect, Shader), + CASE1(CAPABILITY, CapabilityGenericPointer, Addresses), + CASE0(CAPABILITY, CapabilityInt8), + CASE1(CAPABILITY, CapabilityInputAttachment, Shader), + CASE1(CAPABILITY, CapabilitySparseResidency, Shader), + CASE1(CAPABILITY, CapabilityMinLod, Shader), + CASE1(CAPABILITY, CapabilityImage1D, Sampled1D), + CASE1(CAPABILITY, CapabilitySampledCubeArray, Shader), + CASE1(CAPABILITY, CapabilityImageBuffer, SampledBuffer), + CASE1(CAPABILITY, CapabilityImageMSArray, Shader), + CASE1(CAPABILITY, CapabilityStorageImageExtendedFormats, Shader), + CASE1(CAPABILITY, CapabilityImageQuery, Shader), + CASE1(CAPABILITY, CapabilityDerivativeControl, Shader), + CASE1(CAPABILITY, CapabilityInterpolationFunction, Shader), + CASE1(CAPABILITY, CapabilityTransformFeedback, Shader), + CASE1(CAPABILITY, CapabilityGeometryStreams, Geometry), + CASE1(CAPABILITY, CapabilityStorageImageReadWithoutFormat, Shader), + CASE1(CAPABILITY, CapabilityStorageImageWriteWithoutFormat, Shader), + CASE1(CAPABILITY, CapabilityMultiViewport, Geometry), // clang-format on }))); @@ -776,9 +739,9 @@ INSTANTIATE_TEST_SUITE_P( CapabilityDependsOnV11, EnumCapabilityTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector{ - CASE1(CAPABILITY, Capability::SubgroupDispatch, DeviceEnqueue), - CASE1(CAPABILITY, Capability::NamedBarrier, Kernel), - CASE1(CAPABILITY, Capability::PipeStorage, Pipes), + CASE1(CAPABILITY, CapabilitySubgroupDispatch, DeviceEnqueue), + CASE1(CAPABILITY, CapabilityNamedBarrier, Kernel), + CASE1(CAPABILITY, CapabilityPipeStorage, Pipes), }))); #undef CASE0 diff --git a/test/operand_pattern_test.cpp b/test/operand_pattern_test.cpp index 58b8a086..a98a9d76 100644 --- a/test/operand_pattern_test.cpp +++ b/test/operand_pattern_test.cpp @@ -103,18 +103,17 @@ INSTANTIATE_TEST_SUITE_P( {PREFIX1}}, // Volatile has no operands. {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, - uint32_t(spv::MemoryAccessMask::Volatile), + SpvMemoryAccessVolatileMask, {PREFIX0}, {PREFIX0}}, // Aligned has one literal number operand. {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, - uint32_t(spv::MemoryAccessMask::Aligned), + SpvMemoryAccessAlignedMask, {PREFIX1}, {PREFIX1, SPV_OPERAND_TYPE_LITERAL_INTEGER}}, // Volatile with Aligned still has just one literal number operand. {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, - uint32_t(spv::MemoryAccessMask::Volatile | - spv::MemoryAccessMask::Aligned), + SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask, {PREFIX1}, {PREFIX1, SPV_OPERAND_TYPE_LITERAL_INTEGER}}, // Newer masks are not tested diff --git a/test/opt/CMakeLists.txt b/test/opt/CMakeLists.txt index ceada132..15966c18 100644 --- a/test/opt/CMakeLists.txt +++ b/test/opt/CMakeLists.txt @@ -18,10 +18,8 @@ add_subdirectory(loop_optimizations) add_spvtools_unittest(TARGET opt SRCS aggressive_dead_code_elim_test.cpp amd_ext_to_khr.cpp - analyze_live_input_test.cpp assembly_builder_test.cpp block_merge_test.cpp - c_interface_test.cpp ccp_test.cpp cfg_cleanup_test.cpp cfg_test.cpp @@ -44,9 +42,8 @@ add_spvtools_unittest(TARGET opt desc_sroa_test.cpp eliminate_dead_const_test.cpp eliminate_dead_functions_test.cpp - eliminate_dead_io_components_test.cpp + eliminate_dead_input_components_test.cpp eliminate_dead_member_test.cpp - eliminate_dead_output_stores_test.cpp feature_manager_test.cpp fix_func_call_arguments_test.cpp fix_storage_class_test.cpp @@ -66,7 +63,6 @@ add_spvtools_unittest(TARGET opt instruction_list_test.cpp instruction_test.cpp interface_var_sroa_test.cpp - invocation_interlock_placement_test.cpp interp_fixup_test.cpp ir_builder.cpp ir_context_test.cpp @@ -104,8 +100,6 @@ add_spvtools_unittest(TARGET opt strip_debug_info_test.cpp strip_nonsemantic_info_test.cpp struct_cfg_analysis_test.cpp - switch_descriptorset_test.cpp - trim_capabilities_pass_test.cpp type_manager_test.cpp types_test.cpp unify_const_test.cpp @@ -118,12 +112,3 @@ add_spvtools_unittest(TARGET opt LIBS SPIRV-Tools-opt PCH_FILE pch_test_opt ) -if (NOT "${SPIRV_SKIP_TESTS}" AND TARGET gmock_main) - if (MSVC) - if (${MSVC_VERSION} LESS 1920) - # The VS 2017 debug build requires /bigobj on test_opt - # https://github.com/KhronosGroup/SPIRV-Tools/issues/5335 - target_compile_options(test_opt PRIVATE /bigobj) - endif() - endif() -endif() diff --git a/test/opt/aggressive_dead_code_elim_test.cpp b/test/opt/aggressive_dead_code_elim_test.cpp index 845c6a58..e51098ed 100644 --- a/test/opt/aggressive_dead_code_elim_test.cpp +++ b/test/opt/aggressive_dead_code_elim_test.cpp @@ -6764,7 +6764,7 @@ TEST_F(AggressiveDCETest, ShaderDebugInfoKeepInFunctionElimStoreVar) { %60 = OpExtInst %void %1 DebugTypeVector %59 %uint_4 %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 %uint_12 %uint_5 %uint_0 %uint_128 %uint_3 %57 = OpExtInst %void %1 DebugTypeComposite %8 %uint_1 %55 %uint_10 %uint_1 %56 %8 %uint_128 %uint_3 %58 - %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2 + %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2 %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 %uint_7 %uint_5 %uint_0 %uint_64 %uint_3 %61 = OpExtInst %void %1 DebugTypeComposite %11 %uint_1 %55 %uint_5 %uint_1 %56 %11 %uint_64 %uint_3 %62 %64 = OpExtInst %void %1 DebugTypeComposite %13 %uint_0 %55 %uint_0 %uint_0 %56 %14 %51 %uint_3 @@ -7777,221 +7777,6 @@ PS_OUTPUT MainPs ( ) SinglePassRunAndMatch(text, true); } -TEST_F(AggressiveDCETest, RemoveOutputTrue) { - // Remove dead n_out output variable from module - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %c_out %c_in %n_out -;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in - OpSource GLSL 450 - OpName %main "main" - OpName %c_out "c_out" - OpName %c_in "c_in" - OpName %n_out "n_out" - OpDecorate %c_out Location 0 - OpDecorate %c_in Location 0 - OpDecorate %n_out Location 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %c_out = OpVariable %_ptr_Output_v4float Output -%_ptr_Input_v4float = OpTypePointer Input %v4float - %c_in = OpVariable %_ptr_Input_v4float Input - %v3float = OpTypeVector %float 3 -%_ptr_Output_v3float = OpTypePointer Output %v3float - %n_out = OpVariable %_ptr_Output_v3float Output - %main = OpFunction %void None %3 - %5 = OpLabel - %12 = OpLoad %v4float %c_in - OpStore %c_out %12 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, false, true); -} - -TEST_F(AggressiveDCETest, RemoveOutputFalse) { - // Remove dead n_out output variable from module - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %c_out %c_in %n_out -;CHECK: OpEntryPoint Vertex %main "main" %c_out %c_in %n_out - OpSource GLSL 450 - OpName %main "main" - OpName %c_out "c_out" - OpName %c_in "c_in" - OpName %n_out "n_out" - OpDecorate %c_out Location 0 - OpDecorate %c_in Location 0 - OpDecorate %n_out Location 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %c_out = OpVariable %_ptr_Output_v4float Output -%_ptr_Input_v4float = OpTypePointer Input %v4float - %c_in = OpVariable %_ptr_Input_v4float Input - %v3float = OpTypeVector %float 3 -%_ptr_Output_v3float = OpTypePointer Output %v3float - %n_out = OpVariable %_ptr_Output_v3float Output - %main = OpFunction %void None %3 - %5 = OpLabel - %12 = OpLoad %v4float %c_in - OpStore %c_out %12 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, false, false); -} - -TEST_F(AggressiveDCETest, RemoveWhenUsingPrintfExtension) { - // Remove dead n_out output variable from module - const std::string text = R"( -; CHECK: OpExtInstImport "NonSemantic.DebugPrintf" -; CHECK-NOT: OpVariable - OpCapability Shader - %1 = OpExtInstImport "NonSemantic.DebugPrintf" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 8 8 1 - OpSource HLSL 660 - OpName %main "main" - %uint = OpTypeInt 32 0 - %void = OpTypeVoid - %5 = OpTypeFunction %void -%_ptr_Function_uint = OpTypePointer Function %uint - %main = OpFunction %void None %5 - %7 = OpLabel - %8 = OpVariable %_ptr_Function_uint Function - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SinglePassRunAndMatch(text, true); -} - -TEST_F(AggressiveDCETest, FunctionReturnPointer) { - // Run DCE when a function returning a pointer to a reference is present - - const std::string text = R"( - OpCapability Shader - OpCapability PhysicalStorageBufferAddresses - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel PhysicalStorageBuffer64 GLSL450 - OpEntryPoint Vertex %2 "main" %3 %4 - OpSource GLSL 450 - OpSourceExtension "GL_EXT_buffer_reference" - OpSourceExtension "GL_EXT_scalar_block_layout" - OpName %4 "color" - OpMemberDecorate %5 0 Offset 0 - OpDecorate %5 Block - OpMemberDecorate %7 0 Offset 0 - OpDecorate %7 Block - OpDecorate %8 AliasedPointer - OpDecorate %4 Location 0 - %9 = OpTypeVoid - %10 = OpTypeFunction %9 - OpTypeForwardPointer %11 PhysicalStorageBuffer - %12 = OpTypeInt 32 0 - %5 = OpTypeStruct %12 - %11 = OpTypePointer PhysicalStorageBuffer %5 -;CHECK: [[pt:%\w+]] = OpTypePointer PhysicalStorageBuffer {{%\w+}} - %13 = OpTypeFunction %11 -;CHECK: [[pt_fn:%\w+]] = OpTypeFunction [[pt]] - %7 = OpTypeStruct %11 - %14 = OpTypePointer PushConstant %7 - %3 = OpVariable %14 PushConstant - %15 = OpTypeInt 32 1 - %16 = OpConstant %15 0 - %17 = OpTypePointer PushConstant %11 - %18 = OpTypePointer Function %11 - %19 = OpTypeFloat 32 - %20 = OpTypeVector %19 4 - %21 = OpTypePointer Output %20 - %4 = OpVariable %21 Output - %22 = OpConstant %19 1 - %23 = OpConstant %19 0 - %24 = OpConstantComposite %20 %22 %23 %22 %22 - %6 = OpFunction %11 None %13 -;CHECK: [[fn:%\w+]] = OpFunction [[pt]] None [[pt_fn]] - %27 = OpLabel - %28 = OpAccessChain %17 %3 %16 - %29 = OpLoad %11 %28 - OpReturnValue %29 - OpFunctionEnd - %2 = OpFunction %9 None %10 - %25 = OpLabel - %8 = OpVariable %18 Function - %26 = OpFunctionCall %11 %6 -;CHECK: {{%\w+}} = OpFunctionCall [[pt]] [[fn]] - OpStore %8 %26 - OpStore %4 %24 - OpReturn - OpFunctionEnd -)"; - - // For physical storage buffer support - SetTargetEnv(SPV_ENV_VULKAN_1_2); - SinglePassRunAndMatch(text, true); -} - -TEST_F(AggressiveDCETest, KeepBeginEndInvocationInterlock) { - // OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT delimit a - // critical section. As such, they should be treated as if they have side - // effects and should not be removed. - const std::string test = - R"(OpCapability Shader -OpCapability FragmentShaderSampleInterlockEXT -OpExtension "SPV_EXT_fragment_shader_interlock" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %1 "main" %gl_FragCoord -OpExecutionMode %1 OriginUpperLeft -OpExecutionMode %1 SampleInterlockOrderedEXT -OpDecorate %gl_FragCoord BuiltIn FragCoord -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%void = OpTypeVoid -%8 = OpTypeFunction %void -%bool = OpTypeBool -%gl_FragCoord = OpVariable %_ptr_Input_v4float Input -%1 = OpFunction %void None %8 -%10 = OpLabel -%11 = OpLoad %v4float %gl_FragCoord -%12 = OpCompositeExtract %float %11 0 -%13 = OpFOrdGreaterThan %bool %12 %float_0 -OpSelectionMerge %14 None -OpBranchConditional %13 %15 %16 -%15 = OpLabel -OpBeginInvocationInterlockEXT -OpBranch %14 -%16 = OpLabel -OpBeginInvocationInterlockEXT -OpBranch %14 -%14 = OpLabel -OpEndInvocationInterlockEXT -OpReturn -OpFunctionEnd -)"; - - SinglePassRunAndCheck(test, test, true, true); -} - } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/amd_ext_to_khr.cpp b/test/opt/amd_ext_to_khr.cpp index a520d600..3340e898 100644 --- a/test/opt/amd_ext_to_khr.cpp +++ b/test/opt/amd_ext_to_khr.cpp @@ -26,17 +26,15 @@ using AmdExtToKhrTest = PassTest<::testing::Test>; using ::testing::HasSubstr; -std::string GetTest(std::string op_code, std::string new_op_code, - bool is_float = false) { +std::string GetTest(std::string op_code, std::string new_op_code) { const std::string text = R"( ; CHECK: OpCapability Shader ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot" ; CHECK: OpFunction ; CHECK-NEXT: OpLabel -; CHECK-NEXT: [[undef:%\w+]] = OpUndef % +; CHECK-NEXT: [[undef:%\w+]] = OpUndef %uint ; CHECK-NEXT: )" + new_op_code + - " %" + (is_float ? "float" : "uint") + - R"( %uint_3 Reduce [[undef]] + R"( %uint %uint_3 Reduce [[undef]] OpCapability Shader OpCapability Groups OpExtension "SPV_AMD_shader_ballot" @@ -46,15 +44,12 @@ std::string GetTest(std::string op_code, std::string new_op_code, %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 - %float = OpTypeFloat 32 %uint_3 = OpConstant %uint 3 %1 = OpFunction %void None %3 %6 = OpLabel - %7 = OpUndef %)" + - (is_float ? "float" : "uint") + R"( + %7 = OpUndef %uint %8 = )" + op_code + - " %" + (is_float ? "float" : "uint") + - R"( %uint_3 Reduce %7 + R"( %uint %uint_3 Reduce %7 OpReturn OpFunctionEnd @@ -69,7 +64,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupIAddNonUniformAMD) { } TEST_F(AmdExtToKhrTest, ReplaceGroupFAddNonUniformAMD) { std::string text = - GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd", true); + GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd"); SinglePassRunAndMatch(text, true); } TEST_F(AmdExtToKhrTest, ReplaceGroupUMinNonUniformAMD) { @@ -84,7 +79,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupSMinNonUniformAMD) { } TEST_F(AmdExtToKhrTest, ReplaceGroupFMinNonUniformAMD) { std::string text = - GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin", true); + GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin"); SinglePassRunAndMatch(text, true); } TEST_F(AmdExtToKhrTest, ReplaceGroupUMaxNonUniformAMD) { @@ -99,7 +94,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupSMaxNonUniformAMD) { } TEST_F(AmdExtToKhrTest, ReplaceGroupFMaxNonUniformAMD) { std::string text = - GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax", true); + GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax"); SinglePassRunAndMatch(text, true); } diff --git a/test/opt/analyze_live_input_test.cpp b/test/opt/analyze_live_input_test.cpp deleted file mode 100755 index 7f1ff2e0..00000000 --- a/test/opt/analyze_live_input_test.cpp +++ /dev/null @@ -1,909 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using AnalyzeLiveInputTest = PassTest<::testing::Test>; - -TEST_F(AnalyzeLiveInputTest, FragMultipleLocations) { - // Should report locations {2, 5} - // - // #version 450 - // - // layout(location = 2) in Vertex - // { - // vec4 color0; - // vec4 color1; - // vec4 color2[3]; - // } iVert; - // - // layout(location = 0) out vec4 oFragColor; - // - // void main() - // { - // oFragColor = iVert.color0 + iVert.color2[1]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %oFragColor %iVert - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %oFragColor "oFragColor" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpName %iVert "iVert" - OpDecorate %oFragColor Location 0 - OpDecorate %Vertex Block - OpDecorate %iVert Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %oFragColor = OpVariable %_ptr_Output_v4float Output - %uint = OpTypeInt 32 0 - %uint_3 = OpConstant %uint 3 -%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3 - %Vertex = OpTypeStruct %v4float %v4float %_arr_v4float_uint_3 -%_ptr_Input_Vertex = OpTypePointer Input %Vertex - %iVert = OpVariable %_ptr_Input_Vertex Input - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_2 = OpConstant %int 2 - %int_1 = OpConstant %int 1 - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 - %20 = OpLoad %v4float %19 - %23 = OpAccessChain %_ptr_Input_v4float %iVert %int_2 %int_1 - %24 = OpLoad %v4float %23 - %25 = OpFAdd %v4float %20 %24 - OpStore %oFragColor %25 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - auto itr4 = live_inputs.find(4); - auto itr5 = live_inputs.find(5); - auto itr6 = live_inputs.find(6); - - // Expect live_inputs == {2, 5} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 == live_inputs.end()); - EXPECT_TRUE(itr2 != live_inputs.end()); - EXPECT_TRUE(itr3 == live_inputs.end()); - EXPECT_TRUE(itr4 == live_inputs.end()); - EXPECT_TRUE(itr5 != live_inputs.end()); - EXPECT_TRUE(itr6 == live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, FragMatrix) { - // Should report locations {2, 8, 9, 10, 11} - // - // #version 450 - // - // uniform ui_name { - // int i; - // } ui_inst; - // - // layout(location = 2) in Vertex - // { - // vec4 color0; - // vec4 color1; - // mat4 color2; - // mat4 color3; - // mat4 color4; - // } iVert; - // - // // Output variable for the color - // layout(location = 0) out vec4 oFragColor; - // - // void main() - // { - // oFragColor = iVert.color0 + iVert.color3[ui_inst.i]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %oFragColor %iVert %ui_inst - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %oFragColor "oFragColor" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpMemberName %Vertex 3 "color3" - OpMemberName %Vertex 4 "color4" - OpName %iVert "iVert" - OpName %ui_name "ui_name" - OpMemberName %ui_name 0 "i" - OpName %ui_inst "ui_inst" - OpDecorate %oFragColor Location 0 - OpDecorate %Vertex Block - OpDecorate %iVert Location 2 - OpMemberDecorate %ui_name 0 Offset 0 - OpDecorate %ui_name Block - OpDecorate %ui_inst DescriptorSet 0 - OpDecorate %ui_inst Binding 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %oFragColor = OpVariable %_ptr_Output_v4float Output -%mat4v4float = OpTypeMatrix %v4float 4 - %Vertex = OpTypeStruct %v4float %v4float %mat4v4float %mat4v4float %mat4v4float -%_ptr_Input_Vertex = OpTypePointer Input %Vertex - %iVert = OpVariable %_ptr_Input_Vertex Input - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_3 = OpConstant %int 3 - %ui_name = OpTypeStruct %int -%_ptr_Uniform_ui_name = OpTypePointer Uniform %ui_name - %ui_inst = OpVariable %_ptr_Uniform_ui_name Uniform -%_ptr_Uniform_int = OpTypePointer Uniform %int - %main = OpFunction %void None %3 - %5 = OpLabel - %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 - %18 = OpLoad %v4float %17 - %24 = OpAccessChain %_ptr_Uniform_int %ui_inst %int_0 - %25 = OpLoad %int %24 - %26 = OpAccessChain %_ptr_Input_v4float %iVert %int_3 %25 - %27 = OpLoad %v4float %26 - %28 = OpFAdd %v4float %18 %27 - OpStore %oFragColor %28 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - auto itr4 = live_inputs.find(4); - auto itr5 = live_inputs.find(5); - auto itr6 = live_inputs.find(6); - auto itr7 = live_inputs.find(7); - auto itr8 = live_inputs.find(8); - auto itr9 = live_inputs.find(9); - auto itr10 = live_inputs.find(10); - auto itr11 = live_inputs.find(11); - auto itr12 = live_inputs.find(12); - auto itr13 = live_inputs.find(13); - auto itr14 = live_inputs.find(14); - auto itr15 = live_inputs.find(15); - - // Expect live_inputs == {2, 8, 9, 10, 11} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 == live_inputs.end()); - EXPECT_TRUE(itr2 != live_inputs.end()); - EXPECT_TRUE(itr3 == live_inputs.end()); - EXPECT_TRUE(itr4 == live_inputs.end()); - EXPECT_TRUE(itr5 == live_inputs.end()); - EXPECT_TRUE(itr6 == live_inputs.end()); - EXPECT_TRUE(itr7 == live_inputs.end()); - EXPECT_TRUE(itr8 != live_inputs.end()); - EXPECT_TRUE(itr9 != live_inputs.end()); - EXPECT_TRUE(itr10 != live_inputs.end()); - EXPECT_TRUE(itr11 != live_inputs.end()); - EXPECT_TRUE(itr12 == live_inputs.end()); - EXPECT_TRUE(itr13 == live_inputs.end()); - EXPECT_TRUE(itr14 == live_inputs.end()); - EXPECT_TRUE(itr15 == live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, FragMemberLocs) { - // Should report location {1} - // - // #version 450 - // - // in Vertex - // { - // layout (location = 1) vec4 Cd; - // layout (location = 0) vec2 uv; - // } iVert; - // - // layout (location = 0) out vec4 fragColor; - // - // void main() - // { - // vec4 color = vec4(iVert.Cd); - // fragColor = color; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %iVert %fragColor - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %color "color" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "Cd" - OpMemberName %Vertex 1 "uv" - OpName %iVert "iVert" - OpName %fragColor "fragColor" - OpMemberDecorate %Vertex 0 Location 1 - OpMemberDecorate %Vertex 1 Location 0 - OpDecorate %Vertex Block - OpDecorate %fragColor Location 0 - OpDecorate %_struct_27 Block - OpMemberDecorate %_struct_27 0 Location 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %v2float = OpTypeVector %float 2 - %Vertex = OpTypeStruct %v4float %v2float -%_ptr_Input_Vertex = OpTypePointer Input %Vertex - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %fragColor = OpVariable %_ptr_Output_v4float Output - %_struct_27 = OpTypeStruct %v4float -%_ptr_Input__struct_27 = OpTypePointer Input %_struct_27 - %iVert = OpVariable %_ptr_Input__struct_27 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %color = OpVariable %_ptr_Function_v4float Function - %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 - %18 = OpLoad %v4float %17 - %19 = OpCompositeExtract %float %18 0 - %20 = OpCompositeExtract %float %18 1 - %21 = OpCompositeExtract %float %18 2 - %22 = OpCompositeExtract %float %18 3 - %23 = OpCompositeConstruct %v4float %19 %20 %21 %22 - OpStore %color %23 - %26 = OpLoad %v4float %color - OpStore %fragColor %26 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - - // Expect live_inputs == {2, 5} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 != live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, ArrayedInput) { - // Tests handling of arrayed input seen in Tesc, Tese and Geom shaders. - // - // Should report location {1, 10}. - // - // #version 450 - // - // layout (vertices = 4) out; - // - // layout (location = 1) in Vertex - // { - // vec4 p; - // vec3 n; - // vec4 f[100]; - // } iVert[]; - // - // layout (location = 0) out vec4 position[4]; - // - // void main() - // { - // vec4 pos = iVert[gl_InvocationID].p * - // iVert[gl_InvocationID].f[7]; - // position[gl_InvocationID] = pos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %iVert %gl_InvocationID %position - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "p" - OpMemberName %Vertex 1 "n" - OpMemberName %Vertex 2 "f" - OpName %iVert "iVert" - OpName %gl_InvocationID "gl_InvocationID" - OpName %position "position" - OpDecorate %Vertex Block - OpDecorate %iVert Location 1 - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpDecorate %position Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 - %uint = OpTypeInt 32 0 - %uint_100 = OpConstant %uint 100 -%_arr_v4float_uint_100 = OpTypeArray %v4float %uint_100 - %Vertex = OpTypeStruct %v4float %v3float %_arr_v4float_uint_100 - %uint_32 = OpConstant %uint 32 -%_arr_Vertex_uint_32 = OpTypeArray %Vertex %uint_32 -%_ptr_Input__arr_Vertex_uint_32 = OpTypePointer Input %_arr_Vertex_uint_32 - %iVert = OpVariable %_ptr_Input__arr_Vertex_uint_32 Input - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_2 = OpConstant %int 2 - %int_7 = OpConstant %int 7 - %uint_4 = OpConstant %uint 4 -%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4 -%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4 - %position = OpVariable %_ptr_Output__arr_v4float_uint_4 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float - %main = OpFunction %void None %3 - %5 = OpLabel - %22 = OpLoad %int %gl_InvocationID - %25 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_0 - %26 = OpLoad %v4float %25 - %30 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_2 %int_7 - %31 = OpLoad %v4float %30 - %32 = OpFMul %v4float %26 %31 - %40 = OpAccessChain %_ptr_Output_v4float %position %22 - OpStore %40 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - auto itr4 = live_inputs.find(4); - auto itr5 = live_inputs.find(5); - auto itr6 = live_inputs.find(6); - auto itr7 = live_inputs.find(7); - auto itr8 = live_inputs.find(8); - auto itr9 = live_inputs.find(9); - auto itr10 = live_inputs.find(10); - auto itr11 = live_inputs.find(11); - - // Expect live_inputs == {1, 10} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 != live_inputs.end()); - EXPECT_TRUE(itr2 == live_inputs.end()); - EXPECT_TRUE(itr3 == live_inputs.end()); - EXPECT_TRUE(itr4 == live_inputs.end()); - EXPECT_TRUE(itr5 == live_inputs.end()); - EXPECT_TRUE(itr6 == live_inputs.end()); - EXPECT_TRUE(itr7 == live_inputs.end()); - EXPECT_TRUE(itr8 == live_inputs.end()); - EXPECT_TRUE(itr9 == live_inputs.end()); - EXPECT_TRUE(itr10 != live_inputs.end()); - EXPECT_TRUE(itr11 == live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, ArrayedInputMemberLocs) { - // Tests handling of member locs with arrayed input seen in Tesc, Tese - // and Geom shaders. - // - // Should report location {1, 12}. - // - // #version 450 - // - // layout (vertices = 4) out; - // - // in Vertex - // { - // layout (location = 1) vec4 p; - // layout (location = 3) vec3 n; - // layout (location = 5) vec4 f[100]; - // } iVert[]; - // - // layout (location = 0) out vec4 position[4]; - // - // void main() - // { - // vec4 pos = iVert[gl_InvocationID].p * - // iVert[gl_InvocationID].f[7]; - // position[gl_InvocationID] = pos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %iVert %gl_InvocationID %position - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "p" - OpMemberName %Vertex 1 "n" - OpMemberName %Vertex 2 "f" - OpName %iVert "iVert" - OpName %gl_InvocationID "gl_InvocationID" - OpName %position "position" - OpMemberDecorate %Vertex 0 Location 1 - OpMemberDecorate %Vertex 1 Location 3 - OpMemberDecorate %Vertex 2 Location 5 - OpDecorate %Vertex Block - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpDecorate %position Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 - %uint = OpTypeInt 32 0 - %uint_100 = OpConstant %uint 100 -%_arr_v4float_uint_100 = OpTypeArray %v4float %uint_100 - %Vertex = OpTypeStruct %v4float %v3float %_arr_v4float_uint_100 - %uint_32 = OpConstant %uint 32 -%_arr_Vertex_uint_32 = OpTypeArray %Vertex %uint_32 -%_ptr_Input__arr_Vertex_uint_32 = OpTypePointer Input %_arr_Vertex_uint_32 - %iVert = OpVariable %_ptr_Input__arr_Vertex_uint_32 Input - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_2 = OpConstant %int 2 - %int_7 = OpConstant %int 7 - %uint_4 = OpConstant %uint 4 -%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4 -%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4 - %position = OpVariable %_ptr_Output__arr_v4float_uint_4 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float - %main = OpFunction %void None %3 - %5 = OpLabel - %22 = OpLoad %int %gl_InvocationID - %25 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_0 - %26 = OpLoad %v4float %25 - %30 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_2 %int_7 - %31 = OpLoad %v4float %30 - %32 = OpFMul %v4float %26 %31 - %40 = OpAccessChain %_ptr_Output_v4float %position %22 - OpStore %40 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - auto itr4 = live_inputs.find(4); - auto itr5 = live_inputs.find(5); - auto itr6 = live_inputs.find(6); - auto itr7 = live_inputs.find(7); - auto itr8 = live_inputs.find(8); - auto itr9 = live_inputs.find(9); - auto itr10 = live_inputs.find(10); - auto itr11 = live_inputs.find(11); - auto itr12 = live_inputs.find(12); - auto itr13 = live_inputs.find(13); - - // Expect live_inputs == {1, 12} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 != live_inputs.end()); - EXPECT_TRUE(itr2 == live_inputs.end()); - EXPECT_TRUE(itr3 == live_inputs.end()); - EXPECT_TRUE(itr4 == live_inputs.end()); - EXPECT_TRUE(itr5 == live_inputs.end()); - EXPECT_TRUE(itr6 == live_inputs.end()); - EXPECT_TRUE(itr7 == live_inputs.end()); - EXPECT_TRUE(itr8 == live_inputs.end()); - EXPECT_TRUE(itr9 == live_inputs.end()); - EXPECT_TRUE(itr10 == live_inputs.end()); - EXPECT_TRUE(itr11 == live_inputs.end()); - EXPECT_TRUE(itr12 != live_inputs.end()); - EXPECT_TRUE(itr13 == live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, Builtins) { - // Tests handling of builtin input seen in Tesc, Tese and Geom shaders. - // - // Should report builtin gl_PointSize only. - // - // #version 460 - // - // layout(triangle_strip, max_vertices = 3) out; - // layout(triangles) in; - // - // void main() - // { - // for (int i = 0; i < 3; i++) - // { - // gl_Position = gl_in[i].gl_Position; - // gl_PointSize = gl_in[i].gl_PointSize; - // - // EmitVertex(); - // } - // - // EndPrimitive(); - // } - const std::string text = R"( - OpCapability Geometry - OpCapability GeometryPointSize - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Geometry %main "main" %_ %gl_in - OpExecutionMode %main Triangles - OpExecutionMode %main Invocations 1 - OpExecutionMode %main OutputTriangleStrip - OpExecutionMode %main OutputVertices 3 - OpSource GLSL 460 - OpName %main "main" - OpName %i "i" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpMemberName %gl_PerVertex_0 1 "gl_PointSize" - OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" - OpName %gl_in "gl_in" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_3 = OpConstant %int 3 - %bool = OpTypeBool - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output -%gl_PerVertex_0 = OpTypeStruct %v4float %float - %uint_3 = OpConstant %uint 3 -%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 -%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Output_float = OpTypePointer Output %float - %main = OpFunction %void None %3 - %5 = OpLabel - %i = OpVariable %_ptr_Function_int Function - OpStore %i %int_0 - OpBranch %10 - %10 = OpLabel - OpLoopMerge %12 %13 None - OpBranch %14 - %14 = OpLabel - %15 = OpLoad %int %i - %18 = OpSLessThan %bool %15 %int_3 - OpBranchConditional %18 %11 %12 - %11 = OpLabel - %32 = OpLoad %int %i - %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0 - %35 = OpLoad %v4float %34 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %35 - %39 = OpLoad %int %i - %41 = OpAccessChain %_ptr_Input_float %gl_in %39 %int_1 - %42 = OpLoad %float %41 - %44 = OpAccessChain %_ptr_Output_float %_ %int_1 - OpStore %44 %42 - OpEmitVertex - OpBranch %13 - %13 = OpLabel - %45 = OpLoad %int %i - %46 = OpIAdd %int %45 %int_1 - OpStore %i %46 - OpBranch %10 - %12 = OpLabel - OpEndPrimitive - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_builtins.find((uint32_t)spv::BuiltIn::PointSize); - auto itr1 = live_builtins.find((uint32_t)spv::BuiltIn::ClipDistance); - auto itr2 = live_builtins.find((uint32_t)spv::BuiltIn::CullDistance); - - // Expect live_builtins == { spv::BuiltIn::PointSize } - EXPECT_TRUE(itr0 != live_builtins.end()); - EXPECT_TRUE(itr1 == live_builtins.end()); - EXPECT_TRUE(itr2 == live_builtins.end()); -} - -TEST_F(AnalyzeLiveInputTest, ArrayedInputPatchLocs) { - // Tests handling of locs with arrayed input patch seen in Tese - // - // Should report location {3}. - // - // #version 450 core - // - // layout(triangles, ccw) in; - // - // layout(fractional_odd_spacing) in; - // - // layout(point_mode) in; - // - // layout(location=2) patch in float patchIn1[2]; - // - // void main() - // { - // vec4 p = gl_in[1].gl_Position; - // gl_Position = p * patchIn1[1]; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationEvaluation %main "main" %gl_in %_ %patchIn1 - OpExecutionMode %main Triangles - OpExecutionMode %main SpacingFractionalOdd - OpExecutionMode %main VertexOrderCcw - OpExecutionMode %main PointMode - OpSource GLSL 450 - OpName %main "main" - OpName %p "p" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %gl_in "gl_in" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpName %_ "" - OpName %patchIn1 "patchIn1" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpDecorate %gl_PerVertex_0 Block - OpDecorate %patchIn1 Patch - OpDecorate %patchIn1 Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float - %uint_32 = OpConstant %uint 32 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%gl_PerVertex_0 = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0 - %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output - %uint_2 = OpConstant %uint 2 -%_arr_float_uint_2 = OpTypeArray %float %uint_2 -%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2 - %patchIn1 = OpVariable %_ptr_Input__arr_float_uint_2 Input -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %main = OpFunction %void None %3 - %5 = OpLabel - %p = OpVariable %_ptr_Function_v4float Function - %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0 - %23 = OpLoad %v4float %22 - OpStore %p %23 - %27 = OpLoad %v4float %p - %33 = OpAccessChain %_ptr_Input_float %patchIn1 %int_1 - %34 = OpLoad %float %33 - %35 = OpVectorTimesScalar %v4float %27 %34 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %35 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - - // Expect live_inputs == {3} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 == live_inputs.end()); - EXPECT_TRUE(itr2 == live_inputs.end()); - EXPECT_TRUE(itr3 != live_inputs.end()); -} - -TEST_F(AnalyzeLiveInputTest, FragMultipleLocationsF16) { - // Should report locations {2, 5} - // - // #version 450 - // - // layout(location = 2) in Vertex - // { - // f16vec4 color0; - // f16vec4 color1; - // f16vec4 color2[3]; - // } iVert; - // - // layout(location = 0) out f16vec4 oFragColor; - // - // void main() - // { - // oFragColor = iVert.color0 + iVert.color2[1]; - // } - const std::string text = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %oFragColor %iVert - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %oFragColor "oFragColor" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpName %iVert "iVert" - OpDecorate %oFragColor Location 0 - OpDecorate %Vertex Block - OpDecorate %iVert Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %half = OpTypeFloat 16 - %v4half = OpTypeVector %half 4 -%_ptr_Output_v4half = OpTypePointer Output %v4half - %oFragColor = OpVariable %_ptr_Output_v4half Output - %uint = OpTypeInt 32 0 - %uint_3 = OpConstant %uint 3 -%_arr_v4half_uint_3 = OpTypeArray %v4half %uint_3 - %Vertex = OpTypeStruct %v4half %v4half %_arr_v4half_uint_3 -%_ptr_Input_Vertex = OpTypePointer Input %Vertex - %iVert = OpVariable %_ptr_Input_Vertex Input - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4half = OpTypePointer Input %v4half - %int_2 = OpConstant %int 2 - %int_1 = OpConstant %int 1 - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpAccessChain %_ptr_Input_v4half %iVert %int_0 - %20 = OpLoad %v4half %19 - %23 = OpAccessChain %_ptr_Input_v4half %iVert %int_2 %int_1 - %24 = OpLoad %v4half %23 - %25 = OpFAdd %v4half %20 %24 - OpStore %oFragColor %25 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - auto result = SinglePassRunToBinary( - text, true, &live_inputs, &live_builtins); - - auto itr0 = live_inputs.find(0); - auto itr1 = live_inputs.find(1); - auto itr2 = live_inputs.find(2); - auto itr3 = live_inputs.find(3); - auto itr4 = live_inputs.find(4); - auto itr5 = live_inputs.find(5); - auto itr6 = live_inputs.find(6); - - // Expect live_inputs == {2, 5} - EXPECT_TRUE(itr0 == live_inputs.end()); - EXPECT_TRUE(itr1 == live_inputs.end()); - EXPECT_TRUE(itr2 != live_inputs.end()); - EXPECT_TRUE(itr3 == live_inputs.end()); - EXPECT_TRUE(itr4 == live_inputs.end()); - EXPECT_TRUE(itr5 != live_inputs.end()); - EXPECT_TRUE(itr6 == live_inputs.end()); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/block_merge_test.cpp b/test/opt/block_merge_test.cpp index 57c5061f..9698fed2 100644 --- a/test/opt/block_merge_test.cpp +++ b/test/opt/block_merge_test.cpp @@ -1201,125 +1201,6 @@ OpFunctionEnd SinglePassRunAndMatch(text, true); } -TEST_F(BlockMergeTest, DontLoseCaseConstruct) { - const std::string text = R"( -OpCapability Shader -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %func "func" -OpExecutionMode %func LocalSize 1 1 1 -OpName %entry "entry"; -OpName %loop "loop" -OpName %loop_merge "loop_merge" -OpName %loop_cont "loop_cont" -OpName %switch "switch" -OpName %switch_merge "switch_merge" -%void = OpTypeVoid -%bool = OpTypeBool -%int = OpTypeInt 32 0 -%void_fn = OpTypeFunction %void -%bool_undef = OpUndef %bool -%int_undef = OpUndef %int -%func = OpFunction %void None %void_fn -%entry = OpLabel -OpBranch %loop -%loop = OpLabel -OpLoopMerge %loop_merge %loop_cont None -OpBranch %switch -%switch = OpLabel -OpSelectionMerge %switch_merge None -OpSwitch %int_undef %switch_merge 0 %break 1 %break -%break = OpLabel -OpBranch %loop_merge -%switch_merge = OpLabel -OpBranch %loop_cont -%loop_cont = OpLabel -OpBranch %loop -%loop_merge = OpLabel -OpReturn -OpFunctionEnd -)"; - - auto result = SinglePassRunAndDisassemble( - text, /* skip_nop = */ true, /* do_validation = */ true); - EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); -} - -TEST_F(BlockMergeTest, DontLoseDefaultCaseConstruct) { - const std::string text = R"( -OpCapability Shader -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %func "func" -OpExecutionMode %func LocalSize 1 1 1 -OpName %entry "entry"; -OpName %loop "loop" -OpName %loop_merge "loop_merge" -OpName %loop_cont "loop_cont" -OpName %switch "switch" -OpName %switch_merge "switch_merge" -%void = OpTypeVoid -%bool = OpTypeBool -%int = OpTypeInt 32 0 -%void_fn = OpTypeFunction %void -%bool_undef = OpUndef %bool -%int_undef = OpUndef %int -%func = OpFunction %void None %void_fn -%entry = OpLabel -OpBranch %loop -%loop = OpLabel -OpLoopMerge %loop_merge %loop_cont None -OpBranch %switch -%switch = OpLabel -OpSelectionMerge %switch_merge None -OpSwitch %int_undef %cont 0 %switch_merge 1 %switch_merge -%cont = OpLabel -OpBranch %loop_cont -%switch_merge = OpLabel -OpBranch %loop_merge -%loop_cont = OpLabel -OpBranch %loop -%loop_merge = OpLabel -OpReturn -OpFunctionEnd -)"; - - auto result = SinglePassRunAndDisassemble( - text, /* skip_nop = */ true, /* do_validation = */ true); - EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); -} - -TEST_F(BlockMergeTest, RebuildStructuredCFG) { - const std::string text = R"( -; CHECK: = OpFunction -; CHECK-NEXT: [[entry:%\w+]] = OpLabel -; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]] None -; CHECK-NEXT: OpSwitch {{%\w+}} [[merge]] 0 [[other:%\w+]] -; CHECK [[other]] = OpLabel -; CHECK: OpBranch [[merge]] -; CHECK [[merge]] = OpLabel -OpCapability Shader -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_1 = OpConstant %int 1 -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -OpBranch %switch -%switch = OpLabel -OpSelectionMerge %merge None -OpSwitch %int_1 %merge 0 %other -%other = OpLabel -OpBranch %merge -%merge = OpLabel -OpReturn -OpFunctionEnd -)"; - - SinglePassRunAndMatch(text, true); -} - // TODO(greg-lunarg): Add tests to verify handling of these cases: // // More complex control flow diff --git a/test/opt/c_interface_test.cpp b/test/opt/c_interface_test.cpp deleted file mode 100755 index a1725255..00000000 --- a/test/opt/c_interface_test.cpp +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (c) 2023 Nintendo -// -// 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 "gtest/gtest.h" -#include "spirv-tools/libspirv.h" - -namespace spvtools { -namespace { - -TEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForInvalidInput) { - const uint32_t spirv[] = { - 0xDEADFEED, // Invalid Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x01000000, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - // Do not register any passes - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, true); - - spv_binary binary = nullptr; - EXPECT_NE(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_EQ(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, SpecifyConsumerWithValidationNoPassesForInvalidInput) { - const uint32_t spirv[] = { - 0xDEADFEED, // Invalid Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x01000000, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - spvOptimizerSetMessageConsumer( - optimizer, - [](spv_message_level_t, const char*, const spv_position_t*, - const char* message) { - std::cout << message << std::endl; - }); - - // Do not register any passes - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, true); - - testing::internal::CaptureStdout(); - - spv_binary binary = nullptr; - EXPECT_NE(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_EQ(binary, nullptr); - - auto output = testing::internal::GetCapturedStdout(); - EXPECT_STRNE(output.c_str(), ""); - - spvOptimizerOptionsDestroy(options); - - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000001, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - // Do not register any passes - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, true); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Should remain unchanged - EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerNoPassesForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - // Do not register any passes - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, true); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Should remain unchanged - EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerLegalizationPassesForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - spvOptimizerRegisterLegalizationPasses(optimizer); - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, false); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Only check that SPV_SUCCESS is returned, do not verify output - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerPerformancePassesForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - const uint32_t expected_spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000001, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - spvOptimizerRegisterPerformancePasses(optimizer); - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, false); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Unreferenced OpTypeInt and OpConstant should be removed - EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, expected_spirv, - sizeof(expected_spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerSizePassesForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - const uint32_t expected_spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000001, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - spvOptimizerRegisterSizePasses(optimizer); - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, false); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Unreferenced OpTypeInt and OpConstant should be removed - EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, expected_spirv, - sizeof(expected_spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerPassFromFlagForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - const uint32_t expected_spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000001, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - EXPECT_TRUE(spvOptimizerRegisterPassFromFlag( - optimizer, "--eliminate-dead-code-aggressive")); - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, false); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Unreferenced OpTypeInt and OpConstant should be removed - EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, expected_spirv, - sizeof(expected_spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerPassesFromFlagsForValidInput) { - const uint32_t spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000003, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001, // GLSL450 - 0x00040015, // OpTypeInt - 0x00000001, // %1 - 0x00000020, // 32 Bits - 0x00000000, // Unsigned - 0x0004002B, // OpConstant - 0x00000001, // %1 - 0x00000002, // %2 - 0x00000001 // 1 - }; - const uint32_t expected_spirv[] = { - 0x07230203, // Magic - 0x00010100, // Version 1.1 - 0x00000000, // No Generator - 0x00000001, // Bound - 0x00000000, // Schema - 0x00020011, // OpCapability - 0x00000001, // Shader - 0x00020011, // OpCapability - 0x00000005, // Linkage - 0x0003000E, // OpMemoryModel - 0x00000000, // Logical - 0x00000001 // GLSL450 - }; - - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - const char* flags[2] = { - "--eliminate-dead-const", - "--eliminate-dead-code-aggressive" - }; - - EXPECT_TRUE(spvOptimizerRegisterPassesFromFlags( - optimizer, flags, sizeof(flags) / sizeof(const char*))); - - auto options = spvOptimizerOptionsCreate(); - ASSERT_NE(options, nullptr); - spvOptimizerOptionsSetRunValidator(options, false); - - spv_binary binary = nullptr; - EXPECT_EQ(SPV_SUCCESS, - spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t), - &binary, options)); - ASSERT_NE(binary, nullptr); - - spvOptimizerOptionsDestroy(options); - - // Unreferenced OpTypeInt and OpConstant should be removed - EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t)); - EXPECT_EQ(memcmp(binary->code, expected_spirv, - sizeof(expected_spirv) / sizeof(uint32_t)), 0); - - spvBinaryDestroy(binary); - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerInvalidPassFromFlag) { - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - EXPECT_FALSE(spvOptimizerRegisterPassFromFlag( - optimizer, "--this-is-not-a-valid-pass")); - - spvOptimizerDestroy(optimizer); -} - -TEST(OptimizerCInterface, DefaultConsumerInvalidPassesFromFlags) { - auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1); - ASSERT_NE(optimizer, nullptr); - - const char* flags[2] = { - "--eliminate-dead-const", - "--this-is-not-a-valid-pass" - }; - - EXPECT_FALSE(spvOptimizerRegisterPassesFromFlags( - optimizer, flags, sizeof(flags) / sizeof(const char*))); - - spvOptimizerDestroy(optimizer); -} - -} // namespace -} // namespace spvtools diff --git a/test/opt/ccp_test.cpp b/test/opt/ccp_test.cpp index a8e9557d..f0f24362 100644 --- a/test/opt/ccp_test.cpp +++ b/test/opt/ccp_test.cpp @@ -14,6 +14,7 @@ #include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/ccp_pass.h" #include "test/opt/pass_fixture.h" diff --git a/test/opt/code_sink_test.cpp b/test/opt/code_sink_test.cpp index 98033fb0..bf5029b6 100644 --- a/test/opt/code_sink_test.cpp +++ b/test/opt/code_sink_test.cpp @@ -14,6 +14,7 @@ #include +#include "gmock/gmock.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/combine_access_chains_test.cpp b/test/opt/combine_access_chains_test.cpp index ef7addc7..5be3ba63 100644 --- a/test/opt/combine_access_chains_test.cpp +++ b/test/opt/combine_access_chains_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/compact_ids_test.cpp b/test/opt/compact_ids_test.cpp index 42f23517..7c232fe4 100644 --- a/test/opt/compact_ids_test.cpp +++ b/test/opt/compact_ids_test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/constant_manager_test.cpp b/test/opt/constant_manager_test.cpp index 54c86527..14e14ec2 100644 --- a/test/opt/constant_manager_test.cpp +++ b/test/opt/constant_manager_test.cpp @@ -13,7 +13,9 @@ // limitations under the License. #include +#include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/build_module.h" #include "source/opt/constants.h" diff --git a/test/opt/constants_test.cpp b/test/opt/constants_test.cpp index 1d4c738f..55c92a51 100644 --- a/test/opt/constants_test.cpp +++ b/test/opt/constants_test.cpp @@ -16,6 +16,7 @@ #include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/types.h" diff --git a/test/opt/convert_relaxed_to_half_test.cpp b/test/opt/convert_relaxed_to_half_test.cpp index 62b9ae45..6a06de84 100644 --- a/test/opt/convert_relaxed_to_half_test.cpp +++ b/test/opt/convert_relaxed_to_half_test.cpp @@ -1570,149 +1570,6 @@ TEST_F(ConvertToHalfTest, HandleNonRelaxedPhi) { EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result)); } -TEST_F(ConvertToHalfTest, DoNotReplaceStructMember) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4814 - - // This test is a case with a non-relaxed phi with a relaxed operand. - // A convert must be inserted at the end of the block associated with - // the operand. - const std::string test = - R"(OpCapability Shader -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %PSMain "PSMain" %out_var_SV_TARGET %MyConstants -OpExecutionMode %PSMain OriginUpperLeft -OpSource HLSL 600 -OpName %type_ConstantBuffer_myStruct "type.ConstantBuffer.myStruct" -OpMemberName %type_ConstantBuffer_myStruct 0 "f" -OpName %MyConstants "MyConstants" -OpName %out_var_SV_TARGET "out.var.SV_TARGET" -OpName %PSMain "PSMain" -OpDecorate %out_var_SV_TARGET Location 0 -OpDecorate %MyConstants DescriptorSet 1 -OpDecorate %MyConstants Binding 2 -OpMemberDecorate %type_ConstantBuffer_myStruct 0 Offset 0 -OpDecorate %type_ConstantBuffer_myStruct Block -%float = OpTypeFloat 32 -%type_ConstantBuffer_myStruct = OpTypeStruct %float -%_ptr_Uniform_type_ConstantBuffer_myStruct = OpTypePointer Uniform %type_ConstantBuffer_myStruct -%_ptr_Output_float = OpTypePointer Output %float -%void = OpTypeVoid -%9 = OpTypeFunction %void -%MyConstants = OpVariable %_ptr_Uniform_type_ConstantBuffer_myStruct Uniform -%out_var_SV_TARGET = OpVariable %_ptr_Output_float Output -%PSMain = OpFunction %void None %9 -%10 = OpLabel -%11 = OpLoad %type_ConstantBuffer_myStruct %MyConstants -%12 = OpCompositeExtract %float %11 0 -OpStore %out_var_SV_TARGET %12 -OpReturn -OpFunctionEnd -)"; - - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndCheck(test, test, true); -} - -TEST_F(ConvertToHalfTest, PreserveImageOperandPrecision) { - // Ensure that a non-relaxed texture coordinate does not get relaxed nor - // converted to half precision if the image instruction is marked relaxed. - - // Also ensure that a relaxed local variable does get converted to half - // precision before being passed to an image opeartor. - - // #version 310 es - // - // precision mediump float; - // - // layout(location = 10) in highp vec4 vertex_uv01; - // layout(binding = 0, set = 3) uniform sampler2D materialParams_baseColorMap; - // - // layout(location = 0) out vec4 fragColor; - // - // void main() { - // vec4 uv = vec4(2.0); - // fragColor = texture(materialParams_baseColorMap, uv.xy); - // fragColor = texture(materialParams_baseColorMap, vertex_uv01.xy); - // } - const std::string test = R"( - OpCapability Shader - OpCapability Float16 - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %4 "main" %13 %25 - OpExecutionMode %4 OriginUpperLeft - OpSource ESSL 310 - OpDecorate %9 RelaxedPrecision -;CHECK: OpDecorate [[uv:%\w+]] RelaxedPrecision - OpDecorate %13 Location 0 - OpDecorate %17 DescriptorSet 3 - OpDecorate %17 Binding 0 - OpDecorate %18 RelaxedPrecision - OpDecorate %23 RelaxedPrecision - OpDecorate %25 Location 10 - %2 = OpTypeVoid - %3 = OpTypeFunction %2 - %6 = OpTypeFloat 32 -;CHECK: [[float32_t:%\w+]] = OpTypeFloat 32 - %7 = OpTypeVector %6 4 -;CHECK: [[vec4_t:%\w+]] = OpTypeVector [[float32_t]] 4 - %8 = OpTypePointer Function %7 - %10 = OpConstant %6 2 - %11 = OpConstantComposite %7 %10 %10 %10 %10 - %12 = OpTypePointer Output %7 -;CHECK: [[output_ptr_t:%\w+]] = OpTypePointer Output [[vec4_t]] - %13 = OpVariable %12 Output -;CHECK: [[output:%\w+]] = OpVariable [[output_ptr_t]] Output - %14 = OpTypeImage %6 2D 0 0 0 1 Unknown - %15 = OpTypeSampledImage %14 - %16 = OpTypePointer UniformConstant %15 - %17 = OpVariable %16 UniformConstant - %19 = OpTypeVector %6 2 -;CHECK: [[vec2_t:%\w+]] = OpTypeVector [[float32_t]] 2 - %24 = OpTypePointer Input %7 -;CHECK: [[input_ptr_t:%\w+]] = OpTypePointer Input [[vec4_t]] - %25 = OpVariable %24 Input - %29 = OpTypeFloat 16 -;CHECK: [[float16_t:%\w+]] = OpTypeFloat 16 - %30 = OpTypeVector %29 4 - %33 = OpTypeVector %29 2 -;CHECK: [[vec2_16b_t:%\w+]] = OpTypeVector [[float16_t]] 2 - %4 = OpFunction %2 None %3 - %5 = OpLabel - -; The only Function storage variable is marked as relaxed - %9 = OpVariable %8 Function -;CHECK: [[uv]] = OpVariable {{%\w+}} Function - OpStore %9 %11 - %18 = OpLoad %15 %17 - %20 = OpLoad %7 %9 - %31 = OpFConvert %30 %20 - %32 = OpFConvert %30 %20 - -; The first sample op should get a 16b coordinate - %21 = OpVectorShuffle %33 %31 %32 0 1 -;CHECK: [[uv_16b:%\w+]] = OpVectorShuffle [[vec2_16b_t]] - %22 = OpImageSampleImplicitLod %7 %18 %21 -;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_16b]] - - OpStore %13 %22 - %23 = OpLoad %15 %17 - %26 = OpLoad %7 %25 - -; The second sample op should get a 32b coordinate - %27 = OpVectorShuffle %19 %26 %26 0 1 -;CHECK: [[uv_32b:%\w+]] = OpVectorShuffle [[vec2_t]] - %28 = OpImageSampleImplicitLod %7 %23 %27 -;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_32b]] - - OpStore %13 %28 - OpReturn - OpFunctionEnd - )"; - - SinglePassRunAndMatch(test, true); -} - } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/copy_prop_array_test.cpp b/test/opt/copy_prop_array_test.cpp index 2d4b7a3b..d6e376ec 100644 --- a/test/opt/copy_prop_array_test.cpp +++ b/test/opt/copy_prop_array_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dataflow.cpp b/test/opt/dataflow.cpp index dcb6bc6a..4742015a 100644 --- a/test/opt/dataflow.cpp +++ b/test/opt/dataflow.cpp @@ -17,6 +17,7 @@ #include #include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "opt/function_utils.h" #include "source/opt/build_module.h" @@ -65,7 +66,7 @@ struct BackwardReachability : public ForwardDataFlowAnalysis { VisitResult Visit(Instruction* inst) override { // Conditional branches can be enqueued from labels, so skip them. - if (inst->opcode() != spv::Op::OpLabel) + if (inst->opcode() != SpvOpLabel) return DataFlowAnalysis::VisitResult::kResultFixed; uint32_t id = inst->result_id(); VisitResult ret = DataFlowAnalysis::VisitResult::kResultFixed; diff --git a/test/opt/dead_insert_elim_test.cpp b/test/opt/dead_insert_elim_test.cpp index fcc3dde4..268e6590 100644 --- a/test/opt/dead_insert_elim_test.cpp +++ b/test/opt/dead_insert_elim_test.cpp @@ -736,113 +736,6 @@ OpFunctionEnd SinglePassRunAndMatch(text, true); } -TEST_F(DeadInsertElimTest, PhiOverEmptyStruct) { - // Reproducer for nullptr access error in MarkInsertChain - // that occurs when processing a phi operation with an - // empty struct result type. - // - // Note: Disassembly created from HLSL source with - // dxc -T cs_6_6 -spirv -Oconfig= - // --eliminate-dead-branches,--merge-return,--ssa-rewrite - // - // RWBuffer buf; - // - // struct S { }; - // - // S fn() { - // S s = (S)0; - // if (buf[0] > 0) { - // return s; - // } - // return s; - // } - // - // [numthreads(1,1,1)] - // void main() { - // fn(); - // } - - const std::string disassembly = - R"(OpCapability Shader - OpCapability SampledBuffer - OpCapability ImageBuffer - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - OpSource HLSL 660 - OpName %S "S" - OpName %type_buffer_image "type.buffer.image" - OpName %buf "buf" - OpName %main "main" - OpName %src_main "src.main" - OpName %bb_entry "bb.entry" - OpName %fn "fn" - OpName %bb_entry_0 "bb.entry" - OpName %s "s" - OpName %if_true "if.true" - OpName %if_merge "if.merge" - OpDecorate %buf DescriptorSet 0 - OpDecorate %buf Binding 0 - %S = OpTypeStruct - %4 = OpConstantNull %S - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %float = OpTypeFloat 32 - %float_0 = OpConstant %float 0 -%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 R32f -%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image - %void = OpTypeVoid - %12 = OpTypeFunction %void - %19 = OpTypeFunction %S -%_ptr_Function_S = OpTypePointer Function %S - %v4float = OpTypeVector %float 4 - %bool = OpTypeBool - %buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant - %false = OpConstantFalse %bool -%_ptr_Function_bool = OpTypePointer Function %bool - %true = OpConstantTrue %bool - %main = OpFunction %void None %12 - %13 = OpLabel - %14 = OpFunctionCall %void %src_main - OpReturn - OpFunctionEnd - %src_main = OpFunction %void None %12 - %bb_entry = OpLabel - %17 = OpFunctionCall %S %fn - OpReturn - OpFunctionEnd - %fn = OpFunction %S None %19 - %bb_entry_0 = OpLabel - %39 = OpVariable %_ptr_Function_bool Function %false - %34 = OpVariable %_ptr_Function_S Function - %s = OpVariable %_ptr_Function_S Function - OpSelectionMerge %33 None - OpSwitch %uint_0 %36 - %36 = OpLabel - OpStore %s %4 - %23 = OpLoad %type_buffer_image %buf - %25 = OpImageRead %v4float %23 %uint_0 None - %26 = OpCompositeExtract %float %25 0 - %28 = OpFOrdGreaterThan %bool %26 %float_0 - OpSelectionMerge %if_merge None - OpBranchConditional %28 %if_true %if_merge - %if_true = OpLabel - OpStore %39 %true - OpStore %34 %4 - OpBranch %33 - %if_merge = OpLabel - OpStore %39 %true - OpStore %34 %4 - OpBranch %33 - %33 = OpLabel - %41 = OpPhi %S %4 %if_true %4 %if_merge - OpReturnValue %41 - OpFunctionEnd -)"; - // Used to crash with a nullptr access violation when processing %41 - SinglePassRunToBinary(disassembly, true); -} - // TODO(greg-lunarg): Add tests to verify handling of these cases: // diff --git a/test/opt/debug_info_manager_test.cpp b/test/opt/debug_info_manager_test.cpp index 3df26a97..e87d0bea 100644 --- a/test/opt/debug_info_manager_test.cpp +++ b/test/opt/debug_info_manager_test.cpp @@ -15,8 +15,11 @@ #include "source/opt/debug_info_manager.h" #include +#include #include +#include "effcee/effcee.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/build_module.h" #include "source/opt/instruction.h" @@ -152,7 +155,7 @@ void main(float in_var_color : COLOR) { EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1); const uint32_t line_number = 77U; - Instruction line(context.get(), spv::Op::OpLine); + Instruction line(context.get(), SpvOpLine); line.SetInOperands({ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}}, @@ -275,7 +278,7 @@ OpFunctionEnd SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); const uint32_t line_number = 7U; - Instruction line(context.get(), spv::Op::OpLine); + Instruction line(context.get(), SpvOpLine); line.SetInOperands({ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}}, {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}}, diff --git a/test/opt/decoration_manager_test.cpp b/test/opt/decoration_manager_test.cpp index b287d5ec..c9fabe78 100644 --- a/test/opt/decoration_manager_test.cpp +++ b/test/opt/decoration_manager_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -87,7 +88,7 @@ class DecorationManagerTest : public ::testing::Test { std::string GetErrorMessage() const { return error_message_; } std::string ToText(const std::vector& inst) { - std::vector binary = {spv::MagicNumber, 0x10200, 0u, 2u, 0u}; + std::vector binary = {SpvMagicNumber, 0x10200, 0u, 2u, 0u}; for (const Instruction* i : inst) i->ToBinaryWithoutAttachedDebugInsts(&binary); std::string text; @@ -117,17 +118,16 @@ class DecorationManagerTest : public ::testing::Test { TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffOpcodesDecorateDecorateId) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); - // This parameter can be interpreted both as { spv::Decoration::Constant } + // This parameter can be interpreted both as { SpvDecorationConstant } // and also as a list of IDs: { 22 } - const std::vector param{ - static_cast(spv::Decoration::Constant)}; + const std::vector param{SpvDecorationConstant}; // OpDecorate %1 Constant Instruction inst1( - &ir_context, spv::Op::OpDecorate, 0u, 0u, + &ir_context, SpvOpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}}); // OpDecorateId %1 %22 ; 'Constant' is decoration number 22 Instruction inst2( - &ir_context, spv::Op::OpDecorateId, 0u, 0u, + &ir_context, SpvOpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, param}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); @@ -137,17 +137,16 @@ TEST_F(DecorationManagerTest, TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffOpcodesDecorateDecorateString) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); - // This parameter can be interpreted both as { spv::Decoration::Constant } + // This parameter can be interpreted both as { SpvDecorationConstant } // and also as a null-terminated string with a single character with value 22. - const std::vector param{ - static_cast(spv::Decoration::Constant)}; + const std::vector param{SpvDecorationConstant}; // OpDecorate %1 Constant Instruction inst1( - &ir_context, spv::Op::OpDecorate, 0u, 0u, + &ir_context, SpvOpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}}); // OpDecorateStringGOOGLE %1 !22 Instruction inst2( - &ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, + &ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, param}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); @@ -157,15 +156,13 @@ TEST_F(DecorationManagerTest, TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant - Instruction inst1( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpDecorate %1 Restrict - Instruction inst2( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Restrict)}}}); + Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationRestrict}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); @@ -175,11 +172,11 @@ TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateIdParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1( - &ir_context, spv::Op::OpDecorateId, 0u, 0u, + &ir_context, SpvOpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {555}}}); // OpDecorate %1 Restrict Instruction inst2( - &ir_context, spv::Op::OpDecorateId, 0u, 0u, + &ir_context, SpvOpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {666}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); @@ -189,11 +186,11 @@ TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateIdParam) { TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateStringParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant - Instruction inst1(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, + Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hello!")}}); // OpDecorate %1 Restrict - Instruction inst2(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, + Instruction inst2(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hellx")}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); @@ -204,15 +201,13 @@ TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateStringParam) { TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant - Instruction inst1( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpDecorate %2 Constant - Instruction inst2( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {2u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {2u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); @@ -221,10 +216,10 @@ TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) { TEST_F(DecorationManagerTest, ComparingSameDecorationIdsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); Instruction inst1( - &ir_context, spv::Op::OpDecorateId, 0u, 0u, + &ir_context, SpvOpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}}); Instruction inst2( - &ir_context, spv::Op::OpDecorateId, 0u, 0u, + &ir_context, SpvOpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); @@ -234,10 +229,10 @@ TEST_F(DecorationManagerTest, ComparingSameDecorationIdsOnDiffTargetAllowed) { TEST_F(DecorationManagerTest, ComparingSameDecorationStringsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); - Instruction inst1(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, + Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}}); - Instruction inst2(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, + Instruction inst2(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); @@ -248,15 +243,13 @@ TEST_F(DecorationManagerTest, TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant - Instruction inst1( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpDecorate %2 Constant - Instruction inst2( - &ir_context, spv::Op::OpDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {2u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {2u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false)); @@ -265,17 +258,15 @@ TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) { TEST_F(DecorationManagerTest, ComparingMemberDecorationsOnSameTypeDiffMember) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant - Instruction inst1( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpMemberDecorate %1 1 Constant - Instruction inst2( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); @@ -285,17 +276,15 @@ TEST_F(DecorationManagerTest, ComparingSameMemberDecorationsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant - Instruction inst1( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpMemberDecorate %2 0 Constant - Instruction inst2( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {2u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {2u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); @@ -305,17 +294,15 @@ TEST_F(DecorationManagerTest, ComparingSameMemberDecorationsOnDiffTargetDisallowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant - Instruction inst1( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {1u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {1u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); // OpMemberDecorate %2 0 Constant - Instruction inst2( - &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, - {{SPV_OPERAND_TYPE_ID, {2u}}, - {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, - {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); + Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u, + {{SPV_OPERAND_TYPE_ID, {2u}}, + {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, + {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false)); @@ -499,7 +486,7 @@ OpGroupDecorate %3 %1 DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) { - return inst.opcode() == spv::Op::OpDecorate && + return inst.opcode() == SpvOpDecorate && inst.GetSingleWordInOperand(0u) == 3u; }); auto decorations = decoManager->GetDecorationsFor(1u, false); @@ -550,10 +537,9 @@ OpGroupDecorate %3 %1 DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) { - return inst.opcode() == spv::Op::OpDecorate && + return inst.opcode() == SpvOpDecorate && inst.GetSingleWordInOperand(0u) == 3u && - spv::Decoration(inst.GetSingleWordInOperand(1u)) == - spv::Decoration::BuiltIn; + inst.GetSingleWordInOperand(1u) == SpvDecorationBuiltIn; }); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); @@ -777,7 +763,7 @@ OpFunctionEnd EXPECT_EQ(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); - decoManager->CloneDecorations(1u, 8u, {spv::Decoration::RelaxedPrecision}); + decoManager->CloneDecorations(1u, 8u, {SpvDecorationRelaxedPrecision}); decorations = decoManager->GetDecorationsFor(8u, false); EXPECT_THAT(GetErrorMessage(), ""); @@ -836,7 +822,7 @@ OpFunctionEnd EXPECT_EQ(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); - decoManager->CloneDecorations(2u, 9u, {spv::Decoration::RelaxedPrecision}); + decoManager->CloneDecorations(2u, 9u, {SpvDecorationRelaxedPrecision}); decorations = decoManager->GetDecorationsFor(9u, false); EXPECT_THAT(GetErrorMessage(), ""); diff --git a/test/opt/def_use_test.cpp b/test/opt/def_use_test.cpp index 5f7731be..0210095d 100644 --- a/test/opt/def_use_test.cpp +++ b/test/opt/def_use_test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include #include @@ -49,9 +50,9 @@ uint32_t NumUses(const std::unique_ptr& context, uint32_t id) { // // If |id| is used multiple times in a single instruction, that instruction's // opcode will appear a corresponding number of times. -std::vector GetUseOpcodes(const std::unique_ptr& context, - uint32_t id) { - std::vector opcodes; +std::vector GetUseOpcodes(const std::unique_ptr& context, + uint32_t id) { + std::vector opcodes; context->get_def_use_mgr()->ForEachUse( id, [&opcodes](Instruction* user, uint32_t) { opcodes.push_back(user->opcode()); @@ -98,7 +99,7 @@ void CheckDef(const InstDefUse& expected_defs_uses, const auto expected_def = expected_defs_uses.defs[i].second; ASSERT_EQ(1u, actual_defs.count(id)) << "expected to def id [" << id << "]"; auto def = actual_defs.at(id); - if (def->opcode() != spv::Op::OpConstant) { + if (def->opcode() != SpvOpConstant) { // Constants don't disassemble properly without a full context. EXPECT_EQ(expected_def, DisassembleInst(actual_defs.at(id))); } @@ -115,7 +116,7 @@ UserMap BuildAllUsers(const DefUseManager* mgr, uint32_t idBound) { for (uint32_t id = 0; id != idBound; ++id) { if (mgr->GetDef(id)) { mgr->ForEachUser(id, [id, &userMap](Instruction* user) { - if (user->opcode() != spv::Op::OpConstant) { + if (user->opcode() != SpvOpConstant) { userMap[id].push_back(user); } }); @@ -1297,23 +1298,21 @@ TEST(DefUseTest, OpSwitch) { { EXPECT_EQ(2u, NumUses(context, 6)); - std::vector opcodes = GetUseOpcodes(context, 6u); - EXPECT_THAT(opcodes, UnorderedElementsAre(spv::Op::OpSwitch, - spv::Op::OpReturnValue)); + std::vector opcodes = GetUseOpcodes(context, 6u); + EXPECT_THAT(opcodes, UnorderedElementsAre(SpvOpSwitch, SpvOpReturnValue)); } { EXPECT_EQ(6u, NumUses(context, 7)); - std::vector opcodes = GetUseOpcodes(context, 7u); + std::vector opcodes = GetUseOpcodes(context, 7u); // OpSwitch is now a user of %7. - EXPECT_THAT(opcodes, UnorderedElementsAre( - spv::Op::OpSelectionMerge, spv::Op::OpBranch, - spv::Op::OpBranch, spv::Op::OpBranch, - spv::Op::OpBranch, spv::Op::OpSwitch)); + EXPECT_THAT(opcodes, UnorderedElementsAre(SpvOpSelectionMerge, SpvOpBranch, + SpvOpBranch, SpvOpBranch, + SpvOpBranch, SpvOpSwitch)); } // Check all ids only used by OpSwitch after replacement. for (const auto id : {8u, 10u, 11u}) { EXPECT_EQ(1u, NumUses(context, id)); - EXPECT_EQ(spv::Op::OpSwitch, GetUseOpcodes(context, id).back()); + EXPECT_EQ(SpvOpSwitch, GetUseOpcodes(context, id).back()); } } @@ -1379,11 +1378,10 @@ TEST(AnalyzeInstDefUse, UseWithNoResultId) { // Analyze the instructions. DefUseManager manager(context.module()); - Instruction label(&context, spv::Op::OpLabel, 0, 2, {}); + Instruction label(&context, SpvOpLabel, 0, 2, {}); manager.AnalyzeInstDefUse(&label); - Instruction branch(&context, spv::Op::OpBranch, 0, 0, - {{SPV_OPERAND_TYPE_ID, {2}}}); + Instruction branch(&context, SpvOpBranch, 0, 0, {{SPV_OPERAND_TYPE_ID, {2}}}); manager.AnalyzeInstDefUse(&branch); context.module()->SetIdBound(3); @@ -1411,7 +1409,7 @@ TEST(AnalyzeInstDefUse, AddNewInstruction) { // Analyze the instructions. DefUseManager manager(context->module()); - Instruction newInst(context.get(), spv::Op::OpConstantTrue, 1, 2, {}); + Instruction newInst(context.get(), SpvOpConstantTrue, 1, 2, {}); manager.AnalyzeInstDefUse(&newInst); InstDefUse expected = { @@ -1705,7 +1703,7 @@ TEST_F(UpdateUsesTest, KeepOldUses) { DefUseManager* def_use_mgr = context->get_def_use_mgr(); Instruction* def = def_use_mgr->GetDef(9); Instruction* use = def_use_mgr->GetDef(10); - def->SetOpcode(spv::Op::OpCopyObject); + def->SetOpcode(SpvOpCopyObject); def->SetInOperands({{SPV_OPERAND_TYPE_ID, {25}}}); context->UpdateDefUse(def); diff --git a/test/opt/desc_sroa_test.cpp b/test/opt/desc_sroa_test.cpp index 7a118f98..91c950e8 100644 --- a/test/opt/desc_sroa_test.cpp +++ b/test/opt/desc_sroa_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/dominator_tree/common_dominators.cpp b/test/opt/dominator_tree/common_dominators.cpp index 9573afa2..dfa03e98 100644 --- a/test/opt/dominator_tree/common_dominators.cpp +++ b/test/opt/dominator_tree/common_dominators.cpp @@ -13,7 +13,9 @@ // limitations under the License. #include +#include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/build_module.h" #include "source/opt/ir_context.h" diff --git a/test/opt/dominator_tree/generated.cpp b/test/opt/dominator_tree/generated.cpp index 2a5bc98a..4fccef05 100644 --- a/test/opt/dominator_tree/generated.cpp +++ b/test/opt/dominator_tree/generated.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include diff --git a/test/opt/dominator_tree/nested_ifs.cpp b/test/opt/dominator_tree/nested_ifs.cpp index 848296a2..0552b758 100644 --- a/test/opt/dominator_tree/nested_ifs.cpp +++ b/test/opt/dominator_tree/nested_ifs.cpp @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. + #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/nested_ifs_post.cpp b/test/opt/dominator_tree/nested_ifs_post.cpp index 217bdece..ad759df8 100644 --- a/test/opt/dominator_tree/nested_ifs_post.cpp +++ b/test/opt/dominator_tree/nested_ifs_post.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/nested_loops.cpp b/test/opt/dominator_tree/nested_loops.cpp index a82f4095..7d03937b 100644 --- a/test/opt/dominator_tree/nested_loops.cpp +++ b/test/opt/dominator_tree/nested_loops.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/nested_loops_with_unreachables.cpp b/test/opt/dominator_tree/nested_loops_with_unreachables.cpp index 2c91bd1e..e87e8dda 100644 --- a/test/opt/dominator_tree/nested_loops_with_unreachables.cpp +++ b/test/opt/dominator_tree/nested_loops_with_unreachables.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/post.cpp b/test/opt/dominator_tree/post.cpp index acbf0127..bb10fdef 100644 --- a/test/opt/dominator_tree/post.cpp +++ b/test/opt/dominator_tree/post.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/simple.cpp b/test/opt/dominator_tree/simple.cpp index eae24385..d11854d5 100644 --- a/test/opt/dominator_tree/simple.cpp +++ b/test/opt/dominator_tree/simple.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/switch_case_fallthrough.cpp b/test/opt/dominator_tree/switch_case_fallthrough.cpp index 9eeb4103..d9dd7d16 100644 --- a/test/opt/dominator_tree/switch_case_fallthrough.cpp +++ b/test/opt/dominator_tree/switch_case_fallthrough.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/unreachable_for.cpp b/test/opt/dominator_tree/unreachable_for.cpp index bf95930d..469e5c14 100644 --- a/test/opt/dominator_tree/unreachable_for.cpp +++ b/test/opt/dominator_tree/unreachable_for.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/dominator_tree/unreachable_for_post.cpp b/test/opt/dominator_tree/unreachable_for_post.cpp index 57278f50..8d3e37b4 100644 --- a/test/opt/dominator_tree/unreachable_for_post.cpp +++ b/test/opt/dominator_tree/unreachable_for_post.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/eliminate_dead_const_test.cpp b/test/opt/eliminate_dead_const_test.cpp index ec4c284e..87aab545 100644 --- a/test/opt/eliminate_dead_const_test.cpp +++ b/test/opt/eliminate_dead_const_test.cpp @@ -13,6 +13,9 @@ // limitations under the License. #include +#include +#include +#include #include #include #include diff --git a/test/opt/eliminate_dead_functions_test.cpp b/test/opt/eliminate_dead_functions_test.cpp index e9f79a10..96deb2a6 100644 --- a/test/opt/eliminate_dead_functions_test.cpp +++ b/test/opt/eliminate_dead_functions_test.cpp @@ -517,39 +517,6 @@ OpFunctionEnd SinglePassRunAndMatch(text, true); } -TEST_F(EliminateDeadFunctionsBasicTest, DependentNonSemanticChain) { - const std::string text = R"( -; CHECK: OpEntryPoint GLCompute [[main:%\w+]] -; CHECK: [[main]] = OpFunction -; CHECK-NOT: = OpFunction -; CHECK: [[ext1:%\w+]] = OpExtInst %void {{%\w+}} 1 [[main]] -; CHECK: [[ext2:%\w+]] = OpExtInst %void {{%\w+}} 2 [[ext1]] -; CHECK: [[ext3:%\w+]] = OpExtInst %void {{%\w+}} 3 [[ext1]] [[ext2]] -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%1 = OpExtInstImport "NonSemantic.Test" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%main_entry = OpLabel -OpReturn -OpFunctionEnd -%dead = OpFunction %void None %void_fn -%dead_entry = OpLabel -OpReturn -OpFunctionEnd -%2 = OpExtInst %void %1 1 %main -%3 = OpExtInst %void %1 2 %2 -%4 = OpExtInst %void %1 3 %2 %3 -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_0); - SinglePassRunAndMatch(text, true); -} - } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/eliminate_dead_input_components_test.cpp b/test/opt/eliminate_dead_input_components_test.cpp new file mode 100644 index 00000000..822914a8 --- /dev/null +++ b/test/opt/eliminate_dead_input_components_test.cpp @@ -0,0 +1,468 @@ +// Copyright (c) 2022 The Khronos Group Inc. +// Copyright (c) 2022 LunarG Inc. +// +// 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 "gmock/gmock.h" +#include "test/opt/pass_fixture.h" +#include "test/opt/pass_utils.h" + +namespace spvtools { +namespace opt { +namespace { + +using ElimDeadInputComponentsTest = PassTest<::testing::Test>; + +TEST_F(ElimDeadInputComponentsTest, ElimOneConstantIndex) { + // Should reduce to uv[2] + // + // #version 450 + // + // layout(location = 0) in vec4 uv[8]; + // + // out gl_PerVertex { + // vec4 gl_Position; + // }; + // + // void main() + // { + // gl_Position = uv[1]; + // } + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 + %21 = OpLoad %v4float %20 + %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %23 %21 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, ElimOneConstantIndexInBounds) { + // Same as ElimOneConstantIndex but with OpInBoundsAccessChain + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpInBoundsAccessChain %_ptr_Input_v4float %uv %int_1 + %21 = OpLoad %v4float %20 + %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %23 %21 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, ElimTwoConstantIndices) { + // Should reduce to uv[4] + // + // #version 450 + // + // layout(location = 0) in vec4 uv[8]; + // + // out gl_PerVertex { + // vec4 gl_Position; + // }; + // + // void main() + // { + // gl_Position = uv[1] + uv[3]; + // } + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %int_3 = OpConstant %int 3 +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_4 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 + %21 = OpLoad %v4float %20 + %23 = OpAccessChain %_ptr_Input_v4float %uv %int_3 + %24 = OpLoad %v4float %23 + %25 = OpFAdd %v4float %21 %24 + %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %27 %25 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, NoElimMaxConstantIndex) { + // Should not reduce uv[8] because of max index of 7 + // + // #version 450 + // + // layout(location = 0) in vec4 uv[8]; + // + // out gl_PerVertex { + // vec4 gl_Position; + // }; + // + // void main() + // { + // gl_Position = uv[1] + uv[7]; + // } + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %int_7 = OpConstant %int 7 +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 + %21 = OpLoad %v4float %20 + %23 = OpAccessChain %_ptr_Input_v4float %uv %int_7 + %24 = OpLoad %v4float %23 + %25 = OpFAdd %v4float %21 %24 + %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %27 %25 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, NoElimNonConstantIndex) { + // Should not reduce uv[8] because of non-constant index of ui + // + // #version 450 + // + // layout(location = 0) in vec4 uv[8]; + // + // out gl_PerVertex { + // vec4 gl_Position; + // }; + // + // uniform ubname { + // int ui; + // } ubinst; + // + // void main() + // { + // gl_Position = uv[1] + uv[ubinst.ui]; + // } + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv %ubinst + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpName %ubname "ubname" + OpMemberName %ubname 0 "ui" + OpName %ubinst "ubinst" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + OpMemberDecorate %ubname 0 Offset 0 + OpDecorate %ubname Block + OpDecorate %ubinst DescriptorSet 0 + OpDecorate %ubinst Binding 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %ubname = OpTypeStruct %int +%_ptr_Uniform_ubname = OpTypePointer Uniform %ubname + %ubinst = OpVariable %_ptr_Uniform_ubname Uniform +%_ptr_Uniform_int = OpTypePointer Uniform %int +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 + %21 = OpLoad %v4float %20 + %26 = OpAccessChain %_ptr_Uniform_int %ubinst %int_0 + %27 = OpLoad %int %26 + %28 = OpAccessChain %_ptr_Input_v4float %uv %27 + %29 = OpLoad %v4float %28 + %30 = OpFAdd %v4float %21 %29 + %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %32 %30 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, NoElimNonIndexedAccessChain) { + // Should not change due to non-indexed access chain + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %uv + OpSource GLSL 450 + OpName %main "main" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpName %_ "" + OpName %uv "uv" + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpDecorate %gl_PerVertex Block + OpDecorate %uv Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%gl_PerVertex = OpTypeStruct %v4float +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %uint = OpTypeInt 32 0 + %uint_8 = OpConstant %uint 8 +%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 +%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 + %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input + %main = OpFunction %void None %3 + %5 = OpLabel + %20 = OpAccessChain %_ptr_Input__arr_v4float_uint_8 %uv + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +TEST_F(ElimDeadInputComponentsTest, ElimStructMember) { + // Should eliminate uv + // + // #version 450 + // + // in Vertex { + // vec4 Cd; + // vec2 uv; + // } iVert; + // + // out vec4 fragColor; + // + // void main() + // { + // vec4 color = vec4(iVert.Cd); + // fragColor = color; + // } + const std::string text = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %iVert %fragColor + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %Vertex "Vertex" + OpMemberName %Vertex 0 "Cd" + OpMemberName %Vertex 1 "uv" + OpName %iVert "iVert" + OpName %fragColor "fragColor" + OpDecorate %Vertex Block + OpDecorate %iVert Location 0 + OpDecorate %fragColor Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %v2float = OpTypeVector %float 2 + %Vertex = OpTypeStruct %v4float %v2float +; CHECK: %Vertex = OpTypeStruct %v4float %v2float +; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float +%_ptr_Input_Vertex = OpTypePointer Input %Vertex +; CHECK: [[pty:%\w+]] = OpTypePointer Input [[sty]] + %iVert = OpVariable %_ptr_Input_Vertex Input +; CHECK: %iVert = OpVariable [[pty]] Input + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float + %fragColor = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %3 + %5 = OpLabel + %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 + %18 = OpLoad %v4float %17 + OpStore %fragColor %18 + OpReturn + OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_3); + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(text, true); +} + +} // namespace +} // namespace opt +} // namespace spvtools diff --git a/test/opt/eliminate_dead_io_components_test.cpp b/test/opt/eliminate_dead_io_components_test.cpp deleted file mode 100755 index b7a2fb50..00000000 --- a/test/opt/eliminate_dead_io_components_test.cpp +++ /dev/null @@ -1,1253 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using ElimDeadIOComponentsTest = PassTest<::testing::Test>; - -TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndex) { - // Should reduce to uv[2] - // - // #version 450 - // - // layout(location = 0) in vec4 uv[8]; - // - // out gl_PerVertex { - // vec4 gl_Position; - // }; - // - // void main() - // { - // gl_Position = uv[1]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 - %21 = OpLoad %v4float %20 - %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %23 %21 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, ElimOneConstantIndexInBounds) { - // Same as ElimOneConstantIndex but with OpInBoundsAccessChain - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_2 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpInBoundsAccessChain %_ptr_Input_v4float %uv %int_1 - %21 = OpLoad %v4float %20 - %23 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %23 %21 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, ElimTwoConstantIndices) { - // Should reduce to uv[4] - // - // #version 450 - // - // layout(location = 0) in vec4 uv[8]; - // - // out gl_PerVertex { - // vec4 gl_Position; - // }; - // - // void main() - // { - // gl_Position = uv[1] + uv[3]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_3 = OpConstant %int 3 -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK-NOT: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_4 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 - %21 = OpLoad %v4float %20 - %23 = OpAccessChain %_ptr_Input_v4float %uv %int_3 - %24 = OpLoad %v4float %23 - %25 = OpFAdd %v4float %21 %24 - %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %27 %25 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, NoElimMaxConstantIndex) { - // Should not reduce uv[8] because of max index of 7 - // - // #version 450 - // - // layout(location = 0) in vec4 uv[8]; - // - // out gl_PerVertex { - // vec4 gl_Position; - // }; - // - // void main() - // { - // gl_Position = uv[1] + uv[7]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %int_7 = OpConstant %int 7 -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 - %21 = OpLoad %v4float %20 - %23 = OpAccessChain %_ptr_Input_v4float %uv %int_7 - %24 = OpLoad %v4float %23 - %25 = OpFAdd %v4float %21 %24 - %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %27 %25 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, NoElimNonConstantIndex) { - // Should not reduce uv[8] because of non-constant index of ui - // - // #version 450 - // - // layout(location = 0) in vec4 uv[8]; - // - // out gl_PerVertex { - // vec4 gl_Position; - // }; - // - // uniform ubname { - // int ui; - // } ubinst; - // - // void main() - // { - // gl_Position = uv[1] + uv[ubinst.ui]; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv %ubinst - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpName %ubname "ubname" - OpMemberName %ubname 0 "ui" - OpName %ubinst "ubinst" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - OpMemberDecorate %ubname 0 Offset 0 - OpDecorate %ubname Block - OpDecorate %ubinst DescriptorSet 0 - OpDecorate %ubinst Binding 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %ubname = OpTypeStruct %int -%_ptr_Uniform_ubname = OpTypePointer Uniform %ubname - %ubinst = OpVariable %_ptr_Uniform_ubname Uniform -%_ptr_Uniform_int = OpTypePointer Uniform %int -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpAccessChain %_ptr_Input_v4float %uv %int_1 - %21 = OpLoad %v4float %20 - %26 = OpAccessChain %_ptr_Uniform_int %ubinst %int_0 - %27 = OpLoad %int %26 - %28 = OpAccessChain %_ptr_Input_v4float %uv %27 - %29 = OpLoad %v4float %28 - %30 = OpFAdd %v4float %21 %29 - %32 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %32 %30 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, NoElimNonIndexedAccessChain) { - // Should not change due to non-indexed access chain - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %uv - OpSource GLSL 450 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %uv "uv" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8 -%_ptr_Input__arr_v4float_uint_8 = OpTypePointer Input %_arr_v4float_uint_8 - %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK: %uv = OpVariable %_ptr_Input__arr_v4float_uint_8 Input - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpAccessChain %_ptr_Input__arr_v4float_uint_8 %uv - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, ElimStructMember) { - // Should eliminate uv - // - // #version 450 - // - // in Vertex { - // vec4 Cd; - // vec2 uv; - // } iVert; - // - // out vec4 fragColor; - // - // void main() - // { - // vec4 color = vec4(iVert.Cd); - // fragColor = color; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %iVert %fragColor - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "Cd" - OpMemberName %Vertex 1 "uv" - OpName %iVert "iVert" - OpName %fragColor "fragColor" - OpDecorate %Vertex Block - OpDecorate %iVert Location 0 - OpDecorate %fragColor Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v2float = OpTypeVector %float 2 - %Vertex = OpTypeStruct %v4float %v2float -; CHECK: %Vertex = OpTypeStruct %v4float %v2float -; CHECK: %Vertex_0 = OpTypeStruct %v4float -%_ptr_Input_Vertex = OpTypePointer Input %Vertex -; CHECK: [[pty:%\w+]] = OpTypePointer Input %Vertex_0 - %iVert = OpVariable %_ptr_Input_Vertex Input -; CHECK: %iVert = OpVariable [[pty]] Input - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %fragColor = OpVariable %_ptr_Output_v4float Output - %main = OpFunction %void None %3 - %5 = OpLabel - %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 - %18 = OpLoad %v4float %17 - OpStore %fragColor %18 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, ElimOutputStructMember) { - // Should eliminate uv from Vertex and all but gl_Position from gl_PerVertex - // - // #version 450 - // - // out Vertex { - // vec4 Cd; - // vec2 uv; - // } oVert; - // - // in vec3 P; - // - // void main() - // { - // vec4 worldSpacePos = vec4(P, 1); - // oVert.Cd = vec4(1, 0.5, 0, 1); - // gl_Position = worldSpacePos; - // } - - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %P %oVert %_ - OpSource GLSL 450 - OpName %main "main" - OpName %P "P" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "Cd" - OpMemberName %Vertex 1 "uv" - OpName %oVert "oVert" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpDecorate %P Location 0 - OpDecorate %Vertex Block - OpDecorate %oVert Location 0 - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 -%_ptr_Input_v3float = OpTypePointer Input %v3float - %P = OpVariable %_ptr_Input_v3float Input - %float_1 = OpConstant %float 1 - %v2float = OpTypeVector %float 2 - %Vertex = OpTypeStruct %v4float %v2float -%_ptr_Output_Vertex = OpTypePointer Output %Vertex - %oVert = OpVariable %_ptr_Output_Vertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %float_0_5 = OpConstant %float 0.5 - %float_0 = OpConstant %float 0 - %27 = OpConstantComposite %v4float %float_1 %float_0_5 %float_0 %float_1 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output -; CHECK: %Vertex = OpTypeStruct %v4float %v2float -; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -; CHECK: %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex -; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float -; CHECK: [[pty:%\w+]] = OpTypePointer Output [[sty]] -; CHECK: %oVert = OpVariable [[pty]] Output -; CHECK: [[sty2:%\w+]] = OpTypeStruct %v4float -; CHECK: [[pty2:%\w+]] = OpTypePointer Output [[sty2]] -; CHECK: %_ = OpVariable [[pty2]] Output - %main = OpFunction %void None %3 - %5 = OpLabel - %13 = OpLoad %v3float %P - %15 = OpCompositeExtract %float %13 0 - %16 = OpCompositeExtract %float %13 1 - %17 = OpCompositeExtract %float %13 2 - %18 = OpCompositeConstruct %v4float %15 %16 %17 %float_1 - %29 = OpAccessChain %_ptr_Output_v4float %oVert %int_0 - OpStore %29 %27 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %18 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Output, false); -} - -TEST_F(ElimDeadIOComponentsTest, ElimOutputArrayMembers) { - // Should reduce to uv[2] - // - // #version 450 - // - // layout(location = 0) out vec2 uv[8]; - // - // void main() - // { - // uv[1] = vec2(1, 0.5); - // } - - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %uv - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %uv "uv" - OpDecorate %uv Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v2float = OpTypeVector %float 2 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_v2float_uint_8 = OpTypeArray %v2float %uint_8 -%_ptr_Output__arr_v2float_uint_8 = OpTypePointer Output %_arr_v2float_uint_8 - %uv = OpVariable %_ptr_Output__arr_v2float_uint_8 Output -;CHECK-NOT: %uv = OpVariable %_ptr_Output__arr_v2float_uint_8 Output -;CHECK: %uv = OpVariable %_ptr_Output__arr_v2float_uint_2 Output - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 - %float_1 = OpConstant %float 1 - %float_0_5 = OpConstant %float 0.5 - %17 = OpConstantComposite %v2float %float_1 %float_0_5 -%_ptr_Output_v2float = OpTypePointer Output %v2float - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpAccessChain %_ptr_Output_v2float %uv %int_1 - OpStore %19 %17 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Output, false); -} - -TEST_F(ElimDeadIOComponentsTest, VertexOnly) { - // Should NOT eliminate uv - // - // #version 450 - // - // in Vertex { - // vec4 Cd; - // vec2 uv; - // } iVert; - // - // out vec4 fragColor; - // - // void main() - // { - // vec4 color = vec4(iVert.Cd); - // fragColor = color; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %iVert %fragColor - OpExecutionMode %main OriginUpperLeft - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "Cd" - OpMemberName %Vertex 1 "uv" - OpName %iVert "iVert" - OpName %fragColor "fragColor" - OpDecorate %Vertex Block - OpDecorate %iVert Location 0 - OpDecorate %fragColor Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v2float = OpTypeVector %float 2 - %Vertex = OpTypeStruct %v4float %v2float -; CHECK: %Vertex = OpTypeStruct %v4float %v2float -%_ptr_Input_Vertex = OpTypePointer Input %Vertex -; CHECK: %_ptr_Input_Vertex = OpTypePointer Input %Vertex - %iVert = OpVariable %_ptr_Input_Vertex Input -; CHECK: %iVert = OpVariable %_ptr_Input_Vertex Input - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %fragColor = OpVariable %_ptr_Output_v4float Output - %main = OpFunction %void None %3 - %5 = OpLabel - %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0 - %18 = OpLoad %v4float %17 - OpStore %fragColor %18 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, true); -} - -TEST_F(ElimDeadIOComponentsTest, TescInput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_in[] - // - // #version 450 - // - // layout (vertices = 4) out; - // - // void main() - // { - // vec4 pos = gl_in[gl_InvocationID].gl_Position; - // gl_out[gl_InvocationID].gl_Position = pos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %gl_in %gl_InvocationID %gl_out - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %pos "pos" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %gl_in "gl_in" - OpName %gl_InvocationID "gl_InvocationID" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpName %gl_out "gl_out" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 - %uint_32 = OpConstant %uint 32 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%gl_PerVertex_0 = OpTypeStruct %v4float - %uint_4 = OpConstant %uint 4 -%_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4 -%_ptr_Output__arr_gl_PerVertex_0_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_4 - %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_4 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float -; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float -; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_32 -; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]] -; CHECK: %gl_in = OpVariable [[pasty]] Input - %main = OpFunction %void None %3 - %5 = OpLabel - %pos = OpVariable %_ptr_Function_v4float Function - %21 = OpLoad %int %gl_InvocationID - %24 = OpAccessChain %_ptr_Input_v4float %gl_in %21 %int_0 - %25 = OpLoad %v4float %24 - OpStore %pos %25 - %31 = OpLoad %int %gl_InvocationID - %32 = OpLoad %v4float %pos - %34 = OpAccessChain %_ptr_Output_v4float %gl_out %31 %int_0 - OpStore %34 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, TescOutput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_out[] - // - // #version 450 - // - // layout (vertices = 4) out; - // - // void main() - // { - // vec4 pos = gl_in[gl_InvocationID].gl_Position; - // gl_out[gl_InvocationID].gl_Position = pos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %gl_in %gl_InvocationID %gl_out - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %pos "pos" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %gl_in "gl_in" - OpName %gl_InvocationID "gl_InvocationID" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpMemberName %gl_PerVertex_0 1 "gl_PointSize" - OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" - OpName %gl_out "gl_out" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float - %uint_32 = OpConstant %uint 32 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 - %uint_4 = OpConstant %uint 4 -%_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4 -%_ptr_Output__arr_gl_PerVertex_0_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_4 - %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_4 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float -; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float -; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_4 -; CHECK: [[pasty:%\w+]] = OpTypePointer Output [[asty]] -; CHECK: %gl_out = OpVariable [[pasty]] Output - %main = OpFunction %void None %3 - %5 = OpLabel - %pos = OpVariable %_ptr_Function_v4float Function - %21 = OpLoad %int %gl_InvocationID - %24 = OpAccessChain %_ptr_Input_v4float %gl_in %21 %int_0 - %25 = OpLoad %v4float %24 - OpStore %pos %25 - %31 = OpLoad %int %gl_InvocationID - %32 = OpLoad %v4float %pos - %34 = OpAccessChain %_ptr_Output_v4float %gl_out %31 %int_0 - OpStore %34 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Output, false); -} - -TEST_F(ElimDeadIOComponentsTest, TeseInput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_in[] - // - // #version 450 - // - // layout(triangles, ccw) in; - // layout(fractional_odd_spacing) in; - // layout(point_mode) in; - // - // void main() - // { - // vec4 p = gl_in[1].gl_Position; - // gl_Position = p; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationEvaluation %main "main" %gl_in %_ - OpExecutionMode %main Triangles - OpExecutionMode %main SpacingFractionalOdd - OpExecutionMode %main VertexOrderCcw - OpExecutionMode %main PointMode - OpSource GLSL 450 - OpName %main "main" - OpName %p "p" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %gl_in "gl_in" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpName %_ "" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 - %uint_32 = OpConstant %uint 32 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%gl_PerVertex_0 = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0 - %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float -; CHECK: %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -; CHECK: [[sty:%\w+]] = OpTypeStruct %v4float -; CHECK: [[asty:%\w+]] = OpTypeArray [[sty]] %uint_32 -; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]] -; CHECK: %gl_in = OpVariable [[pasty]] Input - %main = OpFunction %void None %3 - %5 = OpLabel - %p = OpVariable %_ptr_Function_v4float Function - %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0 - %23 = OpLoad %v4float %22 - OpStore %p %23 - %27 = OpLoad %v4float %p - %29 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %29 %27 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, TeseOutput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_out - // - // #version 450 - // - // layout(triangles, ccw) in; - // layout(fractional_odd_spacing) in; - // layout(point_mode) in; - // - // void main() - // { - // vec4 p = gl_in[1].gl_Position; - // gl_Position = p; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationEvaluation %main "main" %gl_in %_ - OpExecutionMode %main Triangles - OpExecutionMode %main SpacingFractionalOdd - OpExecutionMode %main VertexOrderCcw - OpExecutionMode %main PointMode - OpSource GLSL 450 - OpName %main "main" - OpName %p "p" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %gl_in "gl_in" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpMemberName %gl_PerVertex_0 1 "gl_PointSize" - OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" - OpName %_ "" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float - %uint_32 = OpConstant %uint 32 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 - %int_0 = OpConstant %int 0 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0 - %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output -%_ptr_Output_v4float = OpTypePointer Output %v4float -; CHECK: %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex -; CHECK: %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %main = OpFunction %void None %3 - %5 = OpLabel - %p = OpVariable %_ptr_Function_v4float Function - %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0 - %23 = OpLoad %v4float %22 - OpStore %p %23 - %27 = OpLoad %v4float %p - %29 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %29 %27 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Output, false); -} - -TEST_F(ElimDeadIOComponentsTest, GeomInput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_in[] - // - // #version 450 - // - // layout(triangle_strip, max_vertices = 3) out; - // layout(triangles) in; - // - // void main() - // { - // for (int i = 0; i < 3; i++) - // { - // gl_Position = gl_in[i].gl_Position; - // EmitVertex(); - // } - // EndPrimitive(); - // } - const std::string text = R"( - OpCapability Geometry - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Geometry %main "main" %_ %gl_in - OpExecutionMode %main Triangles - OpExecutionMode %main Invocations 1 - OpExecutionMode %main OutputTriangleStrip - OpExecutionMode %main OutputVertices 3 - OpSource GLSL 460 - OpName %main "main" - OpName %i "i" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpName %_ "" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpMemberName %gl_PerVertex_0 1 "gl_PointSize" - OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" - OpName %gl_in "gl_in" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_3 = OpConstant %int 3 - %bool = OpTypeBool - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output -%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 - %uint_3 = OpConstant %uint 3 -%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 -%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -; CHECK: [[asty:%\w+]] = OpTypeArray %gl_PerVertex %uint_3 -; CHECK: [[pasty:%\w+]] = OpTypePointer Input [[asty]] -; CHECK: %gl_in = OpVariable [[pasty]] Input - %main = OpFunction %void None %3 - %5 = OpLabel - %i = OpVariable %_ptr_Function_int Function - OpStore %i %int_0 - OpBranch %10 - %10 = OpLabel - OpLoopMerge %12 %13 None - OpBranch %14 - %14 = OpLabel - %15 = OpLoad %int %i - %18 = OpSLessThan %bool %15 %int_3 - OpBranchConditional %18 %11 %12 - %11 = OpLabel - %32 = OpLoad %int %i - %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0 - %35 = OpLoad %v4float %34 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %35 - OpEmitVertex - OpBranch %13 - %13 = OpLabel - %38 = OpLoad %int %i - %40 = OpIAdd %int %38 %int_1 - OpStore %i %40 - OpBranch %10 - %12 = OpLabel - OpEndPrimitive - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Input, false); -} - -TEST_F(ElimDeadIOComponentsTest, GeomOutput) { - // Eliminate PointSize, ClipDistance, CullDistance from gl_out - // - // #version 450 - // - // layout(triangle_strip, max_vertices = 3) out; - // layout(triangles) in; - // - // void main() - // { - // for (int i = 0; i < 3; i++) - // { - // gl_Position = gl_in[i].gl_Position; - // EmitVertex(); - // } - // EndPrimitive(); - // } - const std::string text = R"( - OpCapability Geometry - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Geometry %main "main" %_ %gl_in - OpExecutionMode %main Triangles - OpExecutionMode %main Invocations 1 - OpExecutionMode %main OutputTriangleStrip - OpExecutionMode %main OutputVertices 3 - OpSource GLSL 460 - OpName %main "main" - OpName %i "i" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpName %gl_in "gl_in" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_3 = OpConstant %int 3 - %bool = OpTypeBool - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output -%gl_PerVertex_0 = OpTypeStruct %v4float - %uint_3 = OpConstant %uint 3 -%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 -%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -; CHECK: %_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0 -; CHECK: %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output - %main = OpFunction %void None %3 - %5 = OpLabel - %i = OpVariable %_ptr_Function_int Function - OpStore %i %int_0 - OpBranch %10 - %10 = OpLabel - OpLoopMerge %12 %13 None - OpBranch %14 - %14 = OpLabel - %15 = OpLoad %int %i - %18 = OpSLessThan %bool %15 %int_3 - OpBranchConditional %18 %11 %12 - %11 = OpLabel - %32 = OpLoad %int %i - %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0 - %35 = OpLoad %v4float %34 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %35 - OpEmitVertex - OpBranch %13 - %13 = OpLabel - %38 = OpLoad %int %i - %40 = OpIAdd %int %38 %int_1 - OpStore %i %40 - OpBranch %10 - %12 = OpLabel - OpEndPrimitive - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - text, true, spv::StorageClass::Output, false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/eliminate_dead_member_test.cpp b/test/opt/eliminate_dead_member_test.cpp index bb0ec039..e277999e 100644 --- a/test/opt/eliminate_dead_member_test.cpp +++ b/test/opt/eliminate_dead_member_test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include "assembly_builder.h" +#include "gmock/gmock.h" #include "pass_fixture.h" #include "pass_utils.h" @@ -977,7 +978,6 @@ TEST_F(EliminateDeadMemberTest, RemoveMemberPtrAccessChain) { OpMemberDecorate %type__Globals 1 Offset 4 OpMemberDecorate %type__Globals 2 Offset 16 OpDecorate %type__Globals Block - OpDecorate %_ptr_Uniform_type__Globals ArrayStride 8 %uint = OpTypeInt 32 0 %uint_0 = OpConstant %uint 0 %uint_1 = OpConstant %uint 1 diff --git a/test/opt/eliminate_dead_output_stores_test.cpp b/test/opt/eliminate_dead_output_stores_test.cpp deleted file mode 100755 index 4c2e44c0..00000000 --- a/test/opt/eliminate_dead_output_stores_test.cpp +++ /dev/null @@ -1,951 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// Copyright (c) 2022 LunarG Inc. -// -// 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 "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using ElimDeadOutputStoresTest = PassTest<::testing::Test>; - -TEST_F(ElimDeadOutputStoresTest, VertMultipleLocations) { - // #version 450 - // - // layout(location = 2) out Vertex - // { - // vec4 color0; - // vec4 color1; - // vec4 color2[3]; - // } oVert; - // - // void main() - // { - // oVert.color0 = vec4(0.0,0.0,0.0,0.0); - // oVert.color1 = vec4(0.1,0.0,0.0,0.0); - // oVert.color2[0] = vec4(0.2,0.0,0.0,0.0); - // oVert.color2[1] = vec4(0.3,0.0,0.0,0.0); - // oVert.color2[2] = vec4(0.4,0.0,0.0,0.0); - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %oVert - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpName %oVert "oVert" - OpDecorate %Vertex Block - OpDecorate %oVert Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_3 = OpConstant %uint 3 -%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3 - %Vertex = OpTypeStruct %v4float %v4float %_arr_v4float_uint_3 -%_ptr_Output_Vertex = OpTypePointer Output %Vertex - %oVert = OpVariable %_ptr_Output_Vertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %float_0 = OpConstant %float 0 - %17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -%float_0_100000001 = OpConstant %float 0.100000001 - %22 = OpConstantComposite %v4float %float_0_100000001 %float_0 %float_0 %float_0 - %int_2 = OpConstant %int 2 -%float_0_200000003 = OpConstant %float 0.200000003 - %26 = OpConstantComposite %v4float %float_0_200000003 %float_0 %float_0 %float_0 -%float_0_300000012 = OpConstant %float 0.300000012 - %29 = OpConstantComposite %v4float %float_0_300000012 %float_0 %float_0 %float_0 -%float_0_400000006 = OpConstant %float 0.400000006 - %32 = OpConstantComposite %v4float %float_0_400000006 %float_0 %float_0 %float_0 - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpAccessChain %_ptr_Output_v4float %oVert %int_0 - OpStore %19 %17 -;CHECK: OpStore %19 %17 - %23 = OpAccessChain %_ptr_Output_v4float %oVert %int_1 - OpStore %23 %22 -;CHECK-NOT: OpStore %23 %22 - %27 = OpAccessChain %_ptr_Output_v4float %oVert %int_2 %int_0 - OpStore %27 %26 -;CHECK-NOT: OpStore %27 %26 - %30 = OpAccessChain %_ptr_Output_v4float %oVert %int_2 %int_1 - OpStore %30 %29 -;CHECK: OpStore %30 %29 - %33 = OpAccessChain %_ptr_Output_v4float %oVert %int_2 %int_2 - OpStore %33 %32 -;CHECK-NOT: OpStore %33 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(2); - live_inputs.insert(5); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, VertMatrix) { - // #version 450 - // - // layout(location = 2) out Vertex - // { - // vec4 color0; - // vec4 color1; - // mat4 color2; - // mat4 color3; - // mat4 color4; - // } oVert; - // - // void main() - // { - // oVert.color0 = vec4(0.0,0.0,0.0,0.0); - // oVert.color1 = vec4(0.1,0.0,0.0,0.0); - // oVert.color2[2] = vec4(0.2,0.0,0.0,0.0); - // oVert.color3[1] = vec4(0.3,0.0,0.0,0.0); - // oVert.color4[0] = vec4(0.4,0.0,0.0,0.0); - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %oVert - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpMemberName %Vertex 3 "color3" - OpMemberName %Vertex 4 "color4" - OpName %oVert "oVert" - OpDecorate %Vertex Block - OpDecorate %oVert Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%mat4v4float = OpTypeMatrix %v4float 4 - %Vertex = OpTypeStruct %v4float %v4float %mat4v4float %mat4v4float %mat4v4float -%_ptr_Output_Vertex = OpTypePointer Output %Vertex - %oVert = OpVariable %_ptr_Output_Vertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %float_0 = OpConstant %float 0 - %15 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -%float_0_100000001 = OpConstant %float 0.100000001 - %20 = OpConstantComposite %v4float %float_0_100000001 %float_0 %float_0 %float_0 - %int_2 = OpConstant %int 2 -%float_0_200000003 = OpConstant %float 0.200000003 - %24 = OpConstantComposite %v4float %float_0_200000003 %float_0 %float_0 %float_0 - %int_3 = OpConstant %int 3 -%float_0_300000012 = OpConstant %float 0.300000012 - %28 = OpConstantComposite %v4float %float_0_300000012 %float_0 %float_0 %float_0 - %int_4 = OpConstant %int 4 -%float_0_400000006 = OpConstant %float 0.400000006 - %32 = OpConstantComposite %v4float %float_0_400000006 %float_0 %float_0 %float_0 - %main = OpFunction %void None %3 - %5 = OpLabel - %17 = OpAccessChain %_ptr_Output_v4float %oVert %int_0 - OpStore %17 %15 -; CHECK: OpStore %17 %15 - %21 = OpAccessChain %_ptr_Output_v4float %oVert %int_1 - OpStore %21 %20 -; CHECK-NOT: OpStore %21 %20 - %25 = OpAccessChain %_ptr_Output_v4float %oVert %int_2 %int_2 - OpStore %25 %24 -; CHECK-NOT: OpStore %25 %24 - %29 = OpAccessChain %_ptr_Output_v4float %oVert %int_3 %int_1 - OpStore %29 %28 -; CHECK: OpStore %29 %28 - %33 = OpAccessChain %_ptr_Output_v4float %oVert %int_4 %int_0 - OpStore %33 %32 -; CHECK-NOT: OpStore %33 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(2); - live_inputs.insert(8); - live_inputs.insert(9); - live_inputs.insert(10); - live_inputs.insert(11); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, VertMemberLocs) { - // #version 450 - // - // out Vertex - // { - // layout (location = 1) vec4 Cd; - // layout (location = 0) vec2 uv; - // } oVert; - // - // layout (location = 0) in vec3 P; - // - // void main() - // { - // oVert.uv = vec2(0.1, 0.7); - // oVert.Cd = vec4(1, 0.5, 0, 1); - // gl_Position = vec4(P, 1); - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %oVert %_ %P - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "Cd" - OpMemberName %Vertex 1 "uv" - OpName %oVert "oVert" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpName %P "P" - OpMemberDecorate %Vertex 0 Location 1 - OpMemberDecorate %Vertex 1 Location 0 - OpDecorate %Vertex Block - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpDecorate %P Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v2float = OpTypeVector %float 2 - %Vertex = OpTypeStruct %v4float %v2float -%_ptr_Output_Vertex = OpTypePointer Output %Vertex - %oVert = OpVariable %_ptr_Output_Vertex Output - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 -%float_0_100000001 = OpConstant %float 0.100000001 -%float_0_699999988 = OpConstant %float 0.699999988 - %16 = OpConstantComposite %v2float %float_0_100000001 %float_0_699999988 -%_ptr_Output_v2float = OpTypePointer Output %v2float - %int_0 = OpConstant %int 0 - %float_1 = OpConstant %float 1 - %float_0_5 = OpConstant %float 0.5 - %float_0 = OpConstant %float 0 - %23 = OpConstantComposite %v4float %float_1 %float_0_5 %float_0 %float_1 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %v3float = OpTypeVector %float 3 -%_ptr_Input_v3float = OpTypePointer Input %v3float - %P = OpVariable %_ptr_Input_v3float Input - %main = OpFunction %void None %3 - %5 = OpLabel - %18 = OpAccessChain %_ptr_Output_v2float %oVert %int_1 - OpStore %18 %16 -; CHECK-NOT: OpStore %18 %16 - %25 = OpAccessChain %_ptr_Output_v4float %oVert %int_0 - OpStore %25 %23 -; CHECK: OpStore %25 %23 - %35 = OpLoad %v3float %P - %36 = OpCompositeExtract %float %35 0 - %37 = OpCompositeExtract %float %35 1 - %38 = OpCompositeExtract %float %35 2 - %39 = OpCompositeConstruct %v4float %36 %37 %38 %float_1 - %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %40 %39 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(1); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, ArrayedOutput) { - // Tests elimination of arrayed output as seen in Tesc shaders. - // - // #version 450 - // - // layout (vertices = 4) out; - // - // layout (location = 0) in vec3 N[]; - // layout (location = 1) in vec3 P[]; - // - // layout (location = 5) out Vertex - // { - // vec4 c; - // vec3 n; - // vec3 f[10]; - // } oVert[]; - // - // void main() - // { - // oVert[gl_InvocationID].c = vec4(1, 0, 0, 1); - // oVert[gl_InvocationID].n = N[gl_InvocationID]; - // oVert[gl_InvocationID].f[3] = vec3(0, 1, 0); - // vec4 worldSpacePos = vec4(P[gl_InvocationID], 1); - // gl_out[gl_InvocationID].gl_Position = worldSpacePos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %oVert %gl_InvocationID %N %P %gl_out - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "c" - OpMemberName %Vertex 1 "n" - OpMemberName %Vertex 2 "f" - OpName %oVert "oVert" - OpName %gl_InvocationID "gl_InvocationID" - OpName %N "N" - OpName %P "P" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %gl_out "gl_out" - OpDecorate %Vertex Block - OpDecorate %oVert Location 5 - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpDecorate %N Location 0 - OpDecorate %P Location 1 - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 - %uint = OpTypeInt 32 0 - %uint_10 = OpConstant %uint 10 -%_arr_v3float_uint_10 = OpTypeArray %v3float %uint_10 - %Vertex = OpTypeStruct %v4float %v3float %_arr_v3float_uint_10 - %uint_4 = OpConstant %uint 4 -%_arr_Vertex_uint_4 = OpTypeArray %Vertex %uint_4 -%_ptr_Output__arr_Vertex_uint_4 = OpTypePointer Output %_arr_Vertex_uint_4 - %oVert = OpVariable %_ptr_Output__arr_Vertex_uint_4 Output - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 - %float_1 = OpConstant %float 1 - %float_0 = OpConstant %float 0 - %24 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 - %uint_32 = OpConstant %uint 32 -%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32 -%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32 - %N = OpVariable %_ptr_Input__arr_v3float_uint_32 Input -%_ptr_Input_v3float = OpTypePointer Input %v3float -%_ptr_Output_v3float = OpTypePointer Output %v3float - %int_2 = OpConstant %int 2 - %int_3 = OpConstant %int 3 - %42 = OpConstantComposite %v3float %float_0 %float_1 %float_0 - %P = OpVariable %_ptr_Input__arr_v3float_uint_32 Input - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_arr_gl_PerVertex_uint_4 = OpTypeArray %gl_PerVertex %uint_4 -%_ptr_Output__arr_gl_PerVertex_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_uint_4 - %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_4 Output - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpLoad %int %gl_InvocationID - %26 = OpAccessChain %_ptr_Output_v4float %oVert %20 %int_0 - OpStore %26 %24 -; CHECK: OpStore %26 %24 - %35 = OpAccessChain %_ptr_Input_v3float %N %20 - %36 = OpLoad %v3float %35 - %38 = OpAccessChain %_ptr_Output_v3float %oVert %20 %int_1 - OpStore %38 %36 -; CHECK-NOT: OpStore %38 %36 - %43 = OpAccessChain %_ptr_Output_v3float %oVert %20 %int_2 %int_3 - OpStore %43 %42 -; CHECK: OpStore %43 %42 - %48 = OpAccessChain %_ptr_Input_v3float %P %20 - %49 = OpLoad %v3float %48 - %50 = OpCompositeExtract %float %49 0 - %51 = OpCompositeExtract %float %49 1 - %52 = OpCompositeExtract %float %49 2 - %53 = OpCompositeConstruct %v4float %50 %51 %52 %float_1 - %62 = OpAccessChain %_ptr_Output_v4float %gl_out %20 %int_0 - OpStore %62 %53 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(5); - live_inputs.insert(10); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, ArrayedOutputMemberLocs) { - // Tests elimination of member location with arrayed output as seen in - // Tesc shaders. - // - // #version 450 - // - // layout (vertices = 4) out; - // - // layout (location = 0) in vec3 N[]; - // layout (location = 1) in vec3 P[]; - // - // out Vertex - // { - // layout (location = 1) vec4 c; - // layout (location = 3) vec3 n; - // layout (location = 5) vec3 f[10]; - // } oVert[]; - // - // void main() - // { - // oVert[gl_InvocationID].c = vec4(1, 0, 0, 1); - // oVert[gl_InvocationID].n = N[gl_InvocationID]; - // oVert[gl_InvocationID].f[3] = vec3(0, 1, 0); - // vec4 worldSpacePos = vec4(P[gl_InvocationID], 1); - // gl_out[gl_InvocationID].gl_Position = worldSpacePos; - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %oVert %gl_InvocationID %N %P %gl_out - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "c" - OpMemberName %Vertex 1 "n" - OpMemberName %Vertex 2 "f" - OpName %oVert "oVert" - OpName %gl_InvocationID "gl_InvocationID" - OpName %N "N" - OpName %P "P" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %gl_out "gl_out" - OpMemberDecorate %Vertex 0 Location 1 - OpMemberDecorate %Vertex 1 Location 3 - OpMemberDecorate %Vertex 2 Location 5 - OpDecorate %Vertex Block - OpDecorate %gl_InvocationID BuiltIn InvocationId - OpDecorate %N Location 0 - OpDecorate %P Location 1 - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 - %uint = OpTypeInt 32 0 - %uint_10 = OpConstant %uint 10 -%_arr_v3float_uint_10 = OpTypeArray %v3float %uint_10 - %Vertex = OpTypeStruct %v4float %v3float %_arr_v3float_uint_10 - %uint_4 = OpConstant %uint 4 -%_arr_Vertex_uint_4 = OpTypeArray %Vertex %uint_4 -%_ptr_Output__arr_Vertex_uint_4 = OpTypePointer Output %_arr_Vertex_uint_4 - %oVert = OpVariable %_ptr_Output__arr_Vertex_uint_4 Output - %int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input - %int_0 = OpConstant %int 0 - %float_1 = OpConstant %float 1 - %float_0 = OpConstant %float 0 - %24 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 - %uint_32 = OpConstant %uint 32 -%_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32 -%_ptr_Input__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32 - %N = OpVariable %_ptr_Input__arr_v3float_uint_32 Input -%_ptr_Input_v3float = OpTypePointer Input %v3float -%_ptr_Output_v3float = OpTypePointer Output %v3float - %int_2 = OpConstant %int 2 - %int_3 = OpConstant %int 3 - %42 = OpConstantComposite %v3float %float_0 %float_1 %float_0 - %P = OpVariable %_ptr_Input__arr_v3float_uint_32 Input - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_arr_gl_PerVertex_uint_4 = OpTypeArray %gl_PerVertex %uint_4 -%_ptr_Output__arr_gl_PerVertex_uint_4 = OpTypePointer Output %_arr_gl_PerVertex_uint_4 - %gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_4 Output - %main = OpFunction %void None %3 - %5 = OpLabel - %20 = OpLoad %int %gl_InvocationID - %26 = OpAccessChain %_ptr_Output_v4float %oVert %20 %int_0 - OpStore %26 %24 -;CHECK: OpStore %26 %24 - %35 = OpAccessChain %_ptr_Input_v3float %N %20 - %36 = OpLoad %v3float %35 - %38 = OpAccessChain %_ptr_Output_v3float %oVert %20 %int_1 - OpStore %38 %36 -;CHECK-NOT: OpStore %38 %36 - %43 = OpAccessChain %_ptr_Output_v3float %oVert %20 %int_2 %int_3 - OpStore %43 %42 -;CHECK: OpStore %43 %42 - %48 = OpAccessChain %_ptr_Input_v3float %P %20 - %49 = OpLoad %v3float %48 - %50 = OpCompositeExtract %float %49 0 - %51 = OpCompositeExtract %float %49 1 - %52 = OpCompositeExtract %float %49 2 - %53 = OpCompositeConstruct %v4float %50 %51 %52 %float_1 - %62 = OpAccessChain %_ptr_Output_v4float %gl_out %20 %int_0 - OpStore %62 %53 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(1); - live_inputs.insert(8); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, ScalarBuiltins) { - // Tests elimination of scalar builtins as seen in vert shaders. - // - // #version 460 - // - // layout (location = 0) in vec3 P; - // - // void main() - // { - // gl_Position = vec4(P, 1.0); - // gl_PointSize = 1.0; - // } - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %_ %P - OpSource GLSL 460 - OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpName %P "P" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpDecorate %P Location 0 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %v3float = OpTypeVector %float 3 -%_ptr_Input_v3float = OpTypePointer Input %v3float - %P = OpVariable %_ptr_Input_v3float Input - %float_1 = OpConstant %float 1 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -%_ptr_Output_float = OpTypePointer Output %float - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpLoad %v3float %P - %21 = OpCompositeExtract %float %19 0 - %22 = OpCompositeExtract %float %19 1 - %23 = OpCompositeExtract %float %19 2 - %24 = OpCompositeConstruct %v4float %21 %22 %23 %float_1 - %26 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %26 %24 -;CHECK: OpStore %26 %24 - %29 = OpAccessChain %_ptr_Output_float %_ %int_1 - OpStore %29 %float_1 -;CHECK-NOT: OpStore %29 %float_1 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - // Omit spv::BuiltIn::PointSize - live_builtins.insert((uint32_t)spv::BuiltIn::ClipDistance); - live_builtins.insert((uint32_t)spv::BuiltIn::CullDistance); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, ArrayedBuiltins) { - // Tests elimination of arrayed builtins as seen in geom, tesc, and tese - // shaders. - // - // #version 460 - // - // layout(triangle_strip, max_vertices = 3) out; - // layout(triangles) in; - // - // void main() - // { - // for (int i = 0; i < 3; i++) - // { - // gl_Position = gl_in[i].gl_Position; - // gl_PointSize = gl_in[i].gl_PointSize; - // - // EmitVertex(); - // } - // - // EndPrimitive(); - // } - const std::string text = R"( - OpCapability Geometry - OpCapability GeometryPointSize - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Geometry %main "main" %_ %gl_in - OpExecutionMode %main Triangles - OpExecutionMode %main Invocations 1 - OpExecutionMode %main OutputTriangleStrip - OpExecutionMode %main OutputVertices 3 - OpSource GLSL 460 - OpName %main "main" - OpName %i "i" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpMemberName %gl_PerVertex 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex 3 "gl_CullDistance" - OpName %_ "" - OpName %gl_PerVertex_0 "gl_PerVertex" - OpMemberName %gl_PerVertex_0 0 "gl_Position" - OpMemberName %gl_PerVertex_0 1 "gl_PointSize" - OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" - OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" - OpName %gl_in "gl_in" - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex Block - OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize - OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance - OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance - OpDecorate %gl_PerVertex_0 Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_3 = OpConstant %int 3 - %bool = OpTypeBool - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output -%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 - %uint_3 = OpConstant %uint 3 -%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 -%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3 - %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Output_v4float = OpTypePointer Output %v4float - %int_1 = OpConstant %int 1 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Output_float = OpTypePointer Output %float - %main = OpFunction %void None %3 - %5 = OpLabel - %i = OpVariable %_ptr_Function_int Function - OpStore %i %int_0 - OpBranch %10 - %10 = OpLabel - OpLoopMerge %12 %13 None - OpBranch %14 - %14 = OpLabel - %15 = OpLoad %int %i - %18 = OpSLessThan %bool %15 %int_3 - OpBranchConditional %18 %11 %12 - %11 = OpLabel - %32 = OpLoad %int %i - %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0 - %35 = OpLoad %v4float %34 - %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %37 %35 -;CHECK: OpStore %37 %35 - %39 = OpLoad %int %i - %41 = OpAccessChain %_ptr_Input_float %gl_in %39 %int_1 - %42 = OpLoad %float %41 - %44 = OpAccessChain %_ptr_Output_float %_ %int_1 - OpStore %44 %42 -;CHECK-NOT: OpStore %44 %42 - OpEmitVertex - OpBranch %13 - %13 = OpLabel - %45 = OpLoad %int %i - %46 = OpIAdd %int %45 %int_1 - OpStore %i %46 - OpBranch %10 - %12 = OpLabel - OpEndPrimitive - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - // Omit spv::BuiltIn::PointSize - live_builtins.insert((uint32_t)spv::BuiltIn::ClipDistance); - live_builtins.insert((uint32_t)spv::BuiltIn::CullDistance); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, ArrayedOutputPatchLocs) { - // Tests elimination of location with arrayed patch output as seen in - // Tesc shaders. - // - // #version 450 core - // - // layout(vertices = 4) out; - // - // layout(location=0) patch out float patchOut0[2]; - // layout(location=2) patch out float patchOut1[2]; - // - // void main() - // { - // patchOut0[1] = 0.0; // Dead loc 1 - // patchOut1[1] = 1.0; // Live loc 3 - // } - const std::string text = R"( - OpCapability Tessellation - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint TessellationControl %main "main" %patchOut0 %patchOut1 - OpExecutionMode %main OutputVertices 4 - OpSource GLSL 450 - OpName %main "main" - OpName %patchOut0 "patchOut0" - OpName %patchOut1 "patchOut1" - OpDecorate %patchOut0 Patch - OpDecorate %patchOut0 Location 0 - OpDecorate %patchOut1 Patch - OpDecorate %patchOut1 Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %uint = OpTypeInt 32 0 - %uint_2 = OpConstant %uint 2 -%_arr_float_uint_2 = OpTypeArray %float %uint_2 -%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 - %patchOut0 = OpVariable %_ptr_Output__arr_float_uint_2 Output - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 - %float_0 = OpConstant %float 0 -%_ptr_Output_float = OpTypePointer Output %float - %patchOut1 = OpVariable %_ptr_Output__arr_float_uint_2 Output - %float_1 = OpConstant %float 1 - %main = OpFunction %void None %3 - %5 = OpLabel - %16 = OpAccessChain %_ptr_Output_float %patchOut0 %int_1 - OpStore %16 %float_0 -;CHECK-NOT: OpStore %16 %float_0 - %19 = OpAccessChain %_ptr_Output_float %patchOut1 %int_1 - OpStore %19 %float_1 -;CHECK: OpStore %19 %float_1 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(3); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -TEST_F(ElimDeadOutputStoresTest, VertMultipleLocationsF16) { - // #version 450 - // - // layout(location = 2) out Vertex - // { - // f16vec4 color0; - // f16vec4 color1; - // f16vec4 color2[3]; - // } oVert; - // - // void main() - // { - // oVert.color0 = f16vec4(0.0,0.0,0.0,0.0); - // oVert.color1 = f16vec4(0.1,0.0,0.0,0.0); - // oVert.color2[0] = f16vec4(0.2,0.0,0.0,0.0); - // oVert.color2[1] = f16vec4(0.3,0.0,0.0,0.0); - // oVert.color2[2] = f16vec4(0.4,0.0,0.0,0.0); - // } - const std::string text = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %oVert - OpSource GLSL 450 - OpName %main "main" - OpName %Vertex "Vertex" - OpMemberName %Vertex 0 "color0" - OpMemberName %Vertex 1 "color1" - OpMemberName %Vertex 2 "color2" - OpName %oVert "oVert" - OpDecorate %Vertex Block - OpDecorate %oVert Location 2 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %half = OpTypeFloat 32 - %v4half = OpTypeVector %half 4 - %uint = OpTypeInt 32 0 - %uint_3 = OpConstant %uint 3 -%_arr_v4half_uint_3 = OpTypeArray %v4half %uint_3 - %Vertex = OpTypeStruct %v4half %v4half %_arr_v4half_uint_3 -%_ptr_Output_Vertex = OpTypePointer Output %Vertex - %oVert = OpVariable %_ptr_Output_Vertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %half_0 = OpConstant %half 0 - %17 = OpConstantComposite %v4half %half_0 %half_0 %half_0 %half_0 -%_ptr_Output_v4half = OpTypePointer Output %v4half - %int_1 = OpConstant %int 1 -%half_0_100000001 = OpConstant %half 0.100000001 - %22 = OpConstantComposite %v4half %half_0_100000001 %half_0 %half_0 %half_0 - %int_2 = OpConstant %int 2 -%half_0_200000003 = OpConstant %half 0.200000003 - %26 = OpConstantComposite %v4half %half_0_200000003 %half_0 %half_0 %half_0 -%half_0_300000012 = OpConstant %half 0.300000012 - %29 = OpConstantComposite %v4half %half_0_300000012 %half_0 %half_0 %half_0 -%half_0_400000006 = OpConstant %half 0.400000006 - %32 = OpConstantComposite %v4half %half_0_400000006 %half_0 %half_0 %half_0 - %main = OpFunction %void None %3 - %5 = OpLabel - %19 = OpAccessChain %_ptr_Output_v4half %oVert %int_0 - OpStore %19 %17 -;CHECK: OpStore %19 %17 - %23 = OpAccessChain %_ptr_Output_v4half %oVert %int_1 - OpStore %23 %22 -;CHECK-NOT: OpStore %23 %22 - %27 = OpAccessChain %_ptr_Output_v4half %oVert %int_2 %int_0 - OpStore %27 %26 -;CHECK-NOT: OpStore %27 %26 - %30 = OpAccessChain %_ptr_Output_v4half %oVert %int_2 %int_1 - OpStore %30 %29 -;CHECK: OpStore %30 %29 - %33 = OpAccessChain %_ptr_Output_v4half %oVert %int_2 %int_2 - OpStore %33 %32 -;CHECK-NOT: OpStore %33 %32 - OpReturn - OpFunctionEnd -)"; - - SetTargetEnv(SPV_ENV_VULKAN_1_3); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - - std::unordered_set live_inputs; - std::unordered_set live_builtins; - live_inputs.insert(2); - live_inputs.insert(5); - SinglePassRunAndMatch(text, true, &live_inputs, - &live_builtins); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/feature_manager_test.cpp b/test/opt/feature_manager_test.cpp index 7e8f92c3..767376cf 100644 --- a/test/opt/feature_manager_test.cpp +++ b/test/opt/feature_manager_test.cpp @@ -14,7 +14,9 @@ #include #include +#include +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/build_module.h" #include "source/opt/ir_context.h" @@ -87,25 +89,6 @@ OpExtension "SPV_KHR_storage_buffer_storage_class" Extension::kSPV_KHR_storage_buffer_storage_class)); } -TEST_F(FeatureManagerTest, GetExtensionsReturnsExtensions) { - const std::string text = R"( -OpCapability Shader -OpMemoryModel Logical GLSL450 -OpExtension "SPV_KHR_variable_pointers" -OpExtension "SPV_KHR_storage_buffer_storage_class" - )"; - - std::unique_ptr context = - BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); - ASSERT_NE(context, nullptr); - - const auto& extensions = context->get_feature_mgr()->GetExtensions(); - EXPECT_EQ(extensions.size(), 2); - EXPECT_TRUE(extensions.contains(Extension::kSPV_KHR_variable_pointers)); - EXPECT_TRUE( - extensions.contains(Extension::kSPV_KHR_storage_buffer_storage_class)); -} - // Test capability checks. TEST_F(FeatureManagerTest, ExplicitlyPresent1) { const std::string text = R"( @@ -117,10 +100,8 @@ OpMemoryModel Logical GLSL450 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); ASSERT_NE(context, nullptr); - EXPECT_TRUE( - context->get_feature_mgr()->HasCapability(spv::Capability::Shader)); - EXPECT_FALSE( - context->get_feature_mgr()->HasCapability(spv::Capability::Kernel)); + EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader)); + EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel)); } TEST_F(FeatureManagerTest, ExplicitlyPresent2) { @@ -133,10 +114,8 @@ OpMemoryModel Logical GLSL450 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); ASSERT_NE(context, nullptr); - EXPECT_FALSE( - context->get_feature_mgr()->HasCapability(spv::Capability::Shader)); - EXPECT_TRUE( - context->get_feature_mgr()->HasCapability(spv::Capability::Kernel)); + EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader)); + EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel)); } TEST_F(FeatureManagerTest, ImplicitlyPresent) { @@ -152,31 +131,10 @@ OpMemoryModel Logical GLSL450 // Check multiple levels of indirection. Tessellation implies Shader, which // implies Matrix. EXPECT_TRUE( - context->get_feature_mgr()->HasCapability(spv::Capability::Tessellation)); - EXPECT_TRUE( - context->get_feature_mgr()->HasCapability(spv::Capability::Shader)); - EXPECT_TRUE( - context->get_feature_mgr()->HasCapability(spv::Capability::Matrix)); - EXPECT_FALSE( - context->get_feature_mgr()->HasCapability(spv::Capability::Kernel)); -} - -TEST_F(FeatureManagerTest, GetCapabilitiesReturnsImplicitCapabilities) { - const std::string text = R"( -OpCapability Tessellation -OpMemoryModel Logical GLSL450 - )"; - - std::unique_ptr context = - BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text); - ASSERT_NE(context, nullptr); - - const auto& capabilities = context->get_feature_mgr()->GetCapabilities(); - // Tesselation implies Shader, which implies Matrix. - EXPECT_EQ(capabilities.size(), 3); - EXPECT_TRUE(capabilities.contains(spv::Capability::Tessellation)); - EXPECT_TRUE(capabilities.contains(spv::Capability::Shader)); - EXPECT_TRUE(capabilities.contains(spv::Capability::Matrix)); + context->get_feature_mgr()->HasCapability(SpvCapabilityTessellation)); + EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityShader)); + EXPECT_TRUE(context->get_feature_mgr()->HasCapability(SpvCapabilityMatrix)); + EXPECT_FALSE(context->get_feature_mgr()->HasCapability(SpvCapabilityKernel)); } } // namespace diff --git a/test/opt/fix_func_call_arguments_test.cpp b/test/opt/fix_func_call_arguments_test.cpp index 606ed261..ecd13a86 100644 --- a/test/opt/fix_func_call_arguments_test.cpp +++ b/test/opt/fix_func_call_arguments_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gmock/gmock.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/fix_storage_class_test.cpp b/test/opt/fix_storage_class_test.cpp index 684e006e..1c0101a0 100644 --- a/test/opt/fix_storage_class_test.cpp +++ b/test/opt/fix_storage_class_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" @@ -874,47 +876,6 @@ TEST_F(FixTypeTest, FixPhiInLoop) { SinglePassRunAndMatch(text, false); } -TEST_F(FixStorageClassTest, SupportsU64Index) { - const std::string text = R"( -; CHECK: OpAccessChain %_ptr_Uniform_float - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "testMain" %gl_LocalInvocationID - OpExecutionMode %1 LocalSize 8 8 1 - OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId - OpDecorate %8 DescriptorSet 0 - OpDecorate %8 Binding 0 - OpDecorate %_runtimearr_float ArrayStride 4 - OpMemberDecorate %_struct_7 0 Offset 0 - OpDecorate %_struct_7 BufferBlock - %ulong = OpTypeInt 64 0 - %ulong_0 = OpConstant %ulong 0 - %float = OpTypeFloat 32 - %float_123 = OpConstant %float 123 - %uint = OpTypeInt 32 0 - %uint_10 = OpConstant %uint 10 -%_runtimearr_float = OpTypeRuntimeArray %float - %_struct_7 = OpTypeStruct %_runtimearr_float -%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7 - %v3uint = OpTypeVector %uint 3 -%_ptr_Input_v3uint = OpTypePointer Input %v3uint - %void = OpTypeVoid - %30 = OpTypeFunction %void -%_ptr_Uniform_float = OpTypePointer Uniform %float - %8 = OpVariable %_ptr_Uniform__struct_7 Uniform -%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input - %1 = OpFunction %void None %30 - %38 = OpLabel - %44 = OpLoad %v3uint %gl_LocalInvocationID - %59 = OpCompositeExtract %uint %44 0 - %60 = OpAccessChain %_ptr_Uniform_float %8 %ulong_0 %59 - OpStore %60 %float_123 - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(text, false); -} } // namespace } // namespace opt diff --git a/test/opt/flatten_decoration_test.cpp b/test/opt/flatten_decoration_test.cpp index d7ac2ab7..63207fd2 100644 --- a/test/opt/flatten_decoration_test.cpp +++ b/test/opt/flatten_decoration_test.cpp @@ -16,6 +16,7 @@ #include #include +#include "gmock/gmock.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/fold_spec_const_op_composite_test.cpp b/test/opt/fold_spec_const_op_composite_test.cpp index 70ba3620..c98a44c3 100644 --- a/test/opt/fold_spec_const_op_composite_test.cpp +++ b/test/opt/fold_spec_const_op_composite_test.cpp @@ -308,397 +308,6 @@ TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeExtractMaxtrix) { builder.GetCode(), JoinAllInsts(expected), /* skip_nop = */ true); } -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertVector) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v3uint = OpTypeVector %uint 3 - %uint_2 = OpConstant %uint 2 - %uint_3 = OpConstant %uint 3 - %8 = OpConstantNull %uint - %9 = OpSpecConstantComposite %v3uint %uint_2 %uint_2 %uint_2 - ; CHECK: %15 = OpConstantComposite %v3uint %uint_3 %uint_2 %uint_2 - ; CHECK: %uint_3_0 = OpConstant %uint 3 - ; CHECK: %17 = OpConstantComposite %v3uint %8 %uint_2 %uint_2 - ; CHECK: %18 = OpConstantNull %uint - %10 = OpSpecConstantOp %v3uint CompositeInsert %uint_3 %9 0 - %11 = OpSpecConstantOp %uint CompositeExtract %10 0 - %12 = OpSpecConstantOp %v3uint CompositeInsert %8 %9 0 - %13 = OpSpecConstantOp %uint CompositeExtract %12 0 - %1 = OpFunction %void None %3 - %14 = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertVectorIntoMatrix) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v2float = OpTypeVector %float 2 - %mat2v2float = OpTypeMatrix %v2float 2 - %float_0 = OpConstant %float 0 - %float_1 = OpConstant %float 1 - %float_2 = OpConstant %float 2 - %v2float_01 = OpConstantComposite %v2float %float_0 %float_1 - %v2float_12 = OpConstantComposite %v2float %float_1 %float_2 - -; CHECK: %10 = OpConstantComposite %v2float %float_0 %float_1 -; CHECK: %11 = OpConstantComposite %v2float %float_1 %float_2 -; CHECK: %12 = OpConstantComposite %mat2v2float %11 %11 -%mat2v2float_1212 = OpConstantComposite %mat2v2float %v2float_12 %v2float_12 - -; CHECK: %15 = OpConstantComposite %mat2v2float %10 %11 - %spec_0 = OpSpecConstantOp %mat2v2float CompositeInsert %v2float_01 %mat2v2float_1212 0 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertMatrix) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 -%mat3v3float = OpTypeMatrix %v3float 3 - %float_1 = OpConstant %float 1 - %float_2 = OpConstant %float 2 - %9 = OpSpecConstantComposite %v3float %float_1 %float_1 %float_1 - %10 = OpSpecConstantComposite %v3float %float_1 %float_1 %float_1 - %11 = OpSpecConstantComposite %v3float %float_1 %float_2 %float_1 - %12 = OpSpecConstantComposite %mat3v3float %9 %10 %11 - ; CHECK: %float_2_0 = OpConstant %float 2 - ; CHECK: %18 = OpConstantComposite %v3float %float_1 %float_1 %float_2 - ; CHECK: %19 = OpConstantComposite %mat3v3float %9 %18 %11 - ; CHECK: %float_2_1 = OpConstant %float 2 - %13 = OpSpecConstantOp %float CompositeExtract %12 2 1 - %14 = OpSpecConstantOp %mat3v3float CompositeInsert %13 %12 1 2 - %15 = OpSpecConstantOp %float CompositeExtract %14 1 2 - %1 = OpFunction %void None %3 - %16 = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertFloatNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_1 = OpConstant %float 1 - -; CHECK: %7 = OpConstantNull %float -; CHECK: %8 = OpConstantComposite %v3float %7 %7 %7 -; CHECK: %12 = OpConstantComposite %v3float %7 %7 %float_1 - %null = OpConstantNull %float - %spec_0 = OpConstantComposite %v3float %null %null %null - %spec_1 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_0 2 - -; CHECK: %float_1_0 = OpConstant %float 1 - %spec_2 = OpSpecConstantOp %float CompositeExtract %spec_1 2 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertFloatSetNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_1 = OpConstant %float 1 - -; CHECK: %7 = OpConstantNull %float -; CHECK: %8 = OpConstantComposite %v3float %7 %7 %float_1 -; CHECK: %12 = OpConstantComposite %v3float %7 %7 %7 - %null = OpConstantNull %float - %spec_0 = OpConstantComposite %v3float %null %null %float_1 - %spec_1 = OpSpecConstantOp %v3float CompositeInsert %null %spec_0 2 - -; CHECK: %13 = OpConstantNull %float - %spec_2 = OpSpecConstantOp %float CompositeExtract %spec_1 2 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertVectorNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_1 = OpConstant %float 1 - %null = OpConstantNull %v3float - -; CHECK: %11 = OpConstantNull %float -; CHECK: %12 = OpConstantComposite %v3float %11 %11 %float_1 - %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_1 %null 2 - - -; CHECK: %float_1_0 = OpConstant %float 1 - %spec_1 = OpSpecConstantOp %float CompositeExtract %spec_0 2 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertNullVectorIntoMatrix) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v2float = OpTypeVector %float 2 - %mat2v2float = OpTypeMatrix %v2float 2 - %null = OpConstantNull %mat2v2float - %float_1 = OpConstant %float 1 - %float_2 = OpConstant %float 2 - %v2float_12 = OpConstantComposite %v2float %float_1 %float_2 - -; CHECK: %13 = OpConstantNull %v2float -; CHECK: %14 = OpConstantComposite %mat2v2float %10 %13 - %spec_0 = OpSpecConstantOp %mat2v2float CompositeInsert %v2float_12 %null 0 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertVectorKeepNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_0 = OpConstant %float 0 - %null_float = OpConstantNull %float - %null_vec = OpConstantNull %v3float - -; CHECK: %15 = OpConstantComposite %v3float %7 %7 %float_0 - %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_0 %null_vec 2 - -; CHECK: %float_0_0 = OpConstant %float 0 - %spec_1 = OpSpecConstantOp %float CompositeExtract %spec_0 2 - -; CHECK: %17 = OpConstantComposite %v3float %7 %7 %7 - %spec_2 = OpSpecConstantOp %v3float CompositeInsert %null_float %null_vec 2 - -; CHECK: %18 = OpConstantNull %float - %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 2 - %1 = OpFunction %void None %3 - %label = OpLabel - %add = OpFAdd %float %spec_3 %spec_3 - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertVectorChainNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_1 = OpConstant %float 1 - %null = OpConstantNull %v3float - -; CHECK: %15 = OpConstantNull %float -; CHECK: %16 = OpConstantComposite %v3float %15 %15 %float_1 -; CHECK: %17 = OpConstantComposite %v3float %15 %float_1 %float_1 -; CHECK: %18 = OpConstantComposite %v3float %float_1 %float_1 %float_1 - %spec_0 = OpSpecConstantOp %v3float CompositeInsert %float_1 %null 2 - %spec_1 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_0 1 - %spec_2 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_1 0 - -; CHECK: %float_1_0 = OpConstant %float 1 -; CHECK: %float_1_1 = OpConstant %float 1 -; CHECK: %float_1_2 = OpConstant %float 1 - %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 0 - %spec_4 = OpSpecConstantOp %float CompositeExtract %spec_2 1 - %spec_5 = OpSpecConstantOp %float CompositeExtract %spec_2 2 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, - CompositeInsertVectorChainReset) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %float_1 = OpConstant %float 1 - %null = OpConstantNull %float -; CHECK: %8 = OpConstantComposite %v3float %7 %7 %float_1 - %spec_0 = OpConstantComposite %v3float %null %null %float_1 - - ; set to null -; CHECK: %13 = OpConstantComposite %v3float %7 %7 %7 - %spec_1 = OpSpecConstantOp %v3float CompositeInsert %null %spec_0 2 - - ; set to back to original value -; CHECK: %14 = OpConstantComposite %v3float %7 %7 %float_1 - %spec_2 = OpSpecConstantOp %v3float CompositeInsert %float_1 %spec_1 2 - -; CHECK: %float_1_0 = OpConstant %float 1 - %spec_3 = OpSpecConstantOp %float CompositeExtract %spec_2 2 - %1 = OpFunction %void None %3 - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertMatrixNull) { - const std::string test = - R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %float = OpTypeFloat 32 - %int = OpTypeInt 32 0 -%v2float = OpTypeVector %float 2 -%mat2v2float = OpTypeMatrix %v2float 2 -%null = OpConstantNull %mat2v2float - %float_1 = OpConstant %float 1 - ; CHECK: %13 = OpConstantNull %v2float - ; CHECK: %14 = OpConstantNull %float - ; CHECK: %15 = OpConstantComposite %v2float %float_1 %14 - ; CHECK: %16 = OpConstantComposite %mat2v2float %13 %15 - %spec = OpSpecConstantOp %mat2v2float CompositeInsert %float_1 %null 1 0 -; extra type def to make sure new type def are not just thrown at end - %v2int = OpTypeVector %int 2 - %main = OpFunction %void None %func - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - -// Silently ignore spec constants that cannot be folded -TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, UnfoldableOp) { - const std::string test = R"( - OpCapability Shader - OpCapability SignedZeroInfNanPreserve - OpExtension "SPV_KHR_float_controls" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" - OpSource GLSL 450 - OpDecorate %v SpecId 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v = OpConstant %float 0x1p-1 -%c = OpSpecConstantOp %float QuantizeToF16 %v -;CHECK: {{%\w+}} = OpSpecConstantOp {{%\w+}} QuantizeToF16 {{%\w+}} - %main = OpFunction %void None %3 - %5 = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(test, false); -} - // All types and some common constants that are potentially required in // FoldSpecConstantOpAndCompositeTest. std::vector CommonTypesAndConstants() { diff --git a/test/opt/fold_test.cpp b/test/opt/fold_test.cpp index a837597a..b3248032 100644 --- a/test/opt/fold_test.cpp +++ b/test/opt/fold_test.cpp @@ -27,6 +27,7 @@ #include "source/opt/ir_context.h" #include "source/opt/module.h" #include "spirv-tools/libspirv.hpp" +#include "test/opt/pass_utils.h" namespace spvtools { namespace opt { @@ -87,9 +88,9 @@ TEST_P(IntegerInstructionFoldingTest, Case) { // Make sure the instruction folded as expected. EXPECT_TRUE(succeeded); if (inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - EXPECT_EQ(inst->opcode(), spv::Op::OpConstant); + EXPECT_EQ(inst->opcode(), SpvOpConstant); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::Constant* constant = const_mrg->GetConstantFromInst(inst); // We expect to see either integer types or 16-bit float types here. @@ -156,8 +157,6 @@ OpName %main "main" %v2half = OpTypeVector %half 2 %v2bool = OpTypeVector %bool 2 %m2x2int = OpTypeMatrix %v2int 2 -%mat4v2float = OpTypeMatrix %v2float 4 -%mat2v4float = OpTypeMatrix %v4float 2 %mat4v4float = OpTypeMatrix %v4float 4 %mat4v4double = OpTypeMatrix %v4double 4 %struct_v2int_int_int = OpTypeStruct %v2int %int %int @@ -176,8 +175,6 @@ OpName %main "main" %_ptr_struct_v2int_int_int = OpTypePointer Function %struct_v2int_int_int %_ptr_v2float = OpTypePointer Function %v2float %_ptr_v2double = OpTypePointer Function %v2double -%int_2 = OpConstant %int 2 -%int_arr_2 = OpTypeArray %int %int_2 %short_0 = OpConstant %short 0 %short_2 = OpConstant %short 2 %short_3 = OpConstant %short 3 @@ -187,6 +184,7 @@ OpName %main "main" %103 = OpConstant %int 7 ; Need a def with an numerical id to define id maps. %int_0 = OpConstant %int 0 %int_1 = OpConstant %int 1 +%int_2 = OpConstant %int 2 %int_3 = OpConstant %int 3 %int_4 = OpConstant %int 4 %int_10 = OpConstant %int 10 @@ -226,7 +224,6 @@ OpName %main "main" %v2int_2_2 = OpConstantComposite %v2int %int_2 %int_2 %v2int_2_3 = OpConstantComposite %v2int %int_2 %int_3 %v2int_3_2 = OpConstantComposite %v2int %int_3 %int_2 -%v2int_n1_n24 = OpConstantComposite %v2int %int_n1 %int_n24 %v2int_4_4 = OpConstantComposite %v2int %int_4 %int_4 %v2int_min_max = OpConstantComposite %v2int %int_min %int_max %v2bool_null = OpConstantNull %v2bool @@ -286,7 +283,6 @@ OpName %main "main" %v2double_null = OpConstantNull %v2double %108 = OpConstant %half 0 %half_1 = OpConstant %half 1 -%half_2 = OpConstant %half 2 %half_0_1 = OpConstantComposite %v2half %108 %half_1 %106 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 %v4float_0_0_0_0 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 @@ -295,10 +291,8 @@ OpName %main "main" %v4float_1_1_1_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 %v4float_1_2_3_4 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4 %v4float_null = OpConstantNull %v4float -%mat2v4float_null = OpConstantNull %mat2v4float -%mat4v4float_null = OpConstantNull %mat4v4float +%mat4v4float_null = OpConstantComposite %mat4v4float %v4float_null %v4float_null %v4float_null %v4float_null %mat4v4float_1_2_3_4 = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4 -%mat4v4float_1_2_3_4_null = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_null %v4float_1_2_3_4 %v4float_null %107 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_0 %v4double_0_0_0_0 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_0 %v4double_0_0_0_1 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_1 @@ -307,9 +301,8 @@ OpName %main "main" %v4double_1_2_3_4 = OpConstantComposite %v4double %double_1 %double_2 %double_3 %double_4 %v4double_1_1_1_0p5 = OpConstantComposite %v4double %double_1 %double_1 %double_1 %double_0p5 %v4double_null = OpConstantNull %v4double -%mat4v4double_null = OpConstantNull %mat4v4double +%mat4v4double_null = OpConstantComposite %mat4v4double %v4double_null %v4double_null %v4double_null %v4double_null %mat4v4double_1_2_3_4 = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4 -%mat4v4double_1_2_3_4_null = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_null %v4double_1_2_3_4 %v4double_null %v4float_n1_2_1_3 = OpConstantComposite %v4float %float_n1 %float_2 %float_1 %float_3 %uint_0x3f800000 = OpConstant %uint 0x3f800000 %uint_0xbf800000 = OpConstant %uint 0xbf800000 @@ -320,11 +313,8 @@ OpName %main "main" %int_0xC05FD666 = OpConstant %int 0xC05FD666 %int_0x66666666 = OpConstant %int 0x66666666 %v4int_0x3FF00000_0x00000000_0xC05FD666_0x66666666 = OpConstantComposite %v4int %int_0x00000000 %int_0x3FF00000 %int_0x66666666 %int_0xC05FD666 -%ushort_0x4400 = OpConstant %ushort 0x4400 -%short_0x4400 = OpConstant %short 0x4400 %ushort_0xBC00 = OpConstant %ushort 0xBC00 %short_0xBC00 = OpConstant %short 0xBC00 -%int_arr_2_undef = OpUndef %int_arr_2 )"; return header; @@ -758,7 +748,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 1), - // Test case 46: UClamp 1 2 x + // Test case 44: UClamp 1 2 x InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -767,7 +757,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 2), - // Test case 47: UClamp 2 x 1 + // Test case 45: UClamp 2 x 1 InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -776,7 +766,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 1), - // Test case 48: Bit-cast int 0 to unsigned int + // Test case 46: Bit-cast int 0 to unsigned int InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -784,7 +774,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0), - // Test case 49: Bit-cast int -24 to unsigned int + // Test case 47: Bit-cast int -24 to unsigned int InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -792,7 +782,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, static_cast(-24)), - // Test case 50: Bit-cast float 1.0f to unsigned int + // Test case 48: Bit-cast float 1.0f to unsigned int InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -800,7 +790,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, static_cast(0x3f800000)), - // Test case 51: Bit-cast ushort 0xBC00 to ushort + // Test case 49: Bit-cast ushort 0xBC00 to ushort InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -808,7 +798,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xBC00), - // Test case 52: Bit-cast short 0xBC00 to ushort + // Test case 50: Bit-cast short 0xBC00 to ushort InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -816,7 +806,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xFFFFBC00), - // Test case 53: Bit-cast half 1 to ushort + // Test case 51: Bit-cast half 1 to ushort InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -824,7 +814,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0x3C00), - // Test case 54: Bit-cast ushort 0xBC00 to short + // Test case 52: Bit-cast ushort 0xBC00 to short InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -832,7 +822,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xBC00), - // Test case 55: Bit-cast short 0xBC00 to short + // Test case 53: Bit-cast short 0xBC00 to short InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -840,7 +830,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xFFFFBC00), - // Test case 56: Bit-cast half 1 to short + // Test case 54: Bit-cast half 1 to short InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -848,7 +838,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0x3C00), - // Test case 57: Bit-cast ushort 0xBC00 to half + // Test case 55: Bit-cast ushort 0xBC00 to half InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -856,7 +846,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xBC00), - // Test case 58: Bit-cast short 0xBC00 to half + // Test case 56: Bit-cast short 0xBC00 to half InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -864,7 +854,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0xFFFFBC00), - // Test case 59: Bit-cast half 1 to half + // Test case 57: Bit-cast half 1 to half InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -872,7 +862,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 0x3C00), - // Test case 60: Bit-cast ubyte 1 to byte + // Test case 58: Bit-cast ubyte 1 to byte InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + @@ -880,61 +870,21 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, 1), - // Test case 61: Bit-cast byte -1 to ubyte + // Test case 59: Bit-cast byte -1 to ubyte InstructionFoldingCase( Header() + "%main = OpFunction %void None %void_func\n" + "%main_lab = OpLabel\n" + "%2 = OpBitcast %ubyte %byte_n1\n" + "OpReturn\n" + "OpFunctionEnd", - 2, 0xFFFFFFFF), - // Test case 62: Negate 2. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %int %int_2\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, -2), - // Test case 63: Negate negative short. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %short %short_0xBC00\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, 0x4400 /* expected to be sign extended. */), - // Test case 64: Negate positive short. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %short %short_0x4400\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, 0xFFFFBC00 /* expected to be sign extended. */), - // Test case 65: Negate a negative short. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %ushort %ushort_0xBC00\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, 0x4400 /* expected to be zero extended. */), - // Test case 66: Negate positive short. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %ushort %ushort_0x4400\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, 0xBC00 /* expected to be zero extended. */) + 2, 0xFFFFFFFF) )); // clang-format on -using UIntVectorInstructionFoldingTest = +using IntVectorInstructionFoldingTest = ::testing::TestWithParam>>; -TEST_P(UIntVectorInstructionFoldingTest, Case) { +TEST_P(IntVectorInstructionFoldingTest, Case) { const auto& tc = GetParam(); // Build module. @@ -946,15 +896,15 @@ TEST_P(UIntVectorInstructionFoldingTest, Case) { // Fold the instruction to test. analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold); - spv::Op original_opcode = inst->opcode(); + SpvOp original_opcode = inst->opcode(); bool succeeded = context->get_instruction_folder().FoldInstruction(inst); // Make sure the instruction folded as expected. EXPECT_EQ(succeeded, inst == nullptr || inst->opcode() != original_opcode); if (succeeded && inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - std::vector opcodes = {spv::Op::OpConstantComposite}; + std::vector opcodes = {SpvOpConstantComposite}; EXPECT_THAT(opcodes, Contains(inst->opcode())); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::Constant* result = const_mrg->GetConstantFromInst(inst); @@ -971,7 +921,7 @@ TEST_P(UIntVectorInstructionFoldingTest, Case) { } // clang-format off -INSTANTIATE_TEST_SUITE_P(TestCase, UIntVectorInstructionFoldingTest, +INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest, ::testing::Values( // Test case 0: fold 0*n InstructionFoldingCase>( @@ -1019,101 +969,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, UIntVectorInstructionFoldingTest, "%2 = OpBitcast %v2uint %v2int_min_max\n" + "OpReturn\n" + "OpFunctionEnd", - 2, {2147483648, 2147483647}), - // Test case 5: fold SNegate vector of uint - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%n = OpVariable %_ptr_int Function\n" + - "%load = OpLoad %int %n\n" + - "%2 = OpSNegate %v2uint %v2uint_0x3f800000_0xbf800000\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {static_cast(-0x3f800000), static_cast(-0xbf800000)}), - // Test case 6: fold vector components of uint (incuding integer overflow) - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpIAdd %v2uint %v2uint_0x3f800000_0xbf800000 %v2uint_0x3f800000_0xbf800000\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {0x7f000000u, 0x7f000000u}) -)); -// clang-format on - -using IntVectorInstructionFoldingTest = - ::testing::TestWithParam>>; - -TEST_P(IntVectorInstructionFoldingTest, Case) { - const auto& tc = GetParam(); - - // Build module. - std::unique_ptr context = - BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - ASSERT_NE(nullptr, context); - - // Fold the instruction to test. - analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold); - bool succeeded = context->get_instruction_folder().FoldInstruction(inst); - - // Make sure the instruction folded as expected. - EXPECT_TRUE(succeeded); - if (succeeded && inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); - inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - std::vector opcodes = {spv::Op::OpConstantComposite}; - EXPECT_THAT(opcodes, Contains(inst->opcode())); - analysis::ConstantManager* const_mrg = context->get_constant_mgr(); - const analysis::Constant* result = const_mrg->GetConstantFromInst(inst); - EXPECT_NE(result, nullptr); - if (result != nullptr) { - const std::vector& componenets = - result->AsVectorConstant()->GetComponents(); - EXPECT_EQ(componenets.size(), tc.expected_result.size()); - for (size_t i = 0; i < componenets.size(); i++) { - EXPECT_EQ(tc.expected_result[i], componenets[i]->GetS32()); - } - } - } -} - -// clang-format off -INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest, -::testing::Values( - // Test case 0: fold negate of a vector - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %v2int %v2int_2_3\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {-2, -3}), - // Test case 1: fold negate of a vector containing negative values. - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %v2int %v2int_n1_n24\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {1, 24}), - // Test case 2: fold negate of a vector at the limits - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpSNegate %v2int %v2int_min_max\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {INT_MIN, -INT_MAX}), - // Test case 3: fold vector components of int - InstructionFoldingCase>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpIMul %v2int %v2int_2_3 %v2int_2_3\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {4,9}) + 2, {2147483648, 2147483647}) )); // clang-format on @@ -1137,9 +993,9 @@ TEST_P(DoubleVectorInstructionFoldingTest, Case) { // Make sure the instruction folded as expected. EXPECT_TRUE(succeeded); if (succeeded && inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - std::vector opcodes = {spv::Op::OpConstantComposite}; + std::vector opcodes = {SpvOpConstantComposite}; EXPECT_THAT(opcodes, Contains(inst->opcode())); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::Constant* result = const_mrg->GetConstantFromInst(inst); @@ -1194,16 +1050,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, DoubleVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {30.0,30.0,30.0,30.0}), - // Test case 4: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {1.0, 2.0, 3.0, 4.0} {30.0, 0.0, 30.0, 0.0} - InstructionFoldingCase>( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpVectorTimesMatrix %v4double %v4double_1_2_3_4 %mat4v4double_1_2_3_4_null\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {30.0,0.0,30.0,0.0}), - // Test case 5: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0} + // Test case 4: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1212,7 +1059,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, DoubleVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0,0.0,0.0,0.0}), - // Test case 6: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} + // Test case 5: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1221,7 +1068,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, DoubleVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0,0.0,0.0,0.0}), - // Test case 7: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0} + // Test case 6: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1229,16 +1076,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, DoubleVectorInstructionFoldingTest, "%2 = OpMatrixTimesVector %v4double %mat4v4double_1_2_3_4 %v4double_1_2_3_4\n" + "OpReturn\n" + "OpFunctionEnd", - 2, {10.0,20.0,30.0,40.0}), - // Test case 8: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {10.0, 20.0, 30.0, 40.0} - InstructionFoldingCase>( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpMatrixTimesVector %v4double %mat4v4double_1_2_3_4_null %v4double_1_2_3_4\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {4.0,8.0,12.0,16.0}) + 2, {10.0,20.0,30.0,40.0}) )); using FloatVectorInstructionFoldingTest = @@ -1256,15 +1094,15 @@ TEST_P(FloatVectorInstructionFoldingTest, Case) { // Fold the instruction to test. analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold); - spv::Op original_opcode = inst->opcode(); + SpvOp original_opcode = inst->opcode(); bool succeeded = context->get_instruction_folder().FoldInstruction(inst); // Make sure the instruction folded as expected. EXPECT_EQ(succeeded, inst == nullptr || inst->opcode() != original_opcode); if (succeeded && inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - std::vector opcodes = {spv::Op::OpConstantComposite}; + std::vector opcodes = {SpvOpConstantComposite}; EXPECT_THAT(opcodes, Contains(inst->opcode())); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::Constant* result = const_mrg->GetConstantFromInst(inst); @@ -1317,16 +1155,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0f,0.0f,0.0f,0.0f}), - // Test case 4: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {1.0, 2.0, 3.0, 4.0} {30.0, 0.0, 30.0, 0.0} - InstructionFoldingCase>( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpVectorTimesMatrix %v4float %v4float_1_2_3_4 %mat4v4float_1_2_3_4_null\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {30.0,0.0,30.0,0.0}), - // Test case 5: OpVectorTimesMatrix Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} + // Test case 4: OpVectorTimesMatrix Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1335,7 +1164,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0f,0.0f,0.0f,0.0f}), - // Test case 6: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {1.0, 2.0, 3.0, 4.0} {30.0, 30.0, 30.0, 30.0} + // Test case 5: OpVectorTimesMatrix Non-Zero Non-Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {1.0, 2.0, 3.0, 4.0} {30.0, 30.0, 30.0, 30.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1344,7 +1173,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {30.0f,30.0f,30.0f,30.0f}), - // Test case 7: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0} + // Test case 6: OpMatrixTimesVector Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0}} {0.0, 0.0, 0.0, 0.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1353,7 +1182,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0f,0.0f,0.0f,0.0f}), - // Test case 8: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} + // Test case 7: OpMatrixTimesVector Non-Zero Zero {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {0.0, 0.0, 0.0, 0.0} {0.0, 0.0, 0.0, 0.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1362,7 +1191,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "OpReturn\n" + "OpFunctionEnd", 2, {0.0f,0.0f,0.0f,0.0f}), - // Test case 9: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0} + // Test case 8: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}, {1.0, 2.0, 3.0, 4.0}} {10.0, 20.0, 30.0, 40.0} InstructionFoldingCase>( Header() + "%main = OpFunction %void None %void_func\n" + @@ -1370,96 +1199,9 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest, "%2 = OpMatrixTimesVector %v4float %mat4v4float_1_2_3_4 %v4float_1_2_3_4\n" + "OpReturn\n" + "OpFunctionEnd", - 2, {10.0f,20.0f,30.0f,40.0f}), - // Test case 10: OpMatrixTimesVector Non-Zero Non-Zero {1.0, 2.0, 3.0, 4.0} {{1.0, 2.0, 3.0, 4.0}, Null, {1.0, 2.0, 3.0, 4.0}, Null} {10.0, 20.0, 30.0, 40.0} - InstructionFoldingCase>( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpMatrixTimesVector %v4float %mat4v4float_1_2_3_4_null %v4float_1_2_3_4\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {4.0,8.0,12.0,16.0}) + 2, {10.0f,20.0f,30.0f,40.0f}) )); // clang-format on - -using FloatMatrixInstructionFoldingTest = ::testing::TestWithParam< - InstructionFoldingCase>>>; - -TEST_P(FloatMatrixInstructionFoldingTest, Case) { - const auto& tc = GetParam(); - - // Build module. - std::unique_ptr context = - BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - ASSERT_NE(nullptr, context); - - // Fold the instruction to test. - analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold); - bool succeeded = context->get_instruction_folder().FoldInstruction(inst); - - // Make sure the instruction folded as expected. - EXPECT_TRUE(succeeded); - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); - - if (inst->opcode() == spv::Op::OpCopyObject) { - inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - analysis::ConstantManager* const_mgr = context->get_constant_mgr(); - const analysis::Constant* result = const_mgr->GetConstantFromInst(inst); - EXPECT_NE(result, nullptr); - if (result != nullptr) { - std::vector matrix = - result->AsMatrixConstant()->GetComponents(); - EXPECT_EQ(matrix.size(), tc.expected_result.size()); - for (size_t c = 0; c < matrix.size(); c++) { - if (matrix[c]->AsNullConstant() != nullptr) { - matrix[c] = const_mgr->GetNullCompositeConstant(matrix[c]->type()); - } - const analysis::VectorConstant* column_const = - matrix[c]->AsVectorConstant(); - ASSERT_NE(column_const, nullptr); - const std::vector& column = - column_const->GetComponents(); - EXPECT_EQ(column.size(), tc.expected_result[c].size()); - for (size_t r = 0; r < column.size(); r++) { - EXPECT_EQ(tc.expected_result[c][r], column[r]->GetFloat()); - } - } - } - } -} - -// clang-format off -INSTANTIATE_TEST_SUITE_P(TestCase, FloatMatrixInstructionFoldingTest, -::testing::Values( - // Test case 0: OpTranspose square null matrix - InstructionFoldingCase>>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpTranspose %mat4v4float %mat4v4float_null\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f}}), - // Test case 1: OpTranspose rectangular null matrix - InstructionFoldingCase>>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpTranspose %mat4v2float %mat2v4float_null\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f}}), - InstructionFoldingCase>>( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%2 = OpTranspose %mat4v4float %mat4v4float_1_2_3_4\n" + - "OpReturn\n" + - "OpFunctionEnd", - 2, {{1.0f, 1.0f, 1.0f, 1.0f},{2.0f, 2.0f, 2.0f, 2.0f},{3.0f, 3.0f, 3.0f, 3.0f},{4.0f, 4.0f, 4.0f, 4.0f}}) -)); -// clang-format on - using BooleanInstructionFoldingTest = ::testing::TestWithParam>; @@ -1480,10 +1222,9 @@ TEST_P(BooleanInstructionFoldingTest, Case) { // Make sure the instruction folded as expected. EXPECT_TRUE(succeeded); if (inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - std::vector bool_opcodes = {spv::Op::OpConstantTrue, - spv::Op::OpConstantFalse}; + std::vector bool_opcodes = {SpvOpConstantTrue, SpvOpConstantFalse}; EXPECT_THAT(bool_opcodes, Contains(inst->opcode())); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::BoolConstant* result = @@ -2092,9 +1833,9 @@ TEST_P(FloatInstructionFoldingTest, Case) { // Make sure the instruction folded as expected. EXPECT_TRUE(succeeded); if (inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - EXPECT_EQ(inst->opcode(), spv::Op::OpConstant); + EXPECT_EQ(inst->opcode(), SpvOpConstant); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::FloatConstant* result = const_mrg->GetConstantFromInst(inst)->AsFloatConstant(); @@ -2525,9 +2266,9 @@ TEST_P(DoubleInstructionFoldingTest, Case) { // Make sure the instruction folded as expected. EXPECT_TRUE(succeeded); if (inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0)); - EXPECT_EQ(inst->opcode(), spv::Op::OpConstant); + EXPECT_EQ(inst->opcode(), SpvOpConstant); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::FloatConstant* result = const_mrg->GetConstantFromInst(inst)->AsFloatConstant(); @@ -3412,7 +3153,7 @@ TEST_P(IntegerInstructionFoldingTestWithMap, Case) { // Make sure the instruction folded as expected. EXPECT_NE(inst, nullptr); if (inst != nullptr) { - EXPECT_EQ(inst->opcode(), spv::Op::OpConstant); + EXPECT_EQ(inst->opcode(), SpvOpConstant); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::IntConstant* result = const_mrg->GetConstantFromInst(inst)->AsIntConstant(); @@ -3460,8 +3201,7 @@ TEST_P(BooleanInstructionFoldingTestWithMap, Case) { // Make sure the instruction folded as expected. EXPECT_NE(inst, nullptr); if (inst != nullptr) { - std::vector bool_opcodes = {spv::Op::OpConstantTrue, - spv::Op::OpConstantFalse}; + std::vector bool_opcodes = {SpvOpConstantTrue, SpvOpConstantFalse}; EXPECT_THAT(bool_opcodes, Contains(inst->opcode())); analysis::ConstantManager* const_mrg = context->get_constant_mgr(); const analysis::BoolConstant* result = @@ -3513,7 +3253,7 @@ TEST_P(GeneralInstructionFoldingTest, Case) { EXPECT_EQ(inst->type_id(), original_inst->type_id()); EXPECT_TRUE((!succeeded) == (tc.expected_result == 0)); if (succeeded) { - EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject); + EXPECT_EQ(inst->opcode(), SpvOpCopyObject); EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result); } else { EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands()); @@ -4520,17 +4260,6 @@ INSTANTIATE_TEST_SUITE_P(FloatRedundantFoldingTest, GeneralInstructionFoldingTes "%2 = OpDot %half %half_0_1 %half_0_1\n" + "OpReturn\n" + "OpFunctionEnd", - 2, 0), - // Test case 23: Don't fold 1.0(half) / 2.0(half) - // We do not have to code to emulate 16-bit float operations. Just make sure we do not crash. - InstructionFoldingCase( - Header() + "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%n = OpVariable %_ptr_half Function\n" + - "%3 = OpLoad %half %n\n" + - "%2 = OpFDiv %half %half_1 %half_2\n" + - "OpReturn\n" + - "OpFunctionEnd", 2, 0) )); @@ -5182,7 +4911,7 @@ TEST_P(ToNegateFoldingTest, Case) { EXPECT_EQ(inst->type_id(), original_inst->type_id()); EXPECT_TRUE((!succeeded) == (tc.expected_result == 0)); if (succeeded) { - EXPECT_EQ(inst->opcode(), spv::Op::OpFNegate); + EXPECT_EQ(inst->opcode(), SpvOpFNegate); EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result); } else { EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands()); @@ -7632,41 +7361,6 @@ INSTANTIATE_TEST_SUITE_P(CompositeExtractOrInsertMatchingTest, MatchingInstructi "%5 = OpCompositeConstruct %v2int %3 %4\n" + "OpReturn\n" + "OpFunctionEnd", - 5, true), - // Test case 16: Don't fold when type cannot be deduced to a constant. - InstructionFoldingCase( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%4 = OpCompositeInsert %struct_v2int_int_int %int_1 %struct_v2int_int_int_null 2\n" + - "OpReturn\n" + - "OpFunctionEnd", - 4, false), - // Test case 17: Don't fold when index into composite is out of bounds. - InstructionFoldingCase( - Header() + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%4 = OpCompositeExtract %int %struct_v2int_int_int 3\n" + - "OpReturn\n" + - "OpFunctionEnd", - 4, false), - // Test case 18: Fold when every element of an array is inserted. - InstructionFoldingCase( - Header() + - "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" + - "; CHECK: [[int2:%\\w+]] = OpConstant [[int]] 2\n" + - "; CHECK-DAG: [[arr_type:%\\w+]] = OpTypeArray [[int]] [[int2]]\n" + - "; CHECK-DAG: [[int10:%\\w+]] = OpConstant [[int]] 10\n" + - "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" + - "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[arr_type]] [[int10]] [[int1]]\n" + - "; CHECK: %5 = OpCopyObject [[arr_type]] [[construct]]\n" + - "%main = OpFunction %void None %void_func\n" + - "%main_lab = OpLabel\n" + - "%4 = OpCompositeInsert %int_arr_2 %int_10 %int_arr_2_undef 0\n" + - "%5 = OpCompositeInsert %int_arr_2 %int_1 %4 1\n" + - "OpReturn\n" + - "OpFunctionEnd", 5, true) )); @@ -8697,7 +8391,6 @@ std::string ImageOperandsTestBody(const std::string& image_instruction) { %v3int = OpTypeVector %int 3 %Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant %gSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant - %110 = OpConstantComposite %v2int %5 %5 %101 = OpConstantComposite %v2int %int_n1 %int_n1 %20 = OpConstantComposite %v2float %float_0 %float_0 %main = OpFunction %void None %22 @@ -8757,12 +8450,7 @@ INSTANTIATE_TEST_SUITE_P(ImageOperandsBitmaskFoldingTest, MatchingInstructionWit InstructionFoldingCase(ImageOperandsTestBody( " OpImageWrite %88 %5 %101 Offset %101 \n" "; CHECK: OpImageWrite %88 %5 %101 ConstOffset %101 \n") - , 0 /* No result-id */, true), - // Test case 8: OpImageFetch with zero constant Offset - InstructionFoldingCase(ImageOperandsTestBody( - " %89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %110 \n" - "; CHECK: %89 = OpImageFetch %10 %88 %101 Lod %5 \n") - , 89, true) + , 0 /* No result-id */, true) )); } // namespace diff --git a/test/opt/freeze_spec_const_test.cpp b/test/opt/freeze_spec_const_test.cpp index 1ccaa3ef..ad0fc32e 100644 --- a/test/opt/freeze_spec_const_test.cpp +++ b/test/opt/freeze_spec_const_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include diff --git a/test/opt/function_test.cpp b/test/opt/function_test.cpp index 6a40e938..34a03871 100644 --- a/test/opt/function_test.cpp +++ b/test/opt/function_test.cpp @@ -13,6 +13,8 @@ // limitations under the License. #include +#include +#include #include #include "function_utils.h" @@ -246,7 +248,7 @@ OpFunctionEnd std::unordered_set non_semantic_ids; func->ForEachInst( [&non_semantic_ids](const Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { non_semantic_ids.insert(inst->result_id()); } }, @@ -283,7 +285,7 @@ OpFunctionEnd std::unordered_set non_semantic_ids; func->ForEachInst( [&non_semantic_ids](const Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { non_semantic_ids.insert(inst->result_id()); } }, diff --git a/test/opt/graphics_robust_access_test.cpp b/test/opt/graphics_robust_access_test.cpp index a1a3b7d3..057b909d 100644 --- a/test/opt/graphics_robust_access_test.cpp +++ b/test/opt/graphics_robust_access_test.cpp @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include +#include "gmock/gmock.h" #include "pass_fixture.h" #include "pass_utils.h" #include "source/opt/graphics_robust_access_pass.h" diff --git a/test/opt/if_conversion_test.cpp b/test/opt/if_conversion_test.cpp index c1425e83..dc7f8316 100644 --- a/test/opt/if_conversion_test.cpp +++ b/test/opt/if_conversion_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/inline_test.cpp b/test/opt/inline_test.cpp index 1e5d9f3b..f3ff81ce 100644 --- a/test/opt/inline_test.cpp +++ b/test/opt/inline_test.cpp @@ -4437,7 +4437,7 @@ OpFunctionEnd // Callee function returns a value generated outside the callee, // e.g. a constant value. This might exercise some logic not yet // exercised by the current tests: the false branch in the "if" -// inside the spv::Op::OpReturnValue case in InlinePass::GenInlineCode? +// inside the SpvOpReturnValue case in InlinePass::GenInlineCode? // SampledImage before function call, but callee is only single block. // Then the SampledImage instruction is not cloned. Documents existing // behaviour. diff --git a/test/opt/inst_bindless_check_test.cpp b/test/opt/inst_bindless_check_test.cpp index 08da367f..90f40bc6 100644 --- a/test/opt/inst_bindless_check_test.cpp +++ b/test/opt/inst_bindless_check_test.cpp @@ -18,6 +18,7 @@ #include #include +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" @@ -27,18 +28,456 @@ namespace { using InstBindlessTest = PassTest<::testing::Test>; -static const std::string kFuncName = "inst_bindless_check_desc"; - -static const std::string kImportDeco = R"( -;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" + - kFuncName + R"(" Import +static const std::string kOutputDecorations = R"( +; CHECK: OpDecorate [[output_buffer_type:%inst_bindless_OutputBuffer]] Block +; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0 +; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4 +; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7 +; CHECK: OpDecorate [[output_buffer_var]] Binding 0 )"; -static const std::string kImportStub = R"( -;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}} -;CHECK: OpFunctionEnd +static const std::string kOutputGlobals = R"( +; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %_runtimearr_uint +; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]] +; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer )"; +static const std::string kStreamWrite4Begin = R"( +; CHECK: %inst_bindless_stream_write_4 = OpFunction %void None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_0 +; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_10 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10 +; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 1 +; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}} +; CHECK: OpSelectionMerge {{%\w+}} None +; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_10 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_23 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_1]] +)"; + +static const std::string kStreamWrite4End = R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_2]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_3]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_4]] +; CHECK: OpBranch {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: OpReturn +; CHECK: OpFunctionEnd +)"; + +// clang-format off +static const std::string kStreamWrite4Frag = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord +; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite4Tese = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_2 +; CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord +; CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite4Vert = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_0 +; CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite4Compute = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite4Ray = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint %90 0 +; CHECK: {{%\w+}} = OpCompositeExtract %uint %90 1 +; CHECK: {{%\w+}} = OpCompositeExtract %uint %90 2 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; +// clang-format on + +static const std::string kStreamWrite5Begin = R"( +; CHECK: %inst_bindless_stream_write_5 = OpFunction %void None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_5:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_0 +; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_11 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_11 +; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 1 +; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}} +; CHECK: OpSelectionMerge {{%\w+}} None +; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_11 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_23 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_1]] +)"; + +static const std::string kStreamWrite5End = R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_2]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_3]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_4]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_5]] +; CHECK: OpBranch {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: OpReturn +; CHECK: OpFunctionEnd +)"; + +// clang-format off +static const std::string kStreamWrite5Frag = kStreamWrite5Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord +; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite5Vert = kStreamWrite5Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_0 +; CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite5End; +// clang-format on + +static const std::string kInputDecorations = R"( +; CHECK: OpDecorate [[input_buffer_type:%inst_bindless_InputBuffer]] Block +; CHECK: OpMemberDecorate [[input_buffer_type]] 0 Offset 0 +; CHECK: OpDecorate [[input_buffer_var:%\w+]] DescriptorSet 7 +; CHECK: OpDecorate [[input_buffer_var]] Binding 1 +)"; + +static const std::string kInputGlobals = R"( +; CHECK: [[input_buffer_type]] = OpTypeStruct %_runtimearr_uint +; CHECK: [[input_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[input_buffer_type]] +; CHECK: [[input_buffer_var]] = OpVariable [[input_ptr_type]] StorageBuffer +)"; + +static const std::string kDirectRead2 = R"( +; CHECK: %inst_bindless_direct_read_2 = OpFunction %uint None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 [[param_1]] +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_2]] +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: OpReturnValue {{%\w+}} +; CHECK: OpFunctionEnd +)"; + +static const std::string kDirectRead3 = R"( + ;CHECK: %inst_bindless_direct_read_3 = OpFunction %uint None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint + ;CHECK: {{%\w+}} = OpLabel + ;CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 [[param_1]] + ;CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} + ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_2]] + ;CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} + ;CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} + ;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_3]] + ;CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} + ;CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} + ;CHECK: OpReturnValue {{%\w+}} + ;CHECK: OpFunctionEnd +)"; + +static const std::string kDirectRead4 = R"( +; CHECK: %inst_bindless_direct_read_4 = OpFunction %uint None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 [[param_1]] +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_2]] +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_3]] +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} [[param_4]] +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} +; CHECK: OpReturnValue {{%\w+}} +; CHECK: OpFunctionEnd +)"; + +TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) { + // Texture2D g_tColor[128]; + // + // SamplerState g_sAniso; + // + // struct PS_INPUT + // { + // float2 vTextureCoords : TEXCOORD2; + // }; + // + // struct PS_OUTPUT + // { + // float4 vColor : SV_Target0; + // }; + // + // PS_OUTPUT MainPs(PS_INPUT i) + // { + // PS_OUTPUT ps_output; + // + // ps_output.vColor = g_tColor[ 37 ].Sample(g_sAniso, i.vTextureCoords.xy); + // return ps_output; + // } + + const std::string before = + R"(OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor +OpExecutionMode %MainPs OriginUpperLeft +OpSource HLSL 500 +OpName %MainPs "MainPs" +OpName %g_tColor "g_tColor" +OpName %g_sAniso "g_sAniso" +OpName %i_vTextureCoords "i.vTextureCoords" +OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" +OpDecorate %g_tColor DescriptorSet 3 +OpDecorate %g_tColor Binding 0 +OpDecorate %g_sAniso DescriptorSet 0 +OpDecorate %i_vTextureCoords Location 0 +OpDecorate %_entryPointOutput_vColor Location 0 +%void = OpTypeVoid +%8 = OpTypeFunction %void +%float = OpTypeFloat 32 +%v2float = OpTypeVector %float 2 +%v4float = OpTypeVector %float 4 +%int = OpTypeInt 32 1 +%int_0 = OpConstant %int 0 +%int_37 = OpConstant %int 37 +%15 = OpTypeImage %float 2D 0 0 0 1 Unknown +%uint = OpTypeInt 32 0 +%uint_128 = OpConstant %uint 128 +%_arr_15_uint_128 = OpTypeArray %15 %uint_128 +%_ptr_UniformConstant__arr_15_uint_128 = OpTypePointer UniformConstant %_arr_15_uint_128 +%g_tColor = OpVariable %_ptr_UniformConstant__arr_15_uint_128 UniformConstant +%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 +%21 = OpTypeSampler +%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 +%g_sAniso = OpVariable %_ptr_UniformConstant_21 UniformConstant +%23 = OpTypeSampledImage %15 +%_ptr_Input_v2float = OpTypePointer Input %v2float +%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float +%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output +%MainPs = OpFunction %void None %8 +%26 = OpLabel +%27 = OpLoad %v2float %i_vTextureCoords +%28 = OpAccessChain %_ptr_UniformConstant_15 %g_tColor %int_37 +%29 = OpLoad %15 %28 +%30 = OpLoad %21 %g_sAniso +%31 = OpSampledImage %23 %29 %30 +%32 = OpImageSampleImplicitLod %v4float %31 %27 +OpStore %_entryPointOutput_vColor %32 +OpReturn +OpFunctionEnd +)"; + + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndCheck( + before, before, true, true, 7u, 23u, false, false, false, false, false); +} + +TEST_F(InstBindlessTest, NoInstrumentNonBindless) { + // This test verifies that the pass will correctly not instrument vanilla + // texture sample. + // + // Texture2D g_tColor; + // + // SamplerState g_sAniso; + // + // struct PS_INPUT + // { + // float2 vTextureCoords : TEXCOORD2; + // }; + // + // struct PS_OUTPUT + // { + // float4 vColor : SV_Target0; + // }; + // + // PS_OUTPUT MainPs(PS_INPUT i) + // { + // PS_OUTPUT ps_output; + // ps_output.vColor = + // g_tColor.Sample(g_sAniso, i.vTextureCoords.xy); + // return ps_output; + // } + + const std::string whole_file = + R"(OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor +OpExecutionMode %MainPs OriginUpperLeft +OpSource HLSL 500 +OpName %MainPs "MainPs" +OpName %g_tColor "g_tColor" +OpName %g_sAniso "g_sAniso" +OpName %i_vTextureCoords "i.vTextureCoords" +OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" +OpDecorate %g_tColor DescriptorSet 0 +OpDecorate %g_tColor Binding 0 +OpDecorate %g_sAniso DescriptorSet 0 +OpDecorate %g_sAniso Binding 0 +OpDecorate %i_vTextureCoords Location 0 +OpDecorate %_entryPointOutput_vColor Location 0 +%void = OpTypeVoid +%8 = OpTypeFunction %void +%float = OpTypeFloat 32 +%v2float = OpTypeVector %float 2 +%v4float = OpTypeVector %float 4 +%12 = OpTypeImage %float 2D 0 0 0 1 Unknown +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant +%14 = OpTypeSampler +%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 +%g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant +%16 = OpTypeSampledImage %12 +%_ptr_Input_v2float = OpTypePointer Input %v2float +%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float +%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output +%MainPs = OpFunction %void None %8 +%19 = OpLabel +%20 = OpLoad %v2float %i_vTextureCoords +%21 = OpLoad %12 %g_tColor +%22 = OpLoad %14 %g_sAniso +%23 = OpSampledImage %16 %21 %22 +%24 = OpImageSampleImplicitLod %v4float %23 %20 +OpStore %_entryPointOutput_vColor %24 +OpReturn +OpFunctionEnd +)"; + + // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndCheck(whole_file, whole_file, true, + true, 7u, 23u, false, false, + false, false, false); +} + TEST_F(InstBindlessTest, Simple) { // Texture2D g_tColor[128]; // @@ -69,11 +508,11 @@ TEST_F(InstBindlessTest, Simple) { const std::string entry = R"( OpCapability Shader -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 )"; @@ -94,10 +533,10 @@ OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block OpDecorate %g_sAniso DescriptorSet 0 OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0)" -+ kImportDeco + -R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +OpDecorate %_entryPointOutput_vColor Location 0 +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord )"; const std::string consts_types_vars = R"( @@ -127,10 +566,29 @@ R"( %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %48 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_56 = OpConstant %uint 56 +; CHECK: %103 = OpConstantNull %v4float )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %10 @@ -144,30 +602,32 @@ R"( %36 = OpSampledImage %26 %34 %35 %37 = OpImageSampleImplicitLod %v4float %36 %30 OpStore %_entryPointOutput_vColor %37 -;CHECK-NOT: %37 = OpImageSampleImplicitLod %v4float %36 %30 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %37 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_57 {{%\w+}} %uint_3 %uint_0 %32 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %16 %33 -;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] +; CHECK-NOT: %37 = OpImageSampleImplicitLod %v4float %36 %30 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %37 +; CHECK: %40 = OpULessThan %bool %32 %uint_128 +; CHECK: OpSelectionMerge %41 None +; CHECK: OpBranchConditional %40 %42 %43 +; CHECK: %42 = OpLabel +; CHECK: %44 = OpLoad %16 %33 +; CHECK: %45 = OpSampledImage %26 %44 %35 +; CHECK: %46 = OpImageSampleImplicitLod %v4float %45 %30 +; CHECK: OpBranch %41 +; CHECK: %43 = OpLabel +; CHECK: %102 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_56 %uint_0 %32 %uint_128 +; CHECK: OpBranch %41 +; CHECK: %41 = OpLabel +; CHECK: %104 = OpPhi %v4float %46 %42 %103 %43 +; CHECK: OpStore %_entryPointOutput_vColor %104 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - entry + names_annots + consts_types_vars + kImportStub + main_func, true, - 23u); + SinglePassRunAndMatch( + entry + names_annots + consts_types_vars + main_func + output_func, true, + 7u, 23u, false, false, false, false, false); } TEST_F(InstBindlessTest, InstrumentMultipleInstructions) { @@ -204,11 +664,11 @@ TEST_F(InstBindlessTest, InstrumentMultipleInstructions) { // clang-format off const std::string defs = R"( OpCapability Shader -OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -220,15 +680,16 @@ OpName %g_sAniso "g_sAniso" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" OpDecorate %g_tColor DescriptorSet 3 -OpDecorate %g_tColor Binding 4 +OpDecorate %g_tColor Binding 0 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4 OpDecorate %PerViewConstantBuffer_t Block -OpDecorate %g_sAniso DescriptorSet 3 +OpDecorate %g_sAniso DescriptorSet 0 OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %10 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -256,14 +717,33 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %56 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_58 = OpConstant %uint 58 +; CHECK: %111 = OpConstantNull %v4float +; CHECK: %uint_64 = OpConstant %uint 64 )"; + // clang-format on - const std::string main_func = R"( -%MainPs = OpFunction %void None %10 + const std::string main_func = + R"(%MainPs = OpFunction %void None %10 %30 = OpLabel %31 = OpLoad %v2float %i_vTextureCoords %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 @@ -273,24 +753,20 @@ OpDecorate %_entryPointOutput_vColor Location 0 %36 = OpLoad %25 %g_sAniso %37 = OpSampledImage %27 %35 %36 %38 = OpImageSampleImplicitLod %v4float %37 %31 -;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_3 %uint_4 %33 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %17 %34 -;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} +; CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 +; CHECK: %48 = OpULessThan %bool %33 %uint_128 +; CHECK: OpSelectionMerge %49 None +; CHECK: OpBranchConditional %48 %50 %51 +; CHECK: %50 = OpLabel +; CHECK: %52 = OpLoad %17 %34 +; CHECK: %53 = OpSampledImage %27 %52 %36 +; CHECK: %54 = OpImageSampleImplicitLod %v4float %53 %31 +; CHECK: OpBranch %49 +; CHECK: %51 = OpLabel +; CHECK: %110 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_58 %uint_0 %33 %uint_128 +; CHECK: OpBranch %49 +; CHECK: %49 = OpLabel +; CHECK: %112 = OpPhi %v4float %54 %50 %111 %51 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1 %40 = OpLoad %uint %39 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40 @@ -298,35 +774,33 @@ OpDecorate %_entryPointOutput_vColor Location 0 %43 = OpSampledImage %27 %42 %36 %44 = OpImageSampleImplicitLod %v4float %43 %31 %45 = OpFAdd %v4float %38 %44 -;CHECK-NOT: %44 = OpImageSampleImplicitLod %v4float %43 %31 -;CHECK-NOT: %45 = OpFAdd %v4float %38 %44 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_66 {{%\w+}} %uint_3 %uint_4 %40 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %17 %41 -;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %45 = OpFAdd %v4float {{%\w+}} {{%\w+}} +; CHECK-NOT: %44 = OpImageSampleImplicitLod %v4float %43 %31 +; CHECK-NOT: %45 = OpFAdd %v4float %38 %44 +; CHECK: %113 = OpULessThan %bool %40 %uint_128 +; CHECK: OpSelectionMerge %114 None +; CHECK: OpBranchConditional %113 %115 %116 +; CHECK: %115 = OpLabel +; CHECK: %117 = OpLoad %17 %41 +; CHECK: %118 = OpSampledImage %27 %117 %36 +; CHECK: %119 = OpImageSampleImplicitLod %v4float %118 %31 +; CHECK: OpBranch %114 +; CHECK: %116 = OpLabel +; CHECK: %121 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_64 %uint_0 %40 %uint_128 +; CHECK: OpBranch %114 +; CHECK: %114 = OpLabel +; CHECK: %122 = OpPhi %v4float %119 %115 %111 %116 +; CHECK: %45 = OpFAdd %v4float %112 %122 OpStore %_entryPointOutput_vColor %45 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, InstrumentOpImage) { @@ -338,11 +812,11 @@ TEST_F(InstBindlessTest, InstrumentOpImage) { const std::string defs = R"( OpCapability Shader OpCapability StorageImageReadWithoutFormat -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -353,13 +827,14 @@ OpName %_ "" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" OpDecorate %g_tColor DescriptorSet 3 -OpDecorate %g_tColor Binding 9 +OpDecorate %g_tColor Binding 0 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -383,10 +858,29 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: uint_0 = OpConstant %uint 0 +; CHECK: bool = OpTypeBool +; CHECK: %86 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %141 = OpConstantNull %v4float )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %3 @@ -399,34 +893,32 @@ OpDecorate %_entryPointOutput_vColor Location 0 %75 = OpImage %20 %66 %71 = OpImageRead %v4float %75 %53 OpStore %_entryPointOutput_vColor %71 -;CHECK-NOT: %71 = OpImageRead %v4float %75 %53 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_9 %64 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %39 %65 -;CHECK: {{%\w+}} = OpImage %20 {{%\w+}} -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %53 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} +; CHECK-NOT: %71 = OpImageRead %v4float %75 %53 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %71 +; CHECK: %78 = OpULessThan %bool %64 %uint_128 +; CHECK: OpSelectionMerge %79 None +; CHECK: OpBranchConditional %78 %80 %81 +; CHECK: %80 = OpLabel +; CHECK: %82 = OpLoad %39 %65 +; CHECK: %83 = OpImage %20 %82 +; CHECK: %84 = OpImageRead %v4float %83 %53 +; CHECK: OpBranch %79 +; CHECK: %81 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %64 %uint_128 +; CHECK: OpBranch %79 +; CHECK: %79 = OpLabel +; CHECK: %142 = OpPhi %v4float %84 %80 %141 %81 +; CHECK: OpStore %_entryPointOutput_vColor %142 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, InstrumentSampledImage) { @@ -437,11 +929,11 @@ TEST_F(InstBindlessTest, InstrumentSampledImage) { // clang-format off const std::string defs = R"( OpCapability Shader -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -451,14 +943,14 @@ OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" OpName %_ "" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpDecorate %g_tColor DescriptorSet 4 -OpDecorate %g_tColor Binding 11 +OpDecorate %g_tColor DescriptorSet 3 +OpDecorate %g_tColor Binding 0 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -482,10 +974,29 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: uint_0 = OpConstant %uint 0 +; CHECK: bool = OpTypeBool +; CHECK: %81 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_49 = OpConstant %uint 49 +; CHECK: %136 = OpConstantNull %v4float )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %3 @@ -497,33 +1008,31 @@ OpDecorate %_entryPointOutput_vColor Location 0 %66 = OpLoad %39 %65 %71 = OpImageSampleImplicitLod %v4float %66 %53 OpStore %_entryPointOutput_vColor %71 -;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %66 %53 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_50 {{%\w+}} %uint_4 %uint_11 %64 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %39 %65 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %53 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} +; CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %66 %53 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %71 +; CHECK: %74 = OpULessThan %bool %64 %uint_128 +; CHECK: OpSelectionMerge %75 None +; CHECK: OpBranchConditional %74 %76 %77 +; CHECK: %76 = OpLabel +; CHECK: %78 = OpLoad %39 %65 +; CHECK: %79 = OpImageSampleImplicitLod %v4float %78 %53 +; CHECK: OpBranch %75 +; CHECK: %77 = OpLabel +; CHECK: %135 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_49 %uint_0 %64 %uint_128 +; CHECK: OpBranch %75 +; CHECK: %75 = OpLabel +; CHECK: %137 = OpPhi %v4float %79 %76 %136 %77 +; CHECK: OpStore %_entryPointOutput_vColor %137 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, InstrumentImageWrite) { @@ -535,11 +1044,11 @@ TEST_F(InstBindlessTest, InstrumentImageWrite) { const std::string defs = R"( OpCapability Shader OpCapability StorageImageWriteWithoutFormat -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -549,14 +1058,15 @@ OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" OpName %_ "" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpDecorate %g_tColor DescriptorSet 30 -OpDecorate %g_tColor Binding 2 +OpDecorate %g_tColor DescriptorSet 3 +OpDecorate %g_tColor Binding 0 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -581,10 +1091,28 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: uint_0 = OpConstant %uint 0 +; CHECK: bool = OpTypeBool +; CHECK: %41 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: _runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %3 @@ -596,33 +1124,30 @@ OpDecorate %_entryPointOutput_vColor Location 0 %66 = OpLoad %20 %65 OpImageWrite %66 %53 %80 OpStore %_entryPointOutput_vColor %80 -;CHECK-NOT: OpImageWrite %66 %53 %80 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %80 -;CHECK: %32 = OpLoad %16 %31 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_30 %uint_2 %30 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %16 %31 -;CHECK: OpImageWrite {{%\w+}} %28 %19 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %_entryPointOutput_vColor %19 +; CHECK-NOT: OpImageWrite %66 %53 %80 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %80 +; CHECK: %35 = OpULessThan %bool %30 %uint_128 +; CHECK: OpSelectionMerge %36 None +; CHECK: OpBranchConditional %35 %37 %38 +; CHECK: %37 = OpLabel +; CHECK: %39 = OpLoad %16 %31 +; CHECK: OpImageWrite %39 %28 %19 +; CHECK: OpBranch %36 +; CHECK: %38 = OpLabel +; CHECK: %95 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %30 %uint_128 +; CHECK: OpBranch %36 +; CHECK: %36 = OpLabel +; CHECK: OpStore %_entryPointOutput_vColor %19 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, InstrumentVertexSimple) { @@ -634,7 +1159,7 @@ TEST_F(InstBindlessTest, InstrumentVertexSimple) { const std::string defs = R"( OpCapability Shader OpCapability Sampled1D -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %main "main" %_ %coords2D @@ -653,19 +1178,20 @@ OpName %foo "foo" OpMemberName %foo 0 "g_idx" OpName %__0 "" OpName %coords2D "coords2D" -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex -;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex +; CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex OpMemberDecorate %gl_PerVertex 0 BuiltIn Position OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance OpDecorate %gl_PerVertex Block -OpDecorate %texSampler1D DescriptorSet 2 -OpDecorate %texSampler1D Binding 13 +OpDecorate %texSampler1D DescriptorSet 0 +OpDecorate %texSampler1D Binding 3 OpMemberDecorate %foo 0 Offset 0 OpDecorate %foo Block -OpDecorate %__0 DescriptorSet 7 +OpDecorate %__0 DescriptorSet 0 OpDecorate %__0 Binding 5 OpDecorate %coords2D Location 0 %void = OpTypeVoid @@ -698,11 +1224,28 @@ OpDecorate %coords2D Location 0 %v2float = OpTypeVector %float 2 %_ptr_Input_v2float = OpTypePointer Input %v2float %coords2D = OpVariable %_ptr_Input_v2float Input -;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint -;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input -;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %54 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_uint = OpTypePointer Input %uint +; CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input +; CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_74 = OpConstant %uint 74 +; CHECK: %106 = OpConstantNull %v4float )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -720,51 +1263,34 @@ OpStore %coords1D %float_1_78900003 %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37 %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 OpStore %40 %38 -;CHECK-NOT: %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37 -;CHECK-NOT: %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 -;CHECK-NOT: OpStore %40 %38 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_70 {{%\w+}} %uint_7 %uint_5 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %int {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %int {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_25 %texSampler1D {{%\w+}} -;CHECK: {{%\w+}} = OpLoad {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %float %coords1D -;CHECK: {{%\w+}} = OpLoad %float %lod -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_75 {{%\w+}} %uint_2 %uint_13 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %25 %38 -;CHECK: {{%\w+}} = OpImageSampleExplicitLod %v4float {{%\w+}} %40 Lod %41 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0 -;CHECK: OpStore %43 {{%\w+}} +; CHECK-NOT: %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37 +; CHECK-NOT: %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0 +; CHECK-NOT: OpStore %40 %38 +; CHECK: %46 = OpULessThan %bool %37 %uint_128 +; CHECK: OpSelectionMerge %47 None +; CHECK: OpBranchConditional %46 %48 %49 +; CHECK: %48 = OpLabel +; CHECK: %50 = OpLoad %25 %38 +; CHECK: %51 = OpImageSampleExplicitLod %v4float %50 %40 Lod %41 +; CHECK: OpBranch %47 +; CHECK: %49 = OpLabel +; CHECK: %52 = OpBitcast %uint %37 +; CHECK: %105 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_74 %uint_0 %52 %uint_128 +; CHECK: OpBranch %47 +; CHECK: %47 = OpLabel +; CHECK: %107 = OpPhi %v4float %51 %48 %106 %49 +; CHECK: %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0 +; CHECK: OpStore %43 %107 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Vert; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, InstrumentTeseSimple) { @@ -776,9 +1302,9 @@ TEST_F(InstBindlessTest, InstrumentTeseSimple) { // #version 450 // #extension GL_EXT_nonuniform_qualifier : enable // - // layout(std140, set = 9, binding = 1) uniform ufoo { uint index; } uniform_index_buffer; + // layout(std140, set = 0, binding = 0) uniform ufoo { uint index; } uniform_index_buffer; // - // layout(set = 9, binding = 2) buffer bfoo { vec4 val; } adds[11]; + // layout(set = 0, binding = 1) buffer bfoo { vec4 val; } adds[11]; // // layout(triangles, equal_spacing, cw) in; // @@ -789,11 +1315,10 @@ TEST_F(InstBindlessTest, InstrumentTeseSimple) { const std::string defs = R"( OpCapability Tessellation -;CHECK: OpCapability Linkage %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint TessellationEvaluation %main "main" %_ -;CHECK: OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord +; CHECK: OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord OpExecutionMode %main Triangles OpExecutionMode %main SpacingEqual OpExecutionMode %main VertexOrderCw @@ -819,15 +1344,16 @@ OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance OpDecorate %gl_PerVertex Block OpMemberDecorate %bfoo 0 Offset 0 OpDecorate %bfoo Block -OpDecorate %adds DescriptorSet 9 +OpDecorate %adds DescriptorSet 0 OpDecorate %adds Binding 1 OpMemberDecorate %ufoo 0 Offset 0 OpDecorate %ufoo Block -OpDecorate %uniform_index_buffer DescriptorSet 9 -OpDecorate %uniform_index_buffer Binding 2 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -;CHECK: OpDecorate %gl_TessCoord BuiltIn TessCoord +OpDecorate %uniform_index_buffer DescriptorSet 0 +OpDecorate %uniform_index_buffer Binding 0 +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId +; CHECK: OpDecorate %gl_TessCoord BuiltIn TessCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -851,322 +1377,66 @@ OpDecorate %uniform_index_buffer Binding 2 %_ptr_Uniform_uint = OpTypePointer Uniform %uint %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float %_ptr_Output_v4float = OpTypePointer Output %v4float -;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint -;CHECK: %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input -;CHECK: %v3float = OpTypeVector %float 3 -;CHECK: %_ptr_Input_v3float = OpTypePointer Input %v3float -;CHECK: %gl_TessCoord = OpVariable %_ptr_Input_v3float Input -;CHECK: %v3uint = OpTypeVector %uint 3 -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %40 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_uint = OpTypePointer Input %uint +; CHECK: %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input +; CHECK: %v3float = OpTypeVector %float 3 +; CHECK: %_ptr_Input_v3float = OpTypePointer Input %v3float +; CHECK: %gl_TessCoord = OpVariable %_ptr_Input_v3float Input +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_63 = OpConstant %uint 63 +; CHECK: %101 = OpConstantNull %v4float )"; + // clang-format on - const std::string main_func = - R"( + const std::string main_func = R"( %main = OpFunction %void None %3 %5 = OpLabel %25 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0 %26 = OpLoad %uint %25 %28 = OpAccessChain %_ptr_StorageBuffer_v4float %adds %26 %int_0 %29 = OpLoad %v4float %28 -;CHECK-NOT: %29 = OpLoad %v4float %28 -;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID -;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord -;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_62 {{%\w+}} %uint_9 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %27 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK-NOT: %29 = OpLoad %v4float %28 +; CHECK: %34 = OpULessThan %bool %28 %uint_11 +; CHECK: OpSelectionMerge %35 None +; CHECK: OpBranchConditional %34 %36 %37 +; CHECK: %36 = OpLabel +; CHECK: %38 = OpLoad %v4float %29 +; CHECK: OpBranch %35 +; CHECK: %37 = OpLabel +; CHECK: %100 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_63 %uint_0 %28 %uint_11 +; CHECK: OpBranch %35 +; CHECK: %35 = OpLabel +; CHECK: %102 = OpPhi %v4float %38 %36 %101 %37 %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0 OpStore %31 %29 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID -;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord -;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_64 {{%\w+}} %uint_9 %uint_1 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v4float %29 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0 -;CHECK: OpStore %31 [[phi_result]] +; CHECK-NOT: OpStore %31 %29 +; CHECK: OpStore %31 %102 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Tese; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); -} - -TEST_F(InstBindlessTest, InstrumentTesc) { - // This test verifies that the pass will correctly instrument tessellation - // control shader - // - // clang-format off - // - // #version 450 - // layout(vertices = 3) out; - // layout(set = 0, binding = 0) uniform texture1D _77; - // layout(set = 0, binding = 1) uniform sampler _78; - - // layout(location = 1) flat in int _3[]; - // layout(location = 0) out vec4 _5[3]; - - // void main() - // { - // float param; - // if (_3[gl_InvocationID] == 0) - // { - // param = 0.0234375; - // } - // else - // { - // param = 1.0156199932098388671875; - // } - // _5[gl_InvocationID] = textureLod(sampler1D(_77, _78), param, 0.0); - // vec4 _203; - // if (gl_InvocationID == 0) - // { - // _203 = gl_in[0].gl_Position; - // } - // else - // { - // _203 = gl_in[2].gl_Position; - // } - // gl_out[gl_InvocationID].gl_Position = _203; - // gl_TessLevelInner[0] = 2.7999999523162841796875; - // gl_TessLevelInner[1] = 2.7999999523162841796875; - // gl_TessLevelOuter[0] = 2.7999999523162841796875; - // gl_TessLevelOuter[1] = 2.7999999523162841796875; - // gl_TessLevelOuter[2] = 2.7999999523162841796875; - // gl_TessLevelOuter[3] = 2.7999999523162841796875; - // } - // - // clang-format on - // - // - - // clang-format off - const std::string defs = R"( -OpCapability Tessellation -OpCapability Sampled1D -;CHECK: OpCapability Linkage -;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" -;CHECK: OpExtension "SPV_KHR_physical_storage_buffer" -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -;CHECK: OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter -;CHECK: OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter %gl_PrimitiveID -OpExecutionMode %main OutputVertices 3 -OpSource GLSL 450 -OpName %main "main" -OpName %_3 "_3" -OpName %gl_InvocationID "gl_InvocationID" -OpName %param "param" -OpName %_5 "_5" -OpName %_77 "_77" -OpName %_78 "_78" -OpName %_203 "_203" -OpName %gl_PerVertex "gl_PerVertex" -OpMemberName %gl_PerVertex 0 "gl_Position" -OpMemberName %gl_PerVertex 1 "gl_PointSize" -OpMemberName %gl_PerVertex 2 "gl_ClipDistance" -OpMemberName %gl_PerVertex 3 "gl_CullDistance" -OpName %gl_in "gl_in" -OpName %gl_PerVertex_0 "gl_PerVertex" -OpMemberName %gl_PerVertex_0 0 "gl_Position" -OpMemberName %gl_PerVertex_0 1 "gl_PointSize" -OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance" -OpMemberName %gl_PerVertex_0 3 "gl_CullDistance" -OpName %gl_out "gl_out" -OpName %gl_TessLevelInner "gl_TessLevelInner" -OpName %gl_TessLevelOuter "gl_TessLevelOuter" -OpDecorate %_3 Flat -OpDecorate %_3 Location 1 -OpDecorate %gl_InvocationID BuiltIn InvocationId -OpDecorate %_5 Location 0 -OpDecorate %_77 DescriptorSet 0 -OpDecorate %_77 Binding 0 -OpDecorate %_78 DescriptorSet 0 -OpDecorate %_78 Binding 1 -OpMemberDecorate %gl_PerVertex 0 BuiltIn Position -OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize -OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance -OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance -OpDecorate %gl_PerVertex Block -OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position -OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize -OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance -OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance -OpDecorate %gl_PerVertex_0 Block -OpDecorate %gl_TessLevelInner Patch -OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner -OpDecorate %gl_TessLevelOuter Patch -OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter -%void = OpTypeVoid -%3 = OpTypeFunction %void -%int = OpTypeInt 32 1 -%uint = OpTypeInt 32 0 -%uint_32 = OpConstant %uint 32 -%_arr_int_uint_32 = OpTypeArray %int %uint_32 -%_ptr_Input__arr_int_uint_32 = OpTypePointer Input %_arr_int_uint_32 -%_3 = OpVariable %_ptr_Input__arr_int_uint_32 Input -%_ptr_Input_int = OpTypePointer Input %int -%gl_InvocationID = OpVariable %_ptr_Input_int Input -%int_0 = OpConstant %int 0 -%bool = OpTypeBool -%float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%float_0_0234375 = OpConstant %float 0.0234375 -%float_1_01561999 = OpConstant %float 1.01561999 -%v4float = OpTypeVector %float 4 -%uint_3 = OpConstant %uint 3 -%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3 -%_ptr_Output__arr_v4float_uint_3 = OpTypePointer Output %_arr_v4float_uint_3 -%_5 = OpVariable %_ptr_Output__arr_v4float_uint_3 Output -%34 = OpTypeImage %float 1D 0 0 0 1 Unknown -%_ptr_UniformConstant_34 = OpTypePointer UniformConstant %34 -%_77 = OpVariable %_ptr_UniformConstant_34 UniformConstant -%38 = OpTypeSampler -%_ptr_UniformConstant_38 = OpTypePointer UniformConstant %38 -%_78 = OpVariable %_ptr_UniformConstant_38 UniformConstant -%42 = OpTypeSampledImage %34 -%float_0 = OpConstant %float 0 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%_ptr_Function_v4float = OpTypePointer Function %v4float -%uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32 -%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32 -%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input -%_ptr_Input_v4float = OpTypePointer Input %v4float -%int_2 = OpConstant %int 2 -%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3 -%_ptr_Output__arr_gl_PerVertex_0_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_3 -%gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_3 Output -%uint_2 = OpConstant %uint 2 -%_arr_float_uint_2 = OpTypeArray %float %uint_2 -%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2 -%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output -%float_2_79999995 = OpConstant %float 2.79999995 -%_ptr_Output_float = OpTypePointer Output %float -%int_1 = OpConstant %int 1 -%uint_4 = OpConstant %uint 4 -%_arr_float_uint_4 = OpTypeArray %float %uint_4 -%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4 -%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output -%int_3 = OpConstant %int 3 -)"; - - const std::string main_func = - R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%param = OpVariable %_ptr_Function_float Function -%_203 = OpVariable %_ptr_Function_v4float Function -%14 = OpLoad %int %gl_InvocationID -%15 = OpAccessChain %_ptr_Input_int %_3 %14 -%16 = OpLoad %int %15 -%19 = OpIEqual %bool %16 %int_0 -OpSelectionMerge %21 None -OpBranchConditional %19 %20 %26 -%20 = OpLabel -;CHECK-NOT: %15 = OpAccessChain %_ptr_Input_int %_3 %14 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID -;CHECK: {{%\w+}} = OpAccessChain %_ptr_Input_int %_3 {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %int {{%\w+}} -;CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %int_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -OpStore %param %float_0_0234375 -OpBranch %21 -%26 = OpLabel -OpStore %param %float_1_01561999 -OpBranch %21 -%21 = OpLabel -%33 = OpLoad %int %gl_InvocationID -%37 = OpLoad %34 %_77 -%41 = OpLoad %38 %_78 -%43 = OpSampledImage %42 %37 %41 -%44 = OpLoad %float %param -;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID -;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_1 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %inst_bindless_check_desc %uint_23 %uint_129 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -%46 = OpImageSampleExplicitLod %v4float %43 %44 Lod %float_0 -%48 = OpAccessChain %_ptr_Output_v4float %_5 %33 -OpStore %48 %46 -;CHECK-NOT: %48 = OpAccessChain %_ptr_Output_v4float %_5 %33 -;CHECK-NOT: OpStore %48 %46 -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: [[access_chain:%\w+]] = OpAccessChain %_ptr_Output_v4float %_5 {{%\w+}} -;CHECK: OpStore [[access_chain]] [[phi_result]] -%49 = OpLoad %int %gl_InvocationID -%50 = OpIEqual %bool %49 %int_0 -OpSelectionMerge %52 None -OpBranchConditional %50 %51 %64 -%51 = OpLabel -%62 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0 -%63 = OpLoad %v4float %62 -OpStore %_203 %63 -OpBranch %52 -%64 = OpLabel -%66 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0 -%67 = OpLoad %v4float %66 -OpStore %_203 %67 -OpBranch %52 -%52 = OpLabel -%72 = OpLoad %int %gl_InvocationID -%73 = OpLoad %v4float %_203 -%74 = OpAccessChain %_ptr_Output_v4float %gl_out %72 %int_0 -OpStore %74 %73 -%81 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0 -OpStore %81 %float_2_79999995 -%83 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1 -OpStore %83 %float_2_79999995 -%88 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0 -OpStore %88 %float_2_79999995 -%89 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1 -OpStore %89 %float_2_79999995 -%90 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2 -OpStore %90 %float_2_79999995 -%92 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3 -OpStore %92 %float_2_79999995 -OpReturn -OpFunctionEnd -)"; - // clang-format on - - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + output_func, + true, 7u, 23u, false, false, + false, false, false); } TEST_F(InstBindlessTest, MultipleDebugFunctions) { @@ -1176,11 +1446,11 @@ TEST_F(InstBindlessTest, MultipleDebugFunctions) { // clang-format off const std::string defs = R"( OpCapability Shader -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %2 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft %1 = OpString "foo5.frag" OpSource HLSL 500 %1 @@ -1201,16 +1471,17 @@ OpName %i_0 "i" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" OpName %param "param" -OpDecorate %g_tColor DescriptorSet 1 -OpDecorate %g_tColor Binding 2 +OpDecorate %g_tColor DescriptorSet 0 +OpDecorate %g_tColor Binding 0 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block -OpDecorate %g_sAniso DescriptorSet 1 -OpDecorate %g_sAniso Binding 3 +OpDecorate %g_sAniso DescriptorSet 0 +OpDecorate %g_sAniso Binding 1 OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %4 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1244,10 +1515,29 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %70 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_109 = OpConstant %uint 109 +; CHECK: %125 = OpConstantNull %v4float )"; + // clang-format on const std::string func1 = R"( %MainPs = OpFunction %void None %4 @@ -1282,43 +1572,38 @@ OpLine %1 24 0 %43 = OpAccessChain %_ptr_Function_v2float %i %int_0 %44 = OpLoad %v2float %43 %45 = OpImageSampleImplicitLod %v4float %41 %44 -;CHECK-NOT: %45 = OpImageSampleImplicitLod %v4float %41 %44 -;CHECK: {{%\w+}} = OpLoad %v2float {{%\w+}} -;CHECK: OpNoLine -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_128 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %27 {{%\w+}} -;CHECK: {{%\w+}} = OpSampledImage %37 {{%\w+}} {{%\w+}} -;CHECK: OpLine %5 24 0 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} {{%\w+}} -;CHECK: OpNoLine -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} +; CHECK-NOT: %45 = OpImageSampleImplicitLod %v4float %41 %44 +; CHECK: OpNoLine +; CHECK: %62 = OpULessThan %bool %50 %uint_128 +; CHECK: OpSelectionMerge %63 None +; CHECK: OpBranchConditional %62 %64 %65 +; CHECK: %64 = OpLabel +; CHECK: %66 = OpLoad %27 %51 +; CHECK: %67 = OpSampledImage %37 %66 %53 +; CHECK: OpLine %5 24 0 +; CHECK: %68 = OpImageSampleImplicitLod %v4float %67 %56 +; CHECK: OpNoLine +; CHECK: OpBranch %63 +; CHECK: %65 = OpLabel +; CHECK: %124 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_109 %uint_0 %50 %uint_128 +; CHECK: OpBranch %63 +; CHECK: %63 = OpLabel +; CHECK: %126 = OpPhi %v4float %68 %64 %125 %65 +; CHECK: OpLine %5 24 0 %47 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0 OpStore %47 %45 -;CHECK-NOT: OpStore %47 %45 -;CHECK: [[store_loc:%\w+]] = OpAccessChain %_ptr_Function_v4float %ps_output %int_0 -;CHECK: OpStore [[store_loc]] [[phi_result]] OpLine %1 25 0 %48 = OpLoad %PS_OUTPUT %ps_output OpReturnValue %48 OpFunctionEnd )"; - // clang-format on + + const std::string output_func = kStreamWrite4Frag; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndMatch( - defs + kImportStub + func1 + func2, true, 23u); + defs + func1 + func2 + output_func, true, 7u, 23u, false, false, false, + false, false); } TEST_F(InstBindlessTest, RuntimeArray) { @@ -1330,12 +1615,12 @@ TEST_F(InstBindlessTest, RuntimeArray) { const std::string defs = R"( OpCapability Shader OpCapability RuntimeDescriptorArray -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -1351,11 +1636,12 @@ OpDecorate %g_tColor Binding 2 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 OpDecorate %PerViewConstantBuffer_t Block OpDecorate %g_sAniso DescriptorSet 1 -OpDecorate %g_sAniso Binding 3 +OpDecorate %g_sAniso Binding 0 OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1382,10 +1668,31 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %41 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %65 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_59 = OpConstant %uint 59 +; CHECK: %116 = OpConstantNull %v4float +; CHECK: %119 = OpTypeFunction %uint %uint %uint %uint %uint )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %3 @@ -1399,34 +1706,46 @@ OpDecorate %_entryPointOutput_vColor Location 0 %68 = OpSampledImage %39 %66 %67 %71 = OpImageSampleImplicitLod %v4float %68 %53 OpStore %_entryPointOutput_vColor %71 -;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %68 %53 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %71 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_1 %uint_2 %32 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %16 %33 -;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result_1:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor [[phi_result_1]] +; CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %68 %53 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %71 +; CHECK: %55 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_2 %uint_2 +; CHECK: %57 = OpULessThan %bool %32 %55 +; CHECK: OpSelectionMerge %58 None +; CHECK: OpBranchConditional %57 %59 %60 +; CHECK: %59 = OpLabel +; CHECK: %61 = OpLoad %16 %33 +; CHECK: %62 = OpSampledImage %26 %61 %35 +; CHECK: %136 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_1 %uint_2 %32 +; CHECK: %137 = OpULessThan %bool %uint_0 %136 +; CHECK: OpSelectionMerge %138 None +; CHECK: OpBranchConditional %137 %139 %140 +; CHECK: %139 = OpLabel +; CHECK: %141 = OpLoad %16 %33 +; CHECK: %142 = OpSampledImage %26 %141 %35 +; CHECK: %143 = OpImageSampleImplicitLod %v4float %142 %30 +; CHECK: OpBranch %138 +; CHECK: %140 = OpLabel +; CHECK: %144 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_59 %uint_1 %32 %uint_0 +; CHECK: OpBranch %138 +; CHECK: %138 = OpLabel +; CHECK: %145 = OpPhi %v4float %143 %139 %116 %140 +; CHECK: OpBranch %58 +; CHECK: %60 = OpLabel +; CHECK: %115 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_59 %uint_0 %32 %55 +; CHECK: OpBranch %58 +; CHECK: %58 = OpLabel +; CHECK: %117 = OpPhi %v4float %145 %138 %116 %60 +; CHECK: OpStore %_entryPointOutput_vColor %117 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Frag + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) { @@ -1440,11 +1759,11 @@ TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) { // clang-format off const std::string defs = R"( OpCapability Shader -;CHECK: OpCapability Linkage +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord OpExecutionMode %MainPs OriginUpperLeft OpSource HLSL 500 OpName %MainPs "MainPs" @@ -1452,14 +1771,15 @@ OpName %g_tColor "g_tColor" OpName %g_sAniso "g_sAniso" OpName %i_vTextureCoords "i.vTextureCoords" OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpDecorate %g_tColor DescriptorSet 1 -OpDecorate %g_tColor Binding 2 -OpDecorate %g_sAniso DescriptorSet 1 -OpDecorate %g_sAniso Binding 2 +OpDecorate %g_tColor DescriptorSet 0 +OpDecorate %g_tColor Binding 0 +OpDecorate %g_sAniso DescriptorSet 0 +OpDecorate %g_sAniso Binding 0 OpDecorate %i_vTextureCoords Location 0 OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; check: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; check: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %8 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1476,8 +1796,32 @@ OpDecorate %_entryPointOutput_vColor Location 0 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %28 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %61 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_39 = OpConstant %uint 39 +; CHECK: %113 = OpConstantNull %v4float )"; + // clang-format on const std::string main_func = R"( %MainPs = OpFunction %void None %8 @@ -1488,43 +1832,51 @@ OpDecorate %_entryPointOutput_vColor Location 0 %23 = OpSampledImage %16 %21 %22 %24 = OpImageSampleImplicitLod %v4float %23 %20 OpStore %_entryPointOutput_vColor %24 -;CHECK-NOT: %24 = OpImageSampleImplicitLod %v4float %23 %20 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %24 -;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_40 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %12 %g_tColor -;CHECK: {{%\w+}} = OpSampledImage %16 {{%\w+}} %22 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] +; CHECK-NOT: %24 = OpImageSampleImplicitLod %v4float %23 %20 +; CHECK-NOT: OpStore %_entryPointOutput_vColor %24 +; CHECK: %50 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %52 = OpULessThan %bool %uint_0 %50 +; CHECK: OpSelectionMerge %54 None +; CHECK: OpBranchConditional %52 %55 %56 +; CHECK: %55 = OpLabel +; CHECK: %57 = OpLoad %12 %g_tColor +; CHECK: %58 = OpSampledImage %16 %57 %22 +; CHECK: %59 = OpImageSampleImplicitLod %v4float %58 %20 +; CHECK: OpBranch %54 +; CHECK: %56 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_39 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %54 +; CHECK: %54 = OpLabel +; CHECK: %114 = OpPhi %v4float %59 %55 %113 %56 +; CHECK: OpStore %_entryPointOutput_vColor %114 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead4 + kStreamWrite4Frag; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, SPV14AddToEntryPoint) { const std::string text = R"( +; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpDecorate [[v1]] DescriptorSet 7 +; CHECK: OpDecorate [[v2]] DescriptorSet 7 +; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer +; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer OpCapability Shader OpExtension "SPV_EXT_descriptor_indexing" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var -;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord OpExecutionMode %foo OriginUpperLeft -OpDecorate %image_var DescriptorSet 4 -OpDecorate %image_var Binding 1 -OpDecorate %sampler_var DescriptorSet 4 -OpDecorate %sampler_var Binding 2 +OpDecorate %image_var DescriptorSet 0 +OpDecorate %image_var Binding 0 +OpDecorate %sampler_var DescriptorSet 0 +OpDecorate %sampler_var Binding 1 OpDecorate %gid DescriptorSet 0 OpDecorate %gid Binding 2 OpDecorate %struct Block @@ -1562,26 +1914,30 @@ OpFunctionEnd )"; SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, true, true, + false, false, false); } TEST_F(InstBindlessTest, SPV14AddToEntryPoints) { const std::string text = R"( +; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpDecorate [[v1]] DescriptorSet 7 +; CHECK: OpDecorate [[v2]] DescriptorSet 7 +; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer +; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer OpCapability Shader -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var -;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord OpEntryPoint Fragment %foo "bar" %gid %image_var %sampler_var -;CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord OpExecutionMode %foo OriginUpperLeft -OpDecorate %image_var DescriptorSet 3 -OpDecorate %image_var Binding 2 -OpDecorate %sampler_var DescriptorSet 3 -OpDecorate %sampler_var Binding 3 -OpDecorate %gid DescriptorSet 3 -OpDecorate %gid Binding 4 +OpDecorate %image_var DescriptorSet 0 +OpDecorate %image_var Binding 0 +OpDecorate %sampler_var DescriptorSet 0 +OpDecorate %sampler_var Binding 1 +OpDecorate %gid DescriptorSet 0 +OpDecorate %gid Binding 2 OpDecorate %struct Block OpMemberDecorate %struct 0 Offset 0 %void = OpTypeVoid @@ -1617,7 +1973,8 @@ OpFunctionEnd )"; SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, true, true, + false, false, false); } TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) { @@ -1627,7 +1984,7 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) { // layout(location=0) in nonuniformEXT flat int nu_ii; // layout(location=0) out float b; // - // layout(set = 6, binding=3) uniform uname { float a; } uniformBuffer[]; + // layout(binding=3) uniform uname { float a; } uniformBuffer[]; // // void main() // { @@ -1640,12 +1997,12 @@ OpCapability Shader OpCapability ShaderNonUniform OpCapability RuntimeDescriptorArray OpCapability UniformBufferArrayNonUniformIndexing -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %b %nu_ii -;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -1658,17 +2015,19 @@ OpName %nu_ii "nu_ii" OpDecorate %b Location 0 OpMemberDecorate %uname 0 Offset 0 OpDecorate %uname Block -OpDecorate %uniformBuffer DescriptorSet 6 +OpDecorate %uniformBuffer DescriptorSet 0 OpDecorate %uniformBuffer Binding 3 OpDecorate %nu_ii Flat OpDecorate %nu_ii Location 0 OpDecorate %nu_ii NonUniform OpDecorate %16 NonUniform OpDecorate %20 NonUniform -;CHECK: OpDecorate {{%\w+}} NonUniform -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -;CHECK: OpDecorate {{%\w+}} NonUniform +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %130 NonUniform +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %127 NonUniform %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1683,12 +2042,34 @@ OpDecorate %20 NonUniform %nu_ii = OpVariable %_ptr_Input_int Input %int_0 = OpConstant %int 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %v4float = OpTypeVector %float 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %26 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %49 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_45 = OpConstant %uint 45 +; CHECK: %101 = OpConstantNull %float +; CHECK: %105 = OpTypeFunction %uint %uint %uint %uint %uint )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -1697,33 +2078,45 @@ OpDecorate %20 NonUniform %19 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %16 %int_0 %20 = OpLoad %float %19 OpStore %b %20 -;CHECK-NOT: %20 = OpLoad %float %19 -;CHECK-NOT: OpStore %b %20 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %7 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_6 %uint_3 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %b [[phi_result]] +; CHECK-NOT: %20 = OpLoad %float %19 +; CHECK-NOT: OpStore %b %20 +; CHECK: %40 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_3 +; CHECK: %42 = OpULessThan %bool %7 %40 +; CHECK: OpSelectionMerge %43 None +; CHECK: OpBranchConditional %42 %44 %45 +; CHECK: %44 = OpLabel +; CHECK: %103 = OpBitcast %uint %7 +; CHECK: %122 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_3 %103 +; CHECK: %123 = OpULessThan %bool %uint_0 %122 +; CHECK: OpSelectionMerge %124 None +; CHECK: OpBranchConditional %123 %125 %126 +; CHECK: %125 = OpLabel +; CHECK: %127 = OpLoad %float %20 +; CHECK: OpBranch %124 +; CHECK: %126 = OpLabel +; CHECK: %128 = OpBitcast %uint %7 +; CHECK: %129 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_1 %128 %uint_0 +; CHECK: OpBranch %124 +; CHECK: %124 = OpLabel +; CHECK: %130 = OpPhi %float %127 %125 %101 %126 +; CHECK: OpBranch %43 +; CHECK: %45 = OpLabel +; CHECK: %47 = OpBitcast %uint %7 +; CHECK: %100 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_0 %47 %40 +; CHECK: OpBranch %43 +; CHECK: %43 = OpLabel +; CHECK: %102 = OpPhi %float %130 %124 %101 %45 +; CHECK: OpStore %b %102 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Frag + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) { @@ -1733,7 +2126,7 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) { // layout(location=0) in nonuniformEXT flat int nu_ii; // layout(location=0) out float b; // - // layout(set = 7, binding=3) buffer bname { float b; } storageBuffer[]; + // layout(binding=3) buffer bname { float b; } storageBuffer[]; // // void main() // { @@ -1746,106 +2139,12 @@ OpCapability Shader OpCapability ShaderNonUniform OpCapability RuntimeDescriptorArray OpCapability StorageBufferArrayNonUniformIndexing -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %b %nu_ii -;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpSourceExtension "GL_EXT_nonuniform_qualifier" -OpName %main "main" -OpName %b "b" -OpName %bname "bname" -OpMemberName %bname 0 "a" -OpName %storageBuffer "storageBuffer" -OpName %nu_ii "nu_ii" -OpDecorate %b Location 0 -OpMemberDecorate %bname 0 Offset 0 -OpDecorate %bname Block -OpDecorate %storageBuffer DescriptorSet 7 -OpDecorate %storageBuffer Binding 3 -OpDecorate %nu_ii Flat -OpDecorate %nu_ii Location 0 -OpDecorate %nu_ii NonUniform -OpDecorate %16 NonUniform -OpDecorate %20 NonUniform -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%_ptr_Output_float = OpTypePointer Output %float -%b = OpVariable %_ptr_Output_float Output -%bname = OpTypeStruct %float -%_runtimearr_bname = OpTypeRuntimeArray %bname -%_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname -%storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%nu_ii = OpVariable %_ptr_Input_int Input -%int_0 = OpConstant %int 0 -%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float -;CHECK: %uint = OpTypeInt 32 0 -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %v4float = OpTypeVector %float 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float -)"; - - const std::string main_func = R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%16 = OpLoad %int %nu_ii -%19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0 -%20 = OpLoad %float %19 -OpStore %b %20 -;CHECK-NOT: %20 = OpLoad %float %19 -;CHECK-NOT: OpStore %b %20 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %7 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_7 %uint_3 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %b [[phi_result]] -OpReturn -OpFunctionEnd -)"; - // clang-format on - - // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); -} - -TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) { - // Same as Deprecated but declaring as StorageBuffer Block - - // clang-format off - const std::string defs = R"( -OpCapability Shader -OpCapability ShaderNonUniform -OpCapability RuntimeDescriptorArray -OpCapability StorageBufferArrayNonUniformIndexing -;CHECK: OpCapability Linkage -OpExtension "SPV_EXT_descriptor_indexing" -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %b %nu_ii -;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -1865,10 +2164,12 @@ OpDecorate %nu_ii Location 0 OpDecorate %nu_ii NonUniform OpDecorate %16 NonUniform OpDecorate %20 NonUniform -;CHECK: OpDecorate {{%\w+}} NonUniform -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -;CHECK: OpDecorate {{%\w+}} NonUniform +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %130 NonUniform +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %127 NonUniform %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1883,12 +2184,34 @@ OpDecorate %20 NonUniform %nu_ii = OpVariable %_ptr_Input_int Input %int_0 = OpConstant %int 0 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %v4float = OpTypeVector %float 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %26 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %49 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_45 = OpConstant %uint 45 +; CHECK: %101 = OpConstantNull %float +; CHECK: %105 = OpTypeFunction %uint %uint %uint %uint %uint )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -1897,33 +2220,176 @@ OpDecorate %20 NonUniform %19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0 %20 = OpLoad %float %19 OpStore %b %20 -;CHECK-NOT: %20 = OpLoad %float %19 -;CHECK-NOT: OpStore %b %20 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %7 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_3 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %b {{%\w+}} +; CHECK-NOT: %20 = OpLoad %float %19 +; CHECK-NOT: OpStore %b %20 +; CHECK: %40 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_3 +; CHECK: %42 = OpULessThan %bool %7 %40 +; CHECK: OpSelectionMerge %43 None +; CHECK: OpBranchConditional %42 %44 %45 +; CHECK: %44 = OpLabel +; CHECK: %103 = OpBitcast %uint %7 +; CHECK: %122 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_3 %103 +; CHECK: %123 = OpULessThan %bool %uint_0 %122 +; CHECK: OpSelectionMerge %124 None +; CHECK: OpBranchConditional %123 %125 %126 +; CHECK: %125 = OpLabel +; CHECK: %127 = OpLoad %float %20 +; CHECK: OpBranch %124 +; CHECK: %126 = OpLabel +; CHECK: %128 = OpBitcast %uint %7 +; CHECK: %129 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_1 %128 %uint_0 +; CHECK: OpBranch %124 +; CHECK: %124 = OpLabel +; CHECK: %130 = OpPhi %float %127 %125 %101 %126 +; CHECK: OpBranch %43 +; CHECK: %45 = OpLabel +; CHECK: %47 = OpBitcast %uint %7 +; CHECK: %100 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_0 %47 %40 +; CHECK: OpBranch %43 +; CHECK: %43 = OpLabel +; CHECK: %102 = OpPhi %float %130 %124 %101 %45 +; CHECK: OpStore %b %102 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Frag + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); +} + +TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) { + // Same as Deprecated but declaring as StorageBuffer Block + + // clang-format off + const std::string defs = R"( +OpCapability Shader +OpCapability ShaderNonUniform +OpCapability RuntimeDescriptorArray +OpCapability StorageBufferArrayNonUniformIndexing +OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %b %nu_ii +; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord +OpExecutionMode %main OriginUpperLeft +OpSource GLSL 450 +OpSourceExtension "GL_EXT_nonuniform_qualifier" +OpName %main "main" +OpName %b "b" +OpName %bname "bname" +OpMemberName %bname 0 "a" +OpName %storageBuffer "storageBuffer" +OpName %nu_ii "nu_ii" +OpDecorate %b Location 0 +OpMemberDecorate %bname 0 Offset 0 +OpDecorate %bname Block +OpDecorate %storageBuffer DescriptorSet 0 +OpDecorate %storageBuffer Binding 3 +OpDecorate %nu_ii Flat +OpDecorate %nu_ii Location 0 +OpDecorate %nu_ii NonUniform +OpDecorate %16 NonUniform +OpDecorate %20 NonUniform +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %130 NonUniform +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %127 NonUniform +%void = OpTypeVoid +%3 = OpTypeFunction %void +%float = OpTypeFloat 32 +%_ptr_Output_float = OpTypePointer Output %float +%b = OpVariable %_ptr_Output_float Output +%bname = OpTypeStruct %float +%_runtimearr_bname = OpTypeRuntimeArray %bname +%_ptr_StorageBuffer__runtimearr_bname = OpTypePointer StorageBuffer %_runtimearr_bname +%storageBuffer = OpVariable %_ptr_StorageBuffer__runtimearr_bname StorageBuffer +%int = OpTypeInt 32 1 +%_ptr_Input_int = OpTypePointer Input %int +%nu_ii = OpVariable %_ptr_Input_int Input +%int_0 = OpConstant %int 0 +%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %26 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %49 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_45 = OpConstant %uint 45 +; CHECK: %101 = OpConstantNull %float +; CHECK: %105 = OpTypeFunction %uint %uint %uint %uint %uint +)"; + // clang-format on + + const std::string main_func = R"( +%main = OpFunction %void None %3 +%5 = OpLabel +%16 = OpLoad %int %nu_ii +%19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0 +%20 = OpLoad %float %19 +OpStore %b %20 +; CHECK-NOT: %20 = OpLoad %float %19 +; CHECK-NOT: OpStore %b %20 +; CHECK: %40 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_3 +; CHECK: %42 = OpULessThan %bool %7 %40 +; CHECK: OpSelectionMerge %43 None +; CHECK: OpBranchConditional %42 %44 %45 +; CHECK: %44 = OpLabel +; CHECK: %103 = OpBitcast %uint %7 +; CHECK: %122 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_3 %103 +; CHECK: %123 = OpULessThan %bool %uint_0 %122 +; CHECK: OpSelectionMerge %124 None +; CHECK: OpBranchConditional %123 %125 %126 +; CHECK: %125 = OpLabel +; CHECK: %127 = OpLoad %float %20 +; CHECK: OpBranch %124 +; CHECK: %126 = OpLabel +; CHECK: %128 = OpBitcast %uint %7 +; CHECK: %129 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_1 %128 %uint_0 +; CHECK: OpBranch %124 +; CHECK: %124 = OpLabel +; CHECK: %130 = OpPhi %float %127 %125 %101 %126 +; CHECK: OpBranch %43 +; CHECK: %45 = OpLabel +; CHECK: %47 = OpBitcast %uint %7 +; CHECK: %100 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_0 %47 %40 +; CHECK: OpBranch %43 +; CHECK: %43 = OpLabel +; CHECK: %102 = OpPhi %float %130 %124 %101 %45 +; CHECK: OpStore %b %102 +OpReturn +OpFunctionEnd +)"; + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Frag + kDirectRead4; + + // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstInitLoadUBOScalar) { @@ -1931,7 +2397,7 @@ TEST_F(InstBindlessTest, InstInitLoadUBOScalar) { // #extension GL_EXT_nonuniform_qualifier : enable // // layout(location=0) out float b; - // layout(set=7, binding=3) uniform uname { float a; } uniformBuffer; + // layout(binding=3) uniform uname { float a; } uniformBuffer; // // void main() // { @@ -1941,12 +2407,12 @@ TEST_F(InstBindlessTest, InstInitLoadUBOScalar) { // clang-format off const std::string defs = R"( OpCapability Shader -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %b -;CHECK: OpEntryPoint Fragment %main "main" %b %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %b %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -1958,10 +2424,11 @@ OpName %uniformBuffer "uniformBuffer" OpDecorate %b Location 0 OpMemberDecorate %uname 0 Offset 0 OpDecorate %uname Block -OpDecorate %uniformBuffer DescriptorSet 7 +OpDecorate %uniformBuffer DescriptorSet 0 OpDecorate %uniformBuffer Binding 3 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1973,15 +2440,36 @@ OpDecorate %uniformBuffer Binding 3 %int = OpTypeInt 32 1 %int_0 = OpConstant %int 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %int = OpTypeInt 32 1 -;CHECK: %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %uint = OpTypeInt 32 0 -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %v4float = OpTypeVector %float 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float +; CHECK: %int = OpTypeInt 32 1 +; CHECK: %int_0 = OpConstant %int 0 +; CHECK: %_ptr_Uniform_float = OpTypePointer Uniform %float +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %21 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %52 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_32 = OpConstant %uint 32 +; CHECK: %104 = OpConstantNull %float )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -1989,32 +2477,31 @@ OpDecorate %uniformBuffer Binding 3 %15 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %int_0 %16 = OpLoad %float %15 OpStore %b %16 -;CHECK-NOT: %16 = OpLoad %float %15 -;CHECK-NOT: OpStore %b %16 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_7 %uint_3 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %float %15 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %b [[phi_result]] +; CHECK-NOT: %16 = OpLoad %float %15 +; CHECK-NOT: OpStore %b %16 +; CHECK: %43 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_3 %uint_0 +; CHECK: %45 = OpULessThan %bool %uint_0 %43 +; CHECK: OpSelectionMerge %47 None +; CHECK: OpBranchConditional %45 %48 %49 +; CHECK: %48 = OpLabel +; CHECK: %50 = OpLoad %float %15 +; CHECK: OpBranch %47 +; CHECK: %49 = OpLabel +; CHECK: %103 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_32 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %47 +; CHECK: %47 = OpLabel +; CHECK: %105 = OpPhi %float %50 %48 %104 %49 +; CHECK: OpStore %b %105 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead4 + kStreamWrite4Frag; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) { @@ -2024,7 +2511,7 @@ TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) { // layout(location=0) in nonuniformEXT flat int nu_ii; // layout(location=1) in float b; // - // layout(set=5, binding=4) buffer bname { float b; } storageBuffer[]; + // layout(binding=4) buffer bname { float b; } storageBuffer[]; // // void main() // { @@ -2036,12 +2523,12 @@ TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) { OpCapability ShaderNonUniform OpCapability RuntimeDescriptorArray OpCapability StorageBufferArrayNonUniformIndexing -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %nu_ii %b -;CHECK: OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -2053,15 +2540,16 @@ OpName %nu_ii "nu_ii" OpName %b "b" OpMemberDecorate %bname 0 Offset 0 OpDecorate %bname BufferBlock -OpDecorate %storageBuffer DescriptorSet 5 +OpDecorate %storageBuffer DescriptorSet 0 OpDecorate %storageBuffer Binding 4 OpDecorate %nu_ii Flat OpDecorate %nu_ii Location 0 OpDecorate %nu_ii NonUniform OpDecorate %14 NonUniform OpDecorate %b Location 1 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -2076,9 +2564,33 @@ OpDecorate %b Location 1 %_ptr_Input_float = OpTypePointer Input %float %b = OpVariable %_ptr_Input_float Input %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %uint = OpTypeInt 32 0 +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %26 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %48 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_45 = OpConstant %uint 45 +; CHECK: %102 = OpTypeFunction %uint %uint %uint %uint %uint )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2087,30 +2599,41 @@ OpDecorate %b Location 1 %18 = OpLoad %float %b %20 = OpAccessChain %_ptr_Uniform_float %storageBuffer %14 %int_0 OpStore %20 %18 -;CHECK-NOT: OpStore %20 %18 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %7 -;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_5 %uint_4 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %20 %19 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %20 %18 +; CHECK: %40 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_4 +; CHECK: %42 = OpULessThan %bool %7 %40 +; CHECK: OpSelectionMerge %43 None +; CHECK: OpBranchConditional %42 %44 %45 +; CHECK: %44 = OpLabel +; CHECK: %100 = OpBitcast %uint %7 +; CHECK: %119 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_4 %100 +; CHECK: %120 = OpULessThan %bool %uint_0 %119 +; CHECK: OpSelectionMerge %121 None +; CHECK: OpBranchConditional %120 %122 %123 +; CHECK: %122 = OpLabel +; CHECK: OpStore %20 %19 +; CHECK: OpBranch %121 +; CHECK: %123 = OpLabel +; CHECK: %124 = OpBitcast %uint %7 +; CHECK: %125 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_1 %124 %uint_0 +; CHECK: OpBranch %121 +; CHECK: %121 = OpLabel +; CHECK: OpBranch %43 +; CHECK: %45 = OpLabel +; CHECK: %46 = OpBitcast %uint %7 +; CHECK: %99 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_45 %uint_0 %46 %40 +; CHECK: OpBranch %43 +; CHECK: %43 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Frag + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) { @@ -2120,7 +2643,7 @@ TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) { // layout(location=0) in nonuniformEXT flat int nu_ii; // layout(location=0) out float b; // - // layout(set=1, binding=3) uniform uname { float a; } uniformBuffer[128]; + // layout(binding=3) uniform uname { float a; } uniformBuffer[128]; // // void main() // { @@ -2132,12 +2655,12 @@ TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) { OpCapability Shader OpCapability ShaderNonUniform OpCapability UniformBufferArrayNonUniformIndexing -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %b %nu_ii -;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -2150,16 +2673,18 @@ OpName %nu_ii "nu_ii" OpDecorate %b Location 0 OpMemberDecorate %uname 0 Offset 0 OpDecorate %uname Block -OpDecorate %uniformBuffer DescriptorSet 1 +OpDecorate %uniformBuffer DescriptorSet 0 OpDecorate %uniformBuffer Binding 3 OpDecorate %nu_ii Flat OpDecorate %nu_ii Location 0 OpDecorate %nu_ii NonUniform OpDecorate %18 NonUniform OpDecorate %22 NonUniform -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -;CHECK: OpDecorate [[load_result:%\w+]] NonUniform +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +)" + kInputDecorations + R"( +; CHECK: OpDecorate %117 NonUniform %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -2176,10 +2701,31 @@ OpDecorate %22 NonUniform %nu_ii = OpVariable %_ptr_Input_int Input %int_0 = OpConstant %int 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float -)"; +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %bool = OpTypeBool +; CHECK: %32 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v4float = OpTypeVector %float 4 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_46 = OpConstant %uint 46 +; CHECK: %88 = OpConstantNull %float +; CHECK: %92 = OpTypeFunction %uint %uint %uint %uint %uint +)" + kInputGlobals; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2188,33 +2734,44 @@ OpDecorate %22 NonUniform %21 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %18 %int_0 %22 = OpLoad %float %21 OpStore %b %22 -;CHECK-NOT: %22 = OpLoad %float %21 -;CHECK-NOT: OpStore %b %22 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %7 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} %uint_1 %uint_3 {{%\w+}} {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %float %22 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %b {{%\w+}} +; CHECK-NOT: %22 = OpLoad %float %21 +; CHECK-NOT: OpStore %b %22 +; CHECK: %25 = OpULessThan %bool %7 %uint_128 +; CHECK: OpSelectionMerge %26 None +; CHECK: OpBranchConditional %25 %27 %28 +; CHECK: %27 = OpLabel +; CHECK: %90 = OpBitcast %uint %7 +; CHECK: %112 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_3 %90 +; CHECK: %113 = OpULessThan %bool %uint_0 %112 +; CHECK: OpSelectionMerge %114 None +; CHECK: OpBranchConditional %113 %115 %116 +; CHECK: %115 = OpLabel +; CHECK: %117 = OpLoad %float %22 +; CHECK: OpBranch %114 +; CHECK: %116 = OpLabel +; CHECK: %118 = OpBitcast %uint %7 +; CHECK: %119 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_46 %uint_1 %118 %uint_0 +; CHECK: OpBranch %114 +; CHECK: %114 = OpLabel +; CHECK: %120 = OpPhi %float %117 %115 %88 %116 +; CHECK: OpBranch %26 +; CHECK: %28 = OpLabel +; CHECK: %30 = OpBitcast %uint %7 +; CHECK: %87 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_46 %uint_0 %30 %uint_128 +; CHECK: OpBranch %26 +; CHECK: %26 = OpLabel +; CHECK: %89 = OpPhi %float %120 %114 %88 %28 +; CHECK: OpStore %b %89 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kStreamWrite4Frag + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2224,12 +2781,12 @@ TEST_F(InstBindlessTest, // // layout (local_size_x = 1, local_size_y = 1) in; // - // layout(set = 2, binding = 0, std140) buffer Input { + // layout(set = 0, binding = 0, std140) buffer Input { // uint index; // float red; // } sbo; // - // layout(set = 2, binding = 1, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2240,12 +2797,12 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability Shader OpCapability RuntimeDescriptorArray -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %main "main" -;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID OpExecutionMode %main LocalSize 1 1 1 OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -2258,13 +2815,14 @@ OpName %images "images" OpMemberDecorate %Input 0 Offset 0 OpMemberDecorate %Input 1 Offset 4 OpDecorate %Input BufferBlock -OpDecorate %sbo DescriptorSet 2 +OpDecorate %sbo DescriptorSet 0 OpDecorate %sbo Binding 0 -OpDecorate %images DescriptorSet 2 +OpDecorate %images DescriptorSet 0 OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -2286,12 +2844,35 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: %v3uint = OpTypeVector %uint 3 -;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint -;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_50 = OpConstant %uint 50 +; CHECK: %112 = OpConstantNull %v4float +; CHECK: %115 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_47 = OpConstant %uint 47 +; CHECK: %140 = OpConstantNull %uint +; CHECK: %uint_53 = OpConstant %uint 53 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2304,64 +2885,70 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_48 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_51 {{%\w+}} %uint_2 %uint_1 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_54 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %31 %29 +; CHECK: %132 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %133 = OpULessThan %bool %uint_0 %132 +; CHECK: OpSelectionMerge %134 None +; CHECK: OpBranchConditional %133 %135 %136 +; CHECK: %135 = OpLabel +; CHECK: %137 = OpLoad %uint %25 +; CHECK: OpBranch %134 +; CHECK: %136 = OpLabel +; CHECK: %139 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_47 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %134 +; CHECK: %134 = OpLabel +; CHECK: %141 = OpPhi %uint %137 %135 %140 %136 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %141 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %141 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %142 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %141 +; CHECK: %143 = OpULessThan %bool %uint_0 %142 +; CHECK: OpSelectionMerge %144 None +; CHECK: OpBranchConditional %143 %145 %146 +; CHECK: %145 = OpLabel +; CHECK: %147 = OpLoad %13 %27 +; CHECK: %148 = OpImageRead %v4float %147 %20 +; CHECK: OpBranch %144 +; CHECK: %146 = OpLabel +; CHECK: %149 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_50 %uint_1 %141 %uint_0 +; CHECK: OpBranch %144 +; CHECK: %144 = OpLabel +; CHECK: %150 = OpPhi %v4float %148 %145 %112 %146 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %111 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_50 %uint_0 %141 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %113 = OpPhi %v4float %150 %144 %112 %53 +; CHECK: %30 = OpCompositeExtract %float %113 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %151 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %152 = OpULessThan %bool %uint_0 %151 +; CHECK: OpSelectionMerge %153 None +; CHECK: OpBranchConditional %152 %154 %155 +; CHECK: %154 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %153 +; CHECK: %155 = OpLabel +; CHECK: %157 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_53 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %153 +; CHECK: %153 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = + kDirectRead2 + kStreamWrite4Compute + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2370,12 +2957,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 3, binding = 1, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 3, binding = 5, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2386,13 +2973,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint RayGenerationNV %main "main" -;CHECK: OpEntryPoint RayGenerationNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint RayGenerationNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -2405,13 +2992,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 3 -OpDecorate %sbo Binding 1 -OpDecorate %images DescriptorSet 3 -OpDecorate %images Binding 5 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -2433,9 +3021,36 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5313 = OpConstant %uint 5313 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2448,64 +3063,69 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_5 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore {{%\w+}} {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2514,12 +3134,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 5, binding = 1, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 5, binding = 3, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2530,13 +3150,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint IntersectionNV %main "main" -;CHECK: OpEntryPoint IntersectionNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint IntersectionNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -2549,13 +3169,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 5 -OpDecorate %sbo Binding 1 -OpDecorate %images DescriptorSet 5 -OpDecorate %images Binding 3 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -2577,10 +3198,35 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5314 = OpConstant %uint 5314 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2593,63 +3239,69 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_5 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}} -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} +; CHECK-NOT: OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2658,12 +3310,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 2, binding = 1, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 2, binding = 3, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2674,13 +3326,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint AnyHitNV %main "main" -;CHECK: OpEntryPoint AnyHitNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint AnyHitNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -2693,13 +3345,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 2 -OpDecorate %sbo Binding 1 -OpDecorate %images DescriptorSet 2 -OpDecorate %images Binding 3 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -2721,10 +3374,36 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5315 = OpConstant %uint 5315 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2737,70 +3416,69 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: %20 = OpLoad %uint %19 -;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 -;CHECK-NOT: %23 = OpLoad %13 %22 -;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 -;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 -;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] -;CHECK: %28 = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_2 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2809,12 +3487,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 1, binding = 2, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2825,13 +3503,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint ClosestHitNV %main "main" -;CHECK: OpEntryPoint ClosestHitNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint ClosestHitNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -2844,13 +3522,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 1 -OpDecorate %sbo Binding 2 -OpDecorate %images DescriptorSet 1 -OpDecorate %images Binding 3 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -2872,10 +3551,36 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5316 = OpConstant %uint 5316 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -2888,70 +3593,69 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: %20 = OpLoad %uint %19 -;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 -;CHECK-NOT: %23 = OpLoad %13 %22 -;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 -;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 -;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] -;CHECK: %28 = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -2960,12 +3664,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 1, binding = 2, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -2976,13 +3680,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint MissNV %main "main" -;CHECK: OpEntryPoint MissNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint MissNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -2995,13 +3699,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 1 -OpDecorate %sbo Binding 2 -OpDecorate %images DescriptorSet 1 -OpDecorate %images Binding 3 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -3023,10 +3728,36 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5317 = OpConstant %uint 5317 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -3039,67 +3770,69 @@ OpDecorate %images NonWritable %29 = OpCompositeExtract %float %27 0 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: %20 = OpLoad %uint %19 -;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 -;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 -;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 -;CHECK-NOT OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]] -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, @@ -3108,12 +3841,12 @@ TEST_F(InstBindlessTest, // #extension GL_EXT_nonuniform_qualifier : require // #extension GL_NV_ray_tracing : require // - // layout(set = 1, binding = 2, std140) buffer StorageBuffer { + // layout(set = 0, binding = 0, std140) buffer StorageBuffer { // uint index; // float red; // } sbo; // - // layout(set = 1, binding = 3, rgba32f) readonly uniform image2D images[]; + // layout(set = 0, binding = 1, rgba32f) readonly uniform image2D images[]; // // void main() // { @@ -3124,13 +3857,13 @@ TEST_F(InstBindlessTest, const std::string defs = R"( OpCapability RuntimeDescriptorArray OpCapability RayTracingNV -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" OpExtension "SPV_NV_ray_tracing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint CallableNV %main "main" -;CHECK: OpEntryPoint CallableNV %main "main" [[launch_id:%\w+]] +; CHECK: OpEntryPoint CallableNV %main "main" %89 OpSource GLSL 460 OpSourceExtension "GL_EXT_nonuniform_qualifier" OpSourceExtension "GL_NV_ray_tracing" @@ -3143,13 +3876,14 @@ OpName %images "images" OpMemberDecorate %StorageBuffer 0 Offset 0 OpMemberDecorate %StorageBuffer 1 Offset 4 OpDecorate %StorageBuffer BufferBlock -OpDecorate %sbo DescriptorSet 1 -OpDecorate %sbo Binding 2 -OpDecorate %images DescriptorSet 1 -OpDecorate %images Binding 3 +OpDecorate %sbo DescriptorSet 0 +OpDecorate %sbo Binding 0 +OpDecorate %images DescriptorSet 0 +OpDecorate %images Binding 1 OpDecorate %images NonWritable -)" + kImportDeco + R"( -;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +; CHECK: OpDecorate %89 BuiltIn LaunchIdNV %void = OpTypeVoid %3 = OpTypeFunction %void %uint = OpTypeInt 32 0 @@ -3171,9 +3905,36 @@ OpDecorate %images NonWritable %v4float = OpTypeVector %float 4 %uint_0 = OpConstant %uint 0 %_ptr_Uniform_float = OpTypePointer Uniform %float -;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %34 = OpTypeFunction %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %bool = OpTypeBool +; CHECK: %57 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_5318 = OpConstant %uint 5318 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %89 = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_51 = OpConstant %uint 51 +; CHECK: %113 = OpConstantNull %v4float +; CHECK: %116 = OpTypeFunction %uint %uint %uint %uint %uint +; CHECK: %uint_48 = OpConstant %uint 48 +; CHECK: %141 = OpConstantNull %uint +; CHECK: %uint_54 = OpConstant %uint 54 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -3184,71 +3945,71 @@ OpDecorate %images NonWritable %23 = OpLoad %13 %22 %27 = OpImageRead %v4float %23 %25 %29 = OpCompositeExtract %float %27 0 -;CHECK-NOT: %20 = OpLoad %uint %19 -;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}} -;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}} -;CHECK-NOT: %23 = OpLoad %13 %22 -;CHECK-NOT: %27 = OpImageRead %v4float %23 %25 -;CHECK-NOT: %29 = OpCompositeExtract %float %27 0 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %27 -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0 -;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 OpStore %31 %29 -;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 -;CHECK-NOT: OpStore %31 %29 -;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %31 %30 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: OpStore %31 %29 +; CHECK: %133 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %134 = OpULessThan %bool %uint_0 %133 +; CHECK: OpSelectionMerge %135 None +; CHECK: OpBranchConditional %134 %136 %137 +; CHECK: %136 = OpLabel +; CHECK: %138 = OpLoad %uint %25 +; CHECK: OpBranch %135 +; CHECK: %137 = OpLabel +; CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_48 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %135 +; CHECK: %135 = OpLabel +; CHECK: %142 = OpPhi %uint %138 %136 %141 %137 +; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images %142 +; CHECK: %28 = OpLoad %13 %27 +; CHECK: %48 = OpFunctionCall %uint %inst_bindless_direct_read_2 %uint_1 %uint_1 +; CHECK: %50 = OpULessThan %bool %142 %48 +; CHECK: OpSelectionMerge %51 None +; CHECK: OpBranchConditional %50 %52 %53 +; CHECK: %52 = OpLabel +; CHECK: %54 = OpLoad %13 %27 +; CHECK: %143 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_1 %142 +; CHECK: %144 = OpULessThan %bool %uint_0 %143 +; CHECK: OpSelectionMerge %145 None +; CHECK: OpBranchConditional %144 %146 %147 +; CHECK: %146 = OpLabel +; CHECK: %148 = OpLoad %13 %27 +; CHECK: %149 = OpImageRead %v4float %148 %20 +; CHECK: OpBranch %145 +; CHECK: %147 = OpLabel +; CHECK: %150 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_1 %142 %uint_0 +; CHECK: OpBranch %145 +; CHECK: %145 = OpLabel +; CHECK: %151 = OpPhi %v4float %149 %146 %113 %147 +; CHECK: OpBranch %51 +; CHECK: %53 = OpLabel +; CHECK: %112 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_51 %uint_0 %142 %48 +; CHECK: OpBranch %51 +; CHECK: %51 = OpLabel +; CHECK: %114 = OpPhi %v4float %151 %145 %113 %53 +; CHECK: %30 = OpCompositeExtract %float %114 0 +; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1 +; CHECK: %152 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %153 = OpULessThan %bool %uint_0 %152 +; CHECK: OpSelectionMerge %154 None +; CHECK: OpBranchConditional %153 %155 %156 +; CHECK: %155 = OpLabel +; CHECK: OpStore %31 %30 +; CHECK: OpBranch %154 +; CHECK: %156 = OpLabel +; CHECK: %158 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_54 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %154 +; CHECK: %154 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kDirectRead2 + kStreamWrite4Ray + kDirectRead4; // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) { @@ -3263,13 +4024,13 @@ TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) { // layout(location = 0) in vec2 inTexcoord; // layout(location = 0) out vec4 outColor; // - // layout(set = 1, binding = 0) uniform Uniforms { + // layout(set = 0, binding = 0) uniform Uniforms { // vec2 var0; // } uniforms; // - // layout(set = 1, binding = 1) uniform sampler uniformSampler; - // layout(set = 1, binding = 2) uniform texture2D uniformTex; - // layout(set = 1, binding = 3) uniform texture2D uniformTexArr[8]; + // layout(set = 0, binding = 1) uniform sampler uniformSampler; + // layout(set = 0, binding = 2) uniform texture2D uniformTex; + // layout(set = 0, binding = 3) uniform texture2D uniformTexArr[8]; // // void main() { // int index = 0; @@ -3283,12 +4044,12 @@ TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) { OpCapability Shader OpCapability ShaderNonUniformEXT OpCapability SampledImageArrayNonUniformIndexingEXT -;CHECK: OpCapability Linkage OpExtension "SPV_EXT_descriptor_indexing" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %inTexcoord %outColor -;CHECK: OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_EXT_nonuniform_qualifier" @@ -3304,25 +4065,26 @@ OpName %Uniforms "Uniforms" OpMemberName %Uniforms 0 "var0" OpName %uniforms "uniforms" OpName %outColor "outColor" -OpDecorate %uniformTexArr DescriptorSet 1 +OpDecorate %uniformTexArr DescriptorSet 0 OpDecorate %uniformTexArr Binding 3 OpDecorate %19 NonUniformEXT OpDecorate %22 NonUniformEXT -OpDecorate %uniformSampler DescriptorSet 1 +OpDecorate %uniformSampler DescriptorSet 0 OpDecorate %uniformSampler Binding 1 OpDecorate %inTexcoord Location 0 -OpDecorate %uniformTex DescriptorSet 1 +OpDecorate %uniformTex DescriptorSet 0 OpDecorate %uniformTex Binding 2 OpMemberDecorate %Uniforms 0 Offset 0 OpDecorate %Uniforms Block -OpDecorate %uniforms DescriptorSet 1 +OpDecorate %uniforms DescriptorSet 0 OpDecorate %uniforms Binding 0 OpDecorate %outColor Location 0 -;CHECK: OpDecorate {{%\w+}} NonUniform -;CHECK: OpDecorate {{%\w+}} NonUniform -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -;CHECK: OpDecorate [[desc_state_result:%\w+]] NonUniform +; CHECK: OpDecorate %63 NonUniform +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +)" + kInputDecorations + R"( +; CHECK: OpDecorate %151 NonUniform %void = OpTypeVoid %3 = OpTypeFunction %void %int = OpTypeInt 32 1 @@ -3354,9 +4116,32 @@ OpDecorate %outColor Location 0 %_ptr_Output_v4float = OpTypePointer Output %v4float %outColor = OpVariable %_ptr_Output_v4float Output %float_0 = OpConstant %float 0 -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float +; CHECK: %bool = OpTypeBool +; CHECK: %68 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_2 = OpConstant %uint 2 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_79 = OpConstant %uint 79 +; CHECK: %122 = OpConstantNull %v4float +; CHECK: %126 = OpTypeFunction %uint %uint %uint %uint %uint +)" + kInputGlobals + R"( +; CHECK: %uint_87 = OpConstant %uint 87 +; CHECK: %165 = OpConstantNull %v2float +; CHECK: %uint_89 = OpConstant %uint 89 )"; + // clang-format on const std::string main_func = R"( %main = OpFunction %void None %3 @@ -3373,26 +4158,6 @@ OpStore %index %int_0 %32 = OpLoad %v2float %inTexcoord %34 = OpImageSampleImplicitLod %v4float %28 %32 %36 = OpCompositeExtract %float %34 0 -;CHECK-NOT: %34 = OpImageSampleImplicitLod %v4float %28 %32 -;CHECK-NOT: %36 = OpCompositeExtract %float %34 0 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpBitcast %uint %19 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_80 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %21 -;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %26 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %32 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} OpStore %x %36 %39 = OpLoad %13 %uniformTex %40 = OpLoad %23 %uniformSampler @@ -3401,48 +4166,38 @@ OpStore %x %36 %47 = OpAccessChain %_ptr_Uniform_v2float %uniforms %int_0 %48 = OpLoad %v2float %47 %49 = OpFMul %v2float %42 %48 -;CHECK-NOT: %48 = OpLoad %v2float %47 -;CHECK-NOT: %49 = OpFMul %v2float %42 %48 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_88 {{%\w+}} %uint_1 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %47 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -;CHECK: %49 = OpFMul %v2float %42 [[phi_result]] %50 = OpImageSampleImplicitLod %v4float %41 %49 %51 = OpCompositeExtract %float %50 0 -OpStore %y %51 -;CHECK-NOT: %50 = OpImageSampleImplicitLod %v4float %41 %49 -;CHECK-NOT: %51 = OpCompositeExtract %float %50 0 -;CHECK: {{%\w+}} = OpSampledImage %27 %39 %40 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_90 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %13 %uniformTex -;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %40 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %49 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: %51 = OpCompositeExtract %float {{%\w+}} 0 +; CHECK-NOT: %51 = OpCompositeExtract %float %50 0 +; CHECK: %157 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +; CHECK: %158 = OpULessThan %bool %uint_0 %157 +; CHECK: OpSelectionMerge %159 None +; CHECK: OpBranchConditional %158 %160 %161 +; CHECK: %160 = OpLabel +; CHECK: %162 = OpLoad %v2float %47 +; CHECK: OpBranch %159 +; CHECK: %161 = OpLabel +; CHECK: %164 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_87 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %159 +; CHECK: %159 = OpLabel +; CHECK: %166 = OpPhi %v2float %162 %160 %165 %161 +; CHECK: %49 = OpFMul %v2float %42 %166 +; CHECK: %167 = OpSampledImage %27 %39 %40 +; CHECK: %168 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_2 %uint_0 +; CHECK: %169 = OpULessThan %bool %uint_0 %168 +; CHECK: OpSelectionMerge %170 None +; CHECK: OpBranchConditional %169 %171 %172 +; CHECK: %171 = OpLabel +; CHECK: %173 = OpLoad %13 %uniformTex +; CHECK: %174 = OpSampledImage %27 %173 %40 +; CHECK: %175 = OpImageSampleImplicitLod %v4float %174 %49 +; CHECK: OpBranch %170 +; CHECK: %172 = OpLabel +; CHECK: %177 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_89 %uint_1 %uint_0 %uint_0 +; CHECK: OpBranch %170 +; CHECK: %170 = OpLabel +; CHECK: %178 = OpPhi %v4float %175 %171 %122 %172 +; CHECK: %51 = OpCompositeExtract %float %178 0 OpStore %y %51 %54 = OpLoad %float %x %55 = OpLoad %float %y @@ -3451,11 +4206,13 @@ OpStore %outColor %57 OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string new_funcs = kStreamWrite4Frag + kDirectRead4; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(defs + kImportStub + main_func, - true, 23u); + SinglePassRunAndMatch(defs + main_func + new_funcs, + true, 7u, 23u, true, true, false, + false, false); } TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) { @@ -3497,145 +4254,161 @@ TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) { // clang-format off const std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord -OpExecutionMode %MainPs OriginUpperLeft -OpSource HLSL 500 -OpName %MainPs "MainPs" -OpName %PerViewPushConst_t "PerViewPushConst_t" -OpMemberName %PerViewPushConst_t 0 "g_B" -OpName %_ "" -OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" -OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0" -OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1" -OpName %__0 "" -OpName %g_tColor "g_tColor" -OpName %g_sAniso "g_sAniso" -OpName %i_vTextureCoords "i.vTextureCoords" -OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpMemberDecorate %PerViewPushConst_t 0 Offset 0 -OpDecorate %PerViewPushConst_t Block -OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 -OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8 -OpDecorate %PerViewConstantBuffer_t Block -OpDecorate %__0 DescriptorSet 0 -OpDecorate %__0 Binding 1 -OpDecorate %g_tColor DescriptorSet 0 -OpDecorate %g_tColor Binding 0 -OpDecorate %g_sAniso DescriptorSet 0 -OpDecorate %g_sAniso Binding 2 -OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%v4float = OpTypeVector %float 4 -%uint = OpTypeInt 32 0 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor +;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %MainPs OriginUpperLeft + OpSource HLSL 500 + OpName %MainPs "MainPs" + OpName %PerViewPushConst_t "PerViewPushConst_t" + OpMemberName %PerViewPushConst_t 0 "g_B" + OpName %_ "" + OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" + OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0" + OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1" + OpName %__0 "" + OpName %g_tColor "g_tColor" + OpName %g_sAniso "g_sAniso" + OpName %i_vTextureCoords "i.vTextureCoords" + OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" + OpMemberDecorate %PerViewPushConst_t 0 Offset 0 + OpDecorate %PerViewPushConst_t Block + OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 + OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8 + OpDecorate %PerViewConstantBuffer_t Block + OpDecorate %__0 DescriptorSet 0 + OpDecorate %__0 Binding 1 + OpDecorate %g_tColor DescriptorSet 0 + OpDecorate %g_tColor Binding 0 + OpDecorate %g_sAniso DescriptorSet 0 + OpDecorate %g_sAniso Binding 2 + OpDecorate %i_vTextureCoords Location 0 + OpDecorate %_entryPointOutput_vColor Location 0 + ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( + ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 %PerViewPushConst_t = OpTypeStruct %uint %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t -%_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 + %_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint -%bool = OpTypeBool -%uint_0 = OpConstant %uint 0 + %bool = OpTypeBool + %uint_0 = OpConstant %uint 0 %PerViewConstantBuffer_t = OpTypeStruct %v2float %v2float %_ptr_Uniform_PerViewConstantBuffer_t = OpTypePointer Uniform %PerViewConstantBuffer_t -%__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform + %__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float -%int_1 = OpConstant %int 1 -%49 = OpTypeImage %float 2D 0 0 0 1 Unknown + %int_1 = OpConstant %int 1 + %49 = OpTypeImage %float 2D 0 0 0 1 Unknown %_ptr_UniformConstant_49 = OpTypePointer UniformConstant %49 -%g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant -%53 = OpTypeSampler + %g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant + %53 = OpTypeSampler %_ptr_UniformConstant_53 = OpTypePointer UniformConstant %53 -%g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant -%57 = OpTypeSampledImage %49 + %g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant + %57 = OpTypeSampledImage %49 %_ptr_Input_v2float = OpTypePointer Input %v2float %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float - )" + kImportStub + R"( -%MainPs = OpFunction %void None %3 -%5 = OpLabel -%69 = OpLoad %v2float %i_vTextureCoords -%82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 -%83 = OpLoad %uint %82 -%84 = OpINotEqual %bool %83 %uint_0 -OpSelectionMerge %91 None -OpBranchConditional %84 %85 %88 -%85 = OpLabel -%86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0 -%87 = OpLoad %v2float %86 -;CHECK-NOT: %87 = OpLoad %v2float %86 -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[desc_state_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_72 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[desc_state_result]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %86 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel - ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -OpBranch %91 -%88 = OpLabel -%89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1 -%90 = OpLoad %v2float %89 -;CHECK-NOT: %90 = OpLoad %v2float %89 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_7 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_76 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %89 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -OpBranch %91 -%91 = OpLabel -%115 = OpPhi %v2float %87 %85 %90 %88 -;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88 -;CHECK: %115 = OpPhi %v2float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -%95 = OpFAdd %v2float %69 %115 -%96 = OpLoad %49 %g_tColor -%97 = OpLoad %53 %g_sAniso -%98 = OpSampledImage %57 %96 %97 -%100 = OpImageSampleImplicitLod %v4float %98 %95 -OpStore %_entryPointOutput_vColor %100 -OpReturn -OpFunctionEnd -)"; + ;CHECK: %uint_7 = OpConstant %uint 7 + ;CHECK: %uint_1 = OpConstant %uint 1 + ;CHECK: %122 = OpTypeFunction %uint %uint %uint %uint + ;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint + )" + kInputGlobals + R"( + ;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint + ;CHECK: %uint_4 = OpConstant %uint 4 + ;CHECK: %148 = OpTypeFunction %void %uint %uint %uint %uint %uint + )" + kOutputGlobals + R"( + ;CHECK: %uint_11 = OpConstant %uint 11 + ;CHECK: %uint_23 = OpConstant %uint 23 + ;CHECK: %uint_2 = OpConstant %uint 2 + ;CHECK: %uint_3 = OpConstant %uint 3 + ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float + ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input + ;CHECK: %v4uint = OpTypeVector %uint 4 + ;CHECK: %uint_5 = OpConstant %uint 5 + ;CHECK: %uint_8 = OpConstant %uint 8 + ;CHECK: %uint_9 = OpConstant %uint 9 + ;CHECK: %uint_10 = OpConstant %uint 10 + ;CHECK: %uint_71 = OpConstant %uint 71 + ;CHECK: %202 = OpConstantNull %v2float + ;CHECK: %uint_75 = OpConstant %uint 75 + %MainPs = OpFunction %void None %3 + %5 = OpLabel + ;CHECK: %140 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_1 %uint_0 + ;CHECK: OpBranch %117 + ;CHECK: %117 = OpLabel + ;CHECK: OpBranch %116 + ;CHECK: %116 = OpLabel + %69 = OpLoad %v2float %i_vTextureCoords + %82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0 + %83 = OpLoad %uint %82 + %84 = OpINotEqual %bool %83 %uint_0 + OpSelectionMerge %91 None + OpBranchConditional %84 %85 %88 + %85 = OpLabel + %86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0 + %87 = OpLoad %v2float %86 + ;CHECK-NOT: %87 = OpLoad %v2float %86 + ;CHECK: %119 = OpIAdd %uint %uint_0 %uint_7 + ;CHECK: %141 = OpULessThan %bool %119 %140 + ;CHECK: OpSelectionMerge %143 None + ;CHECK: OpBranchConditional %141 %144 %145 + ;CHECK: %144 = OpLabel + ;CHECK: %146 = OpLoad %v2float %86 + ;CHECK: OpBranch %143 + ;CHECK: %145 = OpLabel + ;CHECK: %201 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_71 %uint_4 %uint_0 %119 %140 + ;CHECK: OpBranch %143 + ;CHECK: %143 = OpLabel + ;CHECK: %203 = OpPhi %v2float %146 %144 %202 %145 + OpBranch %91 + %88 = OpLabel + %89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1 + %90 = OpLoad %v2float %89 + ;CHECK-NOT: %90 = OpLoad %v2float %89 + ;CHECK: %204 = OpIAdd %uint %uint_8 %uint_7 + ;CHECK: %205 = OpULessThan %bool %204 %140 + ;CHECK: OpSelectionMerge %206 None + ;CHECK: OpBranchConditional %205 %207 %208 + ;CHECK: %207 = OpLabel + ;CHECK: %209 = OpLoad %v2float %89 + ;CHECK: OpBranch %206 + ;CHECK: %208 = OpLabel + ;CHECK: %211 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_75 %uint_4 %uint_0 %204 %140 + ;CHECK: OpBranch %206 + ;CHECK: %206 = OpLabel + ;CHECK: %212 = OpPhi %v2float %209 %207 %202 %208 + OpBranch %91 + %91 = OpLabel + %115 = OpPhi %v2float %87 %85 %90 %88 + ;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88 + ;CHECK: %115 = OpPhi %v2float %203 %143 %212 %206 + %95 = OpFAdd %v2float %69 %115 + %96 = OpLoad %49 %g_tColor + %97 = OpLoad %53 %g_sAniso + %98 = OpSampledImage %57 %96 %97 + %100 = OpImageSampleImplicitLod %v4float %98 %95 + OpStore %_entryPointOutput_vColor %100 + OpReturn + OpFunctionEnd +)" + kDirectRead3 + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) { @@ -3676,129 +4449,153 @@ TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) { // clang-format off const std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor -OpExecutionMode %MainPs OriginUpperLeft -OpSource HLSL 500 -OpName %MainPs "MainPs" -OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" -OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" -OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" -OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" -OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" -OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" -OpName %_ "" -OpName %PerViewPushConst_t "PerViewPushConst_t" -OpMemberName %PerViewPushConst_t 0 "g_c" -OpName %__0 "" -OpName %g_tColor "g_tColor" -OpName %g_sAniso "g_sAniso" -OpName %i_vTextureCoords "i.vTextureCoords" -OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 -OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 -OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 -OpDecorate %_BindlessFastEnvMapCB_PS_t Block -OpDecorate %_ DescriptorSet 0 -OpDecorate %_ Binding 2 -OpMemberDecorate %PerViewPushConst_t 0 Offset 0 -OpDecorate %PerViewPushConst_t Block -OpDecorate %g_tColor DescriptorSet 0 -OpDecorate %g_tColor Binding 0 -OpDecorate %g_sAniso DescriptorSet 0 -OpDecorate %g_sAniso Binding 1 -OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%v4float = OpTypeVector %float 4 -%v3float = OpTypeVector %float 3 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor + OpExecutionMode %MainPs OriginUpperLeft + OpSource HLSL 500 + OpName %MainPs "MainPs" + OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" + OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" + OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" + OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" + OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" + OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" + OpName %_ "" + OpName %PerViewPushConst_t "PerViewPushConst_t" + OpMemberName %PerViewPushConst_t 0 "g_c" + OpName %__0 "" + OpName %g_tColor "g_tColor" + OpName %g_sAniso "g_sAniso" + OpName %i_vTextureCoords "i.vTextureCoords" + OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 + OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 + OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 + OpDecorate %_BindlessFastEnvMapCB_PS_t Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 2 + OpMemberDecorate %PerViewPushConst_t 0 Offset 0 + OpDecorate %PerViewPushConst_t Block + OpDecorate %g_tColor DescriptorSet 0 + OpDecorate %g_tColor Binding 0 + OpDecorate %g_sAniso DescriptorSet 0 + OpDecorate %g_sAniso Binding 1 + OpDecorate %i_vTextureCoords Location 0 + OpDecorate %_entryPointOutput_vColor Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 %mat4v3float = OpTypeMatrix %v3float 4 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float -%uint = OpTypeInt 32 0 -%uint_128 = OpConstant %uint 128 + %uint = OpTypeInt 32 0 + %uint_128 = OpConstant %uint 128 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t -%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 + %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 %PerViewPushConst_t = OpTypeStruct %uint %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t -%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant + %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint -%int_2 = OpConstant %int 2 + %int_2 = OpConstant %int 2 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float -%46 = OpTypeImage %float 2D 0 0 0 1 Unknown + %46 = OpTypeImage %float 2D 0 0 0 1 Unknown %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 -%g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant -%50 = OpTypeSampler + %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant + %50 = OpTypeSampler %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50 -%g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant -%54 = OpTypeSampledImage %46 + %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant + %54 = OpTypeSampledImage %46 %_ptr_Input_v2float = OpTypePointer Input %v2float %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float -)" + kImportStub + R"( -%MainPs = OpFunction %void None %3 -%5 = OpLabel -%66 = OpLoad %v2float %i_vTextureCoords -%79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 -%80 = OpLoad %uint %79 -%81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 -%82 = OpLoad %v2float %81 -;CHECK-NOT: %82 = OpLoad %v2float %81 -;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %81 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -%86 = OpFAdd %v2float %66 %82 -;CHECK-NOT: %86 = OpFAdd %v2float %66 %82 -;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}} -%87 = OpLoad %46 %g_tColor -%88 = OpLoad %50 %g_sAniso -%89 = OpSampledImage %54 %87 %88 -%91 = OpImageSampleImplicitLod %v4float %89 %86 -OpStore %_entryPointOutput_vColor %91 -OpReturn -OpFunctionEnd -)"; +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %uint_80 = OpConstant %uint 80 +;CHECK: %uint_64 = OpConstant %uint 64 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %105 = OpTypeFunction %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %bool = OpTypeBool +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %132 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_78 = OpConstant %uint 78 +;CHECK: %185 = OpConstantNull %v2float + %MainPs = OpFunction %void None %3 + %5 = OpLabel +;CHECK: %123 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_2 %uint_0 +;CHECK: OpBranch %93 +;CHECK: %93 = OpLabel +;CHECK: OpBranch %92 +;CHECK: %92 = OpLabel + %66 = OpLoad %v2float %i_vTextureCoords + %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 + %80 = OpLoad %uint %79 + %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 + %82 = OpLoad %v2float %81 +;CHECK-NOT: %82 = OpLoad %v2float %81 +;CHECK: %96 = OpIMul %uint %uint_80 %80 +;CHECK: %97 = OpIAdd %uint %uint_0 %96 +;CHECK: %99 = OpIAdd %uint %97 %uint_64 +;CHECK: %101 = OpIAdd %uint %99 %uint_7 +;CHECK: %125 = OpULessThan %bool %101 %123 +;CHECK: OpSelectionMerge %127 None +;CHECK: OpBranchConditional %125 %128 %129 +;CHECK: %128 = OpLabel +;CHECK: %130 = OpLoad %v2float %81 +;CHECK: OpBranch %127 +;CHECK: %129 = OpLabel +;CHECK: %184 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_78 %uint_4 %uint_0 %101 %123 +;CHECK: OpBranch %127 +;CHECK: %127 = OpLabel +;CHECK: %186 = OpPhi %v2float %130 %128 %185 %129 + %86 = OpFAdd %v2float %66 %82 +;CHECK-NOT: %86 = OpFAdd %v2float %66 %82 +;CHECK: %86 = OpFAdd %v2float %66 %186 + %87 = OpLoad %46 %g_tColor + %88 = OpLoad %50 %g_sAniso + %89 = OpSampledImage %54 %87 %88 + %91 = OpImageSampleImplicitLod %v4float %89 %86 + OpStore %_entryPointOutput_vColor %91 + OpReturn + OpFunctionEnd +)" + kDirectRead3 + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) { @@ -3809,151 +4606,173 @@ TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) { // clang-format off const std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord -OpExecutionMode %MainPs OriginUpperLeft -OpSource HLSL 500 -OpName %MainPs "MainPs" -OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" -OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" -OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" -OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" -OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" -OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" -OpName %_ "" -OpName %PerViewPushConst_t "PerViewPushConst_t" -OpMemberName %PerViewPushConst_t 0 "g_c" -OpName %__0 "" -OpName %g_tColor "g_tColor" -OpName %g_sAniso "g_sAniso" -OpName %i_vTextureCoords "i.vTextureCoords" -OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 -OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 -OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 -OpDecorate %_BindlessFastEnvMapCB_PS_t Block -OpDecorate %_ DescriptorSet 0 -OpDecorate %_ Binding 2 -OpMemberDecorate %PerViewPushConst_t 0 Offset 0 -OpDecorate %PerViewPushConst_t Block -OpDecorate %g_tColor DescriptorSet 0 -OpDecorate %g_tColor Binding 0 -OpDecorate %g_sAniso DescriptorSet 0 -OpDecorate %g_sAniso Binding 1 -OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%v4float = OpTypeVector %float 4 -%v3float = OpTypeVector %float 3 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor +;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %MainPs OriginUpperLeft + OpSource HLSL 500 + OpName %MainPs "MainPs" + OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" + OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" + OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" + OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" + OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" + OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" + OpName %_ "" + OpName %PerViewPushConst_t "PerViewPushConst_t" + OpMemberName %PerViewPushConst_t 0 "g_c" + OpName %__0 "" + OpName %g_tColor "g_tColor" + OpName %g_sAniso "g_sAniso" + OpName %i_vTextureCoords "i.vTextureCoords" + OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 + OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 + OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 + OpDecorate %_BindlessFastEnvMapCB_PS_t Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 2 + OpMemberDecorate %PerViewPushConst_t 0 Offset 0 + OpDecorate %PerViewPushConst_t Block + OpDecorate %g_tColor DescriptorSet 0 + OpDecorate %g_tColor Binding 0 + OpDecorate %g_sAniso DescriptorSet 0 + OpDecorate %g_sAniso Binding 1 + OpDecorate %i_vTextureCoords Location 0 + OpDecorate %_entryPointOutput_vColor Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 %mat4v3float = OpTypeMatrix %v3float 4 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float -%uint = OpTypeInt 32 0 -%uint_128 = OpConstant %uint 128 + %uint = OpTypeInt 32 0 + %uint_128 = OpConstant %uint 128 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t -%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 + %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 %PerViewPushConst_t = OpTypeStruct %uint %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t -%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant + %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint -%int_2 = OpConstant %int 2 + %int_2 = OpConstant %int 2 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float -%46 = OpTypeImage %float 2D 0 0 0 1 Unknown + %46 = OpTypeImage %float 2D 0 0 0 1 Unknown %_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 -%g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant -%50 = OpTypeSampler + %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant + %50 = OpTypeSampler %_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50 -%g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant -%54 = OpTypeSampledImage %46 + %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant + %54 = OpTypeSampledImage %46 %_ptr_Input_v2float = OpTypePointer Input %v2float %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %v4uint = OpTypeVector %uint 4 -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -)" + kImportStub + R"( -%MainPs = OpFunction %void None %3 -%5 = OpLabel -%66 = OpLoad %v2float %i_vTextureCoords -%79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 -%80 = OpLoad %uint %79 -%81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 -%82 = OpLoad %v2float %81 -%86 = OpFAdd %v2float %66 %82 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %uint_80 = OpConstant %uint 80 +;CHECK: %uint_64 = OpConstant %uint 64 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %104 = OpTypeFunction %uint %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %bool = OpTypeBool +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %135 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_78 = OpConstant %uint 78 +;CHECK: %189 = OpConstantNull %v2float +;CHECK: %uint_83 = OpConstant %uint 83 +;CHECK: %201 = OpConstantNull %v4float + %MainPs = OpFunction %void None %3 + %5 = OpLabel +;CHECK: %126 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_2 %uint_0 +;CHECK: %191 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %uint_0 +;CHECK: OpBranch %93 +;CHECK: %93 = OpLabel +;CHECK: OpBranch %92 +;CHECK: %92 = OpLabel + %66 = OpLoad %v2float %i_vTextureCoords + %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0 + %80 = OpLoad %uint %79 + %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2 + %82 = OpLoad %v2float %81 + %86 = OpFAdd %v2float %66 %82 ;CHECK-NOT: %82 = OpLoad %v2float %81 ;CHECK-NOT: %86 = OpFAdd %v2float %66 %82 -;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %81 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}} -%87 = OpLoad %46 %g_tColor -%88 = OpLoad %50 %g_sAniso -%89 = OpSampledImage %54 %87 %88 -%91 = OpImageSampleImplicitLod %v4float %89 %86 -OpStore %_entryPointOutput_vColor %91 +;CHECK: %96 = OpIMul %uint %uint_80 %80 +;CHECK: %97 = OpIAdd %uint %uint_0 %96 +;CHECK: %99 = OpIAdd %uint %97 %uint_64 +;CHECK: %101 = OpIAdd %uint %99 %uint_7 +;CHECK: %128 = OpULessThan %bool %101 %126 +;CHECK: OpSelectionMerge %130 None +;CHECK: OpBranchConditional %128 %131 %132 +;CHECK: %131 = OpLabel +;CHECK: %133 = OpLoad %v2float %81 +;CHECK: OpBranch %130 +;CHECK: %132 = OpLabel +;CHECK: %188 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_78 %uint_4 %uint_0 %101 %126 +;CHECK: OpBranch %130 +;CHECK: %130 = OpLabel +;CHECK: %190 = OpPhi %v2float %133 %131 %189 %132 +;CHECK: %86 = OpFAdd %v2float %66 %190 + %87 = OpLoad %46 %g_tColor + %88 = OpLoad %50 %g_sAniso + %89 = OpSampledImage %54 %87 %88 + %91 = OpImageSampleImplicitLod %v4float %89 %86 + OpStore %_entryPointOutput_vColor %91 ;CHECK-NOT: %91 = OpImageSampleImplicitLod %v4float %89 %86 ;CHECK-NOT: OpStore %_entryPointOutput_vColor %91 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_84 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %46 %g_tColor -;CHECK: {{%\w+}} = OpSampledImage %54 {{%\w+}} %88 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %86 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}} -OpReturn -OpFunctionEnd -)"; +;CHECK: %192 = OpULessThan %bool %uint_0 %191 +;CHECK: OpSelectionMerge %193 None +;CHECK: OpBranchConditional %192 %194 %195 +;CHECK: %194 = OpLabel +;CHECK: %196 = OpLoad %46 %g_tColor +;CHECK: %197 = OpSampledImage %54 %196 %88 +;CHECK: %198 = OpImageSampleImplicitLod %v4float %197 %86 +;CHECK: OpBranch %193 +;CHECK: %195 = OpLabel +;CHECK: %200 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_83 %uint_1 %uint_0 %uint_0 %uint_0 +;CHECK: OpBranch %193 +;CHECK: %193 = OpLabel +;CHECK: %202 = OpPhi %v4float %198 %194 %201 %195 +;CHECK: OpStore %_entryPointOutput_vColor %202 + OpReturn + OpFunctionEnd +)" + kDirectRead4 + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, true, true, + true, false, true); } TEST_F(InstBindlessTest, Descriptor16BitIdxRef) { @@ -3964,107 +4783,142 @@ TEST_F(InstBindlessTest, Descriptor16BitIdxRef) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability Int16 -OpCapability StoragePushConstant16 -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord -OpExecutionMode %MainPs OriginUpperLeft -OpSource HLSL 500 -OpName %MainPs "MainPs" -OpName %g_tColor "g_tColor" -OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" -OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" -OpName %_ "" -OpName %g_sAniso "g_sAniso" -OpName %i_vTextureCoords "i.vTextureCoords" -OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpDecorate %g_tColor DescriptorSet 1 -OpDecorate %g_tColor Binding 2 -OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 -OpDecorate %PerViewConstantBuffer_t Block -OpDecorate %g_sAniso DescriptorSet 1 -OpDecorate %g_sAniso Binding 2 -OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%10 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%v4float = OpTypeVector %float 4 -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%16 = OpTypeImage %float 2D 0 0 0 1 Unknown -%uint = OpTypeInt 32 0 -%uint_128 = OpConstant %uint 128 + OpCapability Shader + OpCapability Int16 + OpCapability StoragePushConstant16 +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor +;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_output_buffer %gl_FragCoord %inst_bindless_input_buffer + OpExecutionMode %MainPs OriginUpperLeft + OpSource HLSL 500 + OpName %MainPs "MainPs" + OpName %g_tColor "g_tColor" + OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t" + OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx" + OpName %_ "" + OpName %g_sAniso "g_sAniso" + OpName %i_vTextureCoords "i.vTextureCoords" + OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" + OpDecorate %g_tColor DescriptorSet 0 + OpDecorate %g_tColor Binding 0 + OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0 + OpDecorate %PerViewConstantBuffer_t Block + OpDecorate %g_sAniso DescriptorSet 0 + OpDecorate %g_sAniso Binding 0 + OpDecorate %i_vTextureCoords Location 0 + OpDecorate %_entryPointOutput_vColor Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +)" + kInputDecorations + R"( + %void = OpTypeVoid + %10 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %16 = OpTypeImage %float 2D 0 0 0 1 Unknown + %uint = OpTypeInt 32 0 + %uint_128 = OpConstant %uint 128 %_arr_16_uint_128 = OpTypeArray %16 %uint_128 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128 -%g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant -%ushort = OpTypeInt 16 0 + %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant + %ushort = OpTypeInt 16 0 %PerViewConstantBuffer_t = OpTypeStruct %ushort %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t -%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant + %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16 -%25 = OpTypeSampler + %25 = OpTypeSampler %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25 -%g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant -%27 = OpTypeSampledImage %16 + %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant + %27 = OpTypeSampledImage %16 %_ptr_Input_v2float = OpTypePointer Input %v2float %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -)" + kImportStub + R"( -%MainPs = OpFunction %void None %10 -%30 = OpLabel -;CHECK: OpBranch %39 -;CHECK: %39 = OpLabel -%31 = OpLoad %v2float %i_vTextureCoords -%32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0 -%33 = OpLoad %ushort %32 -%34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33 -%35 = OpLoad %16 %34 -%36 = OpLoad %25 %g_sAniso -%37 = OpSampledImage %27 %35 %36 -%38 = OpImageSampleImplicitLod %v4float %37 %31 -OpStore %_entryPointOutput_vColor %38 -;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 -;CHECK-NOT: OpStore %_entryPointOutput_vColor %38 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpUConvert %uint %33 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %16 %34 -;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36 -;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]] -OpReturn -OpFunctionEnd -)"; +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %51 = OpTypeFunction %void %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_60 = OpConstant %uint 60 +;CHECK: %106 = OpConstantNull %v4float +;CHECK: %111 = OpTypeFunction %uint %uint %uint %uint %uint +)" + kInputGlobals + R"( + %MainPs = OpFunction %void None %10 + %30 = OpLabel +;CHECK: OpBranch %108 +;CHECK: %108 = OpLabel +;CHECK: OpBranch %39 +;CHECK: %39 = OpLabel + %31 = OpLoad %v2float %i_vTextureCoords + %32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0 + %33 = OpLoad %ushort %32 + %34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33 + %35 = OpLoad %16 %34 + %36 = OpLoad %25 %g_sAniso + %37 = OpSampledImage %27 %35 %36 + %38 = OpImageSampleImplicitLod %v4float %37 %31 + OpStore %_entryPointOutput_vColor %38 +;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31 +;CHECK-NOT: OpStore %_entryPointOutput_vColor %38 +;CHECK: %41 = OpUConvert %uint %33 +;CHECK: %43 = OpULessThan %bool %41 %uint_128 +;CHECK: OpSelectionMerge %44 None +;CHECK: OpBranchConditional %43 %45 %46 +;CHECK: %45 = OpLabel +;CHECK: %47 = OpLoad %16 %34 +;CHECK: %48 = OpSampledImage %27 %47 %36 +;CHECK: %109 = OpUConvert %uint %33 +;CHECK: %131 = OpFunctionCall %uint %inst_bindless_direct_read_4 %uint_0 %uint_0 %uint_0 %109 +;CHECK: %132 = OpULessThan %bool %uint_0 %131 +;CHECK: OpSelectionMerge %133 None +;CHECK: OpBranchConditional %132 %134 %135 +;CHECK: %134 = OpLabel +;CHECK: %136 = OpLoad %16 %34 +;CHECK: %137 = OpSampledImage %27 %136 %36 +;CHECK: %138 = OpImageSampleImplicitLod %v4float %137 %31 +;CHECK: OpBranch %133 +;CHECK: %135 = OpLabel +;CHECK: %139 = OpUConvert %uint %33 +;CHECK: %140 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_60 %uint_1 %139 %uint_0 +;CHECK: OpBranch %133 +;CHECK: %133 = OpLabel +;CHECK: %141 = OpPhi %v4float %138 %134 %106 %135 +;CHECK: OpBranch %44 +;CHECK: %46 = OpLabel +;CHECK: %105 = OpFunctionCall %void %inst_bindless_stream_write_4 %uint_60 %uint_0 %41 %uint_128 +;CHECK: OpBranch %44 +;CHECK: %44 = OpLabel +;CHECK: %107 = OpPhi %v4float %141 %133 %106 %46 +;CHECK: OpStore %_entryPointOutput_vColor %107 + OpReturn + OpFunctionEnd +)" + kStreamWrite4Frag + kDirectRead4; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, true, true, + false, false, true); } TEST_F(InstBindlessTest, UniformArray16bitIdxRef) { @@ -4105,133 +4959,158 @@ TEST_F(InstBindlessTest, UniformArray16bitIdxRef) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability Int16 -OpCapability StoragePushConstant16 -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor -;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord -OpExecutionMode %MainPs OriginUpperLeft -OpSource HLSL 500 -OpName %MainPs "MainPs" -OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" -OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" -OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" -OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" -OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" -OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" -OpName %_ "" -OpName %PerViewPushConst_t "PerViewPushConst_t" -OpMemberName %PerViewPushConst_t 0 "g_c" -OpName %__0 "" -OpName %g_tColor "g_tColor" -OpName %g_sAniso "g_sAniso" -OpName %i_vTextureCoords "i.vTextureCoords" -OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 -OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 -OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 -OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 -OpDecorate %_BindlessFastEnvMapCB_PS_t Block -OpDecorate %_ DescriptorSet 0 -OpDecorate %_ Binding 0 -OpMemberDecorate %PerViewPushConst_t 0 Offset 0 -OpDecorate %PerViewPushConst_t Block -OpDecorate %g_tColor DescriptorSet 0 -OpDecorate %g_tColor Binding 0 -OpDecorate %g_sAniso DescriptorSet 0 -OpDecorate %g_sAniso Binding 0 -OpDecorate %i_vTextureCoords Location 0 -OpDecorate %_entryPointOutput_vColor Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%14 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%v4float = OpTypeVector %float 4 -%v3float = OpTypeVector %float 3 + OpCapability Shader + OpCapability Int16 + OpCapability StoragePushConstant16 +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor +;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %MainPs OriginUpperLeft + OpSource HLSL 500 + OpName %MainPs "MainPs" + OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t" + OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal" + OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins" + OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff" + OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t" + OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants" + OpName %_ "" + OpName %PerViewPushConst_t "PerViewPushConst_t" + OpMemberName %PerViewPushConst_t 0 "g_c" + OpName %__0 "" + OpName %g_tColor "g_tColor" + OpName %g_sAniso "g_sAniso" + OpName %i_vTextureCoords "i.vTextureCoords" + OpName %_entryPointOutput_vColor "@entryPointOutput.vColor" + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48 + OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64 + OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80 + OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0 + OpDecorate %_BindlessFastEnvMapCB_PS_t Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + OpMemberDecorate %PerViewPushConst_t 0 Offset 0 + OpDecorate %PerViewPushConst_t Block + OpDecorate %g_tColor DescriptorSet 0 + OpDecorate %g_tColor Binding 0 + OpDecorate %g_sAniso DescriptorSet 0 + OpDecorate %g_sAniso Binding 0 + OpDecorate %i_vTextureCoords Location 0 + OpDecorate %_entryPointOutput_vColor Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %14 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 %mat4v3float = OpTypeMatrix %v3float 4 %PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float -%uint = OpTypeInt 32 0 -%uint_128 = OpConstant %uint 128 + %uint = OpTypeInt 32 0 + %uint_128 = OpConstant %uint 128 %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128 %_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 %_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t -%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%ushort = OpTypeInt 16 0 + %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %ushort = OpTypeInt 16 0 %PerViewPushConst_t = OpTypeStruct %ushort %_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t -%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant + %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant %_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort -%int_2 = OpConstant %int 2 + %int_2 = OpConstant %int 2 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float -%30 = OpTypeImage %float 2D 0 0 0 1 Unknown + %30 = OpTypeImage %float 2D 0 0 0 1 Unknown %_ptr_UniformConstant_30 = OpTypePointer UniformConstant %30 -%g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant -%32 = OpTypeSampler + %g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant + %32 = OpTypeSampler %_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32 -%g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant -%34 = OpTypeSampledImage %30 + %g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant + %34 = OpTypeSampledImage %30 %_ptr_Input_v2float = OpTypePointer Input %v2float %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float -)" + kImportStub + R"( -%MainPs = OpFunction %void None %14 -%37 = OpLabel -%38 = OpLoad %v2float %i_vTextureCoords -%39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0 -%40 = OpLoad %ushort %39 -%41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2 -%42 = OpLoad %v2float %41 -%43 = OpFAdd %v2float %38 %42 -;CHECK-NOT: %42 = OpLoad %v2float %41 -;CHECK-NOT: %43 = OpFAdd %v2float %38 %42 -;CHECK: {{%\w+}} = OpUConvert %uint %40 -;CHECK: {{%\w+}} = OpIMul %uint %uint_80 {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_82 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v2float %41 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}} -;CHECK: %43 = OpFAdd %v2float %38 {{%\w+}} -%44 = OpLoad %30 %g_tColor -%45 = OpLoad %32 %g_sAniso -%46 = OpSampledImage %34 %44 %45 -%47 = OpImageSampleImplicitLod %v4float %46 %43 -OpStore %_entryPointOutput_vColor %47 -OpReturn -OpFunctionEnd -)"; +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %uint_80 = OpConstant %uint 80 +;CHECK: %uint_64 = OpConstant %uint 64 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %61 = OpTypeFunction %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %bool = OpTypeBool +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %88 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_81 = OpConstant %uint 81 +;CHECK: %142 = OpConstantNull %v2float + %MainPs = OpFunction %void None %14 + %37 = OpLabel +;CHECK: %79 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_0 %uint_0 +;CHECK: OpBranch %49 +;CHECK: %49 = OpLabel +;CHECK: OpBranch %48 +;CHECK: %48 = OpLabel + %38 = OpLoad %v2float %i_vTextureCoords + %39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0 + %40 = OpLoad %ushort %39 + %41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2 + %42 = OpLoad %v2float %41 + %43 = OpFAdd %v2float %38 %42 +;CHECK-NOT: %42 = OpLoad %v2float %41 +;CHECK-NOT: %43 = OpFAdd %v2float %38 %42 +;CHECK: %52 = OpUConvert %uint %40 +;CHECK: %53 = OpIMul %uint %uint_80 %52 +;CHECK: %54 = OpIAdd %uint %uint_0 %53 +;CHECK: %56 = OpIAdd %uint %54 %uint_64 +;CHECK: %58 = OpIAdd %uint %56 %uint_7 +;CHECK: %81 = OpULessThan %bool %58 %79 +;CHECK: OpSelectionMerge %83 None +;CHECK: OpBranchConditional %81 %84 %85 +;CHECK: %84 = OpLabel +;CHECK: %86 = OpLoad %v2float %41 +;CHECK: OpBranch %83 +;CHECK: %85 = OpLabel +;CHECK: %141 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_81 %uint_4 %uint_0 %58 %79 +;CHECK: OpBranch %83 +;CHECK: %83 = OpLabel +;CHECK: %143 = OpPhi %v2float %86 %84 %142 %85 +;CHECK: %43 = OpFAdd %v2float %38 %143 + %44 = OpLoad %30 %g_tColor + %45 = OpLoad %32 %g_sAniso + %46 = OpSampledImage %34 %44 %45 + %47 = OpImageSampleImplicitLod %v4float %46 %43 + OpStore %_entryPointOutput_vColor %47 + OpReturn + OpFunctionEnd + )" + kDirectRead3 + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) { @@ -4255,98 +5134,120 @@ TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) { // clang-format off std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position -;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex -OpSource GLSL 450 -OpSourceExtension "GL_EXT_scalar_block_layout" -OpName %main "main" -OpName %v_vtxResult "v_vtxResult" -OpName %Block "Block" -OpMemberName %Block 0 "var" -OpName %_ "" -OpName %a_position "a_position" -OpDecorate %v_vtxResult RelaxedPrecision -OpDecorate %v_vtxResult Location 0 -OpMemberDecorate %Block 0 RowMajor -OpMemberDecorate %Block 0 RelaxedPrecision -OpMemberDecorate %Block 0 Offset 0 -OpMemberDecorate %Block 0 MatrixStride 16 -OpDecorate %Block Block -OpDecorate %_ DescriptorSet 0 -OpDecorate %_ Binding 0 -OpDecorate %21 RelaxedPrecision -;CHECK-NOT: OpDecorate %21 RelaxedPrecision -;CHECK: OpDecorate %v_vtxResult RelaxedPrecision -;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision -OpDecorate %a_position Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex -;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex -;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position +;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex + OpSource GLSL 450 + OpSourceExtension "GL_EXT_scalar_block_layout" + OpName %main "main" + OpName %v_vtxResult "v_vtxResult" + OpName %Block "Block" + OpMemberName %Block 0 "var" + OpName %_ "" + OpName %a_position "a_position" + OpDecorate %v_vtxResult RelaxedPrecision + OpDecorate %v_vtxResult Location 0 + OpMemberDecorate %Block 0 RowMajor + OpMemberDecorate %Block 0 RelaxedPrecision + OpMemberDecorate %Block 0 Offset 0 + OpMemberDecorate %Block 0 MatrixStride 16 + OpDecorate %Block Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + OpDecorate %21 RelaxedPrecision +;CHECK-NOT: OpDecorate %21 RelaxedPrecision +;CHECK: OpDecorate %116 RelaxedPrecision + OpDecorate %a_position Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +;CHECK: OpDecorate %61 RelaxedPrecision +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex +;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 %_ptr_Output_float = OpTypePointer Output %float %v_vtxResult = OpVariable %_ptr_Output_float Output -%v2float = OpTypeVector %float 2 + %v2float = OpTypeVector %float 2 %mat4v2float = OpTypeMatrix %v2float 4 -%Block = OpTypeStruct %mat4v2float + %Block = OpTypeStruct %mat4v2float %_ptr_Uniform_Block = OpTypePointer Uniform %Block -%_ = OpVariable %_ptr_Uniform_Block Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%int_2 = OpConstant %int 2 -%uint = OpTypeInt 32 0 -%uint_1 = OpConstant %uint 1 + %_ = OpVariable %_ptr_Uniform_Block Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %int_2 = OpConstant %int 2 + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 %_ptr_Uniform_float = OpTypePointer Uniform %float -%v4float = OpTypeVector %float 4 + %v4float = OpTypeVector %float 4 %_ptr_Input_v4float = OpTypePointer Input %v4float -%a_position = OpVariable %_ptr_Input_v4float Input -;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint -;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input -;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -%20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 -%21 = OpLoad %float %20 -;CHECK-NOT: %21 = OpLoad %float %20 -;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_2 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %uint_1 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[load_result]] = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}} -OpStore %v_vtxResult %21 -;CHECK-NOT: OpStore %v_vtxResult %21$ -;CHECK: OpStore %v_vtxResult [[phi_result]] -OpReturn -OpFunctionEnd -)"; + %a_position = OpVariable %_ptr_Input_v4float Input +;CHECK; %uint_0 = OpConstant %uint 0 +;CHECK; %uint_16 = OpConstant %uint 16 +;CHECK; %uint_4 = OpConstant %uint 4 +;CHECK; %uint_3 = OpConstant %uint 3 +;CHECK; %37 = OpTypeFunction %uint %uint %uint %uint +;CHECK;%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK;%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK; %bool = OpTypeBool +;CHECK; %63 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK; %uint_11 = OpConstant %uint 11 +;CHECK; %uint_23 = OpConstant %uint 23 +;CHECK; %uint_2 = OpConstant %uint 2 +;CHECK;%_ptr_Input_uint = OpTypePointer Input %uint +;CHECK;%gl_VertexIndex = OpVariable %_ptr_Input_uint Input +;CHECK;%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input +;CHECK; %uint_5 = OpConstant %uint 5 +;CHECK; %uint_7 = OpConstant %uint 7 +;CHECK; %uint_8 = OpConstant %uint 8 +;CHECK; %uint_9 = OpConstant %uint 9 +;CHECK; %uint_10 = OpConstant %uint 10 +;CHECK; %uint_45 = OpConstant %uint 45 +;CHECK; %115 = OpConstantNull %float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: %55 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_0 %uint_0 +;CHECK: OpBranch %26 +;CHECK: %26 = OpLabel +;CHECK: OpBranch %25 +;CHECK: %25 = OpLabel + %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 + %21 = OpLoad %float %20 +;CHECK-NOT: %21 = OpLoad %float %20 +;CHECK: %30 = OpIMul %uint %uint_4 %int_2 +;CHECK: %31 = OpIAdd %uint %uint_0 %30 +;CHECK: %32 = OpIMul %uint %uint_16 %uint_1 +;CHECK: %33 = OpIAdd %uint %31 %32 +;CHECK: %35 = OpIAdd %uint %33 %uint_3 +;CHECK: %57 = OpULessThan %bool %35 %55 +;CHECK: OpSelectionMerge %58 None +;CHECK: OpBranchConditional %57 %59 %60 +;CHECK: %59 = OpLabel +;CHECK: %61 = OpLoad %float %20 +;CHECK: OpBranch %58 +;CHECK: %60 = OpLabel +;CHECK: %114 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_45 %uint_4 %uint_0 %35 %55 +;CHECK: OpBranch %58 +;CHECK: %58 = OpLabel +;CHECK: %116 = OpPhi %float %61 %59 %115 %60 + OpStore %v_vtxResult %21 +;CHECK-NOT: OpStore %v_vtxResult %21 +;CHECK: OpStore %v_vtxResult %116 + OpReturn + OpFunctionEnd + )" + kDirectRead3 + kStreamWrite5Vert; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) { @@ -4370,99 +5271,120 @@ TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) { // clang-format off const std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position -;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex -OpSource GLSL 450 -OpSourceExtension "GL_EXT_scalar_block_layout" -OpName %main "main" -OpName %v_vtxResult "v_vtxResult" -OpName %Block "Block" -OpMemberName %Block 0 "var" -OpName %_ "" -OpName %a_position "a_position" -OpDecorate %v_vtxResult RelaxedPrecision -OpDecorate %v_vtxResult Location 0 -OpMemberDecorate %Block 0 ColMajor -OpMemberDecorate %Block 0 RelaxedPrecision -OpMemberDecorate %Block 0 Offset 0 -OpMemberDecorate %Block 0 MatrixStride 8 -OpDecorate %Block Block -OpDecorate %_ DescriptorSet 0 -OpDecorate %_ Binding 0 -OpDecorate %21 RelaxedPrecision -;CHECK-NOT: OpDecorate %21 RelaxedPrecision -;CHECK: OpDecorate %v_vtxResult RelaxedPrecision -;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision -OpDecorate %a_position Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex -;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex -;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position +;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex + OpSource GLSL 450 + OpSourceExtension "GL_EXT_scalar_block_layout" + OpName %main "main" + OpName %v_vtxResult "v_vtxResult" + OpName %Block "Block" + OpMemberName %Block 0 "var" + OpName %_ "" + OpName %a_position "a_position" + OpDecorate %v_vtxResult RelaxedPrecision + OpDecorate %v_vtxResult Location 0 + OpMemberDecorate %Block 0 ColMajor + OpMemberDecorate %Block 0 RelaxedPrecision + OpMemberDecorate %Block 0 Offset 0 + OpMemberDecorate %Block 0 MatrixStride 8 + OpDecorate %Block Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + OpDecorate %21 RelaxedPrecision +;CHECK-NOT: OpDecorate %21 RelaxedPrecision +;CHECK: OpDecorate %115 RelaxedPrecision + OpDecorate %a_position Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +;CHECK: OpDecorate %61 RelaxedPrecision +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex +;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 %_ptr_Output_float = OpTypePointer Output %float %v_vtxResult = OpVariable %_ptr_Output_float Output -%v2float = OpTypeVector %float 2 + %v2float = OpTypeVector %float 2 %mat4v2float = OpTypeMatrix %v2float 4 -%Block = OpTypeStruct %mat4v2float + %Block = OpTypeStruct %mat4v2float %_ptr_Uniform_Block = OpTypePointer Uniform %Block -%_ = OpVariable %_ptr_Uniform_Block Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%int_2 = OpConstant %int 2 -%uint = OpTypeInt 32 0 -%uint_1 = OpConstant %uint 1 + %_ = OpVariable %_ptr_Uniform_Block Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %int_2 = OpConstant %int 2 + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 %_ptr_Uniform_float = OpTypePointer Uniform %float -%v4float = OpTypeVector %float 4 + %v4float = OpTypeVector %float 4 %_ptr_Input_v4float = OpTypePointer Input %v4float -%a_position = OpVariable %_ptr_Input_v4float Input -;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint -;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input -;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input -;CHECK: [[null_float:%\w+]] = OpConstantNull %float -)" + kImportStub + R"( + %a_position = OpVariable %_ptr_Input_v4float Input +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %37 = OpTypeFunction %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %bool = OpTypeBool +;CHECK: %63 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint +;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input +;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_45 = OpConstant %uint 45 +;CHECK: %114 = OpConstantNull %float %main = OpFunction %void None %3 -%5 = OpLabel -%20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 -%21 = OpLoad %float %20 -;CHECK-NOT: %21 = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpIMul %uint %uint_8 %int_2 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %uint_1 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK:[[load_result]] = OpLoad %float %20 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}} -OpStore %v_vtxResult %21 -;CHECK-NOT: OpStore %v_vtxResult %21$ -;CHECK: OpStore %v_vtxResult [[phi_result]] -OpReturn -OpFunctionEnd -)"; + %5 = OpLabel +;CHECK: %55 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_0 %uint_0 +;CHECK: OpBranch %26 +;CHECK: %26 = OpLabel +;CHECK: OpBranch %25 +;CHECK: %25 = OpLabel + %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1 + %21 = OpLoad %float %20 +;CHECK-NOT: %21 = OpLoad %float %20 +;CHECK: %29 = OpIMul %uint %uint_8 %int_2 +;CHECK: %30 = OpIAdd %uint %uint_0 %29 +;CHECK: %32 = OpIMul %uint %uint_4 %uint_1 +;CHECK: %33 = OpIAdd %uint %30 %32 +;CHECK: %35 = OpIAdd %uint %33 %uint_3 +;CHECK: %57 = OpULessThan %bool %35 %55 +;CHECK: OpSelectionMerge %58 None +;CHECK: OpBranchConditional %57 %59 %60 +;CHECK: %59 = OpLabel +;CHECK: %61 = OpLoad %float %20 +;CHECK: OpBranch %58 +;CHECK: %60 = OpLabel +;CHECK: %113 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_45 %uint_4 %uint_0 %35 %55 +;CHECK: OpBranch %58 +;CHECK: %58 = OpLabel +;CHECK: %115 = OpPhi %float %61 %59 %114 %60 + OpStore %v_vtxResult %21 +;CHECK-NOT: OpStore %v_vtxResult %21 +;CHECK: OpStore %v_vtxResult %115 + OpReturn + OpFunctionEnd + )" + kDirectRead3 + kStreamWrite5Vert; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); ValidatorOptions()->uniform_buffer_standard_layout = true; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) { @@ -4474,7 +5396,7 @@ TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) { // layout(location = 0) in highp vec4 a_position; // layout(location = 0) out highp vec2 v_vtxResult; // - // layout(set = 3, binding = 7, std430, row_major) uniform Block + // layout(set = 0, binding = 0, std430, row_major) uniform Block // { // lowp mat2 var[3][4]; // }; @@ -4486,103 +5408,130 @@ TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) { // clang-format off const std::string text = R"( -OpCapability Shader -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position -;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex -OpSource GLSL 450 -OpSourceExtension "GL_EXT_scalar_block_layout" -OpName %main "main" -OpName %v_vtxResult "v_vtxResult" -OpName %Block "Block" -OpMemberName %Block 0 "var" -OpName %_ "" -OpName %a_position "a_position" -OpDecorate %v_vtxResult Location 0 -OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32 -OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128 -OpMemberDecorate %Block 0 RowMajor -OpMemberDecorate %Block 0 RelaxedPrecision -OpMemberDecorate %Block 0 Offset 0 -OpMemberDecorate %Block 0 MatrixStride 16 -OpDecorate %Block Block -OpDecorate %_ DescriptorSet 3 -OpDecorate %_ Binding 7 -OpDecorate %26 RelaxedPrecision -;CHECK-NOT: OpDecorate %26 RelaxedPrecision -;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision -OpDecorate %a_position Location 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex -;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex -;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 + OpCapability Shader +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position +;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex + OpSource GLSL 450 + OpSourceExtension "GL_EXT_scalar_block_layout" + OpName %main "main" + OpName %v_vtxResult "v_vtxResult" + OpName %Block "Block" + OpMemberName %Block 0 "var" + OpName %_ "" + OpName %a_position "a_position" + OpDecorate %v_vtxResult Location 0 + OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32 + OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128 + OpMemberDecorate %Block 0 RowMajor + OpMemberDecorate %Block 0 RelaxedPrecision + OpMemberDecorate %Block 0 Offset 0 + OpMemberDecorate %Block 0 MatrixStride 16 + OpDecorate %Block Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + OpDecorate %26 RelaxedPrecision +;CHECK-NOT: OpDecorate %26 RelaxedPrecision +;CHECK: OpDecorate %125 RelaxedPrecision + OpDecorate %a_position Location 0 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kInputDecorations + R"( +;CHECK: OpDecorate %70 RelaxedPrecision +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex +;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 %_ptr_Output_v2float = OpTypePointer Output %v2float %v_vtxResult = OpVariable %_ptr_Output_v2float Output %mat2v2float = OpTypeMatrix %v2float 2 -%uint = OpTypeInt 32 0 -%uint_4 = OpConstant %uint 4 + %uint = OpTypeInt 32 0 + %uint_4 = OpConstant %uint 4 %_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4 -%uint_3 = OpConstant %uint 3 + %uint_3 = OpConstant %uint 3 %_arr__arr_mat2v2float_uint_4_uint_3 = OpTypeArray %_arr_mat2v2float_uint_4 %uint_3 -%Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3 + %Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3 %_ptr_Uniform_Block = OpTypePointer Uniform %Block -%_ = OpVariable %_ptr_Uniform_Block Uniform -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%int_2 = OpConstant %int 2 -%int_3 = OpConstant %int 3 -%int_1 = OpConstant %int 1 + %_ = OpVariable %_ptr_Uniform_Block Uniform + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %int_2 = OpConstant %int 2 + %int_3 = OpConstant %int 3 + %int_1 = OpConstant %int 1 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float -%v4float = OpTypeVector %float 4 + %v4float = OpTypeVector %float 4 %_ptr_Input_v4float = OpTypePointer Input %v4float -%a_position = OpVariable %_ptr_Input_v4float Input -;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint -;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input -;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input -;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1 -;CHECK: {{%\w+}} = OpIMul %uint %uint_128 %int_2 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIMul %uint %uint_32 %int_3 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_1 -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_19 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} -%26 = OpLoad %v2float %25 -OpStore %v_vtxResult %26 -;CHECK-NOT: %26 = OpLoad %v2float %25 -;CHECK-NOT: OpStore %v_vtxResult %26 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[load_result]] = OpLoad %v2float %25 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result]] = OpPhi %v2float [[load_result]] {{%\w+}} [[null_v2float]] {{%\w+}} -;CHECK: OpStore %v_vtxResult [[phi_result]] -OpReturn -OpFunctionEnd -)"; + %a_position = OpVariable %_ptr_Input_v4float Input +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %uint_128 = OpConstant %uint 128 +;CHECK: %uint_32 = OpConstant %uint 32 +;CHECK: %uint_16 = OpConstant %uint 16 +;CHECK: %uint_19 = OpConstant %uint 19 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %46 = OpTypeFunction %uint %uint %uint %uint +;CHECK:%_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kInputGlobals + R"( +;CHECK:%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %bool = OpTypeBool +;CHECK: %72 = OpTypeFunction %void %uint %uint %uint %uint %uint +)" + kOutputGlobals + R"( +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint +;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input +;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_51 = OpConstant %uint 51 +;CHECK: %124 = OpConstantNull %v2float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: %64 = OpFunctionCall %uint %inst_bindless_direct_read_3 %uint_1 %uint_0 %uint_0 +;CHECK: OpBranch %31 +;CHECK: %31 = OpLabel +;CHECK: OpBranch %30 +;CHECK: %30 = OpLabel + %25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1 + %26 = OpLoad %v2float %25 + OpStore %v_vtxResult %26 +;CHECK-NOT: %26 = OpLoad %v2float %25 +;CHECK-NOT: OpStore %v_vtxResult %26 +;CHECK: %34 = OpIMul %uint %uint_128 %int_2 +;CHECK: %35 = OpIAdd %uint %uint_0 %34 +;CHECK: %37 = OpIMul %uint %uint_32 %int_3 +;CHECK: %38 = OpIAdd %uint %35 %37 +;CHECK: %40 = OpIMul %uint %uint_4 %int_1 +;CHECK: %41 = OpIAdd %uint %38 %40 +;CHECK: %43 = OpIAdd %uint %41 %uint_19 +;CHECK: %66 = OpULessThan %bool %43 %64 +;CHECK: OpSelectionMerge %67 None +;CHECK: OpBranchConditional %66 %68 %69 +;CHECK: %68 = OpLabel +;CHECK: %70 = OpLoad %v2float %25 +;CHECK: OpBranch %67 +;CHECK: %69 = OpLabel +;CHECK: %123 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_51 %uint_4 %uint_0 %43 %64 +;CHECK: OpBranch %67 +;CHECK: %67 = OpLabel +;CHECK: %125 = OpPhi %v2float %70 %68 %124 %69 +;CHECK: OpStore %v_vtxResult %125 + OpReturn + OpFunctionEnd + )" + kDirectRead3 + kStreamWrite5Vert; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, false, true); } TEST_F(InstBindlessTest, ImageBufferOOBRead) { @@ -4599,76 +5548,101 @@ TEST_F(InstBindlessTest, ImageBufferOOBRead) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability ImageBuffer -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %x %s %ii -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpName %main "main" -OpName %x "x" -OpName %s "s" -OpName %ii "ii" -OpDecorate %x Location 11 -OpDecorate %s DescriptorSet 3 -OpDecorate %s Binding 7 -OpDecorate %s NonWritable -OpDecorate %ii Flat -OpDecorate %ii Location 13 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%x = OpVariable %_ptr_Output_v4float Output -%10 = OpTypeImage %float Buffer 0 0 0 2 R32f -%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 -%s = OpVariable %_ptr_UniformConstant_10 UniformConstant -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%ii = OpVariable %_ptr_Input_int Input -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -%main = OpFunction %void None %3 -%5 = OpLabel -;CHECK: OpBranch %19 -;CHECK: %19 = OpLabel -%13 = OpLoad %10 %s -%17 = OpLoad %int %ii -%18 = OpImageRead %v4float %13 %17 -OpStore %x %18 -;CHECK-NOT: %18 = OpImageRead %v4float %13 %17 -;CHECK-NOT: OpStore %x %18 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_34 {{%\w+}} %uint_3 %uint_7 %uint_0 %22 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %10 %s -;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %17 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %x [[phi_result]] -OpReturn -OpFunctionEnd -)"; + OpCapability Shader + OpCapability ImageBuffer +;CHECK: OpCapability ImageQuery +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %x %s %ii + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %x "x" + OpName %s "s" + OpName %ii "ii" + OpDecorate %x Location 11 + OpDecorate %s DescriptorSet 3 + OpDecorate %s Binding 7 + OpDecorate %s NonWritable + OpDecorate %ii Flat + OpDecorate %ii Location 13 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %_ptr_Output_v4float = OpTypePointer Output %v4float + %x = OpVariable %_ptr_Output_v4float Output + %10 = OpTypeImage %float Buffer 0 0 0 2 R32f + %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 + %s = OpVariable %_ptr_UniformConstant_10 UniformConstant + %int = OpTypeInt 32 1 + %_ptr_Input_int = OpTypePointer Input %int + %ii = OpVariable %_ptr_Input_int Input +;CHECK: %uint = OpTypeInt 32 0 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %35 = OpTypeFunction %void %uint %uint %uint %uint %uint +;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_33 = OpConstant %uint 33 +;CHECK: %93 = OpConstantNull %v4float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: OpBranch %21 +;CHECK: %21 = OpLabel +;CHECK: OpBranch %20 +;CHECK: %20 = OpLabel +;CHECK: OpBranch %19 +;CHECK: %19 = OpLabel + %13 = OpLoad %10 %s + %17 = OpLoad %int %ii + %18 = OpImageRead %v4float %13 %17 + OpStore %x %18 +;CHECK-NOT: %18 = OpImageRead %v4float %13 %17 +;CHECK-NOT: OpStore %x %18 +;CHECK: %23 = OpBitcast %uint %17 +;CHECK: %25 = OpImageQuerySize %uint %13 +;CHECK: %27 = OpULessThan %bool %23 %25 +;CHECK: OpSelectionMerge %29 None +;CHECK: OpBranchConditional %27 %30 %31 +;CHECK: %30 = OpLabel +;CHECK: %32 = OpLoad %10 %s +;CHECK: %33 = OpImageRead %v4float %32 %17 +;CHECK: OpBranch %29 +;CHECK: %31 = OpLabel +;CHECK: %92 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_33 %uint_7 %uint_0 %23 %25 +;CHECK: OpBranch %29 +;CHECK: %29 = OpLabel +;CHECK: %94 = OpPhi %v4float %33 %30 %93 %31 +;CHECK: OpStore %x %94 + OpReturn + OpFunctionEnd + )" + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, true, true); } TEST_F(InstBindlessTest, ImageBufferOOBWrite) { @@ -4685,75 +5659,98 @@ TEST_F(InstBindlessTest, ImageBufferOOBWrite) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability ImageBuffer -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %s %ii %x -;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %gl_FragCoord -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpName %main "main" -OpName %s "s" -OpName %ii "ii" -OpName %x "x" -OpDecorate %s DescriptorSet 3 -OpDecorate %s Binding 7 -OpDecorate %s NonReadable -OpDecorate %ii Flat -OpDecorate %ii Location 13 -OpDecorate %x Location 11 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%7 = OpTypeImage %float Buffer 0 0 0 2 R32f -%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7 -%s = OpVariable %_ptr_UniformConstant_7 UniformConstant -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%ii = OpVariable %_ptr_Input_int Input -%v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%x = OpVariable %_ptr_Output_v4float Output -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: %19 = OpLabel -%10 = OpLoad %7 %s -%14 = OpLoad %int %ii -%18 = OpLoad %v4float %x -OpImageWrite %10 %14 %18 -;CHECK-NOT: OpImageWrite %10 %14 %18 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %7 %s -;CHECK: OpImageWrite {{%\w+}} %14 %18 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -OpReturn -OpFunctionEnd -)"; + OpCapability Shader + OpCapability ImageBuffer +;CHECK: OpCapability ImageQuery +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %s %ii %x +;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %s "s" + OpName %ii "ii" + OpName %x "x" + OpDecorate %s DescriptorSet 3 + OpDecorate %s Binding 7 + OpDecorate %s NonReadable + OpDecorate %ii Flat + OpDecorate %ii Location 13 + OpDecorate %x Location 11 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %7 = OpTypeImage %float Buffer 0 0 0 2 R32f + %_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7 + %s = OpVariable %_ptr_UniformConstant_7 UniformConstant + %int = OpTypeInt 32 1 + %_ptr_Input_int = OpTypePointer Input %int + %ii = OpVariable %_ptr_Input_int Input + %v4float = OpTypeVector %float 4 + %_ptr_Output_v4float = OpTypePointer Output %v4float + %x = OpVariable %_ptr_Output_v4float Output +;CHECK: %uint = OpTypeInt 32 0 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %34 = OpTypeFunction %void %uint %uint %uint %uint %uint +;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_34 = OpConstant %uint 34 + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: OpBranch %21 +;CHECK: %21 = OpLabel +;CHECK: OpBranch %20 +;CHECK: %20 = OpLabel +;CHECK: OpBranch %19 +;CHECK: %19 = OpLabel + %10 = OpLoad %7 %s + %14 = OpLoad %int %ii + %18 = OpLoad %v4float %x + OpImageWrite %10 %14 %18 +;CHECK-NOT: OpImageWrite %10 %14 %18 +;CHECK: %23 = OpBitcast %uint %14 +;CHECK: %25 = OpImageQuerySize %uint %10 +;CHECK: %27 = OpULessThan %bool %23 %25 +;CHECK: OpSelectionMerge %29 None +;CHECK: OpBranchConditional %27 %30 %31 +;CHECK: %30 = OpLabel +;CHECK: %32 = OpLoad %7 %s +;CHECK: OpImageWrite %32 %14 %18 +;CHECK: OpBranch %29 +;CHECK: %31 = OpLabel +;CHECK: %91 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_34 %uint_7 %uint_0 %23 %25 +;CHECK: OpBranch %29 +;CHECK: %29 = OpLabel + OpReturn + OpFunctionEnd + )" + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, true, true); } TEST_F(InstBindlessTest, TextureBufferOOBFetch) { @@ -4770,75 +5767,102 @@ TEST_F(InstBindlessTest, TextureBufferOOBFetch) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability SampledBuffer -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %x %s %ii -;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpName %main "main" -OpName %x "x" -OpName %s "s" -OpName %ii "ii" -OpDecorate %x Location 11 -OpDecorate %s DescriptorSet 3 -OpDecorate %s Binding 7 -OpDecorate %ii Flat -OpDecorate %ii Location 13 -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%x = OpVariable %_ptr_Output_v4float Output -%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown -%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 -%s = OpVariable %_ptr_UniformConstant_10 UniformConstant -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%ii = OpVariable %_ptr_Input_int Input -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -%main = OpFunction %void None %3 -%5 = OpLabel -;CHECK: OpBranch %19 -;CHECK: %19 = OpLabel -%13 = OpLoad %10 %s -%17 = OpLoad %int %ii -%18 = OpImageFetch %v4float %13 %17 -OpStore %x %18 -;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17 -;CHECK-NOT: OpStore %x %18 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %10 %s -;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %17 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %x [[phi_result]] -OpReturn -OpFunctionEnd -)"; + OpCapability Shader + OpCapability SampledBuffer +;CHECK: OpCapability ImageQuery +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %x %s %ii +;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %x "x" + OpName %s "s" + OpName %ii "ii" + OpDecorate %x Location 11 + OpDecorate %s DescriptorSet 3 + OpDecorate %s Binding 7 + OpDecorate %ii Flat + OpDecorate %ii Location 13 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %_ptr_Output_v4float = OpTypePointer Output %v4float + %x = OpVariable %_ptr_Output_v4float Output + %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown + %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 + %s = OpVariable %_ptr_UniformConstant_10 UniformConstant + %int = OpTypeInt 32 1 + %_ptr_Input_int = OpTypePointer Input %int + %ii = OpVariable %_ptr_Input_int Input +;CHECK: %uint = OpTypeInt 32 0 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %uint_6 = OpConstant %uint 6 +;CHECK: %35 = OpTypeFunction %void %uint %uint %uint %uint %uint +;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_32 = OpConstant %uint 32 +;CHECK: %94 = OpConstantNull %v4float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: OpBranch %21 +;CHECK: %21 = OpLabel +;CHECK: OpBranch %20 +;CHECK: %20 = OpLabel +;CHECK: OpBranch %19 +;CHECK: %19 = OpLabel + %13 = OpLoad %10 %s + %17 = OpLoad %int %ii + %18 = OpImageFetch %v4float %13 %17 + OpStore %x %18 +;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17 +;CHECK-NOT: OpStore %x %18 +;CHECK: %23 = OpBitcast %uint %17 +;CHECK: %25 = OpImageQuerySize %uint %13 +;CHECK: %27 = OpULessThan %bool %23 %25 +;CHECK: OpSelectionMerge %29 None +;CHECK: OpBranchConditional %27 %30 %31 +;CHECK: %30 = OpLabel +;CHECK: %32 = OpLoad %10 %s +;CHECK: %33 = OpImageFetch %v4float %32 %17 +;CHECK: OpBranch %29 +;CHECK: %31 = OpLabel +;CHECK: %93 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_32 %uint_6 %uint_0 %23 %25 +;CHECK: OpBranch %29 +;CHECK: %29 = OpLabel +;CHECK: %95 = OpPhi %v4float %33 %30 %94 %31 +;CHECK: OpStore %x %95 + OpReturn + OpFunctionEnd + )" + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, true, true); } TEST_F(InstBindlessTest, SamplerBufferOOBFetch) { @@ -4855,80 +5879,105 @@ TEST_F(InstBindlessTest, SamplerBufferOOBFetch) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability SampledBuffer -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %x %s %ii -;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpName %main "main" -OpName %x "x" -OpName %s "s" -OpName %ii "ii" -OpDecorate %x Location 11 -OpDecorate %s DescriptorSet 3 -OpDecorate %s Binding 7 -OpDecorate %ii Flat -OpDecorate %ii Location 13 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%x = OpVariable %_ptr_Output_v4float Output -%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown -%11 = OpTypeSampledImage %10 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%s = OpVariable %_ptr_UniformConstant_11 UniformConstant -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%ii = OpVariable %_ptr_Input_int Input -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -;CHECK: OpBranch %21 -;CHECK: %21 = OpLabel -%14 = OpLoad %11 %s -%18 = OpLoad %int %ii -%19 = OpImage %10 %14 -%20 = OpImageFetch %v4float %19 %18 -OpStore %x %20 -;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18 -;CHECK-NOT: OpStore %x %20 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %11 %s -;CHECK: {{%\w+}} = OpImage %10 {{%\w+}} -;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %x [[phi_result]] -OpReturn -OpFunctionEnd -)"; + OpCapability Shader + OpCapability SampledBuffer +;CHECK: OpCapability ImageQuery +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %x %s %ii +;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %x "x" + OpName %s "s" + OpName %ii "ii" + OpDecorate %x Location 11 + OpDecorate %s DescriptorSet 3 + OpDecorate %s Binding 7 + OpDecorate %ii Flat + OpDecorate %ii Location 13 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %_ptr_Output_v4float = OpTypePointer Output %v4float + %x = OpVariable %_ptr_Output_v4float Output + %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown + %11 = OpTypeSampledImage %10 + %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 + %s = OpVariable %_ptr_UniformConstant_11 UniformConstant + %int = OpTypeInt 32 1 + %_ptr_Input_int = OpTypePointer Input %int + %ii = OpVariable %_ptr_Input_int Input +;CHECK: %uint = OpTypeInt 32 0 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %uint_6 = OpConstant %uint 6 +;CHECK: %38 = OpTypeFunction %void %uint %uint %uint %uint %uint +;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_34 = OpConstant %uint 34 +;CHECK: %97 = OpConstantNull %v4float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: OpBranch %23 +;CHECK: %23 = OpLabel +;CHECK: OpBranch %22 +;CHECK: %22 = OpLabel +;CHECK: OpBranch %21 +;CHECK: %21 = OpLabel + %14 = OpLoad %11 %s + %18 = OpLoad %int %ii + %19 = OpImage %10 %14 + %20 = OpImageFetch %v4float %19 %18 + OpStore %x %20 +;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18 +;CHECK-NOT: OpStore %x %20 +;CHECK: %25 = OpBitcast %uint %18 +;CHECK: %27 = OpImageQuerySize %uint %19 +;CHECK: %29 = OpULessThan %bool %25 %27 +;CHECK: OpSelectionMerge %31 None +;CHECK: OpBranchConditional %29 %32 %33 +;CHECK: %32 = OpLabel +;CHECK: %34 = OpLoad %11 %s +;CHECK: %35 = OpImage %10 %34 +;CHECK: %36 = OpImageFetch %v4float %35 %18 +;CHECK: OpBranch %31 +;CHECK: %33 = OpLabel +;CHECK: %96 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_34 %uint_6 %uint_0 %25 %27 +;CHECK: OpBranch %31 +;CHECK: %31 = OpLabel +;CHECK: %98 = OpPhi %v4float %36 %32 %97 %33 +;CHECK: OpStore %x %98 + OpReturn + OpFunctionEnd + )" + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, true, true); } TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) { @@ -4946,356 +5995,114 @@ TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) { // clang-format off const std::string text = R"( -OpCapability Shader -OpCapability SampledBuffer -;CHECK: OpCapability Linkage -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" %x %tBuf %s %ii -;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %gl_FragCoord -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 450 -OpName %main "main" -OpName %x "x" -OpName %tBuf "tBuf" -OpName %s "s" -OpName %ii "ii" -OpDecorate %x Location 11 -OpDecorate %tBuf DescriptorSet 3 -OpDecorate %tBuf Binding 7 -OpDecorate %s DescriptorSet 3 -OpDecorate %s Binding 8 -OpDecorate %ii Flat -OpDecorate %ii Location 13 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%x = OpVariable %_ptr_Output_v4float Output -%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown -%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 -%tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant -%14 = OpTypeSampler -%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 -%s = OpVariable %_ptr_UniformConstant_14 UniformConstant -%18 = OpTypeSampledImage %10 -%int = OpTypeInt 32 1 -%_ptr_Input_int = OpTypePointer Input %int -%ii = OpVariable %_ptr_Input_int Input -;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float -;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input -;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float -%main = OpFunction %void None %3 -%5 = OpLabel -%13 = OpLoad %10 %tBuf -%17 = OpLoad %14 %s -%19 = OpSampledImage %18 %13 %17 -%23 = OpLoad %int %ii -%24 = OpImage %10 %19 -%25 = OpImageFetch %v4float %24 %23 -OpStore %x %25 -;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23 -;CHECK-NOT: OpStore %x %25 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_43 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %10 %tBuf -;CHECK: {{%\w+}} = OpSampledImage %18 {{%\w+}} %17 -;CHECK: {{%\w+}} = OpImage %10 {{%\w+}} -;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %23 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}} -;CHECK: OpStore %x [[phi_result]] -OpReturn -OpFunctionEnd -)"; + OpCapability Shader + OpCapability SampledBuffer +;CHECK: OpCapability ImageQuery +;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %x %tBuf %s %ii +;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %inst_bindless_output_buffer %gl_FragCoord + OpExecutionMode %main OriginUpperLeft + OpSource GLSL 450 + OpName %main "main" + OpName %x "x" + OpName %tBuf "tBuf" + OpName %s "s" + OpName %ii "ii" + OpDecorate %x Location 11 + OpDecorate %tBuf DescriptorSet 3 + OpDecorate %tBuf Binding 7 + OpDecorate %s DescriptorSet 3 + OpDecorate %s Binding 8 + OpDecorate %ii Flat + OpDecorate %ii Location 13 +;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %_ptr_Output_v4float = OpTypePointer Output %v4float + %x = OpVariable %_ptr_Output_v4float Output + %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown + %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 + %tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant + %14 = OpTypeSampler + %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 + %s = OpVariable %_ptr_UniformConstant_14 UniformConstant + %18 = OpTypeSampledImage %10 + %int = OpTypeInt 32 1 + %_ptr_Input_int = OpTypePointer Input %int + %ii = OpVariable %_ptr_Input_int Input +;CHECK: %uint = OpTypeInt 32 0 +;CHECK: %uint_0 = OpConstant %uint 0 +;CHECK: %bool = OpTypeBool +;CHECK: %uint_6 = OpConstant %uint 6 +;CHECK: %44 = OpTypeFunction %void %uint %uint %uint %uint %uint +;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +;CHECK: %uint_11 = OpConstant %uint 11 +;CHECK: %uint_4 = OpConstant %uint 4 +;CHECK: %uint_1 = OpConstant %uint 1 +;CHECK: %uint_23 = OpConstant %uint 23 +;CHECK: %uint_2 = OpConstant %uint 2 +;CHECK: %uint_3 = OpConstant %uint 3 +;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +;CHECK: %v4uint = OpTypeVector %uint 4 +;CHECK: %uint_5 = OpConstant %uint 5 +;CHECK: %uint_7 = OpConstant %uint 7 +;CHECK: %uint_8 = OpConstant %uint 8 +;CHECK: %uint_9 = OpConstant %uint 9 +;CHECK: %uint_10 = OpConstant %uint 10 +;CHECK: %uint_42 = OpConstant %uint 42 +;CHECK: %103 = OpConstantNull %v4float + %main = OpFunction %void None %3 + %5 = OpLabel +;CHECK: OpBranch %28 +;CHECK: %28 = OpLabel +;CHECK: OpBranch %27 +;CHECK: %27 = OpLabel +;CHECK: OpBranch %26 +;CHECK: %26 = OpLabel + %13 = OpLoad %10 %tBuf + %17 = OpLoad %14 %s + %19 = OpSampledImage %18 %13 %17 + %23 = OpLoad %int %ii + %24 = OpImage %10 %19 + %25 = OpImageFetch %v4float %24 %23 + OpStore %x %25 +;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23 +;CHECK-NOT: OpStore %x %25 +;CHECK: %30 = OpBitcast %uint %23 +;CHECK: %32 = OpImageQuerySize %uint %24 +;CHECK: %34 = OpULessThan %bool %30 %32 +;CHECK: OpSelectionMerge %36 None +;CHECK: OpBranchConditional %34 %37 %38 +;CHECK: %37 = OpLabel +;CHECK: %39 = OpLoad %10 %tBuf +;CHECK: %40 = OpSampledImage %18 %39 %17 +;CHECK: %41 = OpImage %10 %40 +;CHECK: %42 = OpImageFetch %v4float %41 %23 +;CHECK: OpBranch %36 +;CHECK: %38 = OpLabel +;CHECK: %102 = OpFunctionCall %void %inst_bindless_stream_write_5 %uint_42 %uint_6 %uint_0 %30 %32 +;CHECK: OpBranch %36 +;CHECK: %36 = OpLabel +;CHECK: %104 = OpPhi %v4float %42 %37 %103 %38 +;CHECK: OpStore %x %104 + OpReturn + OpFunctionEnd + )" + kStreamWrite5Frag; // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); -} - -TEST_F(InstBindlessTest, DeviceBufferAddressOOB) { - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; - // layout(set = 0, binding = 0) uniform ufoo { - // bufStruct data; - // int nWrites; - // } u_info; - // layout(buffer_reference, std140) buffer bufStruct { - // int a[4]; - // }; - // void main() { - // for (int i=0; i < u_info.nWrites; ++i) { - // u_info.data.a[i] = 0xdeadca71; - // } - // } - - // clang-format off - const std::string text = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -;CHECK: OpCapability Linkage -;CHECK: OpCapability Int64 -OpExtension "SPV_KHR_physical_storage_buffer" -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint Vertex %main "main" %u_info -;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex -OpSource GLSL 450 -OpSourceExtension "GL_EXT_buffer_reference" -OpName %main "main" -OpName %i "i" -OpName %ufoo "ufoo" -OpMemberName %ufoo 0 "data" -OpMemberName %ufoo 1 "nWrites" -OpName %bufStruct "bufStruct" -OpMemberName %bufStruct 0 "a" -OpName %u_info "u_info" -OpMemberDecorate %ufoo 0 Offset 0 -OpMemberDecorate %ufoo 1 Offset 8 -OpDecorate %ufoo Block -OpDecorate %_arr_int_uint_4 ArrayStride 16 -OpMemberDecorate %bufStruct 0 Offset 0 -OpDecorate %bufStruct Block -OpDecorate %u_info DescriptorSet 0 -OpDecorate %u_info Binding 0 -%void = OpTypeVoid -%3 = OpTypeFunction %void -%int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int -%int_0 = OpConstant %int 0 -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer -%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %int -%uint = OpTypeInt 32 0 -%uint_4 = OpConstant %uint 4 -%_arr_int_uint_4 = OpTypeArray %int %uint_4 -%bufStruct = OpTypeStruct %_arr_int_uint_4 -%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct -%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo -%u_info = OpVariable %_ptr_Uniform_ufoo Uniform -%int_1 = OpConstant %int 1 -%_ptr_Uniform_int = OpTypePointer Uniform %int -%bool = OpTypeBool -%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct -%int_n559035791 = OpConstant %int -559035791 -%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%i = OpVariable %_ptr_Function_int Function -OpStore %i %int_0 -OpBranch %10 -%10 = OpLabel -OpLoopMerge %12 %13 None -OpBranch %14 -%14 = OpLabel -%15 = OpLoad %int %i -%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_3 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_56 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[load_result:%\w+]] = OpLoad %int %26 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %int [[load_result]] {{%\w+}} {{%\w+}} {{%\w+}} -%27 = OpLoad %int %26 -%29 = OpSLessThan %bool %15 %27 -;CHECK-NOT: %27 = OpLoad %int %26 -;CHECK-NOT: %29 = OpSLessThan %bool %15 %27 -;CHECK: %29 = OpSLessThan %bool %15 [[phi_result]] -OpBranchConditional %29 %11 %12 -%11 = OpLabel -%31 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -%32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 -;CHECK-NOT: %32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[load_result_2:%\w+]] = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_bufStruct {{%\w+}} -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result_2:%\w+]] = OpPhi %_ptr_PhysicalStorageBuffer_bufStruct [[load_result_2]] {{%\w+}} {{%\w+}} {{%\w+}} -%33 = OpLoad %int %i -%36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 -;CHECK-NOT: %36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 -;CHECK: %36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int [[phi_result_2]] %int_0 %33 -OpStore %36 %int_n559035791 Aligned 16 -OpBranch %13 -%13 = OpLabel -%37 = OpLoad %int %i -%38 = OpIAdd %int %37 %int_1 -OpStore %i %38 -OpBranch %10 -%12 = OpLabel -OpReturn -OpFunctionEnd)"; - // clang-format on - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); -} - -TEST_F(InstBindlessTest, VertexIndexOOB) { - // #version 450 - // layout(std140, binding = 0) uniform foo { uint tex_index[1]; } - // uniform_index_buffer; layout(location = 0) out flat uint index; vec2 - // vertices[3]; void main() { - // vertices[0] = vec2(-1.0, -1.0); - // vertices[1] = vec2( 1.0, -1.0); - // vertices[2] = vec2( 0.0, 1.0); - // gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0); - // index = uniform_index_buffer.tex_index[0]; - // } - // clang-format off - const std::string text = R"( -OpCapability Shader -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %main "main" %vertices %_ %gl_VertexIndex %index %uniform_index_buffer -OpSource GLSL 450 -OpName %main "main" -OpName %vertices "vertices" -OpName %gl_PerVertex "gl_PerVertex" -OpMemberName %gl_PerVertex 0 "gl_Position" -OpMemberName %gl_PerVertex 1 "gl_PointSize" -OpMemberName %gl_PerVertex 2 "gl_ClipDistance" -OpMemberName %gl_PerVertex 3 "gl_CullDistance" -OpName %_ "" -OpName %gl_VertexIndex "gl_VertexIndex" -OpName %index "index" -OpName %foo "foo" -OpMemberName %foo 0 "tex_index" -OpName %uniform_index_buffer "uniform_index_buffer" -OpMemberDecorate %gl_PerVertex 0 BuiltIn Position -OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize -OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance -OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance -OpDecorate %gl_PerVertex Block -OpDecorate %gl_VertexIndex BuiltIn VertexIndex -OpDecorate %index Flat -OpDecorate %index Location 0 -OpDecorate %_arr_uint_uint_1 ArrayStride 16 -OpMemberDecorate %foo 0 Offset 0 -OpDecorate %foo Block -OpDecorate %uniform_index_buffer DescriptorSet 0 -OpDecorate %uniform_index_buffer Binding 0 -%void = OpTypeVoid -%3 = OpTypeFunction %void -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%uint = OpTypeInt 32 0 -%uint_3 = OpConstant %uint 3 -%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3 -%_ptr_Private__arr_v2float_uint_3 = OpTypePointer Private %_arr_v2float_uint_3 -%vertices = OpVariable %_ptr_Private__arr_v2float_uint_3 Private -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%float_n1 = OpConstant %float -1 -%16 = OpConstantComposite %v2float %float_n1 %float_n1 -%_ptr_Private_v2float = OpTypePointer Private %v2float -%int_1 = OpConstant %int 1 -%float_1 = OpConstant %float 1 -%21 = OpConstantComposite %v2float %float_1 %float_n1 -%int_2 = OpConstant %int 2 -%float_0 = OpConstant %float 0 -%25 = OpConstantComposite %v2float %float_0 %float_1 -%v4float = OpTypeVector %float 4 -%uint_1 = OpConstant %uint 1 -%_arr_float_uint_1 = OpTypeArray %float %uint_1 -%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex -%_ = OpVariable %_ptr_Output_gl_PerVertex Output -%_ptr_Input_int = OpTypePointer Input %int -%gl_VertexIndex = OpVariable %_ptr_Input_int Input -%int_3 = OpConstant %int 3 -%_ptr_Output_v4float = OpTypePointer Output %v4float -%_ptr_Output_uint = OpTypePointer Output %uint -%index = OpVariable %_ptr_Output_uint Output -%_arr_uint_uint_1 = OpTypeArray %uint %uint_1 -%foo = OpTypeStruct %_arr_uint_uint_1 -%_ptr_Uniform_foo = OpTypePointer Uniform %foo -%uniform_index_buffer = OpVariable %_ptr_Uniform_foo Uniform -%_ptr_Uniform_uint = OpTypePointer Uniform %uint -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%18 = OpAccessChain %_ptr_Private_v2float %vertices %int_0 -OpStore %18 %16 -%22 = OpAccessChain %_ptr_Private_v2float %vertices %int_1 -OpStore %22 %21 -%26 = OpAccessChain %_ptr_Private_v2float %vertices %int_2 -OpStore %26 %25 -%35 = OpLoad %int %gl_VertexIndex -%37 = OpSMod %int %35 %int_3 -%38 = OpAccessChain %_ptr_Private_v2float %vertices %37 -%39 = OpLoad %v2float %38 -%40 = OpCompositeExtract %float %39 0 -%41 = OpCompositeExtract %float %39 1 -%42 = OpCompositeConstruct %v4float %40 %41 %float_0 %float_1 -%44 = OpAccessChain %_ptr_Output_v4float %_ %int_0 -OpStore %44 %42 -%52 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0 %int_0 -%53 = OpLoad %uint %52 -;CHECK-NOT: %53 = OpLoad %uint %52 -;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %int_0 -;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}} -;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 -;CHECK: {{%\w+}} = OpLoad %int %gl_VertexIndex -;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_87 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}} -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %uint %52 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %index [[phi_result]] -OpStore %index %53 -;CHECK-NOT: OpStore %index %53 -OpReturn -;CHECK: OpReturn -OpFunctionEnd)"; - // clang-format on - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23u); + SinglePassRunAndMatch(text, true, 7u, 23u, false, + false, true, true, true); } // TODO(greg-lunarg): Add tests to verify handling of these cases: diff --git a/test/opt/inst_buff_addr_check_test.cpp b/test/opt/inst_buff_addr_check_test.cpp index 72d34385..e095eb77 100644 --- a/test/opt/inst_buff_addr_check_test.cpp +++ b/test/opt/inst_buff_addr_check_test.cpp @@ -19,6 +19,7 @@ #include #include +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" @@ -26,14 +27,145 @@ namespace spvtools { namespace opt { namespace { -static const std::string kFuncName = "inst_buff_addr_search_and_test"; -static const std::string kImportDeco = R"( -;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" + - kFuncName + R"(" Import +static const std::string kOutputDecorations = R"( +; CHECK: OpDecorate [[output_buffer_type:%inst_buff_addr_OutputBuffer]] Block +; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0 +; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4 +; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7 +; CHECK: OpDecorate [[output_buffer_var]] Binding 0 )"; -static const std::string kImportStub = R"( -;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}} -;CHECK: OpFunctionEnd + +static const std::string kOutputGlobals = R"( +; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %_runtimearr_uint +; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]] +; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer +)"; + +static const std::string kStreamWrite4Begin = R"( +; CHECK: {{%\w+}} = OpFunction %void None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint +; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_0 +; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_10 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10 +; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 1 +; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}} +; CHECK: OpSelectionMerge {{%\w+}} None +; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_10 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_23 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_1]] +)"; + +static const std::string kStreamWrite4End = R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_2]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_3]] +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} [[param_4]] +; CHECK: OpBranch {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: OpReturn +; CHECK: OpFunctionEnd +)"; + +// clang-format off +static const std::string kStreamWrite4Frag = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord +; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; + +static const std::string kStreamWrite4Compute = kStreamWrite4Begin + R"( +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 +; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 {{%\w+}} +; CHECK: OpStore {{%\w+}} {{%\w+}} +)" + kStreamWrite4End; +// clang-format on + +static const std::string kInputDecorations = R"( +; CHECK: OpDecorate [[input_buffer_type:%inst_buff_addr_InputBuffer]] Block +; CHECK: OpMemberDecorate [[input_buffer_type]] 0 Offset 0 +; CHECK: OpDecorate [[input_buffer_var:%\w+]] DescriptorSet 7 +; CHECK: OpDecorate [[input_buffer_var]] Binding 2 +)"; + +static const std::string kInputGlobals = R"( +; CHECK: [[input_buffer_type]] = OpTypeStruct %_runtimearr_ulong +; CHECK: [[input_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[input_buffer_type]] +; CHECK: [[input_buffer_var]] = OpVariable [[input_ptr_type]] StorageBuffer +)"; + +static const std::string kSearchAndTest = R"( +; CHECK: {{%\w+}} = OpFunction %bool None {{%\w+}} +; CHECK: [[param_1:%\w+]] = OpFunctionParameter %ulong +; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint +; CHECK: {{%\w+}} = OpLabel +; CHECK: OpBranch {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpPhi %uint %uint_1 {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK: OpLoopMerge {{%\w+}} {{%\w+}} None +; CHECK: OpBranch {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}} +; CHECK: {{%\w+}} = OpUGreaterThan %bool {{%\w+}} [[param_1]] +; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpLabel +; CHECK: {{%\w+}} = OpISub %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}} +; CHECK: {{%\w+}} = OpISub %ulong [[param_1]] {{%\w+}} +; CHECK: {{%\w+}} = OpUConvert %ulong [[param_2]] +; CHECK: {{%\w+}} = OpIAdd %ulong {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 %uint_0 +; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}} +; CHECK: {{%\w+}} = OpUConvert %uint {{%\w+}} +; CHECK: {{%\w+}} = OpISub %uint {{%\w+}} %uint_1 +; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}} +; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}} +; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}} +; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}} +; CHECK: OpReturnValue {{%\w+}} +; CHECK: OpFunctionEnd )"; // clang-format on @@ -62,13 +194,13 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferStore) { const std::string defs = R"( OpCapability Shader OpCapability PhysicalStorageBufferAddresses -;CHECK: OpCapability Int64 +; CHECK: OpCapability Int64 OpExtension "SPV_EXT_physical_storage_buffer" -;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel PhysicalStorageBuffer64 GLSL450 OpEntryPoint GLCompute %main "main" -;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID OpExecutionMode %main LocalSize 1 1 1 OpSource GLSL 450 OpSourceExtension "GL_EXT_buffer_reference" @@ -93,8 +225,11 @@ OpMemberDecorate %bufStruct 1 Offset 32 OpDecorate %bufStruct Block OpDecorate %u_info DescriptorSet 0 OpDecorate %u_info Binding 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId )"; const std::string globals = R"( @@ -115,11 +250,32 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer %int_1 = OpConstant %int 1 %int_3239 = OpConstant %int 3239 %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -;CHECK: %ulong = OpTypeInt 64 0 -;CHECK: %bool = OpTypeBool -;CHECK: %v3uint = OpTypeVector %uint 3 -;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint -;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +; CHECK: %ulong = OpTypeInt 64 0 +; CHECK: %uint_4 = OpConstant %uint 4 +; CHECK: %bool = OpTypeBool +; CHECK: %28 = OpTypeFunction %bool %ulong %uint +; CHECK: %uint_1 = OpConstant %uint 1 +; CHECK: %_runtimearr_ulong = OpTypeRuntimeArray %ulong +)" + kInputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_ulong = OpTypePointer StorageBuffer %ulong +; CHECK: %uint_0 = OpConstant %uint 0 +; CHECK: %uint_32 = OpConstant %uint 32 +; CHECK: %70 = OpTypeFunction %void %uint %uint %uint %uint +; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint +)" + kOutputGlobals + R"( +; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint +; CHECK: %uint_10 = OpConstant %uint 10 +; CHECK: %uint_23 = OpConstant %uint 23 +; CHECK: %uint_5 = OpConstant %uint 5 +; CHECK: %uint_3 = OpConstant %uint 3 +; CHECK: %v3uint = OpTypeVector %uint 3 +; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint +; CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input +; CHECK: %uint_6 = OpConstant %uint 6 +; CHECK: %uint_7 = OpConstant %uint 7 +; CHECK: %uint_8 = OpConstant %uint 8 +; CHECK: %uint_9 = OpConstant %uint 9 +; CHECK: %uint_48 = OpConstant %uint 48 )"; // clang-format off @@ -129,35 +285,36 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 -;CHECK-NOT: %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -;CHECK-NOT: %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 -;CHECK-NOT: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 -;CHECK: %20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -;CHECK: %21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20 -;CHECK: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %22 -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} {{%\w+}} %uint_4 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 +; CHECK-NOT: %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 +; CHECK-NOT: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 +; CHECK: %20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 +; CHECK: %21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20 +; CHECK: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1 +; CHECK: %24 = OpConvertPtrToU %ulong %22 +; CHECK: %61 = OpFunctionCall %bool %inst_buff_addr_search_and_test %24 %uint_4 +; CHECK: OpSelectionMerge %62 None +; CHECK: OpBranchConditional %61 %63 %64 +; CHECK: %63 = OpLabel OpStore %22 %int_3239 Aligned 16 -;CHECK: OpStore %22 %int_3239 Aligned 16 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK: OpStore %22 %int_3239 Aligned 16 +; CHECK: OpBranch %62 +; CHECK: %64 = OpLabel +; CHECK: %65 = OpUConvert %uint %24 +; CHECK: %67 = OpShiftRightLogical %ulong %24 %uint_32 +; CHECK: %68 = OpUConvert %uint %67 +; CHECK: %124 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_48 %uint_2 %65 %68 +; CHECK: OpBranch %62 +; CHECK: %62 = OpLabel OpReturn OpFunctionEnd )"; + const std::string output_funcs = kSearchAndTest + kStreamWrite4Compute; + // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndMatch( - defs + decorates + globals + kImportStub + main_func, true, 23u); + defs + decorates + globals + main_func + output_funcs, true, 7u, 23u); } TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) { @@ -187,7 +344,7 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) { const std::string defs = R"( OpCapability Shader OpCapability PhysicalStorageBufferAddresses -;CHECK: OpCapability Int64 +; CHECK: OpCapability Int64 OpExtension "SPV_EXT_physical_storage_buffer" OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" @@ -197,7 +354,7 @@ OpExecutionMode %main LocalSize 1 1 1 OpSource GLSL 450 OpSourceExtension "GL_EXT_buffer_reference" OpName %main "main" -;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID +; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID OpName %blockType "blockType" OpMemberName %blockType 0 "x" OpMemberName %blockType 1 "next" @@ -215,9 +372,13 @@ OpMemberDecorate %rootBlock 0 Offset 0 OpDecorate %rootBlock Block OpDecorate %r DescriptorSet 0 OpDecorate %r Binding 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId +; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId )"; + // clang-format on const std::string globals = R"( %void = OpTypeVoid @@ -235,7 +396,7 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType %int_531 = OpConstant %int 531 %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -)"; +)" + kInputGlobals + kOutputGlobals; const std::string main_func = R"( %main = OpFunction %void None %3 @@ -246,49 +407,48 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0 OpStore %26 %int_531 Aligned 16 -;CHECK-NOT: %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 -;CHECK-NOT: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %21 -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_45 {{%\w+}} {{%\w+}} %uint_8 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_blockType %52 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpPhi %_ptr_PhysicalStorageBuffer_blockType {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int {{%\w+}} %int_0 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %26 -;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} {{%\w+}} %uint_4 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %26 %int_531 Aligned 16 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel +; CHECK-NOT: %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 +; CHECK-NOT: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0 +; CHECK: %30 = OpConvertPtrToU %ulong %21 +; CHECK: %67 = OpFunctionCall %bool %inst_buff_addr_search_and_test %30 %uint_8 +; CHECK: OpSelectionMerge %68 None +; CHECK: OpBranchConditional %67 %69 %70 +; CHECK: %69 = OpLabel +; CHECK: %71 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 +; CHECK: OpBranch %68 +; CHECK: %70 = OpLabel +; CHECK: %72 = OpUConvert %uint %30 +; CHECK: %74 = OpShiftRightLogical %ulong %30 %uint_32 +; CHECK: %75 = OpUConvert %uint %74 +; CHECK: %131 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_44 %uint_2 %72 %75 +; CHECK: %133 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_blockType %132 +; CHECK: OpBranch %68 +; CHECK: %68 = OpLabel +; CHECK: %134 = OpPhi %_ptr_PhysicalStorageBuffer_blockType %71 %69 %133 %70 +; CHECK: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %134 %int_0 +; CHECK: %135 = OpConvertPtrToU %ulong %26 +; CHECK: %136 = OpFunctionCall %bool %inst_buff_addr_search_and_test %135 %uint_4 +; CHECK: OpSelectionMerge %137 None +; CHECK: OpBranchConditional %136 %138 %139 +; CHECK: %138 = OpLabel +; CHECK: OpStore %26 %int_531 Aligned 16 +; CHECK: OpBranch %137 +; CHECK: %139 = OpLabel +; CHECK: %140 = OpUConvert %uint %135 +; CHECK: %141 = OpShiftRightLogical %ulong %135 %uint_32 +; CHECK: %142 = OpUConvert %uint %141 +; CHECK: %144 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_46 %uint_2 %140 %142 +; CHECK: OpBranch %137 +; CHECK: %137 = OpLabel OpReturn OpFunctionEnd )"; - // clang-format on + + const std::string output_funcs = kSearchAndTest + kStreamWrite4Compute; SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndMatch( - defs + decorates + globals + kImportStub + main_func, true, 23u); + defs + decorates + globals + main_func + output_funcs, true, 7u, 23u); } TEST_F(InstBuffAddrTest, StructLoad) { @@ -315,11 +475,11 @@ TEST_F(InstBuffAddrTest, StructLoad) { OpCapability Shader OpCapability Int64 OpCapability PhysicalStorageBufferAddresses -;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" +; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel PhysicalStorageBuffer64 GLSL450 OpEntryPoint Fragment %main "main" -;CHECK: OpEntryPoint Fragment %main "main" %gl_FragCoord +; CHECK: OpEntryPoint Fragment %main "main" %inst_buff_addr_input_buffer %inst_buff_addr_output_buffer %gl_FragCoord OpExecutionMode %main OriginUpperLeft OpSource GLSL 450 OpSourceExtension "GL_ARB_gpu_shader_int64" @@ -338,8 +498,11 @@ OpMemberName %TestBuffer 0 "test" OpMemberDecorate %Test_0 0 Offset 0 OpMemberDecorate %TestBuffer 0 Offset 0 OpDecorate %TestBuffer Block -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8 +)" + kInputDecorations + R"( +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord )"; const std::string globals = R"( @@ -356,415 +519,50 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffe %int_0 = OpConstant %int 0 %_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0 %ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704 -;CHECK: {{%\w+}} = OpConstantNull %Test_0 +; CHECK: %47 = OpTypeFunction %bool %ulong %uint +)" + kInputGlobals + R"( +; CHECK: %90 = OpTypeFunction %void %uint %uint %uint %uint +)" + kOutputGlobals + R"( +; CHECK: %143 = OpConstantNull %Test_0 )"; + // clang-format on - const std::string main_func = R"( + const std::string main_func = + R"( %main = OpFunction %void None %3 %5 = OpLabel %37 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %ulong_18446744073172680704 %38 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %37 %int_0 %39 = OpLoad %Test_0 %38 Aligned 16 -;CHECK-NOT: %39 = OpLoad %Test_0 %38 Aligned 16 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %38 -;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord -;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 -;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_38 {{%\w+}} {{%\w+}} %uint_4 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %Test_0 %38 Aligned 16 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} +; CHECK-NOT: %39 = OpLoad %Test_0 %38 Aligned 16 +; CHECK: %43 = OpConvertPtrToU %ulong %38 +; CHECK: %80 = OpFunctionCall %bool %inst_buff_addr_search_and_test %43 %uint_4 +; CHECK: OpSelectionMerge %81 None +; CHECK: OpBranchConditional %80 %82 %83 +; CHECK: %82 = OpLabel +; CHECK: %84 = OpLoad %Test_0 %38 Aligned 16 +; CHECK: OpBranch %81 +; CHECK: %83 = OpLabel +; CHECK: %85 = OpUConvert %uint %43 +; CHECK: %87 = OpShiftRightLogical %ulong %43 %uint_32 +; CHECK: %88 = OpUConvert %uint %87 +; CHECK: %142 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_37 %uint_2 %85 %88 +; CHECK: OpBranch %81 +; CHECK: %81 = OpLabel +; CHECK: %144 = OpPhi %Test_0 %84 %82 %143 %83 %40 = OpCopyLogical %Test %39 -;CHECK-NOT: %40 = OpCopyLogical %Test %39 -;CHECK: %40 = OpCopyLogical %Test [[phi_result]] +; CHECK-NOT: %40 = OpCopyLogical %Test %39 +; CHECK: %40 = OpCopyLogical %Test %144 OpReturn OpFunctionEnd )"; - // clang-format on - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); + const std::string output_funcs = kSearchAndTest + kStreamWrite4Frag; + + SetTargetEnv(SPV_ENV_VULKAN_1_2); SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); SinglePassRunAndMatch( - defs + decorates + globals + kImportStub + main_func, true); -} - -TEST_F(InstBuffAddrTest, PaddedStructLoad) { - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // #extension GL_ARB_gpu_shader_int64 : enable - // struct Test { - // uvec3 pad_1; // Offset 0 Size 12 - // double pad_2; // Offset 16 Size 8 (alignment requirement) - // float a; // Offset 24 Size 4 - // }; // Total Size 28 - // - // layout(buffer_reference, std430, buffer_reference_align = 16) buffer - // TestBuffer { Test test; }; - // - // Test GetTest(uint64_t ptr) { - // return TestBuffer(ptr).test; - // } - // - // void main() { - // GetTest(0xe0000000); - // } - - const std::string defs = - R"( -OpCapability Shader -OpCapability Float64 -OpCapability Int64 -OpCapability PhysicalStorageBufferAddresses -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint Vertex %main "main" -OpSource GLSL 450 -OpSourceExtension "GL_ARB_gpu_shader_int64" -OpSourceExtension "GL_EXT_buffer_reference" -OpName %main "main" -OpName %Test "Test" -OpMemberName %Test 0 "pad_1" -OpMemberName %Test 1 "pad_2" -OpMemberName %Test 2 "a" -OpName %GetTest_u641_ "GetTest(u641;" -OpName %ptr "ptr" -OpName %Test_0 "Test" -OpMemberName %Test_0 0 "pad_1" -OpMemberName %Test_0 1 "pad_2" -OpMemberName %Test_0 2 "a" -OpName %TestBuffer "TestBuffer" -OpMemberName %TestBuffer 0 "test" -OpName %param "param" -)"; - - // clang-format off - const std::string decorates = R"( -OpDecorate %TestBuffer Block -OpMemberDecorate %Test_0 0 Offset 0 -OpMemberDecorate %Test_0 1 Offset 16 -OpMemberDecorate %Test_0 2 Offset 24 -OpMemberDecorate %TestBuffer 0 Offset 0 -)" + kImportDeco + R"( -;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex -;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex -)"; - - const std::string globals = R"( -%void = OpTypeVoid -%3 = OpTypeFunction %void -%ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%uint = OpTypeInt 32 0 -%v3uint = OpTypeVector %uint 3 -%double = OpTypeFloat 64 -%float = OpTypeFloat 32 -%Test = OpTypeStruct %v3uint %double %float -%13 = OpTypeFunction %Test %_ptr_Function_ulong -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffer -%Test_0 = OpTypeStruct %v3uint %double %float -%TestBuffer = OpTypeStruct %Test_0 -%_ptr_PhysicalStorageBuffer_TestBuffer = OpTypePointer PhysicalStorageBuffer %TestBuffer -%int = OpTypeInt 32 1 -%int_0 = OpConstant %int 0 -%_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0 -%_ptr_Function_Test = OpTypePointer Function %Test -%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704 -;CHECK: {{%\w+}} = OpConstantNull %Test_0 -)"; - - const std::string main_func = R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%param = OpVariable %_ptr_Function_ulong Function -OpStore %param %ulong_18446744073172680704 -%35 = OpFunctionCall %Test %GetTest_u641_ %param -OpReturn -OpFunctionEnd -%GetTest_u641_ = OpFunction %Test None %13 -%ptr = OpFunctionParameter %_ptr_Function_ulong -%16 = OpLabel -%28 = OpVariable %_ptr_Function_Test Function -%17 = OpLoad %ulong %ptr -%21 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %17 -%25 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %21 %int_0 -%26 = OpLoad %Test_0 %25 Aligned 16 -%29 = OpCopyLogical %Test %26 -;CHECK-NOT: %30 = OpLoad %Test %28 -;CHECK-NOT: %26 = OpLoad %Test_0 %25 Aligned 16 -;CHECK-NOT: %29 = OpCopyLogical %Test %26 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %25 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_28 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %Test_0 %25 Aligned 16 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: %29 = OpCopyLogical %Test [[phi_result]] -OpStore %28 %29 -%30 = OpLoad %Test %28 -OpReturnValue %30 -OpFunctionEnd -)"; - // clang-format on - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch( - defs + decorates + globals + kImportStub + main_func, true); -} - -TEST_F(InstBuffAddrTest, DeviceBufferAddressOOB) { - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; - // layout(set = 0, binding = 0) uniform ufoo { - // bufStruct data; - // int nWrites; - // } u_info; - // layout(buffer_reference, std140) buffer bufStruct { - // int a[4]; - // }; - // void main() { - // for (int i=0; i < u_info.nWrites; ++i) { - // u_info.data.a[i] = 0xdeadca71; - // } - // } - - // clang-format off - const std::string text = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint Vertex %main "main" %u_info -;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex -OpSource GLSL 450 -OpSourceExtension "GL_EXT_buffer_reference" -OpName %main "main" -OpName %i "i" -OpName %ufoo "ufoo" -OpMemberName %ufoo 0 "data" -OpMemberName %ufoo 1 "nWrites" -OpName %bufStruct "bufStruct" -OpMemberName %bufStruct 0 "a" -OpName %u_info "u_info" -OpMemberDecorate %ufoo 0 Offset 0 -OpMemberDecorate %ufoo 1 Offset 8 -OpDecorate %ufoo Block -OpDecorate %_arr_int_uint_4 ArrayStride 16 -OpMemberDecorate %bufStruct 0 Offset 0 -OpDecorate %bufStruct Block -OpDecorate %u_info DescriptorSet 0 -OpDecorate %u_info Binding 0 -)" + kImportDeco + R"( -%void = OpTypeVoid -%3 = OpTypeFunction %void -%int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int -%int_0 = OpConstant %int 0 -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer -%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %int -%uint = OpTypeInt 32 0 -%uint_4 = OpConstant %uint 4 -%_arr_int_uint_4 = OpTypeArray %int %uint_4 -%bufStruct = OpTypeStruct %_arr_int_uint_4 -%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct -%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo -%u_info = OpVariable %_ptr_Uniform_ufoo Uniform -%int_1 = OpConstant %int 1 -%_ptr_Uniform_int = OpTypePointer Uniform %int -%bool = OpTypeBool -%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct -%int_n559035791 = OpConstant %int -559035791 -%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -)" + kImportStub + R"( -%main = OpFunction %void None %3 -%5 = OpLabel -%i = OpVariable %_ptr_Function_int Function -OpStore %i %int_0 -OpBranch %10 -%10 = OpLabel -OpLoopMerge %12 %13 None -OpBranch %14 -%14 = OpLabel -%15 = OpLoad %int %i -%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 -%27 = OpLoad %int %26 -%29 = OpSLessThan %bool %15 %27 -OpBranchConditional %29 %11 %12 -%11 = OpLabel -%31 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -%32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 -%33 = OpLoad %int %i -%36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 -OpStore %36 %int_n559035791 Aligned 16 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %36 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_4 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpStore %36 %int_n559035791 Aligned 16 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -OpBranch %13 -%13 = OpLabel -%37 = OpLoad %int %i -%38 = OpIAdd %int %37 %int_1 -OpStore %i %38 -OpBranch %10 -%12 = OpLabel -OpReturn -OpFunctionEnd)"; - // clang-format on - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndMatch(text, true, 23); -} - -TEST_F(InstBuffAddrTest, UVec3ScalarAddressOOB) { - // clang-format off - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // #extension GL_EXT_scalar_block_layout : enable - // layout(buffer_reference, std430, scalar) readonly buffer IndexBuffer - // { - // uvec3 indices[]; - // }; - // layout(set = 0, binding = 0) uniform ufoo { - // IndexBuffer data; - // int nReads; - // } u_info; - // void main() { - // uvec3 readvec; - // for (int i=0; i < u_info.nReads; ++i) { - // readvec = u_info.data.indices[i]; - // } - // } - const std::string text = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint Vertex %main "main" %u_info -OpSource GLSL 450 -OpSourceExtension "GL_EXT_buffer_reference" -OpSourceExtension "GL_EXT_scalar_block_layout" -OpName %main "main" -OpName %i "i" -OpName %ufoo "ufoo" -OpMemberName %ufoo 0 "data" -OpMemberName %ufoo 1 "nReads" -OpName %IndexBuffer "IndexBuffer" -OpMemberName %IndexBuffer 0 "indices" -OpName %u_info "u_info" -OpName %readvec "readvec" -OpMemberDecorate %ufoo 0 Offset 0 -OpMemberDecorate %ufoo 1 Offset 8 -OpDecorate %ufoo Block -OpDecorate %_runtimearr_v3uint ArrayStride 12 -OpMemberDecorate %IndexBuffer 0 NonWritable -OpMemberDecorate %IndexBuffer 0 Offset 0 -OpDecorate %IndexBuffer Block -OpDecorate %u_info DescriptorSet 0 -OpDecorate %u_info Binding 0 -)" + kImportDeco + R"( -%void = OpTypeVoid -%3 = OpTypeFunction %void -%int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int -%int_0 = OpConstant %int 0 -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_IndexBuffer PhysicalStorageBuffer -%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_IndexBuffer %int -%uint = OpTypeInt 32 0 -%v3uint = OpTypeVector %uint 3 -%_runtimearr_v3uint = OpTypeRuntimeArray %v3uint -%IndexBuffer = OpTypeStruct %_runtimearr_v3uint -%_ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer PhysicalStorageBuffer %IndexBuffer -%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo -%u_info = OpVariable %_ptr_Uniform_ufoo Uniform -%int_1 = OpConstant %int 1 -%_ptr_Uniform_int = OpTypePointer Uniform %int -%bool = OpTypeBool -)" + kImportStub + R"( -%_ptr_Function_v3uint = OpTypePointer Function %v3uint -%_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_IndexBuffer -%_ptr_PhysicalStorageBuffer_v3uint = OpTypePointer PhysicalStorageBuffer %v3uint -%main = OpFunction %void None %3 -%5 = OpLabel -%i = OpVariable %_ptr_Function_int Function -%readvec = OpVariable %_ptr_Function_v3uint Function -OpStore %i %int_0 -OpBranch %10 -%10 = OpLabel -OpLoopMerge %12 %13 None -OpBranch %14 -%14 = OpLabel -%15 = OpLoad %int %i -%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 -%27 = OpLoad %int %26 -%29 = OpSLessThan %bool %15 %27 -OpBranchConditional %29 %11 %12 -%11 = OpLabel -%33 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer %u_info %int_0 -%34 = OpLoad %_ptr_PhysicalStorageBuffer_IndexBuffer %33 -%35 = OpLoad %int %i -%37 = OpAccessChain %_ptr_PhysicalStorageBuffer_v3uint %34 %int_0 %35 -%38 = OpLoad %v3uint %37 Aligned 4 -OpStore %readvec %38 -;CHECK-NOT: %38 = OpLoad %v3uint %37 Aligned 4 -;CHECK-NOT: OpStore %readvec %38 -;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %37 -;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex -;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex -;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 -;CHECK: [[test_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_67 {{%\w+}} {{%\w+}} %uint_12 -;CHECK: OpSelectionMerge {{%\w+}} None -;CHECK: OpBranchConditional [[test_result]] {{%\w+}} {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: {{%\w+}} = OpLoad %v3uint %37 Aligned 4 -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: OpBranch {{%\w+}} -;CHECK: {{%\w+}} = OpLabel -;CHECK: [[phi_result:%\w+]] = OpPhi %v3uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -;CHECK: OpStore %readvec [[phi_result]] -OpBranch %13 -%13 = OpLabel -%39 = OpLoad %int %i -%40 = OpIAdd %int %39 %int_1 -OpStore %i %40 -OpBranch %10 -%12 = OpLabel -OpReturn -OpFunctionEnd -)"; - // clang-format on - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); - SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - ValidatorOptions()->scalar_block_layout = true; - SinglePassRunAndMatch(text, true, 23); + defs + decorates + globals + main_func + output_funcs, true); } } // namespace diff --git a/test/opt/inst_debug_printf_test.cpp b/test/opt/inst_debug_printf_test.cpp index 24c0bc65..57e50440 100644 --- a/test/opt/inst_debug_printf_test.cpp +++ b/test/opt/inst_debug_printf_test.cpp @@ -18,6 +18,7 @@ #include #include +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" @@ -29,13 +30,12 @@ static const std::string kOutputDecorations = R"( ; CHECK: OpDecorate [[output_buffer_type:%inst_printf_OutputBuffer]] Block ; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0 ; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4 -; CHECK: OpMemberDecorate [[output_buffer_type]] 2 Offset 8 ; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7 ; CHECK: OpDecorate [[output_buffer_var]] Binding 3 )"; static const std::string kOutputGlobals = R"( -; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %uint %_runtimearr_uint +; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %_runtimearr_uint ; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]] ; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer )"; @@ -74,7 +74,7 @@ OpExtension "SPV_KHR_non_semantic_info" ; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %2 "MainPs" %3 %4 -; CHECK: OpEntryPoint Fragment %2 "MainPs" %3 %4 +; CHECK: OpEntryPoint Fragment %2 "MainPs" %3 %4 %gl_FragCoord OpExecutionMode %2 OriginUpperLeft %5 = OpString "Color is %vn" )"; @@ -87,7 +87,10 @@ OpDecorate %7 DescriptorSet 0 OpDecorate %7 Binding 0 OpDecorate %3 Location 0 OpDecorate %4 Location 0 -)" + kOutputDecorations; +; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4 +)" + kOutputDecorations + R"( +; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord +)"; const std::string globals = R"(%void = OpTypeVoid @@ -107,11 +110,14 @@ OpDecorate %4 Location 0 %_ptr_Output_v4float = OpTypePointer Output %v4float %4 = OpVariable %_ptr_Output_v4float Output ; CHECK: %uint = OpTypeInt 32 0 -; CHECK: [[func_type:%\w+]] = OpTypeFunction %void %uint %uint %uint %uint %uint %uint %uint +; CHECK: %38 = OpTypeFunction %void %uint %uint %uint %uint %uint %uint ; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint )" + kOutputGlobals + R"( ; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint ; CHECK: %bool = OpTypeBool +; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float +; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input +; CHECK: %v4uint = OpTypeVector %uint 4 )"; // clang-format on @@ -125,66 +131,78 @@ OpDecorate %4 Location 0 %25 = OpImageSampleImplicitLod %v4float %24 %21 %26 = OpExtInst %void %1 1 %5 %25 ; CHECK-NOT: %26 = OpExtInst %void %1 1 %5 %25 -; CHECK: {{%\w+}} = OpCompositeExtract %float %25 0 -; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -; CHECK: {{%\w+}} = OpCompositeExtract %float %25 1 -; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -; CHECK: {{%\w+}} = OpCompositeExtract %float %25 2 -; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -; CHECK: {{%\w+}} = OpCompositeExtract %float %25 3 -; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}} -; CHECK: {{%\w+}} = OpFunctionCall %void %inst_printf_stream_write_5 %uint_23 %uint_36 %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} -; CHECK: OpBranch {{%\w+}} -; CHECK: {{%\w+}} = OpLabel +; CHECK: %29 = OpCompositeExtract %float %25 0 +; CHECK: %30 = OpBitcast %uint %29 +; CHECK: %31 = OpCompositeExtract %float %25 1 +; CHECK: %32 = OpBitcast %uint %31 +; CHECK: %33 = OpCompositeExtract %float %25 2 +; CHECK: %34 = OpBitcast %uint %33 +; CHECK: %35 = OpCompositeExtract %float %25 3 +; CHECK: %36 = OpBitcast %uint %35 +; CHECK: %101 = OpFunctionCall %void %inst_printf_stream_write_6 %uint_36 %uint_5 %30 %32 %34 %36 +; CHECK: OpBranch %102 +; CHECK: %102 = OpLabel OpStore %4 %25 OpReturn OpFunctionEnd )"; const std::string output_func = R"( -; CHECK: %inst_printf_stream_write_5 = OpFunction %void None {{%\w+}} -; CHECK: [[sw_shader_id:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_inst_idx:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_param_1:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_param_2:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_param_3:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_param_4:%\w+]] = OpFunctionParameter %uint -; CHECK: [[sw_param_5:%\w+]] = OpFunctionParameter %uint -; CHECK: {{%\w+}} = OpLabel -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1 -; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_8 -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8 -; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 2 -; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}} -; CHECK: OpSelectionMerge {{%\w+}} None -; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} -; CHECK: {{%\w+}} = OpLabel -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} %uint_8 -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_shader_id]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_inst_idx]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_param_1]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_param_2]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_param_3]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_param_4]] -; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7 -; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}} -; CHECK: OpStore {{%\w+}} [[sw_param_5]] -; CHECK: OpBranch {{%\w+}} -; CHECK: {{%\w+}} = OpLabel +; CHECK: %inst_printf_stream_write_6 = OpFunction %void None %38 +; CHECK: %39 = OpFunctionParameter %uint +; CHECK: %40 = OpFunctionParameter %uint +; CHECK: %41 = OpFunctionParameter %uint +; CHECK: %42 = OpFunctionParameter %uint +; CHECK: %43 = OpFunctionParameter %uint +; CHECK: %44 = OpFunctionParameter %uint +; CHECK: %45 = OpLabel +; CHECK: %52 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_0 +; CHECK: %55 = OpAtomicIAdd %uint %52 %uint_4 %uint_0 %uint_12 +; CHECK: %56 = OpIAdd %uint %55 %uint_12 +; CHECK: %57 = OpArrayLength %uint %inst_printf_output_buffer 1 +; CHECK: %59 = OpULessThanEqual %bool %56 %57 +; CHECK: OpSelectionMerge %60 None +; CHECK: OpBranchConditional %59 %61 %60 +; CHECK: %61 = OpLabel +; CHECK: %62 = OpIAdd %uint %55 %uint_0 +; CHECK: %64 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %62 +; CHECK: OpStore %64 %uint_12 +; CHECK: %66 = OpIAdd %uint %55 %uint_1 +; CHECK: %67 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %66 +; CHECK: OpStore %67 %uint_23 +; CHECK: %69 = OpIAdd %uint %55 %uint_2 +; CHECK: %70 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %69 +; CHECK: OpStore %70 %39 +; CHECK: %72 = OpIAdd %uint %55 %uint_3 +; CHECK: %73 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %72 +; CHECK: OpStore %73 %uint_4 +; CHECK: %76 = OpLoad %v4float %gl_FragCoord +; CHECK: %78 = OpBitcast %v4uint %76 +; CHECK: %79 = OpCompositeExtract %uint %78 0 +; CHECK: %80 = OpIAdd %uint %55 %uint_4 +; CHECK: %81 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %80 +; CHECK: OpStore %81 %79 +; CHECK: %82 = OpCompositeExtract %uint %78 1 +; CHECK: %83 = OpIAdd %uint %55 %uint_5 +; CHECK: %84 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %83 +; CHECK: OpStore %84 %82 +; CHECK: %86 = OpIAdd %uint %55 %uint_7 +; CHECK: %87 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %86 +; CHECK: OpStore %87 %40 +; CHECK: %89 = OpIAdd %uint %55 %uint_8 +; CHECK: %90 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %89 +; CHECK: OpStore %90 %41 +; CHECK: %92 = OpIAdd %uint %55 %uint_9 +; CHECK: %93 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %92 +; CHECK: OpStore %93 %42 +; CHECK: %95 = OpIAdd %uint %55 %uint_10 +; CHECK: %96 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %95 +; CHECK: OpStore %96 %43 +; CHECK: %98 = OpIAdd %uint %55 %uint_11 +; CHECK: %99 = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1 %98 +; CHECK: OpStore %99 %44 +; CHECK: OpBranch %60 +; CHECK: %60 = OpLabel ; CHECK: OpReturn ; CHECK: OpFunctionEnd )"; diff --git a/test/opt/instruction_test.cpp b/test/opt/instruction_test.cpp index 67961eb6..dd749ab4 100644 --- a/test/opt/instruction_test.cpp +++ b/test/opt/instruction_test.cpp @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/instruction.h" - #include +#include #include #include #include "gmock/gmock.h" +#include "source/opt/instruction.h" #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.h" #include "test/opt/pass_fixture.h" @@ -39,7 +39,7 @@ using VulkanBufferTest = PassTest<::testing::Test>; TEST(InstructionTest, CreateTrivial) { Instruction empty; - EXPECT_EQ(spv::Op::OpNop, empty.opcode()); + EXPECT_EQ(SpvOpNop, empty.opcode()); EXPECT_EQ(0u, empty.type_id()); EXPECT_EQ(0u, empty.result_id()); EXPECT_EQ(0u, empty.NumOperands()); @@ -51,8 +51,8 @@ TEST(InstructionTest, CreateTrivial) { TEST(InstructionTest, CreateWithOpcodeAndNoOperands) { IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr); - Instruction inst(&context, spv::Op::OpReturn); - EXPECT_EQ(spv::Op::OpReturn, inst.opcode()); + Instruction inst(&context, SpvOpReturn); + EXPECT_EQ(SpvOpReturn, inst.opcode()); EXPECT_EQ(0u, inst.type_id()); EXPECT_EQ(0u, inst.result_id()); EXPECT_EQ(0u, inst.NumOperands()); @@ -81,8 +81,8 @@ TEST(InstructionTest, OperandAsLiteralUint64_64bits) { } // The words for an OpTypeInt for 32-bit signed integer resulting in Id 44. -uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(spv::Op::OpTypeInt), - 44, 32, 1}; +uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(SpvOpTypeInt), 44, + 32, 1}; // The operands that would be parsed from kSampleInstructionWords spv_parsed_operand_t kSampleParsedOperands[] = { {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0}, @@ -91,19 +91,18 @@ spv_parsed_operand_t kSampleParsedOperands[] = { }; // A valid parse of kSampleParsedOperands. -spv_parsed_instruction_t kSampleParsedInstruction = { - kSampleInstructionWords, - uint16_t(4), - uint16_t(spv::Op::OpTypeInt), - SPV_EXT_INST_TYPE_NONE, - 0, // type id - 44, // result id - kSampleParsedOperands, - 3}; +spv_parsed_instruction_t kSampleParsedInstruction = {kSampleInstructionWords, + uint16_t(4), + uint16_t(SpvOpTypeInt), + SPV_EXT_INST_TYPE_NONE, + 0, // type id + 44, // result id + kSampleParsedOperands, + 3}; // The words for an OpAccessChain instruction. uint32_t kSampleAccessChainInstructionWords[] = { - (7 << 16) | uint32_t(spv::Op::OpAccessChain), 100, 101, 102, 103, 104, 105}; + (7 << 16) | uint32_t(SpvOpAccessChain), 100, 101, 102, 103, 104, 105}; // The operands that would be parsed from kSampleAccessChainInstructionWords. spv_parsed_operand_t kSampleAccessChainOperands[] = { @@ -119,7 +118,7 @@ spv_parsed_operand_t kSampleAccessChainOperands[] = { spv_parsed_instruction_t kSampleAccessChainInstruction = { kSampleAccessChainInstructionWords, uint16_t(7), - uint16_t(spv::Op::OpAccessChain), + uint16_t(SpvOpAccessChain), SPV_EXT_INST_TYPE_NONE, 100, // type id 101, // result id @@ -128,7 +127,7 @@ spv_parsed_instruction_t kSampleAccessChainInstruction = { // The words for an OpControlBarrier instruction. uint32_t kSampleControlBarrierInstructionWords[] = { - (4 << 16) | uint32_t(spv::Op::OpControlBarrier), 100, 101, 102}; + (4 << 16) | uint32_t(SpvOpControlBarrier), 100, 101, 102}; // The operands that would be parsed from kSampleControlBarrierInstructionWords. spv_parsed_operand_t kSampleControlBarrierOperands[] = { @@ -142,7 +141,7 @@ spv_parsed_operand_t kSampleControlBarrierOperands[] = { spv_parsed_instruction_t kSampleControlBarrierInstruction = { kSampleControlBarrierInstructionWords, uint16_t(4), - uint16_t(spv::Op::OpControlBarrier), + uint16_t(SpvOpControlBarrier), SPV_EXT_INST_TYPE_NONE, 0, // type id 0, // result id @@ -152,7 +151,7 @@ spv_parsed_instruction_t kSampleControlBarrierInstruction = { TEST(InstructionTest, CreateWithOpcodeAndOperands) { IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr); Instruction inst(&context, kSampleParsedInstruction); - EXPECT_EQ(spv::Op::OpTypeInt, inst.opcode()); + EXPECT_EQ(SpvOpTypeInt, inst.opcode()); EXPECT_EQ(0u, inst.type_id()); EXPECT_EQ(44u, inst.result_id()); EXPECT_EQ(3u, inst.NumOperands()); diff --git a/test/opt/interface_var_sroa_test.cpp b/test/opt/interface_var_sroa_test.cpp index 6f51b087..77624587 100644 --- a/test/opt/interface_var_sroa_test.cpp +++ b/test/opt/interface_var_sroa_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/invocation_interlock_placement_test.cpp b/test/opt/invocation_interlock_placement_test.cpp deleted file mode 100755 index 2c4ff65e..00000000 --- a/test/opt/invocation_interlock_placement_test.cpp +++ /dev/null @@ -1,613 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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 "spirv-tools/optimizer.hpp" -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using InterlockInvocationPlacementTest = PassTest<::testing::Test>; - -TEST_F(InterlockInvocationPlacementTest, CheckUnchangedIfNotFragment) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - %2 = OpLabel - OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - EXPECT_EQ( - Pass::Status::SuccessWithoutChange, - std::get<1>(SinglePassRunAndDisassemble( - kTest, /* skip_nop= */ false, /* do_validation= */ false))); -} - -TEST_F(InterlockInvocationPlacementTest, CheckUnchangedWithoutCapability) { - const std::string kTest = R"( - OpCapability Shader - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - %2 = OpLabel - OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - EXPECT_EQ( - Pass::Status::SuccessWithoutChange, - std::get<1>(SinglePassRunAndDisassemble( - kTest, /* skip_nop= */ false, /* do_validation= */ false))); -} - -TEST_F(InterlockInvocationPlacementTest, CheckSingleBasicBlock) { - // We're using OpNoLine as a generic standin for any other instruction, to - // test that begin and end aren't moved. - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 -; CHECK: OpLabel - %2 = OpLabel -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckFunctionCallExtractionBegin) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %foo = OpFunction %void None %1 -; CHECK: OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT - %2 = OpLabel - OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpReturn -; CHECK: OpFunctionEnd - OpFunctionEnd - %main = OpFunction %void None %1 -; CHECK: OpLabel - %3 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpFunctionCall - %4 = OpFunctionCall %void %foo -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckFunctionCallExtractionEnd) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %foo = OpFunction %void None %1 -; CHECK: OpLabel -; CHECK-NOT: OpEndInvocationInterlockEXT - %2 = OpLabel - OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn -; CHECK: OpFunctionEnd - OpFunctionEnd - %main = OpFunction %void None %1 -; CHECK: OpLabel - %3 = OpLabel -; CHECK-NEXT: OpFunctionCall - %4 = OpFunctionCall %void %foo -; CHECK-NEXT: OpEndInvocationInterlockEXT -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, - CheckFunctionCallExtractionRepeatedCall) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %foo = OpFunction %void None %1 -; CHECK: OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - %2 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn -; CHECK: OpFunctionEnd - OpFunctionEnd - %main = OpFunction %void None %1 -; CHECK: OpLabel - %3 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpFunctionCall - %4 = OpFunctionCall %void %foo -; CHECK-NEXT: OpFunctionCall - %5 = OpFunctionCall %void %foo -; CHECK-NEXT: OpEndInvocationInterlockEXT -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, - CheckFunctionCallExtractionNestedCall) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %foo = OpFunction %void None %1 -; CHECK: OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - %2 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn -; CHECK: OpFunctionEnd - OpFunctionEnd - %bar = OpFunction %void None %1 -; CHECK: OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - %3 = OpLabel - %4 = OpFunctionCall %void %foo - OpReturn -; CHECK: OpFunctionEnd - OpFunctionEnd - %main = OpFunction %void None %1 -; CHECK: OpLabel - %5 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpFunctionCall - %6 = OpFunctionCall %void %bar -; CHECK-NEXT: OpEndInvocationInterlockEXT -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckLoopExtraction) { - // Tests that any begin or end instructions in a loop are moved outside of the - // loop. - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - %void = OpTypeVoid - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - - %2 = OpLabel -; CHECK: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpBranch %3 - - %3 = OpLabel - OpLoopMerge %3 %4 None -; CHECK: OpBranchConditional -; CHECK-NOT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpBranchConditional %true %4 %5 - - %4 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK: OpBranch - OpBranch %3 - -; CHECK-NEXT: OpLabel - %5 = OpLabel -; CHECK-NEXT: OpEndInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckAddBeginToElse) { - // Test that if there is a begin in a single branch of a conditional, begin - // will be added to the other branch. - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - - %2 = OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT - OpSelectionMerge %5 None -; CHECK: OpBranchConditional - OpBranchConditional %true %3 %4 - -; CHECK-NEXT: OpLabel - %3 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpBranch - OpBranch %5 - - %4 = OpLabel -; CHECK: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpBranch - OpBranch %5 - -; CHECK-NEXT: OpLabel - %5 = OpLabel - OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckAddEndToElse) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - - %2 = OpLabel -; CHECK: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpSelectionMerge %5 None -; CHECK: OpBranchConditional - OpBranchConditional %true %3 %4 - -; CHECK-NEXT: OpLabel - %3 = OpLabel - OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpBranch - OpBranch %5 - - %4 = OpLabel -; CHECK: OpEndInvocationInterlockEXT -; CHECK-NEXT: OpBranch - OpBranch %5 - -; CHECK-NEXT: OpLabel - %5 = OpLabel -; CHECK-NOT: OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckSplitIfWithoutElseBegin) { - // Test that if there is a begin in the then branch of a conditional, and no - // else branch, an else branch with a begin will created. - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - - %2 = OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT - OpSelectionMerge %5 None -; CHECK: OpBranchConditional - OpBranchConditional %true %3 %5 - -; CHECK-NEXT: OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpBranch - -; CHECK-NEXT: OpLabel - %3 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpBranch %5 - -; CHECK: OpLabel - %5 = OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckSplitIfWithoutElseEnd) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - - %2 = OpLabel - -; CHECK: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpSelectionMerge [[merge:%\d+]] - OpSelectionMerge %5 None -; CHECK-NEXT: OpBranchConditional %true [[then:%\d+]] [[else:%\d+]] - OpBranchConditional %true %3 %5 - -; CHECK-NEXT: [[else]] = OpLabel -; CHECK-NEXT: OpEndInvocationInterlockEXT -; CHECK-NEXT: OpBranch [[merge]] - -; CHECK-NEXT: [[then]] = OpLabel - %3 = OpLabel -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpBranch [[merge]] - OpBranch %5 - -; CHECK-NEXT: [[merge]] = OpLabel - %5 = OpLabel -; CHECK-NEXT: OpReturn - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(InterlockInvocationPlacementTest, CheckSplitSwitch) { - // Test that if there is a begin or end in a single branch of a switch, begin - // or end will be added to all the other branches. - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderSampleInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpExecutionMode %main SampleInterlockOrderedEXT - OpName %main "main" - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %1 = OpTypeFunction %void - %main = OpFunction %void None %1 - -; CHECK: OpLabel - %2 = OpLabel -; CHECK-NEXT: OpSelectionMerge [[merge:%\d+]] - OpSelectionMerge %8 None -; CHECK-NEXT: OpSwitch %uint_1 [[default:%\d+]] 0 [[case_0:%\d+]] 1 [[case_1:%\d+]] 2 [[case_2:%\d+]] - OpSwitch %uint_1 %8 0 %4 1 %5 2 %8 - -; CHECK-NEXT: [[case_2]] = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpBranch [[merge]] - -; CHECK-NEXT: [[default]] = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpBranch [[merge]] - -; CHECK-NEXT: [[case_0]] = OpLabel - %4 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpBranch [[merge]] - OpBranch %8 - -; CHECK-NEXT: [[case_1]] = OpLabel - %5 = OpLabel -; CHECK-NEXT: OpBeginInvocationInterlockEXT -; CHECK-NOT: OpEndInvocationInterlockEXT - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpNoLine - OpNoLine -; CHECK-NEXT: OpBranch [[merge]] - OpBranch %8 - -; CHECK-NEXT: [[merge]] = OpLabel - %8 = OpLabel -; CHECK-NOT: OpBeginInvocationInterlockEXT - OpBeginInvocationInterlockEXT -; CHECK-NEXT: OpEndInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = SinglePassRunAndMatch( - kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/ir_builder.cpp b/test/opt/ir_builder.cpp index f0cfc184..cb234e00 100644 --- a/test/opt/ir_builder.cpp +++ b/test/opt/ir_builder.cpp @@ -12,16 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/ir_builder.h" - +#include #include +#include #include #include "effcee/effcee.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/basic_block.h" #include "source/opt/build_module.h" #include "source/opt/instruction.h" +#include "source/opt/ir_builder.h" #include "source/opt/type_manager.h" #include "spirv-tools/libspirv.hpp" @@ -199,7 +201,7 @@ TEST_F(IRBuilderTest, TestCondBranchAddition) { // TODO(1841): Handle id overflow. fn.begin().InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context.get(), spv::Op::OpLabel, 0, context->TakeNextId(), {}))))); + context.get(), SpvOpLabel, 0, context->TakeNextId(), {}))))); BasicBlock& bb_true = *fn.begin(); { InstructionBuilder builder(context.get(), &*bb_true.begin()); @@ -209,7 +211,7 @@ TEST_F(IRBuilderTest, TestCondBranchAddition) { // TODO(1841): Handle id overflow. fn.begin().InsertBefore(std::unique_ptr( new BasicBlock(std::unique_ptr(new Instruction( - context.get(), spv::Op::OpLabel, 0, context->TakeNextId(), {}))))); + context.get(), SpvOpLabel, 0, context->TakeNextId(), {}))))); BasicBlock& bb_cond = *fn.begin(); InstructionBuilder builder(context.get(), &bb_cond); diff --git a/test/opt/ir_context_test.cpp b/test/opt/ir_context_test.cpp index 621fe8cf..dcae7cf8 100644 --- a/test/opt/ir_context_test.cpp +++ b/test/opt/ir_context_test.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "OpenCLDebugInfo100.h" @@ -228,12 +229,12 @@ TEST_F(IRContextTest, KillMemberName) { // Make sure all of the name are removed. for (auto& inst : context->debugs2()) { - EXPECT_EQ(inst.opcode(), spv::Op::OpNop); + EXPECT_EQ(inst.opcode(), SpvOpNop); } // Make sure all of the decorations are removed. for (auto& inst : context->annotations()) { - EXPECT_EQ(inst.opcode(), spv::Op::OpNop); + EXPECT_EQ(inst.opcode(), SpvOpNop); } } @@ -275,17 +276,17 @@ TEST_F(IRContextTest, KillGroupDecoration) { // Check the OpDecorate instruction auto inst = context->annotation_begin(); - EXPECT_EQ(inst->opcode(), spv::Op::OpDecorate); + EXPECT_EQ(inst->opcode(), SpvOpDecorate); EXPECT_EQ(inst->GetSingleWordInOperand(0), 3); // Check the OpDecorationGroup Instruction ++inst; - EXPECT_EQ(inst->opcode(), spv::Op::OpDecorationGroup); + EXPECT_EQ(inst->opcode(), SpvOpDecorationGroup); EXPECT_EQ(inst->result_id(), 3); // Check that %5 is no longer part of the group. ++inst; - EXPECT_EQ(inst->opcode(), spv::Op::OpGroupDecorate); + EXPECT_EQ(inst->opcode(), SpvOpGroupDecorate); EXPECT_EQ(inst->NumInOperands(), 2); EXPECT_EQ(inst->GetSingleWordInOperand(0), 3); EXPECT_EQ(inst->GetSingleWordInOperand(1), 4); @@ -339,12 +340,12 @@ TEST_F(IRContextTest, KillGroupDecorationWitNoDecorations) { // Check the OpDecorationGroup Instruction auto inst = context->annotation_begin(); - EXPECT_EQ(inst->opcode(), spv::Op::OpDecorationGroup); + EXPECT_EQ(inst->opcode(), SpvOpDecorationGroup); EXPECT_EQ(inst->result_id(), 3); // Check that %5 is no longer part of the group. ++inst; - EXPECT_EQ(inst->opcode(), spv::Op::OpGroupDecorate); + EXPECT_EQ(inst->opcode(), SpvOpGroupDecorate); EXPECT_EQ(inst->NumInOperands(), 2); EXPECT_EQ(inst->GetSingleWordInOperand(0), 3); EXPECT_EQ(inst->GetSingleWordInOperand(1), 4); @@ -1148,339 +1149,6 @@ OpFunctionEnd)"; 20); } -struct TargetEnvCompareTestData { - spv_target_env later_env, earlier_env; -}; - -using TargetEnvCompareTest = ::testing::TestWithParam; - -TEST_P(TargetEnvCompareTest, Case) { - // If new environments are added, then we must update the list of tests. - ASSERT_EQ(SPV_ENV_VULKAN_1_3 + 1, SPV_ENV_MAX); - - const auto& tc = GetParam(); - - std::unique_ptr module(new Module()); - IRContext localContext(tc.later_env, std::move(module), - spvtools::MessageConsumer()); - EXPECT_TRUE(localContext.IsTargetEnvAtLeast(tc.earlier_env)); - - if (tc.earlier_env != tc.later_env) { - std::unique_ptr module(new Module()); - IRContext localContext(tc.earlier_env, std::move(module), - spvtools::MessageConsumer()); - EXPECT_FALSE(localContext.IsTargetEnvAtLeast(tc.later_env)); - } -} - -TEST_F(IRContextTest, ReturnsTrueWhenExtensionIsRemoved) { - const std::string text = R"( - OpCapability Shader - OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 1); - - EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock)); - - EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 0); -} - -TEST_F(IRContextTest, ReturnsFalseWhenExtensionIsNotRemoved) { - const std::string text = R"( - OpCapability Shader - OpExtension "SPV_KHR_device_group" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 1); - - EXPECT_FALSE(ctx->RemoveExtension(kSPV_KHR_shader_clock)); - - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 1); -} - -TEST_F(IRContextTest, RemovesExtensionIfLast) { - const std::string text = R"( - OpCapability Shader - OpExtension "SPV_KHR_device_group" - OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 2); - - EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock)); - - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 1); -} - -TEST_F(IRContextTest, RemovesExtensionIfFirst) { - const std::string text = R"( - OpCapability Shader - OpExtension "SPV_KHR_shader_clock" - OpExtension "SPV_KHR_device_group" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 2); - - EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock)); - - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group)); - EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 1); -} - -TEST_F(IRContextTest, RemovesMultipleExtensions) { - const std::string text = R"( - OpCapability Shader - OpExtension "SPV_KHR_shader_clock" - OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 2); - - EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock)); - - EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock)); - EXPECT_EQ(std::distance(ctx->module()->extension_begin(), - ctx->module()->extension_end()), - 0); -} - -TEST_F(IRContextTest, ReturnsTrueWhenCapabilityIsRemoved) { - const std::string text = R"( - OpCapability Shader - OpCapability ShaderClockKHR - OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::ShaderClockKHR)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 2); - - EXPECT_TRUE(ctx->RemoveCapability(spv::Capability::ShaderClockKHR)); - - EXPECT_FALSE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::ShaderClockKHR)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 1); -} - -TEST_F(IRContextTest, ReturnsFalseWhenCapabilityIsNotRemoved) { - const std::string text = R"( - OpCapability Shader - OpCapability DeviceGroup - OpExtension "SPV_KHR_device_group" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 2); - - EXPECT_FALSE(ctx->RemoveCapability(spv::Capability::ShaderClockKHR)); - - EXPECT_TRUE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 2); -} - -TEST_F(IRContextTest, RemovesMultipleCapabilities) { - const std::string text = R"( - OpCapability Shader - OpCapability DeviceGroup - OpCapability DeviceGroup - OpExtension "SPV_KHR_device_group" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %6 = OpTypeFunction %void - %1 = OpFunction %void None %6 - %9 = OpLabel - OpReturn - OpFunctionEnd)"; - - std::unique_ptr ctx = - BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text, - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - EXPECT_TRUE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 3); - - EXPECT_TRUE(ctx->RemoveCapability(spv::Capability::DeviceGroup)); - - EXPECT_FALSE( - ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup)); - EXPECT_EQ(std::distance(ctx->module()->capability_begin(), - ctx->module()->capability_end()), - 1); -} - -INSTANTIATE_TEST_SUITE_P( - TestCase, TargetEnvCompareTest, - ::testing::Values( - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_4}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_4}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_4}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_UNIVERSAL_1_5}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_5}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_UNIVERSAL_1_6}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_0, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_0}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_4, SPV_ENV_VULKAN_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_1}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_1}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_4}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_2, SPV_ENV_UNIVERSAL_1_5}, - TargetEnvCompareTestData{SPV_ENV_UNIVERSAL_1_6, SPV_ENV_VULKAN_1_2}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_0}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_1}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_2}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_3}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_4}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_5}, - TargetEnvCompareTestData{SPV_ENV_VULKAN_1_3, SPV_ENV_UNIVERSAL_1_6})); - } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/ir_loader_test.cpp b/test/opt/ir_loader_test.cpp index 769a25dd..ccdd032e 100644 --- a/test/opt/ir_loader_test.cpp +++ b/test/opt/ir_loader_test.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -243,10 +244,10 @@ TEST(IrBuilder, DistributeLineDebugInfo) { auto& lines = def_use_mgr->GetDef(check.id)->dbg_line_insts(); for (uint32_t i = 0; i < check.line_numbers.size(); ++i) { if (check.line_numbers[i] == kNoLine) { - EXPECT_EQ(lines[i].opcode(), spv::Op::OpNoLine); + EXPECT_EQ(lines[i].opcode(), SpvOpNoLine); continue; } - EXPECT_EQ(lines[i].opcode(), spv::Op::OpLine); + EXPECT_EQ(lines[i].opcode(), SpvOpLine); EXPECT_EQ(lines[i].GetSingleWordOperand(kOpLineOperandLineIndex), check.line_numbers[i]); } @@ -285,10 +286,9 @@ OpFunctionEnd spvtools::opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - std::vector opcodes; + std::vector opcodes; for (auto* inst = def_use_mgr->GetDef(1); - inst && (inst->opcode() != spv::Op::OpFunctionEnd); - inst = inst->NextNode()) { + inst && (inst->opcode() != SpvOpFunctionEnd); inst = inst->NextNode()) { inst->ForEachInst( [&opcodes](spvtools::opt::Instruction* sub_inst) { opcodes.push_back(sub_inst->opcode()); @@ -296,9 +296,9 @@ OpFunctionEnd true); } - EXPECT_THAT(opcodes, ContainerEq(std::vector{ - spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul, - spv::Op::OpFSub, spv::Op::OpReturn})); + EXPECT_THAT(opcodes, + ContainerEq(std::vector{SpvOpFAdd, SpvOpLine, SpvOpFMul, + SpvOpFSub, SpvOpReturn})); } TEST(IrBuilder, BuildModule_WithExtraLines_IsDefault) { @@ -333,10 +333,9 @@ OpFunctionEnd spvtools::opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - std::vector opcodes; + std::vector opcodes; for (auto* inst = def_use_mgr->GetDef(1); - inst && (inst->opcode() != spv::Op::OpFunctionEnd); - inst = inst->NextNode()) { + inst && (inst->opcode() != SpvOpFunctionEnd); inst = inst->NextNode()) { inst->ForEachInst( [&opcodes](spvtools::opt::Instruction* sub_inst) { opcodes.push_back(sub_inst->opcode()); @@ -344,10 +343,9 @@ OpFunctionEnd true); } - EXPECT_THAT(opcodes, ContainerEq(std::vector{ - spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul, - spv::Op::OpLine, spv::Op::OpFSub, spv::Op::OpLine, - spv::Op::OpReturn})); + EXPECT_THAT(opcodes, ContainerEq(std::vector{ + SpvOpFAdd, SpvOpLine, SpvOpFMul, SpvOpLine, + SpvOpFSub, SpvOpLine, SpvOpReturn})); } TEST(IrBuilder, ConsumeDebugInfoInst) { @@ -1299,9 +1297,8 @@ TEST(IrBuilder, OpUndefOutsideFunction) { const auto opundef_count = std::count_if( context->module()->types_values_begin(), - context->module()->types_values_end(), [](const Instruction& inst) { - return inst.opcode() == spv::Op::OpUndef; - }); + context->module()->types_values_end(), + [](const Instruction& inst) { return inst.opcode() == SpvOpUndef; }); EXPECT_EQ(3, opundef_count); std::vector binary; diff --git a/test/opt/local_access_chain_convert_test.cpp b/test/opt/local_access_chain_convert_test.cpp index b35f3a3f..07fb537c 100644 --- a/test/opt/local_access_chain_convert_test.cpp +++ b/test/opt/local_access_chain_convert_test.cpp @@ -1348,56 +1348,6 @@ OpFunctionEnd true); } -TEST_F(LocalAccessChainConvertTest, VkMemoryModelTest) { - const std::string text = - R"( -; CHECK: OpCapability Shader -; CHECK: OpCapability VulkanMemoryModel -; CHECK: OpExtension "SPV_KHR_vulkan_memory_model" - OpCapability Shader - OpCapability VulkanMemoryModel - OpExtension "SPV_KHR_vulkan_memory_model" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical Vulkan - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - OpSource GLSL 450 - OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" - OpSourceExtension "GL_GOOGLE_include_directive" - OpName %main "main" - OpName %a "a" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Function_v4float = OpTypePointer Function %v4float - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 -%_ptr_Function_float = OpTypePointer Function %float - %float_1 = OpConstant %float 1 -; CHECK: OpFunction -; CHECK-NEXT: OpLabel -; CHECK-NEXT: [[a:%\w+]] = OpVariable -; Make sure the access chains were removed. -; CHECK: [[ld:%\w+]] = OpLoad {{%\w+}} [[a]] -; CHECK: [[ex:%\w+]] = OpCompositeExtract {{%\w+}} [[ld]] 0 -; CHECK: [[ld2:%\w+]] = OpLoad {{%\w+}} [[a]] -; CHECK: [[v:%\w+]] = OpCompositeInsert {{%\w+}} [[ex]] [[ld2]] 0 -; CHECK: OpStore [[a]] [[v]] - %main = OpFunction %void None %3 - %5 = OpLabel - %a = OpVariable %_ptr_Function_v4float Function - %13 = OpAccessChain %_ptr_Function_float %a %uint_0 - %14 = OpLoad %float %13 - %17 = OpAccessChain %_ptr_Function_float %a %uint_0 - OpStore %17 %14 - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(text, false); -} - // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Assorted vector and matrix types diff --git a/test/opt/local_redundancy_elimination_test.cpp b/test/opt/local_redundancy_elimination_test.cpp index 01f76661..291e1bc2 100644 --- a/test/opt/local_redundancy_elimination_test.cpp +++ b/test/opt/local_redundancy_elimination_test.cpp @@ -15,7 +15,9 @@ #include #include "gmock/gmock.h" +#include "source/opt/build_module.h" #include "source/opt/value_number_table.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/local_single_block_elim.cpp b/test/opt/local_single_block_elim.cpp index 7d19c227..28b8a07d 100644 --- a/test/opt/local_single_block_elim.cpp +++ b/test/opt/local_single_block_elim.cpp @@ -1502,49 +1502,6 @@ TEST_F(LocalSingleBlockLoadStoreElimTest, DebugValueTest) { SinglePassRunAndMatch(text, false); } -TEST_F(LocalSingleBlockLoadStoreElimTest, VkMemoryModelTest) { - const std::string text = - R"( -; CHECK: OpCapability Shader -; CHECK: OpCapability VulkanMemoryModel -; CHECK: OpExtension "SPV_KHR_vulkan_memory_model" - OpCapability Shader - OpCapability VulkanMemoryModel - OpExtension "SPV_KHR_vulkan_memory_model" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical Vulkan - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - OpSource GLSL 450 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_1 = OpConstant %int 1 - %bool = OpTypeBool - %false = OpConstantFalse %bool -; CHECK: OpFunction -; CHECK-NEXT: OpLabel -; CHECK-NEXT: [[a:%\w+]] = OpVariable -; CHECK-NEXT: [[b:%\w+]] = OpVariable -; CHECK: OpStore [[a]] [[v:%\w+]] -; CHECK-NOT: OpLoad %int [[a]] -; CHECK: OpStore [[b]] [[v]] - %main = OpFunction %void None %3 - %5 = OpLabel - %a = OpVariable %_ptr_Function_int Function - %b = OpVariable %_ptr_Function_int Function - OpStore %a %int_0 - %16 = OpLoad %int %a - OpStore %b %16 - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(text, false); -} - // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Other target variable types diff --git a/test/opt/local_single_store_elim_test.cpp b/test/opt/local_single_store_elim_test.cpp index ffe352ed..8f43a11d 100644 --- a/test/opt/local_single_store_elim_test.cpp +++ b/test/opt/local_single_store_elim_test.cpp @@ -1750,58 +1750,6 @@ TEST_F(LocalSingleStoreElimTest, DebugValuesForAllLocalsAndParams) { SinglePassRunAndMatch(text, false); } -TEST_F(LocalSingleStoreElimTest, VkMemoryModelTest) { - const std::string text = - R"( -; CHECK: OpCapability Shader -; CHECK: OpCapability VulkanMemoryModel -; CHECK: OpExtension "SPV_KHR_vulkan_memory_model" - OpCapability Shader - OpCapability VulkanMemoryModel - OpExtension "SPV_KHR_vulkan_memory_model" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical Vulkan - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - OpSource GLSL 450 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 -%_ptr_Function_int = OpTypePointer Function %int - %int_0 = OpConstant %int 0 - %int_1 = OpConstant %int 1 - %bool = OpTypeBool - %false = OpConstantFalse %bool -; CHECK: OpFunction -; CHECK-NEXT: OpLabel -; CHECK-NEXT: [[a:%\w+]] = OpVariable -; CHECK-NEXT: [[b:%\w+]] = OpVariable -; CHECK: OpStore [[a]] [[v:%\w+]] -; CHECK: OpStore [[b]] -; Make sure the load was removed. -; CHECK: OpLabel -; CHECK-NOT: OpLoad %int [[a]] -; CHECK: OpStore [[b]] [[v]] - %main = OpFunction %void None %3 - %5 = OpLabel - %a = OpVariable %_ptr_Function_int Function - %b = OpVariable %_ptr_Function_int Function - OpStore %a %int_0 - OpStore %b %int_1 - OpSelectionMerge %15 None - OpBranchConditional %false %14 %15 - %14 = OpLabel - %16 = OpLoad %int %a - OpStore %b %16 - OpBranch %15 - %15 = OpLabel - OpReturn - OpFunctionEnd -)"; - - SinglePassRunAndMatch(text, false); -} - // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Other types diff --git a/test/opt/loop_optimizations/CMakeLists.txt b/test/opt/loop_optimizations/CMakeLists.txt index 6e20f72f..e3620787 100644 --- a/test/opt/loop_optimizations/CMakeLists.txt +++ b/test/opt/loop_optimizations/CMakeLists.txt @@ -21,7 +21,6 @@ add_spvtools_unittest(TARGET opt_loops fusion_illegal.cpp fusion_legal.cpp fusion_pass.cpp - hoist_access_chains.cpp hoist_all_loop_types.cpp hoist_double_nested_loops.cpp hoist_from_independent_loops.cpp diff --git a/test/opt/loop_optimizations/dependence_analysis.cpp b/test/opt/loop_optimizations/dependence_analysis.cpp index 40520f57..8aeb20af 100644 --- a/test/opt/loop_optimizations/dependence_analysis.cpp +++ b/test/opt/loop_optimizations/dependence_analysis.cpp @@ -14,11 +14,17 @@ #include #include +#include +#include #include #include +#include "gmock/gmock.h" +#include "source/opt/iterator.h" #include "source/opt/loop_dependence.h" #include "source/opt/loop_descriptor.h" +#include "source/opt/pass.h" +#include "source/opt/tree_iterator.h" #include "test/opt//assembly_builder.h" #include "test/opt//function_utils.h" #include "test/opt//pass_fixture.h" @@ -129,7 +135,7 @@ TEST(DependencyAnalysis, ZIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 13)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -286,7 +292,7 @@ TEST(DependencyAnalysis, SymbolicZIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 22)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -522,7 +528,7 @@ TEST(DependencyAnalysis, SIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 17)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -595,7 +601,7 @@ TEST(DependencyAnalysis, SIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 68)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -916,7 +922,7 @@ TEST(DependencyAnalysis, SymbolicSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 29)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -972,7 +978,7 @@ TEST(DependencyAnalysis, SymbolicSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 114)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -1414,7 +1420,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 29)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1435,7 +1441,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 54)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1457,7 +1463,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 75)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1478,7 +1484,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 99)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1500,7 +1506,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 121)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1521,7 +1527,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 142)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1543,7 +1549,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 162)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1564,7 +1570,7 @@ TEST(DependencyAnalysis, Crossing) { const Instruction* store = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 183)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } } @@ -1840,7 +1846,7 @@ TEST(DependencyAnalysis, WeakZeroSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 19)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -1908,7 +1914,7 @@ TEST(DependencyAnalysis, WeakZeroSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 54)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -1975,7 +1981,7 @@ TEST(DependencyAnalysis, WeakZeroSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 84)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -2043,7 +2049,7 @@ TEST(DependencyAnalysis, WeakZeroSIV) { const Instruction* store[4]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 111)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -2204,7 +2210,7 @@ TEST(DependencyAnalysis, MultipleSubscriptZIVSIV) { const Instruction* store[6]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 11)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -2437,7 +2443,7 @@ TEST(DependencyAnalysis, IrrelevantSubscripts) { const Instruction* store[1]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 25)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -2473,7 +2479,7 @@ TEST(DependencyAnalysis, IrrelevantSubscripts) { const Instruction* store[1]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 56)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -2784,12 +2790,12 @@ TEST(DependencyAnalysis, MIV) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load[loads_found] = &inst; ++loads_found; } @@ -3074,12 +3080,12 @@ TEST(DependencyAnalysis, SubscriptPartitioning) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load[loads_found] = &inst; ++loads_found; } @@ -3455,11 +3461,11 @@ TEST(DependencyAnalysis, Delta) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -3496,11 +3502,11 @@ TEST(DependencyAnalysis, Delta) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -3528,11 +3534,11 @@ TEST(DependencyAnalysis, Delta) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -3563,11 +3569,11 @@ TEST(DependencyAnalysis, Delta) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -3605,11 +3611,11 @@ TEST(DependencyAnalysis, Delta) { ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id)); for (const Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } diff --git a/test/opt/loop_optimizations/dependence_analysis_helpers.cpp b/test/opt/loop_optimizations/dependence_analysis_helpers.cpp index 62061998..715cf541 100644 --- a/test/opt/loop_optimizations/dependence_analysis_helpers.cpp +++ b/test/opt/loop_optimizations/dependence_analysis_helpers.cpp @@ -13,11 +13,17 @@ // limitations under the License. #include +#include +#include #include +#include "gmock/gmock.h" +#include "source/opt/iterator.h" #include "source/opt/loop_dependence.h" #include "source/opt/loop_descriptor.h" +#include "source/opt/pass.h" #include "source/opt/scalar_analysis.h" +#include "source/opt/tree_iterator.h" #include "test/opt/assembly_builder.h" #include "test/opt/function_utils.h" #include "test/opt/pass_fixture.h" @@ -166,7 +172,7 @@ TEST(DependencyAnalysisHelpers, UnsupportedLoops) { const Instruction* store[1] = {nullptr}; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 16)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -193,7 +199,7 @@ TEST(DependencyAnalysisHelpers, UnsupportedLoops) { const Instruction* store[1] = {nullptr}; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 47)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store[stores_found] = &inst; ++stores_found; } @@ -1489,7 +1495,7 @@ TEST(DependencyAnalysisHelpers, const_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 30)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -1570,7 +1576,7 @@ TEST(DependencyAnalysisHelpers, const_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 65)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -1649,7 +1655,7 @@ TEST(DependencyAnalysisHelpers, const_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 96)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -1728,7 +1734,7 @@ TEST(DependencyAnalysisHelpers, const_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 126)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2061,7 +2067,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_const) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 30)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2142,7 +2148,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_const) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 66)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2223,7 +2229,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_const) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 96)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2304,7 +2310,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_const) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 127)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2699,7 +2705,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 35)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2778,7 +2784,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 90)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2857,7 +2863,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 139)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } @@ -2936,7 +2942,7 @@ TEST(DependencyAnalysisHelpers, symbolic_to_symbolic) { const Instruction* stores[2]; int stores_found = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 188)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[stores_found] = &inst; ++stores_found; } diff --git a/test/opt/loop_optimizations/fusion_compatibility.cpp b/test/opt/loop_optimizations/fusion_compatibility.cpp index 9acfe8fc..cda8576c 100644 --- a/test/opt/loop_optimizations/fusion_compatibility.cpp +++ b/test/opt/loop_optimizations/fusion_compatibility.cpp @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/loop_optimizations/fusion_illegal.cpp b/test/opt/loop_optimizations/fusion_illegal.cpp index bff416b6..26d54457 100644 --- a/test/opt/loop_optimizations/fusion_illegal.cpp +++ b/test/opt/loop_optimizations/fusion_illegal.cpp @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/loop_optimizations/fusion_legal.cpp b/test/opt/loop_optimizations/fusion_legal.cpp index ef7daeea..56b0b76f 100644 --- a/test/opt/loop_optimizations/fusion_legal.cpp +++ b/test/opt/loop_optimizations/fusion_legal.cpp @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include +#include #include #include "effcee/effcee.h" diff --git a/test/opt/loop_optimizations/hoist_access_chains.cpp b/test/opt/loop_optimizations/hoist_access_chains.cpp deleted file mode 100755 index 0c688b31..00000000 --- a/test/opt/loop_optimizations/hoist_access_chains.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) 2023 The Khronos Group Inc. -// -// 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 "gmock/gmock.h" -#include "source/opt/licm_pass.h" -#include "test/opt/pass_fixture.h" - -namespace spvtools { -namespace opt { -namespace { - -using PassClassTest = PassTest<::testing::Test>; - -/* - Tests for the LICM pass to check it handles access chains correctly - - Generated from the following GLSL fragment shader ---eliminate-local-multi-store has also been run on the spv binary -#version 460 -void main() { - for (uint i = 0; i < 123u; ++i) { - vec2 do_not_hoist_store = vec2(0.0f); - float do_not_hoist_access_chain_load = do_not_hoist_store.x; - } -} -*/ - -TEST_F(PassClassTest, HoistAccessChains) { - const std::string before_hoist = R"(OpCapability Shader -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 460 -OpName %main "main" -OpName %i "i" -OpName %do_not_hoist_store "do_not_hoist_store" -OpName %do_not_hoist_access_chain_load "do_not_hoist_access_chain_load" -%void = OpTypeVoid -%7 = OpTypeFunction %void -%uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_0 = OpConstant %uint 0 -%uint_123 = OpConstant %uint 123 -%bool = OpTypeBool -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%_ptr_Function_v2float = OpTypePointer Function %v2float -%float_0 = OpConstant %float 0 -%17 = OpConstantComposite %v2float %float_0 %float_0 -%_ptr_Function_float = OpTypePointer Function %float -%int = OpTypeInt 32 1 -%int_1 = OpConstant %int 1 -%main = OpFunction %void None %7 -%21 = OpLabel -%i = OpVariable %_ptr_Function_uint Function -%do_not_hoist_store = OpVariable %_ptr_Function_v2float Function -%do_not_hoist_access_chain_load = OpVariable %_ptr_Function_float Function -OpStore %i %uint_0 -OpBranch %22 -%22 = OpLabel -OpLoopMerge %23 %24 None -OpBranch %25 -%25 = OpLabel -%26 = OpLoad %uint %i -%27 = OpULessThan %bool %26 %uint_123 -OpBranchConditional %27 %28 %23 -%28 = OpLabel -OpStore %do_not_hoist_store %17 -%29 = OpAccessChain %_ptr_Function_float %do_not_hoist_store %uint_0 -%30 = OpLoad %float %29 -OpStore %do_not_hoist_access_chain_load %30 -OpBranch %24 -%24 = OpLabel -%31 = OpLoad %uint %i -%32 = OpIAdd %uint %31 %int_1 -OpStore %i %32 -OpBranch %22 -%23 = OpLabel -OpReturn -OpFunctionEnd -)"; - - const std::string after_hoist = R"(OpCapability Shader -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %main "main" -OpExecutionMode %main OriginUpperLeft -OpSource GLSL 460 -OpName %main "main" -OpName %i "i" -OpName %do_not_hoist_store "do_not_hoist_store" -OpName %do_not_hoist_access_chain_load "do_not_hoist_access_chain_load" -%void = OpTypeVoid -%7 = OpTypeFunction %void -%uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_0 = OpConstant %uint 0 -%uint_123 = OpConstant %uint 123 -%bool = OpTypeBool -%float = OpTypeFloat 32 -%v2float = OpTypeVector %float 2 -%_ptr_Function_v2float = OpTypePointer Function %v2float -%float_0 = OpConstant %float 0 -%17 = OpConstantComposite %v2float %float_0 %float_0 -%_ptr_Function_float = OpTypePointer Function %float -%int = OpTypeInt 32 1 -%int_1 = OpConstant %int 1 -%main = OpFunction %void None %7 -%21 = OpLabel -%i = OpVariable %_ptr_Function_uint Function -%do_not_hoist_store = OpVariable %_ptr_Function_v2float Function -%do_not_hoist_access_chain_load = OpVariable %_ptr_Function_float Function -OpStore %i %uint_0 -%29 = OpAccessChain %_ptr_Function_float %do_not_hoist_store %uint_0 -OpBranch %22 -%22 = OpLabel -OpLoopMerge %23 %24 None -OpBranch %25 -%25 = OpLabel -%26 = OpLoad %uint %i -%27 = OpULessThan %bool %26 %uint_123 -OpBranchConditional %27 %28 %23 -%28 = OpLabel -OpStore %do_not_hoist_store %17 -%30 = OpLoad %float %29 -OpStore %do_not_hoist_access_chain_load %30 -OpBranch %24 -%24 = OpLabel -%31 = OpLoad %uint %i -%32 = OpIAdd %uint %31 %int_1 -OpStore %i %32 -OpBranch %22 -%23 = OpLabel -OpReturn -OpFunctionEnd -)"; - - SinglePassRunAndCheck(before_hoist, after_hoist, true); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/loop_optimizations/lcssa.cpp b/test/opt/loop_optimizations/lcssa.cpp index 32c2f723..ace6ce19 100644 --- a/test/opt/loop_optimizations/lcssa.cpp +++ b/test/opt/loop_optimizations/lcssa.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "effcee/effcee.h" @@ -20,6 +21,7 @@ #include "source/opt/build_module.h" #include "source/opt/loop_descriptor.h" #include "source/opt/loop_utils.h" +#include "source/opt/pass.h" #include "test/opt//assembly_builder.h" #include "test/opt/function_utils.h" diff --git a/test/opt/loop_optimizations/loop_descriptions.cpp b/test/opt/loop_optimizations/loop_descriptions.cpp index 3dd0b930..b3f4f440 100644 --- a/test/opt/loop_optimizations/loop_descriptions.cpp +++ b/test/opt/loop_optimizations/loop_descriptions.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/loop_optimizations/loop_fission.cpp b/test/opt/loop_optimizations/loop_fission.cpp index 41e40c3b..bc3ec39b 100644 --- a/test/opt/loop_optimizations/loop_fission.cpp +++ b/test/opt/loop_optimizations/loop_fission.cpp @@ -12,13 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/loop_fission.h" - #include +#include #include #include "gmock/gmock.h" +#include "source/opt/loop_fission.h" +#include "source/opt/loop_unroller.h" #include "source/opt/loop_utils.h" +#include "source/opt/pass.h" #include "test/opt/assembly_builder.h" #include "test/opt/function_utils.h" #include "test/opt/pass_fixture.h" diff --git a/test/opt/loop_optimizations/peeling.cpp b/test/opt/loop_optimizations/peeling.cpp index 34c33074..10d8add3 100644 --- a/test/opt/loop_optimizations/peeling.cpp +++ b/test/opt/loop_optimizations/peeling.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "effcee/effcee.h" @@ -764,7 +765,7 @@ TEST_F(PeelingTest, PeelingUncountable) { EXPECT_EQ(ld.NumLoops(), 1u); Instruction* loop_count = context->get_def_use_mgr()->GetDef(16); - EXPECT_EQ(loop_count->opcode(), spv::Op::OpLoad); + EXPECT_EQ(loop_count->opcode(), SpvOpLoad); LoopPeeling peel(&*ld.begin(), loop_count); EXPECT_TRUE(peel.CanPeelLoop()); @@ -816,7 +817,7 @@ CHECK-NEXT: OpLoopMerge EXPECT_EQ(ld.NumLoops(), 1u); Instruction* loop_count = context->get_def_use_mgr()->GetDef(16); - EXPECT_EQ(loop_count->opcode(), spv::Op::OpLoad); + EXPECT_EQ(loop_count->opcode(), SpvOpLoad); LoopPeeling peel(&*ld.begin(), loop_count); EXPECT_TRUE(peel.CanPeelLoop()); @@ -1089,7 +1090,7 @@ TEST_F(PeelingTest, PeelingLoopWithStore) { EXPECT_EQ(ld.NumLoops(), 1u); Instruction* loop_count = context->get_def_use_mgr()->GetDef(15); - EXPECT_EQ(loop_count->opcode(), spv::Op::OpLoad); + EXPECT_EQ(loop_count->opcode(), SpvOpLoad); LoopPeeling peel(&*ld.begin(), loop_count); EXPECT_TRUE(peel.CanPeelLoop()); @@ -1141,7 +1142,7 @@ CHECK-NEXT: OpLoopMerge EXPECT_EQ(ld.NumLoops(), 1u); Instruction* loop_count = context->get_def_use_mgr()->GetDef(15); - EXPECT_EQ(loop_count->opcode(), spv::Op::OpLoad); + EXPECT_EQ(loop_count->opcode(), SpvOpLoad); LoopPeeling peel(&*ld.begin(), loop_count); EXPECT_TRUE(peel.CanPeelLoop()); diff --git a/test/opt/loop_optimizations/peeling_pass.cpp b/test/opt/loop_optimizations/peeling_pass.cpp index ad7fcdc3..284ad838 100644 --- a/test/opt/loop_optimizations/peeling_pass.cpp +++ b/test/opt/loop_optimizations/peeling_pass.cpp @@ -17,6 +17,7 @@ #include #include "gmock/gmock.h" +#include "source/opt/ir_builder.h" #include "source/opt/loop_descriptor.h" #include "source/opt/loop_peeling.h" #include "test/opt/pass_fixture.h" @@ -29,27 +30,27 @@ class PeelingPassTest : public PassTest<::testing::Test> { public: // Generic routine to run the loop peeling pass and check LoopPeelingPass::LoopPeelingStats AssembleAndRunPeelingTest( - const std::string& text_head, const std::string& text_tail, - spv::Op opcode, const std::string& res_id, const std::string& op1, + const std::string& text_head, const std::string& text_tail, SpvOp opcode, + const std::string& res_id, const std::string& op1, const std::string& op2) { std::string opcode_str; switch (opcode) { - case spv::Op::OpSLessThan: + case SpvOpSLessThan: opcode_str = "OpSLessThan"; break; - case spv::Op::OpSGreaterThan: + case SpvOpSGreaterThan: opcode_str = "OpSGreaterThan"; break; - case spv::Op::OpSLessThanEqual: + case SpvOpSLessThanEqual: opcode_str = "OpSLessThanEqual"; break; - case spv::Op::OpSGreaterThanEqual: + case SpvOpSGreaterThanEqual: opcode_str = "OpSGreaterThanEqual"; break; - case spv::Op::OpIEqual: + case SpvOpIEqual: opcode_str = "OpIEqual"; break; - case spv::Op::OpINotEqual: + case SpvOpINotEqual: opcode_str = "OpINotEqual"; break; default: @@ -68,9 +69,9 @@ class PeelingPassTest : public PassTest<::testing::Test> { // Generic routine to run the loop peeling pass and check LoopPeelingPass::LoopPeelingStats RunPeelingTest( - const std::string& text_head, const std::string& text_tail, - spv::Op opcode, const std::string& res_id, const std::string& op1, - const std::string& op2, size_t nb_of_loops) { + const std::string& text_head, const std::string& text_tail, SpvOp opcode, + const std::string& res_id, const std::string& op1, const std::string& op2, + size_t nb_of_loops) { LoopPeelingPass::LoopPeelingStats stats = AssembleAndRunPeelingTest( text_head, text_tail, opcode, res_id, op1, op2); @@ -85,7 +86,7 @@ class PeelingPassTest : public PassTest<::testing::Test> { std::vector>; void BuildAndCheckTrace(const std::string& text_head, - const std::string& text_tail, spv::Op opcode, + const std::string& text_tail, SpvOp opcode, const std::string& res_id, const std::string& op1, const std::string& op2, const PeelTraceType& expected_peel_trace, @@ -202,7 +203,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { OpFunctionEnd )"; - auto run_test = [&text_head, &text_tail, this](spv::Op opcode, + auto run_test = [&text_head, &text_tail, this](SpvOp opcode, const std::string& op1, const std::string& op2) { auto stats = @@ -224,7 +225,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv < 4"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%32", "%int_4"); + run_test(SpvOpSLessThan, "%32", "%int_4"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -232,7 +233,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 4 > iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%int_4", "%32"); + run_test(SpvOpSGreaterThan, "%int_4", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -240,7 +241,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv < 5"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%32", "%int_5"); + run_test(SpvOpSLessThan, "%32", "%int_5"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -248,7 +249,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 5 > iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%int_5", "%32"); + run_test(SpvOpSGreaterThan, "%int_5", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -258,7 +259,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv < 16"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%32", "%int_16"); + run_test(SpvOpSLessThan, "%32", "%int_16"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -266,7 +267,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 16 > iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%int_16", "%32"); + run_test(SpvOpSGreaterThan, "%int_16", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -274,7 +275,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv < 17"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%32", "%int_17"); + run_test(SpvOpSLessThan, "%32", "%int_17"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -282,7 +283,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 17 > iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%int_17", "%32"); + run_test(SpvOpSGreaterThan, "%int_17", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -293,7 +294,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv > 5"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%32", "%int_5"); + run_test(SpvOpSGreaterThan, "%32", "%int_5"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -301,7 +302,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 5 < iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%int_5", "%32"); + run_test(SpvOpSLessThan, "%int_5", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -309,7 +310,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv > 4"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%32", "%int_4"); + run_test(SpvOpSGreaterThan, "%32", "%int_4"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -317,7 +318,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 4 < iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%int_4", "%32"); + run_test(SpvOpSLessThan, "%int_4", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -327,7 +328,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv > 16"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%32", "%int_16"); + run_test(SpvOpSGreaterThan, "%32", "%int_16"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -335,7 +336,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 16 < iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%int_16", "%32"); + run_test(SpvOpSLessThan, "%int_16", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -343,7 +344,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv > 17"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThan, "%32", "%int_17"); + run_test(SpvOpSGreaterThan, "%32", "%int_17"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -351,7 +352,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 17 < iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThan, "%int_17", "%32"); + run_test(SpvOpSLessThan, "%int_17", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -362,7 +363,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv <= 4"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%32", "%int_4"); + run_test(SpvOpSLessThanEqual, "%32", "%int_4"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -370,7 +371,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 4 => iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%int_4", "%32"); + run_test(SpvOpSGreaterThanEqual, "%int_4", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -378,7 +379,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv <= 3"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%32", "%int_3"); + run_test(SpvOpSLessThanEqual, "%32", "%int_3"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -386,7 +387,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 3 => iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%int_3", "%32"); + run_test(SpvOpSGreaterThanEqual, "%int_3", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -396,7 +397,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv <= 16"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%32", "%int_16"); + run_test(SpvOpSLessThanEqual, "%32", "%int_16"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -404,7 +405,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 16 => iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%int_16", "%32"); + run_test(SpvOpSGreaterThanEqual, "%int_16", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -412,7 +413,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv <= 15"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%32", "%int_15"); + run_test(SpvOpSLessThanEqual, "%32", "%int_15"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -420,7 +421,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 15 => iv"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%int_15", "%32"); + run_test(SpvOpSGreaterThanEqual, "%int_15", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -431,7 +432,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv >= 5"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%32", "%int_5"); + run_test(SpvOpSGreaterThanEqual, "%32", "%int_5"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -439,7 +440,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 35 >= iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%int_5", "%32"); + run_test(SpvOpSLessThanEqual, "%int_5", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -447,7 +448,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv >= 4"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%32", "%int_4"); + run_test(SpvOpSGreaterThanEqual, "%32", "%int_4"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -455,7 +456,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 4 <= iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%int_4", "%32"); + run_test(SpvOpSLessThanEqual, "%int_4", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 2u); } @@ -465,7 +466,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv >= 17"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%32", "%int_17"); + run_test(SpvOpSGreaterThanEqual, "%32", "%int_17"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -473,7 +474,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 17 <= iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%int_17", "%32"); + run_test(SpvOpSLessThanEqual, "%int_17", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -481,7 +482,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv >= 16"); std::pair peel_info = - run_test(spv::Op::OpSGreaterThanEqual, "%32", "%int_16"); + run_test(SpvOpSGreaterThanEqual, "%32", "%int_16"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -489,7 +490,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 16 <= iv"); std::pair peel_info = - run_test(spv::Op::OpSLessThanEqual, "%int_16", "%32"); + run_test(SpvOpSLessThanEqual, "%int_16", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 2u); } @@ -500,7 +501,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv == 1"); std::pair peel_info = - run_test(spv::Op::OpIEqual, "%32", "%int_1"); + run_test(SpvOpIEqual, "%32", "%int_1"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 1u); } @@ -508,7 +509,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 1 == iv"); std::pair peel_info = - run_test(spv::Op::OpIEqual, "%int_1", "%32"); + run_test(SpvOpIEqual, "%int_1", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 1u); } @@ -518,7 +519,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv == 19"); std::pair peel_info = - run_test(spv::Op::OpIEqual, "%32", "%int_19"); + run_test(SpvOpIEqual, "%32", "%int_19"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 1u); } @@ -526,7 +527,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 19 == iv"); std::pair peel_info = - run_test(spv::Op::OpIEqual, "%int_19", "%32"); + run_test(SpvOpIEqual, "%int_19", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 1u); } @@ -537,7 +538,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before iv != 1"); std::pair peel_info = - run_test(spv::Op::OpINotEqual, "%32", "%int_1"); + run_test(SpvOpINotEqual, "%32", "%int_1"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 1u); } @@ -545,7 +546,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel before 1 != iv"); std::pair peel_info = - run_test(spv::Op::OpINotEqual, "%int_1", "%32"); + run_test(SpvOpINotEqual, "%int_1", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kBefore); EXPECT_EQ(peel_info.second, 1u); } @@ -555,7 +556,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after iv != 19"); std::pair peel_info = - run_test(spv::Op::OpINotEqual, "%32", "%int_19"); + run_test(SpvOpINotEqual, "%32", "%int_19"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 1u); } @@ -563,7 +564,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { SCOPED_TRACE("Peel after 19 != iv"); std::pair peel_info = - run_test(spv::Op::OpINotEqual, "%int_19", "%32"); + run_test(SpvOpINotEqual, "%int_19", "%32"); EXPECT_EQ(peel_info.first, LoopPeelingPass::PeelDirection::kAfter); EXPECT_EQ(peel_info.second, 1u); } @@ -572,7 +573,7 @@ TEST_F(PeelingPassTest, PeelingPassBasic) { { SCOPED_TRACE("No Peel: 20 => iv"); - auto stats = RunPeelingTest(text_head, text_tail, spv::Op::OpSLessThanEqual, + auto stats = RunPeelingTest(text_head, text_tail, SpvOpSLessThanEqual, "%22", "%int_20", "%32", 1); EXPECT_EQ(stats.peeled_loops_.size(), 0u); @@ -672,7 +673,7 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { )"; auto run_test = [&text_head, &text_tail, this]( - spv::Op opcode, const std::string& op1, + SpvOp opcode, const std::string& op1, const std::string& op2, const PeelTraceType& expected_peel_trace) { BuildAndCheckTrace(text_head, text_tail, opcode, "%22", op1, op2, @@ -684,13 +685,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv < 3"); - run_test(spv::Op::OpSLessThan, "%38", "%int_3", + run_test(SpvOpSLessThan, "%38", "%int_3", {{LoopPeelingPass::PeelDirection::kBefore, 3u}}); } { SCOPED_TRACE("Peel before 3 > iv"); - run_test(spv::Op::OpSGreaterThan, "%int_3", "%38", + run_test(SpvOpSGreaterThan, "%int_3", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 3u}}); } @@ -698,13 +699,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv < 8"); - run_test(spv::Op::OpSLessThan, "%38", "%int_8", + run_test(SpvOpSLessThan, "%38", "%int_8", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } { SCOPED_TRACE("Peel after 8 > iv"); - run_test(spv::Op::OpSGreaterThan, "%int_8", "%38", + run_test(SpvOpSGreaterThan, "%int_8", "%38", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } @@ -713,13 +714,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv > 2"); - run_test(spv::Op::OpSGreaterThan, "%38", "%int_2", + run_test(SpvOpSGreaterThan, "%38", "%int_2", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } { SCOPED_TRACE("Peel before 2 < iv"); - run_test(spv::Op::OpSLessThan, "%int_2", "%38", + run_test(SpvOpSLessThan, "%int_2", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } @@ -727,13 +728,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv > 7"); - run_test(spv::Op::OpSGreaterThan, "%38", "%int_7", + run_test(SpvOpSGreaterThan, "%38", "%int_7", {{LoopPeelingPass::PeelDirection::kAfter, 3u}}); } { SCOPED_TRACE("Peel after 7 < iv"); - run_test(spv::Op::OpSLessThan, "%int_7", "%38", + run_test(SpvOpSLessThan, "%int_7", "%38", {{LoopPeelingPass::PeelDirection::kAfter, 3u}}); } @@ -742,13 +743,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv <= 1"); - run_test(spv::Op::OpSLessThanEqual, "%38", "%int_1", + run_test(SpvOpSLessThanEqual, "%38", "%int_1", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } { SCOPED_TRACE("Peel before 1 => iv"); - run_test(spv::Op::OpSGreaterThanEqual, "%int_1", "%38", + run_test(SpvOpSGreaterThanEqual, "%int_1", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } @@ -756,13 +757,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv <= 7"); - run_test(spv::Op::OpSLessThanEqual, "%38", "%int_7", + run_test(SpvOpSLessThanEqual, "%38", "%int_7", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } { SCOPED_TRACE("Peel after 7 => iv"); - run_test(spv::Op::OpSGreaterThanEqual, "%int_7", "%38", + run_test(SpvOpSGreaterThanEqual, "%int_7", "%38", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } @@ -771,13 +772,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv >= 2"); - run_test(spv::Op::OpSGreaterThanEqual, "%38", "%int_2", + run_test(SpvOpSGreaterThanEqual, "%38", "%int_2", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } { SCOPED_TRACE("Peel before 2 <= iv"); - run_test(spv::Op::OpSLessThanEqual, "%int_2", "%38", + run_test(SpvOpSLessThanEqual, "%int_2", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 2u}}); } @@ -785,13 +786,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv >= 8"); - run_test(spv::Op::OpSGreaterThanEqual, "%38", "%int_8", + run_test(SpvOpSGreaterThanEqual, "%38", "%int_8", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } { SCOPED_TRACE("Peel after 8 <= iv"); - run_test(spv::Op::OpSLessThanEqual, "%int_8", "%38", + run_test(SpvOpSLessThanEqual, "%int_8", "%38", {{LoopPeelingPass::PeelDirection::kAfter, 2u}}); } // Test EQ @@ -799,13 +800,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv == 0"); - run_test(spv::Op::OpIEqual, "%38", "%int_0", + run_test(SpvOpIEqual, "%38", "%int_0", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } { SCOPED_TRACE("Peel before 0 == iv"); - run_test(spv::Op::OpIEqual, "%int_0", "%38", + run_test(SpvOpIEqual, "%int_0", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } @@ -813,13 +814,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv == 9"); - run_test(spv::Op::OpIEqual, "%38", "%int_9", + run_test(SpvOpIEqual, "%38", "%int_9", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } { SCOPED_TRACE("Peel after 9 == iv"); - run_test(spv::Op::OpIEqual, "%int_9", "%38", + run_test(SpvOpIEqual, "%int_9", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } @@ -828,13 +829,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel before iv != 0"); - run_test(spv::Op::OpINotEqual, "%38", "%int_0", + run_test(SpvOpINotEqual, "%38", "%int_0", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } { SCOPED_TRACE("Peel before 0 != iv"); - run_test(spv::Op::OpINotEqual, "%int_0", "%38", + run_test(SpvOpINotEqual, "%int_0", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } @@ -842,13 +843,13 @@ TEST_F(PeelingPassTest, MultiplePeelingPass) { { SCOPED_TRACE("Peel after iv != 9"); - run_test(spv::Op::OpINotEqual, "%38", "%int_9", + run_test(SpvOpINotEqual, "%38", "%int_9", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } { SCOPED_TRACE("Peel after 9 != iv"); - run_test(spv::Op::OpINotEqual, "%int_9", "%38", + run_test(SpvOpINotEqual, "%int_9", "%38", {{LoopPeelingPass::PeelDirection::kBefore, 1u}}); } } @@ -951,7 +952,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { auto run_test = [&text_head, &text_tail, this]( - spv::Op opcode, const std::string& op1, const std::string& op2, + SpvOp opcode, const std::string& op1, const std::string& op2, const PeelTraceType& expected_peel_trace, size_t nb_of_loops) { BuildAndCheckTrace(text_head, text_tail, opcode, "%30", op1, op2, expected_peel_trace, nb_of_loops); @@ -962,7 +963,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { SCOPED_TRACE("Peel before iv_i < 3"); // Expect peel before by a factor of 3 and 4 loops at the end. - run_test(spv::Op::OpSLessThan, "%42", "%int_3", + run_test(SpvOpSLessThan, "%42", "%int_3", {{LoopPeelingPass::PeelDirection::kBefore, 3u}}, 4); } // Peeling outer loop after by a factor of 3. @@ -970,7 +971,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { SCOPED_TRACE("Peel after iv_i < 7"); // Expect peel after by a factor of 3 and 4 loops at the end. - run_test(spv::Op::OpSLessThan, "%42", "%int_7", + run_test(SpvOpSLessThan, "%42", "%int_7", {{LoopPeelingPass::PeelDirection::kAfter, 3u}}, 4); } @@ -979,7 +980,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { SCOPED_TRACE("Peel before iv_j < 3"); // Expect peel before by a factor of 3 and 3 loops at the end. - run_test(spv::Op::OpSLessThan, "%46", "%int_3", + run_test(SpvOpSLessThan, "%46", "%int_3", {{LoopPeelingPass::PeelDirection::kBefore, 3u}}, 3); } // Peeling inner loop after by a factor of 3. @@ -987,7 +988,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { SCOPED_TRACE("Peel after iv_j < 7"); // Expect peel after by a factor of 3 and 3 loops at the end. - run_test(spv::Op::OpSLessThan, "%46", "%int_7", + run_test(SpvOpSLessThan, "%46", "%int_7", {{LoopPeelingPass::PeelDirection::kAfter, 3u}}, 3); } @@ -996,7 +997,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { SCOPED_TRACE("No peel"); // Expect no peeling and 2 loops at the end. - run_test(spv::Op::OpSLessThan, "%46", "%42", {}, 2); + run_test(SpvOpSLessThan, "%46", "%42", {}, 2); } // Could do a peeling of 3, but the goes over the threshold. @@ -1006,7 +1007,7 @@ TEST_F(PeelingPassTest, PeelingNestedPass) { size_t current_threshold = LoopPeelingPass::GetLoopPeelingThreshold(); LoopPeelingPass::SetLoopPeelingThreshold(1u); // Expect no peeling and 2 loops at the end. - run_test(spv::Op::OpSLessThan, "%46", "%int_7", {}, 2); + run_test(SpvOpSLessThan, "%46", "%int_7", {}, 2); LoopPeelingPass::SetLoopPeelingThreshold(current_threshold); } } diff --git a/test/opt/loop_optimizations/unroll_assumptions.cpp b/test/opt/loop_optimizations/unroll_assumptions.cpp index 81657a50..159e4a14 100644 --- a/test/opt/loop_optimizations/unroll_assumptions.cpp +++ b/test/opt/loop_optimizations/unroll_assumptions.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/loop_optimizations/unroll_simple.cpp b/test/opt/loop_optimizations/unroll_simple.cpp index 6468adf4..299fb2d5 100644 --- a/test/opt/loop_optimizations/unroll_simple.cpp +++ b/test/opt/loop_optimizations/unroll_simple.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "gmock/gmock.h" diff --git a/test/opt/module_test.cpp b/test/opt/module_test.cpp index a93a50b0..17a13650 100644 --- a/test/opt/module_test.cpp +++ b/test/opt/module_test.cpp @@ -12,14 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/module.h" - #include +#include +#include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "source/opt/build_module.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" #include "spirv-tools/libspirv.hpp" #include "test/opt/module_utils.h" @@ -322,7 +324,7 @@ OpFunctionEnd std::unordered_set non_semantic_ids; context->module()->ForEachInst( [&non_semantic_ids](const Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (inst->opcode() == SpvOpExtInst) { non_semantic_ids.insert(inst->result_id()); } }, diff --git a/test/opt/module_utils.h b/test/opt/module_utils.h index 6859188f..007f132c 100644 --- a/test/opt/module_utils.h +++ b/test/opt/module_utils.h @@ -17,7 +17,6 @@ #include #include "source/opt/module.h" -#include "gtest/gtest.h" namespace spvtest { diff --git a/test/opt/pass_manager_test.cpp b/test/opt/pass_manager_test.cpp index ec11069b..4f36d5b2 100644 --- a/test/opt/pass_manager_test.cpp +++ b/test/opt/pass_manager_test.cpp @@ -144,8 +144,8 @@ class AppendTypeVoidInstPass : public Pass { const char* name() const override { return "AppendTypeVoidInstPass"; } Status Process() override { - auto inst = MakeUnique(context(), spv::Op::OpTypeVoid, 0, - result_id_, std::vector{}); + auto inst = MakeUnique(context(), SpvOpTypeVoid, 0, result_id_, + std::vector{}); context()->AddType(std::move(inst)); return Status::SuccessWithChange; } diff --git a/test/opt/pass_merge_return_test.cpp b/test/opt/pass_merge_return_test.cpp index 494f2e95..04bd5d9b 100644 --- a/test/opt/pass_merge_return_test.cpp +++ b/test/opt/pass_merge_return_test.cpp @@ -14,7 +14,9 @@ #include +#include "gmock/gmock.h" #include "spirv-tools/libspirv.hpp" +#include "spirv-tools/optimizer.hpp" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/pass_remove_duplicates_test.cpp b/test/opt/pass_remove_duplicates_test.cpp index 131a6b4b..887fdfdb 100644 --- a/test/opt/pass_remove_duplicates_test.cpp +++ b/test/opt/pass_remove_duplicates_test.cpp @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include +#include "gmock/gmock.h" #include "source/opt/build_module.h" #include "source/opt/ir_context.h" #include "source/opt/pass_manager.h" @@ -89,7 +91,7 @@ class RemoveDuplicatesTest : public ::testing::Test { std::string GetErrorMessage() const { return error_message_; } std::string ToText(const std::vector& inst) { - std::vector binary = {spv::MagicNumber, 0x10200, 0u, 2u, 0u}; + std::vector binary = {SpvMagicNumber, 0x10200, 0u, 2u, 0u}; for (const Instruction* i : inst) i->ToBinaryWithoutAttachedDebugInsts(&binary); std::string text; diff --git a/test/opt/private_to_local_test.cpp b/test/opt/private_to_local_test.cpp index f7c37c91..8b5ec59e 100644 --- a/test/opt/private_to_local_test.cpp +++ b/test/opt/private_to_local_test.cpp @@ -15,6 +15,7 @@ #include #include "gmock/gmock.h" +#include "source/opt/build_module.h" #include "source/opt/value_number_table.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" diff --git a/test/opt/propagator_test.cpp b/test/opt/propagator_test.cpp index 307a2a12..fb8e487c 100644 --- a/test/opt/propagator_test.cpp +++ b/test/opt/propagator_test.cpp @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/propagator.h" - #include #include +#include #include #include "gmock/gmock.h" @@ -23,6 +22,8 @@ #include "source/opt/build_module.h" #include "source/opt/cfg.h" #include "source/opt/ir_context.h" +#include "source/opt/pass.h" +#include "source/opt/propagator.h" namespace spvtools { namespace opt { @@ -106,11 +107,11 @@ TEST_F(PropagatorTest, LocalPropagate) { const auto visit_fn = [this](Instruction* instr, BasicBlock** dest_bb) { *dest_bb = nullptr; - if (instr->opcode() == spv::Op::OpStore) { + if (instr->opcode() == SpvOpStore) { uint32_t lhs_id = instr->GetSingleWordOperand(0); uint32_t rhs_id = instr->GetSingleWordOperand(1); Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id); - if (rhs_def->opcode() == spv::Op::OpConstant) { + if (rhs_def->opcode() == SpvOpConstant) { uint32_t val = rhs_def->GetSingleWordOperand(2); values_[lhs_id] = val; return SSAPropagator::kInteresting; @@ -174,15 +175,15 @@ TEST_F(PropagatorTest, PropagateThroughPhis) { const auto visit_fn = [this, &phi_instr](Instruction* instr, BasicBlock** dest_bb) { *dest_bb = nullptr; - if (instr->opcode() == spv::Op::OpLoad) { + if (instr->opcode() == SpvOpLoad) { uint32_t rhs_id = instr->GetSingleWordOperand(2); Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id); - if (rhs_def->opcode() == spv::Op::OpConstant) { + if (rhs_def->opcode() == SpvOpConstant) { uint32_t val = rhs_def->GetSingleWordOperand(2); values_[instr->result_id()] = val; return SSAPropagator::kInteresting; } - } else if (instr->opcode() == spv::Op::OpPhi) { + } else if (instr->opcode() == SpvOpPhi) { phi_instr = instr; SSAPropagator::PropStatus retval; for (uint32_t i = 2; i < instr->NumOperands(); i += 2) { diff --git a/test/opt/redundancy_elimination_test.cpp b/test/opt/redundancy_elimination_test.cpp index eb78497b..28eda73e 100644 --- a/test/opt/redundancy_elimination_test.cpp +++ b/test/opt/redundancy_elimination_test.cpp @@ -15,6 +15,8 @@ #include #include "gmock/gmock.h" +#include "source/opt/build_module.h" +#include "source/opt/value_number_table.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/register_liveness.cpp b/test/opt/register_liveness.cpp index 3870e2f9..7cb210f1 100644 --- a/test/opt/register_liveness.cpp +++ b/test/opt/register_liveness.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include diff --git a/test/opt/relax_float_ops_test.cpp b/test/opt/relax_float_ops_test.cpp index e486df30..b9cb0de0 100644 --- a/test/opt/relax_float_ops_test.cpp +++ b/test/opt/relax_float_ops_test.cpp @@ -18,6 +18,7 @@ #include #include +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/remove_unused_interface_variables_test.cpp b/test/opt/remove_unused_interface_variables_test.cpp index 8bb40f7b..ddf027f1 100644 --- a/test/opt/remove_unused_interface_variables_test.cpp +++ b/test/opt/remove_unused_interface_variables_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gmock/gmock.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/replace_desc_array_access_using_var_index_test.cpp b/test/opt/replace_desc_array_access_using_var_index_test.cpp index 6018be23..9ab9eb11 100644 --- a/test/opt/replace_desc_array_access_using_var_index_test.cpp +++ b/test/opt/replace_desc_array_access_using_var_index_test.cpp @@ -14,6 +14,8 @@ #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/replace_invalid_opc_test.cpp b/test/opt/replace_invalid_opc_test.cpp index aee0d6e2..1be904b4 100644 --- a/test/opt/replace_invalid_opc_test.cpp +++ b/test/opt/replace_invalid_opc_test.cpp @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include +#include "gmock/gmock.h" #include "pass_utils.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" @@ -402,7 +404,6 @@ TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplace) { OpReturn OpFunctionEnd)"; - SetTargetEnv(SPV_ENV_UNIVERSAL_1_2); auto result = SinglePassRunAndDisassemble( text, /* skip_nop = */ true, /* do_validation = */ false); EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); @@ -431,40 +432,9 @@ TEST_F(ReplaceInvalidOpcodeTest, BarrierReplace) { OpReturn OpFunctionEnd)"; - SetTargetEnv(SPV_ENV_UNIVERSAL_1_2); SinglePassRunAndMatch(text, false); } -// Since version 1.3 OpControlBarriers are allowed is more shaders. -// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpControlBarrier -TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplaceV13) { - const std::string text = R"( - OpCapability Shader - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" - OpExecutionMode %main LocalSize 1 1 1 - OpSource GLSL 450 - OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" - OpSourceExtension "GL_GOOGLE_include_directive" - OpName %main "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %uint_2 = OpConstant %uint 2 -%uint_264 = OpConstant %uint 264 - %main = OpFunction %void None %3 - %5 = OpLabel - OpControlBarrier %uint_2 %uint_2 %uint_264 - OpReturn - OpFunctionEnd)"; - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_3); - auto result = SinglePassRunAndDisassemble( - text, /* skip_nop = */ true, /* do_validation = */ false); - EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); -} - TEST_F(ReplaceInvalidOpcodeTest, MessageTest) { const std::string text = R"( OpCapability Shader diff --git a/test/opt/scalar_analysis.cpp b/test/opt/scalar_analysis.cpp index 4779658d..df2aa8f8 100644 --- a/test/opt/scalar_analysis.cpp +++ b/test/opt/scalar_analysis.cpp @@ -12,13 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/scalar_analysis.h" - #include +#include +#include #include #include "gmock/gmock.h" +#include "source/opt/iterator.h" +#include "source/opt/loop_descriptor.h" #include "source/opt/pass.h" +#include "source/opt/scalar_analysis.h" +#include "source/opt/tree_iterator.h" #include "test/opt/assembly_builder.h" #include "test/opt/function_utils.h" #include "test/opt/pass_fixture.h" @@ -105,10 +109,10 @@ TEST_F(ScalarAnalysisTest, BasicEvolutionTest) { const Instruction* store = nullptr; const Instruction* load = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 11)) { - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { store = &inst; } - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -232,7 +236,7 @@ TEST_F(ScalarAnalysisTest, LoadTest) { const Instruction* load = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 28)) { - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { load = &inst; } } @@ -348,7 +352,7 @@ TEST_F(ScalarAnalysisTest, SimplifySimple) { const Instruction* load = nullptr; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 21)) { - if (inst.opcode() == spv::Op::OpLoad && inst.result_id() == 33) { + if (inst.opcode() == SpvOp::SpvOpLoad && inst.result_id() == 33) { load = &inst; } } @@ -502,11 +506,11 @@ TEST_F(ScalarAnalysisTest, Simplify) { int store_count = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 22)) { - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { loads[load_count] = &inst; ++load_count; } - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[store_count] = &inst; ++store_count; } @@ -741,11 +745,11 @@ TEST_F(ScalarAnalysisTest, SimplifyMultiplyInductions) { int store_count = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 31)) { - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { loads[load_count] = &inst; ++load_count; } - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores[store_count] = &inst; ++store_count; } @@ -876,7 +880,7 @@ TEST_F(ScalarAnalysisTest, SimplifyNegativeSteps) { int load_count = 0; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 29)) { - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { loads[load_count] = &inst; ++load_count; } @@ -1021,10 +1025,10 @@ TEST_F(ScalarAnalysisTest, SimplifyInductionsAndLoads) { std::vector stores{}; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 30)) { - if (inst.opcode() == spv::Op::OpLoad) { + if (inst.opcode() == SpvOp::SpvOpLoad) { loads.push_back(&inst); } - if (inst.opcode() == spv::Op::OpStore) { + if (inst.opcode() == SpvOp::SpvOpStore) { stores.push_back(&inst); } } @@ -1190,7 +1194,7 @@ TEST_F(ScalarAnalysisTest, InductionWithVariantStep) { std::vector phis{}; for (const Instruction& inst : *spvtest::GetBasicBlock(f, 21)) { - if (inst.opcode() == spv::Op::OpPhi) { + if (inst.opcode() == SpvOp::SpvOpPhi) { phis.push_back(&inst); } } diff --git a/test/opt/scalar_replacement_test.cpp b/test/opt/scalar_replacement_test.cpp index 0ba285bb..0c97c80b 100644 --- a/test/opt/scalar_replacement_test.cpp +++ b/test/opt/scalar_replacement_test.cpp @@ -12,9 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "source/opt/scalar_replacement_pass.h" + #include -#include "source/opt/scalar_replacement_pass.h" +#include "gmock/gmock.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" @@ -2308,54 +2310,6 @@ TEST_F(ScalarReplacementTest, UndefImageMember) { SinglePassRunAndMatch(text, true); } -TEST_F(ScalarReplacementTest, RestrictPointer) { - // This test makes sure that a variable with the restrict pointer decoration - // is replaced, and that the pointer is applied to the new variable. - const std::string text = R"( -; CHECK: OpDecorate [[new_var:%\w+]] RestrictPointer -; CHECK: [[struct_type:%\w+]] = OpTypeStruct %int -; CHECK: [[ptr_type:%\w+]] = OpTypePointer PhysicalStorageBuffer [[struct_type]] -; CHECK: [[dup_struct_type:%\w+]] = OpTypeStruct %int -; CHECK: {{%\w+}} = OpTypePointer PhysicalStorageBuffer [[dup_struct_type]] -; CHECK: [[var_type:%\w+]] = OpTypePointer Function [[ptr_type]] -; CHECK: [[new_var]] = OpVariable [[var_type]] Function - OpCapability Shader - OpCapability PhysicalStorageBufferAddresses - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel PhysicalStorageBuffer64 GLSL450 - OpEntryPoint Fragment %2 "main" - OpExecutionMode %2 OriginUpperLeft - OpMemberDecorate %3 0 Offset 0 - OpDecorate %3 Block - OpMemberDecorate %4 0 Offset 0 - OpDecorate %4 Block - OpDecorate %5 RestrictPointer - %6 = OpTypeVoid - %7 = OpTypeFunction %6 - %8 = OpTypeInt 32 1 - %9 = OpConstant %8 0 - %3 = OpTypeStruct %8 - %10 = OpTypePointer PhysicalStorageBuffer %3 - %11 = OpTypeStruct %10 - %4 = OpTypeStruct %8 - %12 = OpTypePointer PhysicalStorageBuffer %4 - %13 = OpTypePointer Function %11 - %14 = OpTypePointer Function %10 - %15 = OpTypePointer Function %12 - %16 = OpUndef %11 - %2 = OpFunction %6 None %7 - %17 = OpLabel - %5 = OpVariable %13 Function - OpStore %5 %16 - %18 = OpAccessChain %14 %5 %9 - OpReturn - OpFunctionEnd - )"; - - SetTargetEnv(SPV_ENV_UNIVERSAL_1_6); - SinglePassRunAndMatch(text, true); -} - } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/simplification_test.cpp b/test/opt/simplification_test.cpp index 7fce2898..7727f567 100644 --- a/test/opt/simplification_test.cpp +++ b/test/opt/simplification_test.cpp @@ -16,6 +16,7 @@ #include "gmock/gmock.h" #include "source/opt/simplification_pass.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" namespace spvtools { diff --git a/test/opt/spread_volatile_semantics_test.cpp b/test/opt/spread_volatile_semantics_test.cpp index 4328c396..dbb889c0 100644 --- a/test/opt/spread_volatile_semantics_test.cpp +++ b/test/opt/spread_volatile_semantics_test.cpp @@ -14,6 +14,7 @@ #include +#include "gmock/gmock.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/strength_reduction_test.cpp b/test/opt/strength_reduction_test.cpp index a37c6c23..31d05036 100644 --- a/test/opt/strength_reduction_test.cpp +++ b/test/opt/strength_reduction_test.cpp @@ -12,11 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include +#include #include #include #include #include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/strip_reflect_info_test.cpp b/test/opt/strip_reflect_info_test.cpp new file mode 100644 index 00000000..f3fc115a --- /dev/null +++ b/test/opt/strip_reflect_info_test.cpp @@ -0,0 +1,231 @@ +// Copyright (c) 2018 Google LLC +// +// 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 "gmock/gmock.h" + +#include "spirv-tools/optimizer.hpp" + +#include "test/opt/pass_fixture.h" +#include "test/opt/pass_utils.h" + +namespace spvtools { +namespace opt { +namespace { + +using StripLineReflectInfoTest = PassTest<::testing::Test>; +using StripNonSemanticInfoTest = PassTest<::testing::Test>; + +// This test acts as an end-to-end code example on how to strip +// reflection info from a SPIR-V module. Use this code pattern +// when you have compiled HLSL code with Glslang or DXC using +// option -fhlsl_functionality1 to insert reflection information, +// but then want to filter out the extra instructions before sending +// it to a driver that does not implement VK_GOOGLE_hlsl_functionality1. +TEST_F(StripLineReflectInfoTest, StripReflectEnd2EndExample) { + // This is a non-sensical example, but exercises the instructions. + std::string before = R"(OpCapability Shader +OpCapability Linkage +OpExtension "SPV_GOOGLE_decorate_string" +OpExtension "SPV_GOOGLE_hlsl_functionality1" +OpMemoryModel Logical Simple +OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar" +OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness" +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); + std::vector binary_in; + tools.Assemble(before, &binary_in); + + // Instantiate the optimizer, and run the strip-reflection-info + // pass over the |binary_in| module, and place the modified module + // into |binary_out|. + spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_1); + optimizer.RegisterPass(spvtools::CreateStripReflectInfoPass()); + std::vector binary_out; + optimizer.Run(binary_in.data(), binary_in.size(), &binary_out); + + // Check results + std::string disassembly; + tools.Disassemble(binary_out.data(), binary_out.size(), &disassembly); + std::string after = R"(OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical Simple +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + EXPECT_THAT(disassembly, testing::Eq(after)); +} + +// This test is functionally the same as the end-to-end test above, +// but uses the test SinglePassRunAndCheck test fixture instead. +TEST_F(StripLineReflectInfoTest, StripHlslSemantic) { + // This is a non-sensical example, but exercises the instructions. + std::string before = R"(OpCapability Shader +OpCapability Linkage +OpExtension "SPV_GOOGLE_decorate_string" +OpExtension "SPV_GOOGLE_hlsl_functionality1" +OpMemoryModel Logical Simple +OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar" +OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness" +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + std::string after = R"(OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical Simple +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + + SinglePassRunAndCheck(before, after, false); +} + +TEST_F(StripLineReflectInfoTest, StripHlslCounterBuffer) { + std::string before = R"(OpCapability Shader +OpCapability Linkage +OpExtension "SPV_GOOGLE_hlsl_functionality1" +OpMemoryModel Logical Simple +OpDecorateId %void HlslCounterBufferGOOGLE %float +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + std::string after = R"(OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical Simple +%void = OpTypeVoid +%float = OpTypeFloat 32 +)"; + + SinglePassRunAndCheck(before, after, false); +} + +TEST_F(StripLineReflectInfoTest, StripHlslSemanticOnMember) { + // This is a non-sensical example, but exercises the instructions. + std::string before = R"(OpCapability Shader +OpCapability Linkage +OpExtension "SPV_GOOGLE_decorate_string" +OpExtension "SPV_GOOGLE_hlsl_functionality1" +OpMemoryModel Logical Simple +OpMemberDecorateStringGOOGLE %struct 0 HlslSemanticGOOGLE "foobar" +%float = OpTypeFloat 32 +%_struct_3 = OpTypeStruct %float +)"; + std::string after = R"(OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical Simple +%float = OpTypeFloat 32 +%_struct_3 = OpTypeStruct %float +)"; + + SinglePassRunAndCheck(before, after, false); +} + +TEST_F(StripNonSemanticInfoTest, StripNonSemanticImport) { + std::string text = R"( +; CHECK-NOT: OpExtension "SPV_KHR_non_semantic_info" +; CHECK-NOT: OpExtInstImport +OpCapability Shader +OpCapability Linkage +OpExtension "SPV_KHR_non_semantic_info" +%ext = OpExtInstImport "NonSemantic.Test" +OpMemoryModel Logical GLSL450 +)"; + + SinglePassRunAndMatch(text, true); +} + +TEST_F(StripNonSemanticInfoTest, StripNonSemanticGlobal) { + std::string text = R"( +; CHECK-NOT: OpExtInst +OpCapability Shader +OpCapability Linkage +OpExtension "SPV_KHR_non_semantic_info" +%ext = OpExtInstImport "NonSemantic.Test" +OpMemoryModel Logical GLSL450 +%void = OpTypeVoid +%1 = OpExtInst %void %ext 1 +)"; + + SinglePassRunAndMatch(text, true); +} + +TEST_F(StripNonSemanticInfoTest, StripNonSemanticInFunction) { + std::string text = R"( +; CHECK-NOT: OpExtInst +OpCapability Shader +OpCapability Linkage +OpExtension "SPV_KHR_non_semantic_info" +%ext = OpExtInstImport "NonSemantic.Test" +OpMemoryModel Logical GLSL450 +%void = OpTypeVoid +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +%1 = OpExtInst %void %ext 1 %foo +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndMatch(text, true); +} + +TEST_F(StripNonSemanticInfoTest, StripNonSemanticAfterFunction) { + std::string text = R"( +; CHECK-NOT: OpExtInst +OpCapability Shader +OpCapability Linkage +OpExtension "SPV_KHR_non_semantic_info" +%ext = OpExtInstImport "NonSemantic.Test" +OpMemoryModel Logical GLSL450 +%void = OpTypeVoid +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +%1 = OpExtInst %void %ext 1 %foo +)"; + + SinglePassRunAndMatch(text, true); +} + +TEST_F(StripNonSemanticInfoTest, StripNonSemanticBetweenFunctions) { + std::string text = R"( +; CHECK-NOT: OpExtInst +OpCapability Shader +OpCapability Linkage +OpExtension "SPV_KHR_non_semantic_info" +%ext = OpExtInstImport "NonSemantic.Test" +OpMemoryModel Logical GLSL450 +%void = OpTypeVoid +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +OpReturn +OpFunctionEnd +%1 = OpExtInst %void %ext 1 %foo +%bar = OpFunction %void None %void_fn +%bar_entry = OpLabel +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndMatch(text, true); +} + +} // namespace +} // namespace opt +} // namespace spvtools diff --git a/test/opt/struct_cfg_analysis_test.cpp b/test/opt/struct_cfg_analysis_test.cpp index 9c72cee9..e7031cb5 100644 --- a/test/opt/struct_cfg_analysis_test.cpp +++ b/test/opt/struct_cfg_analysis_test.cpp @@ -17,6 +17,7 @@ #include #include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/switch_descriptorset_test.cpp b/test/opt/switch_descriptorset_test.cpp deleted file mode 100755 index f26178f8..00000000 --- a/test/opt/switch_descriptorset_test.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2023 LunarG Inc. -// -// 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. - -// Bindless Check Instrumentation Tests. -// Tests ending with V2 use version 2 record format. - -#include -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using SwitchDescriptorSetTest = PassTest<::testing::Test>; - -TEST_F(SwitchDescriptorSetTest, Basic) { - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // - // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; - // - // layout(set = 7, binding = 7) uniform ufoo { - // bufStruct data; - // uint offset; - // } u_info; - // - // layout(buffer_reference, std140) buffer bufStruct { - // layout(offset = 0) int a[2]; - // layout(offset = 32) int b; - // }; - // - // void main() { - // u_info.data.b = 0xca7; - // } - - const std::string spirv = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -OpExtension "SPV_EXT_physical_storage_buffer" -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 -OpSource GLSL 450 -OpSourceExtension "GL_EXT_buffer_reference" -OpName %main "main" -OpName %ufoo "ufoo" -OpMemberName %ufoo 0 "data" -OpMemberName %ufoo 1 "offset" -OpName %bufStruct "bufStruct" -OpMemberName %bufStruct 0 "a" -OpMemberName %bufStruct 1 "b" -OpName %u_info "u_info" -OpMemberDecorate %ufoo 0 Offset 0 -OpMemberDecorate %ufoo 1 Offset 8 -OpDecorate %ufoo Block -OpDecorate %_arr_int_uint_2 ArrayStride 16 -OpMemberDecorate %bufStruct 0 Offset 0 -OpMemberDecorate %bufStruct 1 Offset 32 -OpDecorate %bufStruct Block -OpDecorate %u_info DescriptorSet 7 -;CHECK: OpDecorate %u_info DescriptorSet 31 -OpDecorate %u_info Binding 7 -;CHECK: OpDecorate %u_info Binding 7 -%void = OpTypeVoid -%3 = OpTypeFunction %void -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer -%uint = OpTypeInt 32 0 -%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint -%int = OpTypeInt 32 1 -%uint_2 = OpConstant %uint 2 -%_arr_int_uint_2 = OpTypeArray %int %uint_2 -%bufStruct = OpTypeStruct %_arr_int_uint_2 %int -%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct -%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo -%u_info = OpVariable %_ptr_Uniform_ufoo Uniform -%int_0 = OpConstant %int 0 -%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct -%int_1 = OpConstant %int 1 -%int_3239 = OpConstant %int 3239 -%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -%main = OpFunction %void None %3 -%5 = OpLabel -%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 -%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 -OpReturn -OpFunctionEnd -)"; - // clang-format off - - SinglePassRunAndMatch(spirv, true, 7, 31); -} - - -// Make sure DescriptorSet decorations that don't match the requested number -// are left unchanged. -TEST_F(SwitchDescriptorSetTest, Unchanged) { - // #version 450 - // #extension GL_EXT_buffer_reference : enable - // - // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; - // - // layout(set = 11, binding = 7) uniform ufoo { - // bufStruct data; - // uint offset; - // } u_info; - // - // layout(buffer_reference, std140) buffer bufStruct { - // layout(offset = 0) int a[2]; - // layout(offset = 32) int b; - // }; - // - // void main() { - // u_info.data.b = 0xca7; - // } - - const std::string spirv = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -OpExtension "SPV_EXT_physical_storage_buffer" -%1 = OpExtInstImport "GLSL.std.450" -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 -OpSource GLSL 450 -OpSourceExtension "GL_EXT_buffer_reference" -OpName %main "main" -OpName %ufoo "ufoo" -OpMemberName %ufoo 0 "data" -OpMemberName %ufoo 1 "offset" -OpName %bufStruct "bufStruct" -OpMemberName %bufStruct 0 "a" -OpMemberName %bufStruct 1 "b" -OpName %u_info "u_info" -OpMemberDecorate %ufoo 0 Offset 0 -OpMemberDecorate %ufoo 1 Offset 8 -OpDecorate %ufoo Block -OpDecorate %_arr_int_uint_2 ArrayStride 16 -OpMemberDecorate %bufStruct 0 Offset 0 -OpMemberDecorate %bufStruct 1 Offset 32 -OpDecorate %bufStruct Block -OpDecorate %u_info DescriptorSet 11 -;CHECK: OpDecorate %u_info DescriptorSet 11 -OpDecorate %u_info Binding 7 -;CHECK: OpDecorate %u_info Binding 7 -%void = OpTypeVoid -%3 = OpTypeFunction %void -OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer -%uint = OpTypeInt 32 0 -%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint -%int = OpTypeInt 32 1 -%uint_2 = OpConstant %uint 2 -%_arr_int_uint_2 = OpTypeArray %int %uint_2 -%bufStruct = OpTypeStruct %_arr_int_uint_2 %int -%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct -%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo -%u_info = OpVariable %_ptr_Uniform_ufoo Uniform -%int_0 = OpConstant %int 0 -%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct -%int_1 = OpConstant %int 1 -%int_3239 = OpConstant %int 3239 -%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int -%main = OpFunction %void None %3 -%5 = OpLabel -%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 -%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 -%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 -OpReturn -OpFunctionEnd -)"; - // clang-format off - - SinglePassRunAndMatch(spirv, true, 7, 31); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/trim_capabilities_pass_test.cpp b/test/opt/trim_capabilities_pass_test.cpp deleted file mode 100755 index 14a8aa3a..00000000 --- a/test/opt/trim_capabilities_pass_test.cpp +++ /dev/null @@ -1,2491 +0,0 @@ -// Copyright (c) 2023 Google Inc. -// -// 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 "spirv-tools/optimizer.hpp" -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using TrimCapabilitiesPassTest = PassTest<::testing::Test>; - -TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) { - // Those are expected changes caused by the test process: - // - SPV is assembled. -> capability goes from text to number. - // - SPV is optimized. - // - SPV is disassembled -> capability goes from number to text. - // - CHECK rule compares both text versions. - // Because some capabilities share the same number (aliases), the text - // compared with the CHECK rules depends on which alias is the first on the - // SPIRV-Headers enum. This could change, and we want to easily distinguish - // real failure from alias order change. This test is only here to list known - // alias transformations. If this test breaks, it's not a bug in the - // optimization pass, but just the SPIRV-Headers enum order that has changed. - // If that happens, tests needs to be updated to the correct alias is used in - // the CHECK rule. - const std::string kTest = R"( - OpCapability Linkage - OpCapability StorageUniform16 - OpCapability StorageUniformBufferBlock16 - OpCapability ShaderViewportIndexLayerNV - OpCapability FragmentBarycentricNV - OpCapability ShadingRateNV - OpCapability ShaderNonUniformEXT - OpCapability RuntimeDescriptorArrayEXT - OpCapability InputAttachmentArrayDynamicIndexingEXT - OpCapability UniformTexelBufferArrayDynamicIndexingEXT - OpCapability StorageTexelBufferArrayDynamicIndexingEXT - OpCapability UniformBufferArrayNonUniformIndexingEXT - OpCapability SampledImageArrayNonUniformIndexingEXT - OpCapability StorageBufferArrayNonUniformIndexingEXT - OpCapability StorageImageArrayNonUniformIndexingEXT - OpCapability InputAttachmentArrayNonUniformIndexingEXT - OpCapability UniformTexelBufferArrayNonUniformIndexingEXT - OpCapability StorageTexelBufferArrayNonUniformIndexingEXT - OpCapability VulkanMemoryModelKHR - OpCapability VulkanMemoryModelDeviceScopeKHR - OpCapability PhysicalStorageBufferAddressesEXT - OpCapability DemoteToHelperInvocationEXT - OpCapability DotProductInputAllKHR - OpCapability DotProductInput4x8BitKHR - OpCapability DotProductInput4x8BitPackedKHR - OpCapability DotProductKHR - OpCapability ComputeDerivativeGroupQuadsNV - OpCapability ComputeDerivativeGroupLinearNV -; CHECK: OpCapability Linkage -; CHECK-NOT: OpCapability StorageUniform16 -; CHECK-NOT: OpCapability StorageUniformBufferBlock16 -; CHECK-NOT: OpCapability ShaderViewportIndexLayerNV -; CHECK-NOT: OpCapability FragmentBarycentricNV -; CHECK-NOT: OpCapability ShadingRateNV -; CHECK-NOT: OpCapability ShaderNonUniformEXT -; CHECK-NOT: OpCapability RuntimeDescriptorArrayEXT -; CHECK-NOT: OpCapability InputAttachmentArrayDynamicIndexingEXT -; CHECK-NOT: OpCapability UniformTexelBufferArrayDynamicIndexingEXT -; CHECK-NOT: OpCapability StorageTexelBufferArrayDynamicIndexingEXT -; CHECK-NOT: OpCapability UniformBufferArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability SampledImageArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability StorageBufferArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability StorageImageArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability InputAttachmentArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability UniformTexelBufferArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability StorageTexelBufferArrayNonUniformIndexingEXT -; CHECK-NOT: OpCapability VulkanMemoryModelKHR -; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScopeKHR -; CHECK-NOT: OpCapability PhysicalStorageBufferAddressesEXT -; CHECK-NOT: OpCapability DemoteToHelperInvocationEXT -; CHECK-NOT: OpCapability DotProductInputAllKHR -; CHECK-NOT: OpCapability DotProductInput4x8BitKHR -; CHECK-NOT: OpCapability DotProductInput4x8BitPackedKHR -; CHECK-NOT: OpCapability DotProductKHR -; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV -; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV -; CHECK: OpCapability UniformAndStorageBuffer16BitAccess -; CHECK: OpCapability StorageBuffer16BitAccess -; CHECK: OpCapability ShaderViewportIndexLayerEXT -; CHECK: OpCapability FragmentBarycentricKHR -; CHECK: OpCapability FragmentDensityEXT -; CHECK: OpCapability ShaderNonUniform -; CHECK: OpCapability RuntimeDescriptorArray -; CHECK: OpCapability InputAttachmentArrayDynamicIndexing -; CHECK: OpCapability UniformTexelBufferArrayDynamicIndexing -; CHECK: OpCapability StorageTexelBufferArrayDynamicIndexing -; CHECK: OpCapability UniformBufferArrayNonUniformIndexing -; CHECK: OpCapability SampledImageArrayNonUniformIndexing -; CHECK: OpCapability StorageBufferArrayNonUniformIndexing -; CHECK: OpCapability StorageImageArrayNonUniformIndexing -; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing -; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndexing -; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing -; CHECK: OpCapability VulkanMemoryModel -; CHECK: OpCapability VulkanMemoryModelDeviceScope -; CHECK: OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability DemoteToHelperInvocation -; CHECK: OpCapability DotProductInputAll -; CHECK: OpCapability DotProductInput4x8Bit -; CHECK: OpCapability DotProductInput4x8BitPacked -; CHECK: OpCapability DotProduct - OpMemoryModel Logical Vulkan - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, LinkagePreventsChanges) { - const std::string kTest = R"( - OpCapability Linkage - OpCapability ClipDistance - OpCapability CullDistance - OpCapability DemoteToHelperInvocation - OpCapability DeviceGroup - OpCapability DrawParameters - OpCapability Float16 - OpCapability Float64 - OpCapability FragmentBarycentricKHR - OpCapability FragmentFullyCoveredEXT - OpCapability FragmentShadingRateKHR - OpCapability GroupNonUniform - OpCapability GroupNonUniformArithmetic - OpCapability GroupNonUniformBallot - OpCapability GroupNonUniformQuad - OpCapability GroupNonUniformShuffle - OpCapability Image1D - OpCapability ImageBuffer - OpCapability ImageGatherExtended - OpCapability ImageMSArray - OpCapability ImageQuery - OpCapability InputAttachment - OpCapability InputAttachmentArrayNonUniformIndexing - OpCapability Int16 - OpCapability Int64 - OpCapability Int64Atomics - OpCapability Int64ImageEXT - OpCapability MeshShadingNV - OpCapability MinLod - OpCapability MultiView - OpCapability MultiViewport - OpCapability PhysicalStorageBufferAddresses - OpCapability RayQueryKHR - OpCapability RayTracingKHR - OpCapability RayTracingNV - OpCapability RayTraversalPrimitiveCullingKHR - OpCapability RuntimeDescriptorArray - OpCapability SampleMaskPostDepthCoverage - OpCapability SampleRateShading - OpCapability Sampled1D - OpCapability SampledBuffer - OpCapability SampledImageArrayNonUniformIndexing - OpCapability Shader - OpCapability ShaderClockKHR - OpCapability ShaderLayer - OpCapability ShaderNonUniform - OpCapability ShaderViewportIndex - OpCapability ShaderViewportIndexLayerEXT - OpCapability SparseResidency - OpCapability StencilExportEXT - OpCapability StorageImageArrayNonUniformIndexingEXT - OpCapability StorageImageExtendedFormats - OpCapability StorageImageReadWithoutFormat - OpCapability StorageImageWriteWithoutFormat - OpCapability StorageInputOutput16 - OpCapability StoragePushConstant16 - OpCapability StorageTexelBufferArrayNonUniformIndexing - OpCapability StorageUniform16 - OpCapability StorageUniformBufferBlock16 - OpCapability Tessellation - OpCapability UniformTexelBufferArrayNonUniformIndexing - OpCapability VulkanMemoryModel - OpExtension "SPV_EXT_fragment_fully_covered" - OpExtension "SPV_EXT_shader_image_int64" - OpExtension "SPV_EXT_shader_stencil_export" - OpExtension "SPV_EXT_shader_viewport_index_layer" - OpExtension "SPV_KHR_fragment_shader_barycentric" - OpExtension "SPV_KHR_fragment_shading_rate" - OpExtension "SPV_KHR_post_depth_coverage" - OpExtension "SPV_KHR_ray_query" - OpExtension "SPV_KHR_ray_tracing" - OpExtension "SPV_KHR_shader_clock" - OpExtension "SPV_NV_mesh_shader" - OpExtension "SPV_NV_ray_tracing" - OpExtension "SPV_NV_viewport_array2" -; CHECK: OpCapability Linkage -; CHECK: OpCapability ClipDistance -; CHECK: OpCapability CullDistance -; CHECK: OpCapability DemoteToHelperInvocation -; CHECK: OpCapability DeviceGroup -; CHECK: OpCapability DrawParameters -; CHECK: OpCapability Float16 -; CHECK: OpCapability Float64 -; CHECK: OpCapability FragmentBarycentricKHR -; CHECK: OpCapability FragmentFullyCoveredEXT -; CHECK: OpCapability FragmentShadingRateKHR -; CHECK: OpCapability GroupNonUniform -; CHECK: OpCapability GroupNonUniformArithmetic -; CHECK: OpCapability GroupNonUniformBallot -; CHECK: OpCapability GroupNonUniformQuad -; CHECK: OpCapability GroupNonUniformShuffle -; CHECK: OpCapability Image1D -; CHECK: OpCapability ImageBuffer -; CHECK: OpCapability ImageGatherExtended -; CHECK: OpCapability ImageMSArray -; CHECK: OpCapability ImageQuery -; CHECK: OpCapability InputAttachment -; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing -; CHECK: OpCapability Int16 -; CHECK: OpCapability Int64 -; CHECK: OpCapability Int64Atomics -; CHECK: OpCapability Int64ImageEXT -; CHECK: OpCapability MeshShadingNV -; CHECK: OpCapability MinLod -; CHECK: OpCapability MultiView -; CHECK: OpCapability MultiViewport -; CHECK: OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability RayQueryKHR -; CHECK: OpCapability RayTracingKHR -; CHECK: OpCapability RayTracingNV -; CHECK: OpCapability RayTraversalPrimitiveCullingKHR -; CHECK: OpCapability RuntimeDescriptorArray -; CHECK: OpCapability SampleMaskPostDepthCoverage -; CHECK: OpCapability SampleRateShading -; CHECK: OpCapability Sampled1D -; CHECK: OpCapability SampledBuffer -; CHECK: OpCapability SampledImageArrayNonUniformIndexing -; CHECK: OpCapability Shader -; CHECK: OpCapability ShaderClockKHR -; CHECK: OpCapability ShaderLayer -; CHECK: OpCapability ShaderNonUniform -; CHECK: OpCapability ShaderViewportIndex -; CHECK: OpCapability ShaderViewportIndexLayerEXT -; CHECK: OpCapability SparseResidency -; CHECK: OpCapability StencilExportEXT -; CHECK: OpCapability StorageImageArrayNonUniformIndexing -; CHECK: OpCapability StorageImageExtendedFormats -; CHECK: OpCapability StorageImageReadWithoutFormat -; CHECK: OpCapability StorageImageWriteWithoutFormat -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpCapability StoragePushConstant16 -; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing -; CHECK: OpCapability Tessellation -; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndex -; CHECK: OpCapability VulkanMemoryModel -; CHECK: OpExtension "SPV_EXT_fragment_fully_covered" -; CHECK: OpExtension "SPV_EXT_shader_image_int64" -; CHECK: OpExtension "SPV_EXT_shader_stencil_export" -; CHECK: OpExtension "SPV_EXT_shader_viewport_index_layer" -; CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" -; CHECK: OpExtension "SPV_KHR_fragment_shading_rate" -; CHECK: OpExtension "SPV_KHR_post_depth_coverage" -; CHECK: OpExtension "SPV_KHR_ray_query" -; CHECK: OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpExtension "SPV_KHR_shader_clock" -; CHECK: OpExtension "SPV_NV_mesh_shader" -; CHECK: OpExtension "SPV_NV_ray_tracing" -; CHECK: OpExtension "SPV_NV_viewport_array2" - OpMemoryModel Logical Vulkan - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_3); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, KeepShader) { - const std::string kTest = R"( - OpCapability Shader -; CHECK: OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, KeepShaderClockWhenInUse) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Int64 - OpCapability ShaderClockKHR - OpExtension "SPV_KHR_shader_clock" -; CHECK: OpCapability ShaderClockKHR -; CHECK: OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %ulong = OpTypeInt 64 0 - %scope = OpConstant %uint 1 - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - %7 = OpReadClockKHR %ulong %scope - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, TrimShaderClockWhenUnused) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Int64 - OpCapability ShaderClockKHR - OpExtension "SPV_KHR_shader_clock" -; CHECK-NOT: OpCapability ShaderClockKHR -; CHECK-NOT: OpExtension "SPV_KHR_shader_clock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemains) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Groups - OpExtension "SPV_AMD_shader_ballot" -; CHECK: OpCapability Groups -; CHECK: OpExtension "SPV_AMD_shader_ballot" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %1 = OpTypeFunction %void - %uint_0 = OpConstant %uint 0 - %2 = OpFunction %void None %1 - %3 = OpLabel - %4 = OpGroupIAddNonUniformAMD %uint %uint_0 ExclusiveScan %uint_0 - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemoved) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Groups - OpExtension "SPV_AMD_shader_ballot" -; CHECK-NOT: OpCapability Groups -; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, MinLod_RemovedIfNotUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Sampled1D - OpCapability MinLod -; CHECK-NOT: OpCapability MinLod - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %v4float = OpTypeVector %float 4 - %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f - %ptr_type_image = OpTypePointer UniformConstant %type_image - %type_sampler = OpTypeSampler - %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler - %float_0 = OpConstant %float 0 - %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0 - %image = OpVariable %ptr_type_image UniformConstant - %sampler = OpVariable %ptr_type_sampler UniformConstant - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - %21 = OpLoad %type_image %image - %22 = OpLoad %type_sampler %sampler - %24 = OpSampledImage %type_sampled_image %21 %22 - %25 = OpImageSampleImplicitLod %v4float %24 %float_000 - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, MinLod_RemainsWithOpImageSampleImplicitLod) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Sampled1D - OpCapability MinLod -; CHECK: OpCapability MinLod - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %float = OpTypeFloat 32 - %v3float = OpTypeVector %float 3 - %v4float = OpTypeVector %float 4 - %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f - %ptr_type_image = OpTypePointer UniformConstant %type_image - %type_sampler = OpTypeSampler - %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler - %float_0 = OpConstant %float 0 - %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0 - %image = OpVariable %ptr_type_image UniformConstant - %sampler = OpVariable %ptr_type_sampler UniformConstant - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - %21 = OpLoad %type_image %image - %22 = OpLoad %type_sampler %sampler - %24 = OpSampledImage %type_sampled_image %21 %22 - %25 = OpImageSampleImplicitLod %v4float %24 %float_000 MinLod %float_0 - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - MinLod_RemainsWithOpImageSparseSampleImplicitLod) { - const std::string kTest = R"( - OpCapability Shader - OpCapability SparseResidency - OpCapability ImageGatherExtended - OpCapability MinLod -; CHECK: OpCapability MinLod - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" - OpExecutionMode %2 OriginUpperLeft - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %float = OpTypeFloat 32 - %v2float = OpTypeVector %float 2 - %v3float = OpTypeVector %float 3 - %v4float = OpTypeVector %float 4 - %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown - %ptr_type_image = OpTypePointer UniformConstant %type_image - %type_sampler = OpTypeSampler - %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler -%type_sampled_image = OpTypeSampledImage %type_image - %sparse_struct = OpTypeStruct %uint %v4float - %float_0 = OpConstant %float 0 - %float_00 = OpConstantComposite %v2float %float_0 %float_0 - %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0 - %image = OpVariable %ptr_type_image UniformConstant - %sampler = OpVariable %ptr_type_sampler UniformConstant - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - %21 = OpLoad %type_image %image - %22 = OpLoad %type_sampler %sampler - %24 = OpSampledImage %type_sampled_image %21 %22 - %25 = OpImageSparseSampleImplicitLod %sparse_struct %24 %float_00 MinLod %float_0 - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, MinLod_DetectsMinLodWithBitmaskImageOperand) { - const std::string kTest = R"( - OpCapability MinLod -; CHECK: OpCapability MinLod - OpCapability Shader - OpCapability SparseResidency - OpCapability ImageGatherExtended - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %1 "main" - OpExecutionMode %1 OriginUpperLeft - %type_sampler = OpTypeSampler - %int = OpTypeInt 32 1 - %float = OpTypeFloat 32 - %v2int = OpTypeVector %int 2 - %v2float = OpTypeVector %float 2 - %v4float = OpTypeVector %float 4 - %ptr_sampler = OpTypePointer UniformConstant %type_sampler - %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown - %ptr_image = OpTypePointer UniformConstant %type_image - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %type_sampled_image = OpTypeSampledImage %type_image - %type_struct = OpTypeStruct %uint %v4float - - %int_1 = OpConstant %int 1 - %float_0 = OpConstant %float 0 - %float_1 = OpConstant %float 1 - %8 = OpConstantComposite %v2float %float_0 %float_0 - %12 = OpConstantComposite %v2int %int_1 %int_1 - - %2 = OpVariable %ptr_sampler UniformConstant - %3 = OpVariable %ptr_image UniformConstant - %27 = OpTypeFunction %void - %1 = OpFunction %void None %27 - %28 = OpLabel - %29 = OpLoad %type_image %3 - %30 = OpLoad %type_sampler %2 - %31 = OpSampledImage %type_sampled_image %29 %30 - %32 = OpImageSparseSampleImplicitLod %type_struct %31 %8 ConstOffset|MinLod %12 %float_0 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointer_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer Input %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointer_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer Input %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %array = OpTypeArray %half %uint_1 - %ptr = OpTypePointer Input %array - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %array = OpTypeArray %half %uint_1 - %ptr = OpTypePointer Input %array - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Input %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Input %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %float = OpTypeFloat 32 - %struct = OpTypeStruct %float %half - %parent = OpTypeStruct %float %struct - %ptr = OpTypePointer Input %parent - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %float = OpTypeFloat 32 - %struct = OpTypeStruct %float %half - %parent = OpTypeStruct %float %struct - %ptr = OpTypePointer Input %parent - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %array = OpTypeArray %struct %uint_1 - %ptr = OpTypePointer Input %array - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %array = OpTypeArray %struct %uint_1 - %ptr = OpTypePointer Input %array - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %vector = OpTypeVector %half 4 - %ptr = OpTypePointer Input %vector - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %vector = OpTypeVector %half 4 - %ptr = OpTypePointer Input %vector - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %vector = OpTypeVector %half 4 - %matrix = OpTypeMatrix %vector 4 - %ptr = OpTypePointer Input %matrix - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %vector = OpTypeVector %half 4 - %matrix = OpTypeMatrix %vector 4 - %ptr = OpTypePointer Input %matrix - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_IsRemovedWithoutInputPointer) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK-NOT: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer Output %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer Output %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageInputOutput16_RemovedWithoutOutputPointer) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageInputOutput16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK-NOT: OpCapability StorageInputOutput16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StoragePushConstant16_RemainsSimplePointer_Vulkan1_0) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StoragePushConstant16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StoragePushConstant16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer PushConstant %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StoragePushConstant16_RemainsSimplePointer_Vulkan1_1) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StoragePushConstant16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK: OpCapability StoragePushConstant16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer PushConstant %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, StoragePushConstant16_RemovedSimplePointer) { - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StoragePushConstant16 - OpExtension "SPV_KHR_16bit_storage" -; CHECK-NOT: OpCapability StoragePushConstant16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %ptr = OpTypePointer Function %half - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_0) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - OpDecorate %struct BufferBlock - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_1) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - OpDecorate %struct BufferBlock - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniformBufferBlock16_RemovedSimplePointer) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK-NOT: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Function %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_0) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - static_assert(spv::Capability::StorageUniform16 == - spv::Capability::UniformAndStorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpCapability UniformAndStorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess -; `-> StorageUniform16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - OpDecorate %struct BufferBlock - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_1) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - static_assert(spv::Capability::StorageUniform16 == - spv::Capability::UniformAndStorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpCapability UniformAndStorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess -; `-> StorageUniform16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - OpDecorate %struct BufferBlock - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_0) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - static_assert(spv::Capability::StorageUniform16 == - spv::Capability::UniformAndStorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpCapability UniformAndStorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK-NOT: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK: OpCapability UniformAndStorageBuffer16BitAccess -; `-> StorageUniform16 -; CHECK: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_0); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_1) { - // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354 - static_assert(spv::Capability::StorageUniformBufferBlock16 == - spv::Capability::StorageBuffer16BitAccess); - static_assert(spv::Capability::StorageUniform16 == - spv::Capability::UniformAndStorageBuffer16BitAccess); - - const std::string kTest = R"( - OpCapability Shader - OpCapability Float16 - OpCapability StorageBuffer16BitAccess - OpCapability UniformAndStorageBuffer16BitAccess - OpExtension "SPV_KHR_16bit_storage" - -; CHECK-NOT: OpCapability StorageBuffer16BitAccess -; `-> StorageUniformBufferBlock16 -; CHECK: OpCapability UniformAndStorageBuffer16BitAccess -; `-> StorageUniform16 -; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage" - - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %2 "main" - %void = OpTypeVoid - %half = OpTypeFloat 16 - %struct = OpTypeStruct %half - %ptr = OpTypePointer Uniform %struct - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd - )"; - SetTargetEnv(SPV_ENV_VULKAN_1_1); - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, FragmentShaderInterlock_RemovedIfNotUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderPixelInterlock_RemainsWhenOrderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK: OpCapability FragmentShaderPixelInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main PixelInterlockOrderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderPixelInterlock_RemainsWhenUnorderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK: OpCapability FragmentShaderPixelInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main PixelInterlockUnorderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderSampleInterlock_RemainsWhenOrderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT -; CHECK: OpCapability FragmentShaderSampleInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main SampleInterlockOrderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderSampleInterlock_RemainsWhenUnorderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT -; CHECK: OpCapability FragmentShaderSampleInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main SampleInterlockUnorderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderShadingRateInterlock_RemainsWhenOrderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT -; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main ShadingRateInterlockOrderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - FragmentShaderShadingRateInterlock_RemainsWhenUnorderedIsUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability FragmentShaderPixelInterlockEXT - OpCapability FragmentShaderSampleInterlockEXT - OpCapability FragmentShaderShadingRateInterlockEXT - OpExtension "SPV_EXT_fragment_shader_interlock" -; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT -; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT -; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT -; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %main ShadingRateInterlockUnorderedEXT - %void = OpTypeVoid - %1 = OpTypeFunction %void - %2 = OpFunction %void None %1 - %3 = OpLabel - OpBeginInvocationInterlockEXT - OpEndInvocationInterlockEXT - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, Int64_RemovedWhenUnused) { - const std::string kTest = R"( - OpCapability Int64 -; CHECK-NOT: OpCapability Int64 - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, Int64_RemainsWhenUsed) { - const std::string kTest = R"( - OpCapability Int64 -; CHECK: OpCapability Int64 - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %int = OpTypeInt 64 0 - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemovedWhenUnused) { - const std::string kTest = R"( - OpCapability Shader - OpCapability RayQueryKHR - OpExtension "SPV_KHR_ray_query" -; CHECK-NOT: OpCapability RayQueryKHR -; CHECK-NOT: OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %main "main" %out_var_TEXCOORD1 - OpSource HLSL 660 - OpName %out_var_TEXCOORD1 "out.var.TEXCOORD1" - OpName %main "main" - OpDecorate %out_var_TEXCOORD1 Flat - OpDecorate %out_var_TEXCOORD1 Location 0 - %uint = OpTypeInt 32 0 - %uint_1234 = OpConstant %uint 1234 -%_ptr_Output_uint = OpTypePointer Output %uint - %void = OpTypeVoid - %7 = OpTypeFunction %void -%out_var_TEXCOORD1 = OpVariable %_ptr_Output_uint Output - %main = OpFunction %void None %7 - %8 = OpLabel - OpStore %out_var_TEXCOORD1 %uint_1234 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - RayQueryKHR_RemainsWhenAccelerationStructureIsPresent) { - const std::string kTest = R"( - OpCapability Shader - OpCapability RayQueryKHR - OpExtension "SPV_KHR_ray_query" -; CHECK: OpCapability RayQueryKHR -; CHECK: OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - OpDecorate %var_bvh DescriptorSet 0 - OpDecorate %var_bvh Binding 0 - %bvh = OpTypeAccelerationStructureKHR - %ptr_bvh = OpTypePointer UniformConstant %bvh - %void = OpTypeVoid - %20 = OpTypeFunction %void - %var_bvh = OpVariable %ptr_bvh UniformConstant - %main = OpFunction %void None %20 - %30 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenRayQueryTypeIsPresent) { - const std::string kTest = R"( - OpCapability Shader - OpCapability RayQueryKHR - OpExtension "SPV_KHR_ray_query" -; CHECK: OpCapability RayQueryKHR -; CHECK: OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - %query = OpTypeRayQueryKHR - %void = OpTypeVoid - %20 = OpTypeFunction %void - %ptr_query = OpTypePointer Function %query - %main = OpFunction %void None %20 - %30 = OpLabel - %var_query = OpVariable %ptr_query Function - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability RayQueryKHR - OpExtension "SPV_KHR_ray_query" -; CHECK: OpCapability RayQueryKHR -; CHECK: OpExtension "SPV_KHR_ray_query" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - OpDecorate %bvh DescriptorSet 0 - OpDecorate %bvh Binding 0 - OpDecorate %output DescriptorSet 0 - OpDecorate %output Binding 1 - OpDecorate %_runtimearr_float ArrayStride 4 - OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0 - OpDecorate %type_RWStructuredBuffer_float BufferBlock - %float = OpTypeFloat 32 - %float_0 = OpConstant %float 0 - %int = OpTypeInt 32 1 - %v3float = OpTypeVector %float 3 - %12 = OpConstantComposite %v3float %float_0 %float_0 %float_0 - %int_0 = OpConstant %int 0 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 -%accelerationStructureKHR = OpTypeAccelerationStructureKHR -%_ptr_UniformConstant_accelerationStructureKHR = OpTypePointer UniformConstant %accelerationStructureKHR -%_runtimearr_float = OpTypeRuntimeArray %float -%type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float -%_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float - %void = OpTypeVoid - %20 = OpTypeFunction %void -%rayQueryKHR = OpTypeRayQueryKHR -%_ptr_Function_rayQueryKHR = OpTypePointer Function %rayQueryKHR - %bool = OpTypeBool -%_ptr_Uniform_float = OpTypePointer Uniform %float - %bvh = OpVariable %_ptr_UniformConstant_accelerationStructureKHR UniformConstant - %output = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform - %main = OpFunction %void None %20 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_rayQueryKHR Function - %26 = OpLoad %accelerationStructureKHR %bvh - OpRayQueryInitializeKHR %25 %26 %uint_0 %uint_0 %12 %float_0 %12 %float_0 - %27 = OpRayQueryProceedKHR %bool %25 - %28 = OpRayQueryGetIntersectionTypeKHR %uint %25 %uint_1 - %29 = OpIEqual %bool %28 %uint_1 - OpSelectionMerge %30 None - OpBranchConditional %29 %31 %30 - %31 = OpLabel - %32 = OpAccessChain %_ptr_Uniform_float %output %int_0 %uint_0 - OpStore %32 %float_0 - OpBranch %30 - %30 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - RayTracingKHR_RemainsWithIntersectionExecutionMode) { - const std::string kTest = R"( - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint IntersectionKHR %main "main" - OpSource HLSL 660 - OpName %main "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %4 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - RayTracingKHR_RemainsWithClosestHitExecutionMode) { - const std::string kTest = R"( - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint ClosestHitKHR %main "main" %a - OpSource HLSL 630 - OpName %Payload "Payload" - OpMemberName %Payload 0 "color" - OpName %a "a" - OpName %main "main" - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %Payload = OpTypeStruct %v4float -%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload - %void = OpTypeVoid - %8 = OpTypeFunction %void - %a = OpVariable %ptr_payload IncomingRayPayloadKHR - %main = OpFunction %void None %8 - %9 = OpLabel - %10 = OpLoad %Payload %a - OpStore %a %10 - OpReturn - OpFunctionEnd - - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithAnyHitExecutionMode) { - const std::string kTest = R"( - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint AnyHitKHR %main "main" %a - OpSource HLSL 630 - OpName %Payload "Payload" - OpMemberName %Payload 0 "color" - OpName %a "a" - OpName %main "main" - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %Payload = OpTypeStruct %v4float -%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload - %void = OpTypeVoid - %8 = OpTypeFunction %void - %a = OpVariable %ptr_payload IncomingRayPayloadKHR - %main = OpFunction %void None %8 - %9 = OpLabel - %10 = OpLoad %Payload %a - OpStore %a %10 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithMissExecutionMode) { - const std::string kTest = R"( - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint MissKHR %main "main" %a - OpSource HLSL 630 - OpName %Payload "Payload" - OpMemberName %Payload 0 "color" - OpName %a "a" - OpName %main "main" - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %Payload = OpTypeStruct %v4float -%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload - %void = OpTypeVoid - %8 = OpTypeFunction %void - %a = OpVariable %ptr_payload IncomingRayPayloadKHR - %main = OpFunction %void None %8 - %9 = OpLabel - %10 = OpLoad %Payload %a - OpStore %a %10 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - RayTracingKHR_RemainsWithRayGenerationExecutionMode) { - const std::string kTest = R"( - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint RayGenerationKHR %main "main" - OpSource HLSL 630 - OpName %main "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %4 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - RayTracingKHR_RemainsWithCallableExecutionMode) { - const std::string kTest = R"( -; CHECK: OpCapability RayTracingKHR -; CHECK: OpExtension "SPV_KHR_ray_tracing" - OpCapability RayTracingKHR - OpExtension "SPV_KHR_ray_tracing" - OpMemoryModel Logical GLSL450 - OpEntryPoint CallableKHR %main "main" %a - OpSource HLSL 660 - OpName %Payload "Payload" - OpMemberName %Payload 0 "data" - OpName %a "a" - OpName %main "main" - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %Payload = OpTypeStruct %v4float -%ptr_payload = OpTypePointer IncomingCallableDataKHR %Payload - %void = OpTypeVoid - %8 = OpTypeFunction %void - %a = OpVariable %ptr_payload IncomingCallableDataKHR - %main = OpFunction %void None %8 - %9 = OpLabel - %10 = OpLoad %Payload %a - OpStore %a %10 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - ImageMSArray_RemainsIfSampledIs2AndArrayedIs1) { - const std::string kTest = R"( - OpCapability ImageMSArray - ; CHECK: OpCapability ImageMSArray - OpCapability Shader - OpCapability StorageImageMultisample - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v2uint = OpTypeVector %u32 2 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 1 1 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v2uint %uint_1 %uint_2 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 Sample %uint_2 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfNotUsed) { - const std::string kTest = R"( - OpCapability Shader - OpCapability ImageMSArray -; CHECK-NOT: OpCapability ImageMSArray - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %out_var_SV_Target - OpExecutionMode %main OriginUpperLeft - OpSource HLSL 660 - OpName %out_var_SV_Target "out.var.SV_Target" - OpName %main "main" - OpDecorate %out_var_SV_Target Location 0 - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %void = OpTypeVoid - %7 = OpTypeFunction %void -%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output - %main = OpFunction %void None %7 - %8 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfArrayedIsNot1) { - const std::string kTest = R"( - OpCapability ImageMSArray - ; CHECK-NOT: OpCapability ImageMSArray - OpCapability Shader - OpCapability StorageImageMultisample - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v2uint = OpTypeVector %u32 2 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 0 1 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v2uint %uint_1 %uint_2 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 Sample %uint_2 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfSampledNot2) { - const std::string kTest = R"( - OpCapability ImageMSArray - ; CHECK-NOT: OpCapability ImageMSArray - OpCapability Shader - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_3 = OpConstant %u32 3 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v3uint = OpTypeVector %u32 3 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 1 0 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, Float64_RemovedWhenUnused) { - const std::string kTest = R"( - OpCapability Float64 -; CHECK-NOT: OpCapability Float64 - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, Float64_RemainsWhenUsed) { - const std::string kTest = R"( - OpCapability Float64 -; CHECK: OpCapability Float64 - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %float = OpTypeFloat 64 - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - ComputeDerivativeGroupQuads_ReamainsWithExecMode) { - const std::string kTest = R"( - OpCapability ComputeDerivativeGroupQuadsNV - OpCapability ComputeDerivativeGroupLinearNV -; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV -; CHECK: OpCapability ComputeDerivativeGroupQuadsNV -; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV - OpCapability Shader -; CHECK: OpExtension "SPV_NV_compute_shader_derivatives" - OpExtension "SPV_NV_compute_shader_derivatives" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 DerivativeGroupQuadsNV - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - ComputeDerivativeGroupLinear_ReamainsWithExecMode) { - const std::string kTest = R"( - OpCapability ComputeDerivativeGroupLinearNV - OpCapability ComputeDerivativeGroupQuadsNV -; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV -; CHECK: OpCapability ComputeDerivativeGroupLinearNV -; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV - OpCapability Shader -; CHECK: OpExtension "SPV_NV_compute_shader_derivatives" - OpExtension "SPV_NV_compute_shader_derivatives" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 DerivativeGroupLinearNV - %void = OpTypeVoid - %float = OpTypeFloat 64 - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageImageReadWithoutFormat_RemovedIfUnused) { - const std::string kTest = R"( - OpCapability StorageImageReadWithoutFormat -; CHECK-NOT: OpCapability StorageImageReadWithoutFormat - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %PSMain "PSMain" %out_var - OpExecutionMode %PSMain OriginUpperLeft - OpDecorate %out_var Location 0 - %float = OpTypeFloat 32 - %float4 = OpTypeVector %float 4 - %float_0 = OpConstant %float 0 -%float4_0000 = OpConstantComposite %float4 %float_0 %float_0 %float_0 %float_0 - %ptr_float4 = OpTypePointer Output %float4 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %out_var = OpVariable %ptr_float4 Output - %PSMain = OpFunction %void None %9 - %10 = OpLabel - OpStore %out_var %float4_0000 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageImageReadWithoutFormat_RemovedIfUnusedOpImageFetch) { - const std::string kTest = R"( - OpCapability StorageImageReadWithoutFormat -; CHECK-NOT: OpCapability StorageImageReadWithoutFormat - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %PSMain "PSMain" %out_var - OpExecutionMode %PSMain OriginUpperLeft - OpDecorate %out_var Location 0 - OpDecorate %texture DescriptorSet 0 - OpDecorate %texture Binding 1 - %float = OpTypeFloat 32 - %float4 = OpTypeVector %float 4 - %int = OpTypeInt 32 1 - %int2 = OpTypeVector %int 2 - %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown - %ptr_image = OpTypePointer UniformConstant %type_image - %int_0 = OpConstant %int 0 - %int2_00 = OpConstantComposite %int2 %int_0 %int_0 - %ptr_float4 = OpTypePointer Output %float4 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %texture = OpVariable %ptr_image UniformConstant - %out_var = OpVariable %ptr_float4 Output - %PSMain = OpFunction %void None %9 - %10 = OpLabel - %11 = OpLoad %type_image %texture - %12 = OpImageFetch %float4 %11 %int2_00 Lod %int_0 - OpStore %out_var %12 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageImageReadWithoutFormat_RemainsWhenRequiredWithRead) { - const std::string kTest = R"( - OpCapability StorageImageReadWithoutFormat -; CHECK: OpCapability StorageImageReadWithoutFormat - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %PSMain "PSMain" %out_var - OpExecutionMode %PSMain OriginUpperLeft - OpDecorate %out_var Location 0 - OpDecorate %texture DescriptorSet 0 - OpDecorate %texture Binding 1 - %float = OpTypeFloat 32 - %float4 = OpTypeVector %float 4 - %int = OpTypeInt 32 1 - %int2 = OpTypeVector %int 2 - %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown - %ptr_image = OpTypePointer UniformConstant %type_image - %int_0 = OpConstant %int 0 - %int2_00 = OpConstantComposite %int2 %int_0 %int_0 - %ptr_float4 = OpTypePointer Output %float4 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %texture = OpVariable %ptr_image UniformConstant - %out_var = OpVariable %ptr_float4 Output - %PSMain = OpFunction %void None %9 - %10 = OpLabel - %11 = OpLoad %type_image %texture - %12 = OpImageRead %float4 %11 %int2_00 Lod %int_0 - OpStore %out_var %12 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageImageReadWithoutFormat_RemainsWhenRequiredWithSparseRead) { - const std::string kTest = R"( - OpCapability StorageImageReadWithoutFormat -; CHECK: OpCapability StorageImageReadWithoutFormat - OpCapability SparseResidency - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %PSMain "PSMain" - OpExecutionMode %PSMain OriginUpperLeft - OpDecorate %texture DescriptorSet 0 - OpDecorate %texture Binding 1 - %float = OpTypeFloat 32 - %float4 = OpTypeVector %float 4 - %int = OpTypeInt 32 1 - %int2 = OpTypeVector %int 2 - %type_image = OpTypeImage %float 2D 2 0 0 2 Unknown - %struct = OpTypeStruct %int %float4 - %ptr_image = OpTypePointer UniformConstant %type_image - %int_0 = OpConstant %int 0 - %int2_00 = OpConstantComposite %int2 %int_0 %int_0 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %texture = OpVariable %ptr_image UniformConstant - %PSMain = OpFunction %void None %9 - %10 = OpLabel - %11 = OpLoad %type_image %texture - %12 = OpImageSparseRead %struct %11 %int2_00 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - StorageImageReadWithoutFormat_RemovedWithReadOnSubpassData) { - const std::string kTest = R"( - OpCapability StorageImageReadWithoutFormat -; CHECK-NOT: OpCapability StorageImageReadWithoutFormat - OpCapability InputAttachment - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %PSMain "PSMain" %out_var - OpExecutionMode %PSMain OriginUpperLeft - OpDecorate %out_var Location 0 - OpDecorate %texture DescriptorSet 0 - OpDecorate %texture Binding 1 - %float = OpTypeFloat 32 - %float4 = OpTypeVector %float 4 - %int = OpTypeInt 32 1 - %int2 = OpTypeVector %int 2 - %type_image = OpTypeImage %float SubpassData 2 0 0 2 Unknown - %ptr_image = OpTypePointer UniformConstant %type_image - %int_0 = OpConstant %int 0 - %int2_00 = OpConstantComposite %int2 %int_0 %int_0 - %ptr_float4 = OpTypePointer Output %float4 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %texture = OpVariable %ptr_image UniformConstant - %out_var = OpVariable %ptr_float4 Output - %PSMain = OpFunction %void None %9 - %10 = OpLabel - %11 = OpLoad %type_image %texture - %12 = OpImageRead %float4 %11 %int2_00 - OpStore %out_var %12 - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) { - const std::string kTest = R"( - OpCapability PhysicalStorageBufferAddresses -; CHECK-NOT: OpCapability PhysicalStorageBufferAddresses - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %1 = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); -} - -TEST_F(TrimCapabilitiesPassTest, - PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer) { - const std::string kTest = R"( - OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability PhysicalStorageBufferAddresses - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - %void = OpTypeVoid - %int = OpTypeInt 32 0 - %struct = OpTypeStruct %int - OpTypeForwardPointer %ptr PhysicalStorageBuffer - %ptr = OpTypePointer PhysicalStorageBuffer %struct - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage) { - const std::string kTest = R"( - OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability PhysicalStorageBufferAddresses - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - %void = OpTypeVoid - %int = OpTypeInt 32 0 - %struct = OpTypeStruct %int - %ptr = OpTypePointer PhysicalStorageBuffer %struct - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %6 = OpLabel - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - PhysicalStorageBuffer_RemainsWithRestrictDecoration) { - const std::string kTest = R"( - OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability PhysicalStorageBufferAddresses - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - OpDecorate %var RestrictPointer - %void = OpTypeVoid - %int = OpTypeInt 32 0 - %struct = OpTypeStruct %int - %ptr = OpTypePointer Function %struct - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %6 = OpLabel - %var = OpVariable %ptr Function - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -TEST_F(TrimCapabilitiesPassTest, - PhysicalStorageBuffer_RemainsWithAliasedDecoration) { - const std::string kTest = R"( - OpCapability PhysicalStorageBufferAddresses -; CHECK: OpCapability PhysicalStorageBufferAddresses - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 2 4 - OpDecorate %var AliasedPointer - %void = OpTypeVoid - %int = OpTypeInt 32 0 - %struct = OpTypeStruct %int - %ptr = OpTypePointer Function %struct - %3 = OpTypeFunction %void - %main = OpFunction %void None %3 - %6 = OpLabel - %var = OpVariable %ptr Function - OpReturn - OpFunctionEnd; - )"; - const auto result = - SinglePassRunAndMatch(kTest, /* skip_nop= */ false); - EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/type_manager_test.cpp b/test/opt/type_manager_test.cpp index cb301711..df216bc9 100644 --- a/test/opt/type_manager_test.cpp +++ b/test/opt/type_manager_test.cpp @@ -12,9 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "source/opt/type_manager.h" - #include +#include #include #include @@ -23,6 +22,7 @@ #include "gtest/gtest.h" #include "source/opt/build_module.h" #include "source/opt/instruction.h" +#include "source/opt/type_manager.h" #include "spirv-tools/libspirv.hpp" namespace spvtools { @@ -98,19 +98,15 @@ std::vector> GenerateAllTypes() { types.emplace_back(new Matrix(v3f32, 4)); // Images - types.emplace_back(new Image(s32, spv::Dim::Dim2D, 0, 0, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); + types.emplace_back(new Image(s32, SpvDim2D, 0, 0, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); auto* image1 = types.back().get(); - types.emplace_back(new Image(s32, spv::Dim::Dim2D, 0, 1, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); - types.emplace_back(new Image(s32, spv::Dim::Dim3D, 0, 1, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); - types.emplace_back(new Image(voidt, spv::Dim::Dim3D, 0, 1, 0, 1, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadWrite)); + types.emplace_back(new Image(s32, SpvDim2D, 0, 1, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); + types.emplace_back(new Image(s32, SpvDim3D, 0, 1, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); + types.emplace_back(new Image(voidt, SpvDim3D, 0, 1, 0, 1, SpvImageFormatRg8, + SpvAccessQualifierReadWrite)); auto* image2 = types.back().get(); // Sampler @@ -144,9 +140,9 @@ std::vector> GenerateAllTypes() { types.emplace_back(new Opaque("world")); // Pointer - types.emplace_back(new Pointer(f32, spv::StorageClass::Input)); - types.emplace_back(new Pointer(sts32f32, spv::StorageClass::Function)); - types.emplace_back(new Pointer(a42f32, spv::StorageClass::Function)); + types.emplace_back(new Pointer(f32, SpvStorageClassInput)); + types.emplace_back(new Pointer(sts32f32, SpvStorageClassFunction)); + types.emplace_back(new Pointer(a42f32, SpvStorageClassFunction)); // Function types.emplace_back(new Function(voidt, {})); @@ -162,18 +158,16 @@ std::vector> GenerateAllTypes() { // Pipe, Forward Pointer, PipeStorage, NamedBarrier, AccelerationStructureNV, // CooperativeMatrixNV - types.emplace_back(new Pipe(spv::AccessQualifier::ReadWrite)); - types.emplace_back(new Pipe(spv::AccessQualifier::ReadOnly)); - types.emplace_back(new ForwardPointer(1, spv::StorageClass::Input)); - types.emplace_back(new ForwardPointer(2, spv::StorageClass::Input)); - types.emplace_back(new ForwardPointer(2, spv::StorageClass::Uniform)); + types.emplace_back(new Pipe(SpvAccessQualifierReadWrite)); + types.emplace_back(new Pipe(SpvAccessQualifierReadOnly)); + types.emplace_back(new ForwardPointer(1, SpvStorageClassInput)); + types.emplace_back(new ForwardPointer(2, SpvStorageClassInput)); + types.emplace_back(new ForwardPointer(2, SpvStorageClassUniform)); types.emplace_back(new PipeStorage()); types.emplace_back(new NamedBarrier()); types.emplace_back(new AccelerationStructureNV()); types.emplace_back(new CooperativeMatrixNV(f32, 24, 24, 24)); - types.emplace_back(new CooperativeMatrixKHR(f32, 8, 8, 8, 1002)); types.emplace_back(new RayQueryKHR()); - types.emplace_back(new HitObjectNV()); return types; } @@ -238,8 +232,6 @@ TEST(TypeManager, TypeStrings) { %arr_long_constant = OpTypeArray %s32 %long_constant %arr_spec_const_op = OpTypeArray %s32 %spec_const_op %cm = OpTypeCooperativeMatrixNV %f64 %id4 %id4 %id4 - %id2 = OpConstant %u32 2 - %cmkhr = OpTypeCooperativeMatrixKHR %f64 %id4 %id4 %id4 %id2 )"; std::vector> type_id_strs = { @@ -278,7 +270,6 @@ TEST(TypeManager, TypeStrings) { {37, "[sint32, id(33), words(0,705032704,1)]"}, {38, "[sint32, id(34), words(2,34)]"}, {39, ""}, - {41, ""}, }; std::unique_ptr context = @@ -823,22 +814,22 @@ OpMemoryModel Logical GLSL450 EXPECT_NE(context, nullptr); Integer u32(32, false); - Pointer u32Ptr(&u32, spv::StorageClass::Function); + Pointer u32Ptr(&u32, SpvStorageClassFunction); Struct st({&u32}); - Pointer stPtr(&st, spv::StorageClass::Input); + Pointer stPtr(&st, SpvStorageClassInput); auto pair = context->get_type_mgr()->GetTypeAndPointerType( - 3u, spv::StorageClass::Function); + 3u, SpvStorageClassFunction); ASSERT_EQ(nullptr, pair.first); ASSERT_EQ(nullptr, pair.second); pair = context->get_type_mgr()->GetTypeAndPointerType( - 1u, spv::StorageClass::Function); + 1u, SpvStorageClassFunction); ASSERT_TRUE(pair.first->IsSame(&u32)); ASSERT_TRUE(pair.second->IsSame(&u32Ptr)); - pair = context->get_type_mgr()->GetTypeAndPointerType( - 2u, spv::StorageClass::Input); + pair = + context->get_type_mgr()->GetTypeAndPointerType(2u, SpvStorageClassInput); ASSERT_TRUE(pair.first->IsSame(&st)); ASSERT_TRUE(pair.second->IsSame(&stPtr)); } @@ -944,15 +935,12 @@ OpMemoryModel Logical GLSL450 std::vector> types = GenerateAllTypes(); uint32_t id = 1u; for (auto& t : types) { - std::cout << ". id " << id << std::endl; context->get_type_mgr()->RegisterType(id, *t); EXPECT_EQ(*t, *context->get_type_mgr()->GetType(id)); } - std::cout << "clear" << id << std::endl; types.clear(); for (; id > 0; --id) { - std::cout << ". remove id " << id << std::endl; context->get_type_mgr()->RemoveId(id); EXPECT_EQ(nullptr, context->get_type_mgr()->GetType(id)); } @@ -1037,8 +1025,6 @@ TEST(TypeManager, GetTypeInstructionAllTypes) { ; CHECK: [[uint:%\w+]] = OpTypeInt 32 0 ; CHECK: [[input_ptr:%\w+]] = OpTypePointer Input [[uint]] ; CHECK: [[uniform_ptr:%\w+]] = OpTypePointer Uniform [[uint]] -; CHECK: [[uint2:%\w+]] = OpConstant [[uint]] 2 -; CHECK: [[uint8:%\w+]] = OpConstant [[uint]] 8 ; CHECK: [[uint24:%\w+]] = OpConstant [[uint]] 24 ; CHECK: [[uint42:%\w+]] = OpConstant [[uint]] 42 ; CHECK: [[uint100:%\w+]] = OpConstant [[uint]] 100 @@ -1094,9 +1080,7 @@ TEST(TypeManager, GetTypeInstructionAllTypes) { ; CHECK: OpTypeNamedBarrier ; CHECK: OpTypeAccelerationStructureKHR ; CHECK: OpTypeCooperativeMatrixNV [[f32]] [[uint24]] [[uint24]] [[uint24]] -; CHECK: OpTypeCooperativeMatrixKHR [[f32]] [[uint8]] [[uint8]] [[uint8]] [[uint2]] ; CHECK: OpTypeRayQueryKHR -; CHECK: OpTypeHitObjectNV OpCapability Shader OpCapability Int64 OpCapability Linkage @@ -1104,8 +1088,6 @@ OpMemoryModel Logical GLSL450 %uint = OpTypeInt 32 0 %1 = OpTypePointer Input %uint %2 = OpTypePointer Uniform %uint -%1002 = OpConstant %uint 2 -%8 = OpConstant %uint 8 %24 = OpConstant %uint 24 %42 = OpConstant %uint 42 %100 = OpConstant %uint 100 @@ -1173,7 +1155,7 @@ OpMemoryModel Logical GLSL450 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); EXPECT_NE(context, nullptr); - context->get_type_mgr()->FindPointerToType(1, spv::StorageClass::Function); + context->get_type_mgr()->FindPointerToType(1, SpvStorageClassFunction); Match(text, context.get()); } @@ -1198,7 +1180,7 @@ OpMemoryModel Logical GLSL450 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); EXPECT_NE(context, nullptr); - context->get_type_mgr()->FindPointerToType(2, spv::StorageClass::Function); + context->get_type_mgr()->FindPointerToType(2, SpvStorageClassFunction); Match(text, context.get()); } diff --git a/test/opt/types_test.cpp b/test/opt/types_test.cpp index 4ceeb140..552ad97c 100644 --- a/test/opt/types_test.cpp +++ b/test/opt/types_test.cpp @@ -34,9 +34,9 @@ class SameTypeTest : public ::testing::Test { u32_t_ = MakeUnique(32, false); f64_t_ = MakeUnique(64); v3u32_t_ = MakeUnique(u32_t_.get(), 3); - image_t_ = MakeUnique(f64_t_.get(), spv::Dim::Dim2D, 1, 1, 0, 0, - spv::ImageFormat::R16, - spv::AccessQualifier::ReadWrite); + image_t_ = + MakeUnique(f64_t_.get(), SpvDim2D, 1, 1, 0, 0, SpvImageFormatR16, + SpvAccessQualifierReadWrite); } // Element types to be used for constructing other types for testing. @@ -72,9 +72,9 @@ TestMultipleInstancesOfTheSameType(Integer, 32, true) TestMultipleInstancesOfTheSameType(Float, 64) TestMultipleInstancesOfTheSameType(Vector, u32_t_.get(), 3) TestMultipleInstancesOfTheSameType(Matrix, v3u32_t_.get(), 4) -TestMultipleInstancesOfTheSameType(Image, f64_t_.get(), spv::Dim::Cube, 0, 0, 1, 1, - spv::ImageFormat::Rgb10A2, - spv::AccessQualifier::WriteOnly) +TestMultipleInstancesOfTheSameType(Image, f64_t_.get(), SpvDimCube, 0, 0, 1, 1, + SpvImageFormatRgb10A2, + SpvAccessQualifierWriteOnly) TestMultipleInstancesOfTheSameType(Sampler) TestMultipleInstancesOfTheSameType(SampledImage, image_t_.get()) // There are three classes of arrays, based on the kinds of length information @@ -98,15 +98,15 @@ TestMultipleInstancesOfTheSameType(RuntimeArray, u32_t_.get()) TestMultipleInstancesOfTheSameType(Struct, std::vector{ u32_t_.get(), f64_t_.get()}) TestMultipleInstancesOfTheSameType(Opaque, "testing rocks") -TestMultipleInstancesOfTheSameType(Pointer, u32_t_.get(), spv::StorageClass::Input) +TestMultipleInstancesOfTheSameType(Pointer, u32_t_.get(), SpvStorageClassInput) TestMultipleInstancesOfTheSameType(Function, u32_t_.get(), {f64_t_.get(), f64_t_.get()}) TestMultipleInstancesOfTheSameType(Event) TestMultipleInstancesOfTheSameType(DeviceEvent) TestMultipleInstancesOfTheSameType(ReserveId) TestMultipleInstancesOfTheSameType(Queue) -TestMultipleInstancesOfTheSameType(Pipe, spv::AccessQualifier::ReadWrite) -TestMultipleInstancesOfTheSameType(ForwardPointer, 10, spv::StorageClass::Uniform) +TestMultipleInstancesOfTheSameType(Pipe, SpvAccessQualifierReadWrite) +TestMultipleInstancesOfTheSameType(ForwardPointer, 10, SpvStorageClassUniform) TestMultipleInstancesOfTheSameType(PipeStorage) TestMultipleInstancesOfTheSameType(NamedBarrier) TestMultipleInstancesOfTheSameType(AccelerationStructureNV) @@ -119,8 +119,8 @@ std::vector> GenerateAllTypes() { std::vector> types; // Forward Pointer - types.emplace_back(new ForwardPointer(10000, spv::StorageClass::Input)); - types.emplace_back(new ForwardPointer(20000, spv::StorageClass::Input)); + types.emplace_back(new ForwardPointer(10000, SpvStorageClassInput)); + types.emplace_back(new ForwardPointer(20000, SpvStorageClassInput)); // Void, Bool types.emplace_back(new Void()); @@ -155,19 +155,15 @@ std::vector> GenerateAllTypes() { types.emplace_back(new Matrix(v3f32, 4)); // Images - types.emplace_back(new Image(s32, spv::Dim::Dim2D, 0, 0, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); + types.emplace_back(new Image(s32, SpvDim2D, 0, 0, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); auto* image1 = types.back().get(); - types.emplace_back(new Image(s32, spv::Dim::Dim2D, 0, 1, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); - types.emplace_back(new Image(s32, spv::Dim::Dim3D, 0, 1, 0, 0, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadOnly)); - types.emplace_back(new Image(voidt, spv::Dim::Dim3D, 0, 1, 0, 1, - spv::ImageFormat::Rg8, - spv::AccessQualifier::ReadWrite)); + types.emplace_back(new Image(s32, SpvDim2D, 0, 1, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); + types.emplace_back(new Image(s32, SpvDim3D, 0, 1, 0, 0, SpvImageFormatRg8, + SpvAccessQualifierReadOnly)); + types.emplace_back(new Image(voidt, SpvDim3D, 0, 1, 0, 1, SpvImageFormatRg8, + SpvAccessQualifierReadWrite)); auto* image2 = types.back().get(); // Sampler @@ -222,10 +218,10 @@ std::vector> GenerateAllTypes() { types.emplace_back(new Opaque("world")); // Pointer - types.emplace_back(new Pointer(f32, spv::StorageClass::Input)); - types.emplace_back(new Pointer(sts32f32, spv::StorageClass::Function)); - types.emplace_back(new Pointer(a42f32, spv::StorageClass::Function)); - types.emplace_back(new Pointer(voidt, spv::StorageClass::Function)); + types.emplace_back(new Pointer(f32, SpvStorageClassInput)); + types.emplace_back(new Pointer(sts32f32, SpvStorageClassFunction)); + types.emplace_back(new Pointer(a42f32, SpvStorageClassFunction)); + types.emplace_back(new Pointer(voidt, SpvStorageClassFunction)); // Function types.emplace_back(new Function(voidt, {})); @@ -240,11 +236,11 @@ std::vector> GenerateAllTypes() { types.emplace_back(new Queue()); // Pipe, Forward Pointer, PipeStorage, NamedBarrier - types.emplace_back(new Pipe(spv::AccessQualifier::ReadWrite)); - types.emplace_back(new Pipe(spv::AccessQualifier::ReadOnly)); - types.emplace_back(new ForwardPointer(1, spv::StorageClass::Input)); - types.emplace_back(new ForwardPointer(2, spv::StorageClass::Input)); - types.emplace_back(new ForwardPointer(2, spv::StorageClass::Uniform)); + types.emplace_back(new Pipe(SpvAccessQualifierReadWrite)); + types.emplace_back(new Pipe(SpvAccessQualifierReadOnly)); + types.emplace_back(new ForwardPointer(1, SpvStorageClassInput)); + types.emplace_back(new ForwardPointer(2, SpvStorageClassInput)); + types.emplace_back(new ForwardPointer(2, SpvStorageClassUniform)); types.emplace_back(new PipeStorage()); types.emplace_back(new NamedBarrier()); @@ -391,13 +387,18 @@ TEST(Types, IsUniqueType) { case Type::kArray: case Type::kRuntimeArray: case Type::kStruct: - case Type::kPointer: expectation = false; break; default: break; } - EXPECT_EQ(t->IsUniqueType(), expectation) + EXPECT_EQ(t->IsUniqueType(false), expectation) + << "expected '" << t->str() << "' to be a " + << (expectation ? "" : "non-") << "unique type"; + + // Allowing variables pointers. + if (t->AsPointer()) expectation = false; + EXPECT_EQ(t->IsUniqueType(true), expectation) << "expected '" << t->str() << "' to be a " << (expectation ? "" : "non-") << "unique type"; } diff --git a/test/opt/upgrade_memory_model_test.cpp b/test/opt/upgrade_memory_model_test.cpp index d213b8be..2cd3c7df 100644 --- a/test/opt/upgrade_memory_model_test.cpp +++ b/test/opt/upgrade_memory_model_test.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include "assembly_builder.h" +#include "gmock/gmock.h" #include "pass_fixture.h" #include "pass_utils.h" diff --git a/test/opt/value_table_test.cpp b/test/opt/value_table_test.cpp index 3d7aaad5..c760f985 100644 --- a/test/opt/value_table_test.cpp +++ b/test/opt/value_table_test.cpp @@ -17,6 +17,7 @@ #include "gmock/gmock.h" #include "source/opt/build_module.h" #include "source/opt/value_number_table.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" namespace spvtools { diff --git a/test/opt/workaround1209_test.cpp b/test/opt/workaround1209_test.cpp index 5b0146b9..50d3c091 100644 --- a/test/opt/workaround1209_test.cpp +++ b/test/opt/workaround1209_test.cpp @@ -12,9 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include +#include #include #include +#include "gmock/gmock.h" +#include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/opt/wrap_opkill_test.cpp b/test/opt/wrap_opkill_test.cpp index efc834cf..e40d701f 100644 --- a/test/opt/wrap_opkill_test.cpp +++ b/test/opt/wrap_opkill_test.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gmock/gmock.h" #include "test/opt/assembly_builder.h" #include "test/opt/pass_fixture.h" #include "test/opt/pass_utils.h" diff --git a/test/reduce/reducer_test.cpp b/test/reduce/reducer_test.cpp index 019e14ec..276aedc8 100644 --- a/test/reduce/reducer_test.cpp +++ b/test/reduce/reducer_test.cpp @@ -222,7 +222,7 @@ TEST(ReducerTest, ExprToConstantAndRemoveUnreferenced) { } bool InterestingWhileOpcodeExists(const std::vector& binary, - spv::Op opcode, uint32_t count, bool dump) { + uint32_t opcode, uint32_t count, bool dump) { if (dump) { std::stringstream ss; ss << "temp_" << count << ".spv"; @@ -238,7 +238,7 @@ bool InterestingWhileOpcodeExists(const std::vector& binary, &*function.begin(), [opcode, &interesting](opt::BasicBlock* block) -> void { for (auto& inst : *block) { - if (inst.opcode() == spv::Op(opcode)) { + if (inst.opcode() == opcode) { interesting = true; break; } @@ -253,12 +253,12 @@ bool InterestingWhileOpcodeExists(const std::vector& binary, bool InterestingWhileIMulReachable(const std::vector& binary, uint32_t count) { - return InterestingWhileOpcodeExists(binary, spv::Op::OpIMul, count, false); + return InterestingWhileOpcodeExists(binary, SpvOpIMul, count, false); } bool InterestingWhileSDivReachable(const std::vector& binary, uint32_t count) { - return InterestingWhileOpcodeExists(binary, spv::Op::OpSDiv, count, false); + return InterestingWhileOpcodeExists(binary, SpvOpSDiv, count, false); } // The shader below was derived from the following GLSL, and optimized. diff --git a/test/reduce/validation_during_reduction_test.cpp b/test/reduce/validation_during_reduction_test.cpp index 8cf14a3c..d8643449 100644 --- a/test/reduce/validation_during_reduction_test.cpp +++ b/test/reduce/validation_during_reduction_test.cpp @@ -67,7 +67,7 @@ class OpVariableDuplicatorReductionOpportunity : public ReductionOpportunity { bool PreconditionHolds() override { Instruction* first_instruction = &*function_->begin()[0].begin(); - return first_instruction->opcode() == spv::Op::OpVariable; + return first_instruction->opcode() == SpvOpVariable; } protected: @@ -75,7 +75,7 @@ class OpVariableDuplicatorReductionOpportunity : public ReductionOpportunity { // Duplicate the first OpVariable instruction. Instruction* first_instruction = &*function_->begin()[0].begin(); - assert(first_instruction->opcode() == spv::Op::OpVariable && + assert(first_instruction->opcode() == SpvOpVariable && "Expected first instruction to be OpVariable"); IRContext* context = first_instruction->context(); Instruction* cloned_instruction = first_instruction->Clone(context); @@ -105,7 +105,7 @@ class OpVariableDuplicatorReductionOpportunityFinder std::vector> result; for (auto& function : *context->module()) { Instruction* first_instruction = &*function.begin()[0].begin(); - if (first_instruction->opcode() == spv::Op::OpVariable) { + if (first_instruction->opcode() == SpvOpVariable) { result.push_back( MakeUnique(&function)); } @@ -523,7 +523,7 @@ TEST(ValidationDuringReductionTest, CheckValidationOptions) { OpFunctionEnd )"; - spv_target_env env = SPV_ENV_VULKAN_1_0; + spv_target_env env = SPV_ENV_UNIVERSAL_1_3; std::vector binary_in; SpirvTools t(env); diff --git a/test/text_to_binary.annotation_test.cpp b/test/text_to_binary.annotation_test.cpp index 826812bf..76776de9 100644 --- a/test/text_to_binary.annotation_test.cpp +++ b/test/text_to_binary.annotation_test.cpp @@ -41,7 +41,7 @@ using ::testing::ValuesIn; using OpDecorateSimpleTest = spvtest::TextToBinaryTestBase<::testing::TestWithParam< - std::tuple>>>; + std::tuple>>>; TEST_P(OpDecorateSimpleTest, AnySimpleDecoration) { // This string should assemble, but should not validate. @@ -51,7 +51,7 @@ TEST_P(OpDecorateSimpleTest, AnySimpleDecoration) { input << " " << operand; input << std::endl; EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())), - Eq(MakeInstruction(spv::Op::OpDecorate, + Eq(MakeInstruction(SpvOpDecorate, {1, uint32_t(std::get<1>(GetParam()).value())}, std::get<1>(GetParam()).operands()))); // Also check disassembly. @@ -64,7 +64,7 @@ TEST_P(OpDecorateSimpleTest, AnySimpleDecoration) { // Like above, but parameters to the decoration are IDs. using OpDecorateSimpleIdTest = spvtest::TextToBinaryTestBase<::testing::TestWithParam< - std::tuple>>>; + std::tuple>>>; TEST_P(OpDecorateSimpleIdTest, AnySimpleDecoration) { // This string should assemble, but should not validate. @@ -74,7 +74,7 @@ TEST_P(OpDecorateSimpleIdTest, AnySimpleDecoration) { input << " %" << operand; input << std::endl; EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())), - Eq(MakeInstruction(spv::Op::OpDecorateId, + Eq(MakeInstruction(SpvOpDecorateId, {1, uint32_t(std::get<1>(GetParam()).value())}, std::get<1>(GetParam()).operands()))); // Also check disassembly. @@ -84,11 +84,11 @@ TEST_P(OpDecorateSimpleIdTest, AnySimpleDecoration) { Eq(input.str())); } -#define CASE(NAME) spv::Decoration::NAME, #NAME +#define CASE(NAME) SpvDecoration##NAME, #NAME INSTANTIATE_TEST_SUITE_P( TextToBinaryDecorateSimple, OpDecorateSimpleTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ // The operand literal values are arbitrarily chosen, // but there are the right number of them. {CASE(RelaxedPrecision), {}}, @@ -134,24 +134,23 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleV11, OpDecorateSimpleTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), - Values(EnumCase{ + Values(EnumCase{ CASE(MaxByteOffset), {128}}))); -INSTANTIATE_TEST_SUITE_P( - TextToBinaryDecorateSimpleV14, OpDecorateSimpleTest, - Combine(Values(SPV_ENV_UNIVERSAL_1_4), - ValuesIn(std::vector>{ - {CASE(Uniform), {}}, - }))); +INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleV14, OpDecorateSimpleTest, + Combine(Values(SPV_ENV_UNIVERSAL_1_4), + ValuesIn(std::vector>{ + {CASE(Uniform), {}}, + }))); -INSTANTIATE_TEST_SUITE_P( - TextToBinaryDecorateSimpleIdV14, OpDecorateSimpleIdTest, - Combine(Values(SPV_ENV_UNIVERSAL_1_4), - ValuesIn(std::vector>{ - // In 1.4, UniformId decoration takes a - // scope Id. - {CASE(UniformId), {1}}, - }))); +INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleIdV14, + OpDecorateSimpleIdTest, + Combine(Values(SPV_ENV_UNIVERSAL_1_4), + ValuesIn(std::vector>{ + // In 1.4, UniformId decoration takes a + // scope Id. + {CASE(UniformId), {1}}, + }))); #undef CASE TEST_F(OpDecorateSimpleTest, WrongDecoration) { @@ -196,14 +195,14 @@ TEST_P(OpDecorateEnumTest, AnyEnumDecoration) { const std::string input = "OpDecorate %1 " + GetParam().enum_name + " " + GetParam().name; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpDecorate, {1, GetParam().enum_value, - GetParam().value}))); + Eq(MakeInstruction(SpvOpDecorate, {1, GetParam().enum_value, + GetParam().value}))); } // Test OpDecorate BuiltIn. // clang-format off #define CASE(NAME) \ - { uint32_t(spv::BuiltIn::NAME), #NAME, uint32_t(spv::Decoration::BuiltIn), "BuiltIn" } + { SpvBuiltIn##NAME, #NAME, SpvDecorationBuiltIn, "BuiltIn" } INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateBuiltIn, OpDecorateEnumTest, ::testing::ValuesIn(std::vector{ CASE(Position), @@ -261,7 +260,7 @@ TEST_F(OpDecorateEnumTest, WrongBuiltIn) { // Test OpDecorate FuncParamAttr // clang-format off #define CASE(NAME) \ - { uint32_t(spv::FunctionParameterAttribute::NAME), #NAME, uint32_t(spv::Decoration::FuncParamAttr), "FuncParamAttr" } + { SpvFunctionParameterAttribute##NAME, #NAME, SpvDecorationFuncParamAttr, "FuncParamAttr" } INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFuncParamAttr, OpDecorateEnumTest, ::testing::ValuesIn(std::vector{ CASE(Zext), @@ -284,7 +283,7 @@ TEST_F(OpDecorateEnumTest, WrongFuncParamAttr) { // Test OpDecorate FPRoundingMode // clang-format off #define CASE(NAME) \ - { uint32_t(spv::FPRoundingMode::NAME), #NAME, uint32_t(spv::Decoration::FPRoundingMode), "FPRoundingMode" } + { SpvFPRoundingMode##NAME, #NAME, SpvDecorationFPRoundingMode, "FPRoundingMode" } INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFPRoundingMode, OpDecorateEnumTest, ::testing::ValuesIn(std::vector{ CASE(RTE), @@ -307,15 +306,15 @@ TEST_F(OpDecorateEnumTest, WrongFPRoundingMode) { // clang-format off #define CASE(ENUM,NAME) \ - { uint32_t(spv::FPFastMathModeMask::ENUM), #NAME, uint32_t(spv::Decoration::FPFastMathMode), "FPFastMathMode" } + { SpvFPFastMathMode##ENUM, #NAME, SpvDecorationFPFastMathMode, "FPFastMathMode" } INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFPFastMathMode, OpDecorateEnumTest, ::testing::ValuesIn(std::vector{ CASE(MaskNone, None), - CASE(NotNaN, NotNaN), - CASE(NotInf, NotInf), - CASE(NSZ, NSZ), - CASE(AllowRecip, AllowRecip), - CASE(Fast, Fast), + CASE(NotNaNMask, NotNaN), + CASE(NotInfMask, NotInf), + CASE(NSZMask, NSZ), + CASE(AllowRecipMask, AllowRecip), + CASE(FastMask, Fast), })); #undef CASE // clang-format on @@ -324,13 +323,13 @@ TEST_F(OpDecorateEnumTest, CombinedFPFastMathMask) { // Sample a single combination. This ensures we've integrated // the instruction parsing logic with spvTextParseMask. const std::string input = "OpDecorate %1 FPFastMathMode NotNaN|NotInf|NSZ"; - const uint32_t expected_enum = uint32_t(spv::Decoration::FPFastMathMode); - const uint32_t expected_mask = uint32_t(spv::FPFastMathModeMask::NotNaN) | - uint32_t(spv::FPFastMathModeMask::NotInf) | - uint32_t(spv::FPFastMathModeMask::NSZ); - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpDecorate, - {1, expected_enum, expected_mask}))); + const uint32_t expected_enum = SpvDecorationFPFastMathMode; + const uint32_t expected_mask = SpvFPFastMathModeNotNaNMask | + SpvFPFastMathModeNotInfMask | + SpvFPFastMathModeNSZMask; + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpDecorate, {1, expected_enum, expected_mask}))); } TEST_F(OpDecorateEnumTest, WrongFPFastMathMode) { @@ -356,8 +355,7 @@ TEST_P(OpDecorateLinkageTest, AnyLinkageDecoration) { const std::string input = "OpDecorate %1 LinkageAttributes \"" + GetParam().external_name + "\" " + GetParam().linkage_type_name; - std::vector expected_operands{ - 1, uint32_t(spv::Decoration::LinkageAttributes)}; + std::vector expected_operands{1, SpvDecorationLinkageAttributes}; std::vector encoded_external_name = MakeVector(GetParam().external_name); expected_operands.insert(expected_operands.end(), @@ -365,11 +363,11 @@ TEST_P(OpDecorateLinkageTest, AnyLinkageDecoration) { encoded_external_name.end()); expected_operands.push_back(GetParam().linkage_type_value); EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpDecorate, expected_operands))); + Eq(MakeInstruction(SpvOpDecorate, expected_operands))); } // clang-format off -#define CASE(ENUM) uint32_t(spv::LinkageType::ENUM), #ENUM +#define CASE(ENUM) SpvLinkageType##ENUM, #ENUM INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateLinkage, OpDecorateLinkageTest, ::testing::ValuesIn(std::vector{ { CASE(Import), "a" }, @@ -389,13 +387,13 @@ TEST_F(OpDecorateLinkageTest, WrongType) { TEST_F(TextToBinaryTest, GroupMemberDecorateGoodOneTarget) { EXPECT_THAT(CompiledInstructions("OpGroupMemberDecorate %group %id0 42"), - Eq(MakeInstruction(spv::Op::OpGroupMemberDecorate, {1, 2, 42}))); + Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 42}))); } TEST_F(TextToBinaryTest, GroupMemberDecorateGoodTwoTargets) { EXPECT_THAT( CompiledInstructions("OpGroupMemberDecorate %group %id0 96 %id1 42"), - Eq(MakeInstruction(spv::Op::OpGroupMemberDecorate, {1, 2, 96, 3, 42}))); + Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 96, 3, 42}))); } TEST_F(TextToBinaryTest, GroupMemberDecorateMissingGroupId) { @@ -445,7 +443,7 @@ TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidSecondTargetMemberNumber) { using OpMemberDecorateSimpleTest = spvtest::TextToBinaryTestBase<::testing::TestWithParam< - std::tuple>>>; + std::tuple>>>; TEST_P(OpMemberDecorateSimpleTest, AnySimpleDecoration) { // This string should assemble, but should not validate. @@ -456,7 +454,7 @@ TEST_P(OpMemberDecorateSimpleTest, AnySimpleDecoration) { input << std::endl; EXPECT_THAT( CompiledInstructions(input.str(), std::get<0>(GetParam())), - Eq(MakeInstruction(spv::Op::OpMemberDecorate, + Eq(MakeInstruction(SpvOpMemberDecorate, {1, 42, uint32_t(std::get<1>(GetParam()).value())}, std::get<1>(GetParam()).operands()))); // Also check disassembly. @@ -466,11 +464,11 @@ TEST_P(OpMemberDecorateSimpleTest, AnySimpleDecoration) { Eq(input.str())); } -#define CASE(NAME) spv::Decoration::NAME, #NAME +#define CASE(NAME) SpvDecoration##NAME, #NAME INSTANTIATE_TEST_SUITE_P( TextToBinaryDecorateSimple, OpMemberDecorateSimpleTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ // The operand literal values are arbitrarily chosen, // but there are the right number of them. {CASE(RelaxedPrecision), {}}, @@ -517,7 +515,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( TextToBinaryDecorateSimpleV11, OpMemberDecorateSimpleTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), - Values(EnumCase{CASE(MaxByteOffset), {128}}))); + Values(EnumCase{CASE(MaxByteOffset), {128}}))); #undef CASE TEST_F(OpMemberDecorateSimpleTest, WrongDecoration) { diff --git a/test/text_to_binary.barrier_test.cpp b/test/text_to_binary.barrier_test.cpp index 380cacb3..f1cb4fbe 100644 --- a/test/text_to_binary.barrier_test.cpp +++ b/test/text_to_binary.barrier_test.cpp @@ -37,7 +37,7 @@ using OpMemoryBarrier = spvtest::TextToBinaryTest; TEST_F(OpMemoryBarrier, Good) { const std::string input = "OpMemoryBarrier %1 %2\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpMemoryBarrier, {1, 2}))); + Eq(MakeInstruction(SpvOpMemoryBarrier, {1, 2}))); EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); } @@ -89,7 +89,7 @@ TEST_F(NamedMemoryBarrierTest, OpcodeAssemblesInV10) { EXPECT_THAT( CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics", SPV_ENV_UNIVERSAL_1_0), - ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _)); + ElementsAre(spvOpcodeMake(4, SpvOpMemoryNamedBarrier), _, _, _)); } TEST_F(NamedMemoryBarrierTest, ArgumentCount) { @@ -107,7 +107,7 @@ TEST_F(NamedMemoryBarrierTest, ArgumentCount) { EXPECT_THAT( CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics", SPV_ENV_UNIVERSAL_1_1), - ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _)); + ElementsAre(spvOpcodeMake(4, SpvOpMemoryNamedBarrier), _, _, _)); EXPECT_THAT( CompileFailure("OpMemoryNamedBarrier %bar %scope %semantics %extra", SPV_ENV_UNIVERSAL_1_1), @@ -128,7 +128,7 @@ using TypeNamedBarrierTest = spvtest::TextToBinaryTest; TEST_F(TypeNamedBarrierTest, OpcodeAssemblesInV10) { EXPECT_THAT( CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_0), - ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _)); + ElementsAre(spvOpcodeMake(2, SpvOpTypeNamedBarrier), _)); } TEST_F(TypeNamedBarrierTest, ArgumentCount) { @@ -137,7 +137,7 @@ TEST_F(TypeNamedBarrierTest, ArgumentCount) { "found 'OpTypeNamedBarrier'.")); EXPECT_THAT( CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1), - ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _)); + ElementsAre(spvOpcodeMake(2, SpvOpTypeNamedBarrier), _)); EXPECT_THAT( CompileFailure("%t = OpTypeNamedBarrier 1 2 3", SPV_ENV_UNIVERSAL_1_1), Eq("Expected or at the beginning of an instruction, " @@ -150,8 +150,7 @@ TEST_F(NamedBarrierInitializeTest, OpcodeAssemblesInV10) { EXPECT_THAT( CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count", SPV_ENV_UNIVERSAL_1_0), - ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _, - _)); + ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _)); } TEST_F(NamedBarrierInitializeTest, ArgumentCount) { @@ -166,8 +165,7 @@ TEST_F(NamedBarrierInitializeTest, ArgumentCount) { EXPECT_THAT( CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count", SPV_ENV_UNIVERSAL_1_1), - ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _, - _)); + ElementsAre(spvOpcodeMake(4, SpvOpNamedBarrierInitialize), _, _, _)); EXPECT_THAT( CompileFailure("%bar = OpNamedBarrierInitialize %type %count \"extra\"", SPV_ENV_UNIVERSAL_1_1), diff --git a/test/text_to_binary.constant_test.cpp b/test/text_to_binary.constant_test.cpp index bc5cd064..7ab4ca51 100644 --- a/test/text_to_binary.constant_test.cpp +++ b/test/text_to_binary.constant_test.cpp @@ -35,21 +35,21 @@ using ::testing::Eq; // Test Sampler Addressing Mode enum values using SamplerAddressingModeTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(SamplerAddressingModeTest, AnySamplerAddressingMode) { const std::string input = "%result = OpConstantSampler %type " + GetParam().name() + " 0 Nearest"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpConstantSampler, - {1, 2, uint32_t(GetParam().value()), 0, 0}))); + Eq(MakeInstruction(SpvOpConstantSampler, + {1, 2, GetParam().value(), 0, 0}))); } // clang-format off -#define CASE(NAME) { spv::SamplerAddressingMode::NAME, #NAME } +#define CASE(NAME) { SpvSamplerAddressingMode##NAME, #NAME } INSTANTIATE_TEST_SUITE_P( TextToBinarySamplerAddressingMode, SamplerAddressingModeTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(None), CASE(ClampToEdge), CASE(Clamp), @@ -67,21 +67,21 @@ TEST_F(SamplerAddressingModeTest, WrongMode) { // Test Sampler Filter Mode enum values using SamplerFilterModeTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(SamplerFilterModeTest, AnySamplerFilterMode) { const std::string input = "%result = OpConstantSampler %type Clamp 0 " + GetParam().name(); EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpConstantSampler, - {1, 2, 2, 0, uint32_t(GetParam().value())}))); + Eq(MakeInstruction(SpvOpConstantSampler, + {1, 2, 2, 0, GetParam().value()}))); } // clang-format off -#define CASE(NAME) { spv::SamplerFilterMode::NAME, #NAME} +#define CASE(NAME) { SpvSamplerFilterMode##NAME, #NAME} INSTANTIATE_TEST_SUITE_P( TextToBinarySamplerFilterMode, SamplerFilterModeTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(Nearest), CASE(Linear), })); @@ -119,119 +119,119 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(std::vector{ // Check 16 bits {"OpTypeInt 16 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0x1234})})}, {"OpTypeInt 16 0", "0x8000", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0x8000})})}, {"OpTypeInt 16 0", "0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 16 0", "65535", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 65535})})}, {"OpTypeInt 16 0", "0xffff", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 65535})})}, {"OpTypeInt 16 1", "0x8000", // Test sign extension. - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffff8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0xffff8000})})}, {"OpTypeInt 16 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-32)})})}, {"OpTypeInt 16 1", "0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 16 1", "-0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 16 1", "-0x0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 16 1", "-32768", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32768)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-32768)})})}, // Check 32 bits {"OpTypeInt 32 0", "42", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 42})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 42})})}, {"OpTypeInt 32 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-32)})})}, {"OpTypeInt 32 1", "0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 32 1", "-0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 32 1", "-0x0", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0})})}, {"OpTypeInt 32 1", "-0x001", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-1)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-1)})})}, {"OpTypeInt 32 1", "2147483647", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0x7fffffffu})})}, {"OpTypeInt 32 1", "-2147483648", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x80000000u})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0x80000000u})})}, {"OpTypeFloat 32", "1.0", - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x3f800000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0x3f800000})})}, {"OpTypeFloat 32", "10.0", - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x41200000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0x41200000})})}, {"OpTypeFloat 32", "-0x1p+128", // -infinity - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0xFF800000})})}, {"OpTypeFloat 32", "0x1p+128", // +infinity - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7F800000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0x7F800000})})}, {"OpTypeFloat 32", "-0x1.8p+128", // A -NaN - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFFC00000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0xFFC00000})})}, {"OpTypeFloat 32", "-0x1.0002p+128", // A +NaN - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800100})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, 0xFF800100})})}, // Check 48 bits {"OpTypeInt 48 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 48 0", "0x800000000001", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 1, 0x00008000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 1, 0x00008000})})}, {"OpTypeInt 48 1", "0x800000000000", // Test sign extension. - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0, 0xffff8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0, 0xffff8000})})}, {"OpTypeInt 48 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, // Check 64 bits {"OpTypeInt 64 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 64 0", "18446744073709551615", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, {"OpTypeInt 64 0", "0xffffffffffffffff", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, {"OpTypeInt 64 1", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 64 1", "-42", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, {"OpTypeInt 64 1", "-0x01", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, {"OpTypeInt 64 1", "9223372036854775807", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0x7fffffffu})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0xffffffffu, 0x7fffffffu})})}, {"OpTypeInt 64 1", "0x7fffffff", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 0x7fffffffu, 0})})}, })); // clang-format on @@ -388,53 +388,53 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(std::vector{ // Check 16 bits {"OpTypeInt 16 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x1234})})}, {"OpTypeInt 16 0", "0x8000", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x8000})})}, {"OpTypeInt 16 1", "0x8000", // Test sign extension. - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0xffff8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0xffff8000})})}, {"OpTypeInt 16 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 16, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, uint32_t(-32)})})}, // Check 32 bits {"OpTypeInt 32 0", "42", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 42})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 42})})}, {"OpTypeInt 32 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, uint32_t(-32)})})}, {"OpTypeFloat 32", "1.0", - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x3f800000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x3f800000})})}, {"OpTypeFloat 32", "10.0", - Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x41200000})})}, + Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x41200000})})}, // Check 48 bits {"OpTypeInt 48 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 48 0", "0x800000000001", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 1, 0x00008000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 1, 0x00008000})})}, {"OpTypeInt 48 1", "0x800000000000", // Test sign extension. - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0, 0xffff8000})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0, 0xffff8000})})}, {"OpTypeInt 48 1", "-32", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 48, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, // Check 64 bits {"OpTypeInt 64 0", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 0}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 64 1", "0x1234", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, 0x1234, 0})})}, {"OpTypeInt 64 1", "-42", - Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), - MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, + Concatenate({MakeInstruction(SpvOpTypeInt, {1, 64, 1}), + MakeInstruction(SpvOpSpecConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, })); // clang-format on @@ -648,7 +648,7 @@ INSTANTIATE_TEST_SUITE_P( // Test OpSpecConstantOp using OpSpecConstantOpTestWithIds = - spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; + spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; // The operands to the OpSpecConstantOp opcode are all Ids. TEST_P(OpSpecConstantOpTestWithIds, Assembly) { @@ -658,7 +658,7 @@ TEST_P(OpSpecConstantOpTestWithIds, Assembly) { input << "\n"; EXPECT_THAT(CompiledInstructions(input.str()), - Eq(MakeInstruction(spv::Op::OpSpecConstantOp, + Eq(MakeInstruction(SpvOpSpecConstantOp, {1, 2, uint32_t(GetParam().value())}, GetParam().operands()))); @@ -667,15 +667,15 @@ TEST_P(OpSpecConstantOpTestWithIds, Assembly) { } // clang-format off -#define CASE1(NAME) { spv::Op::Op##NAME, #NAME, {3} } -#define CASE2(NAME) { spv::Op::Op##NAME, #NAME, {3, 4} } -#define CASE3(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5} } -#define CASE4(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6} } -#define CASE5(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7} } -#define CASE6(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7, 8} } +#define CASE1(NAME) { SpvOp##NAME, #NAME, {3} } +#define CASE2(NAME) { SpvOp##NAME, #NAME, {3, 4} } +#define CASE3(NAME) { SpvOp##NAME, #NAME, {3, 4, 5} } +#define CASE4(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6} } +#define CASE5(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6, 7} } +#define CASE6(NAME) { SpvOp##NAME, #NAME, {3, 4, 5, 6, 7, 8} } INSTANTIATE_TEST_SUITE_P( TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithIds, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ // Conversion CASE1(SConvert), CASE1(FConvert), @@ -759,7 +759,7 @@ INSTANTIATE_TEST_SUITE_P( // clang-format on using OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers = - spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; + spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; // The operands to the OpSpecConstantOp opcode are two Ids followed by a // sequence of literal numbers. @@ -770,7 +770,7 @@ TEST_P(OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, Assembly) { input << "\n"; EXPECT_THAT(CompiledInstructions(input.str()), - Eq(MakeInstruction(spv::Op::OpSpecConstantOp, + Eq(MakeInstruction(SpvOpSpecConstantOp, {1, 2, uint32_t(GetParam().value()), 3, 4}, GetParam().operands()))); @@ -778,11 +778,11 @@ TEST_P(OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, Assembly) { EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str()); } -#define CASE(NAME) spv::Op::Op##NAME, #NAME +#define CASE(NAME) SpvOp##NAME, #NAME INSTANTIATE_TEST_SUITE_P( TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ // For VectorShuffle, there are two vector operands, and at least // two selector Ids. OpenCL can have up to 16-element vectors. {CASE(VectorShuffle), {0, 0}}, @@ -797,7 +797,7 @@ INSTANTIATE_TEST_SUITE_P( })); using OpSpecConstantOpTestWithOneIdThenLiteralNumbers = - spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; + spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; // The operands to the OpSpecConstantOp opcode are one Id followed by a // sequence of literal numbers. @@ -808,7 +808,7 @@ TEST_P(OpSpecConstantOpTestWithOneIdThenLiteralNumbers, Assembly) { input << "\n"; EXPECT_THAT(CompiledInstructions(input.str()), - Eq(MakeInstruction(spv::Op::OpSpecConstantOp, + Eq(MakeInstruction(SpvOpSpecConstantOp, {1, 2, uint32_t(GetParam().value()), 3}, GetParam().operands()))); @@ -816,11 +816,11 @@ TEST_P(OpSpecConstantOpTestWithOneIdThenLiteralNumbers, Assembly) { EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str()); } -#define CASE(NAME) spv::Op::Op##NAME, #NAME +#define CASE(NAME) SpvOp##NAME, #NAME INSTANTIATE_TEST_SUITE_P( TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithOneIdThenLiteralNumbers, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ // For CompositeExtract, the universal limit permits up to 255 literal // indices. Let's only test a few. {CASE(CompositeExtract), {0}}, diff --git a/test/text_to_binary.control_flow_test.cpp b/test/text_to_binary.control_flow_test.cpp index bc64aa3f..472cb6da 100644 --- a/test/text_to_binary.control_flow_test.cpp +++ b/test/text_to_binary.control_flow_test.cpp @@ -40,22 +40,22 @@ using ::testing::ValuesIn; // Test OpSelectionMerge using OpSelectionMergeTest = spvtest::TextToBinaryTestBase< - TestWithParam>>; + TestWithParam>>; TEST_P(OpSelectionMergeTest, AnySingleSelectionControlMask) { const std::string input = "OpSelectionMerge %1 " + GetParam().name(); - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSelectionMerge, - {1, uint32_t(GetParam().value())}))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpSelectionMerge, {1, GetParam().value()}))); } // clang-format off -#define CASE(VALUE,NAME) { spv::SelectionControlMask::VALUE, NAME} +#define CASE(VALUE,NAME) { SpvSelectionControl##VALUE, NAME} INSTANTIATE_TEST_SUITE_P(TextToBinarySelectionMerge, OpSelectionMergeTest, - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ CASE(MaskNone, "None"), - CASE(Flatten, "Flatten"), - CASE(DontFlatten, "DontFlatten"), + CASE(FlattenMask, "Flatten"), + CASE(DontFlattenMask, "DontFlatten"), })); #undef CASE // clang-format on @@ -63,11 +63,9 @@ INSTANTIATE_TEST_SUITE_P(TextToBinarySelectionMerge, OpSelectionMergeTest, TEST_F(OpSelectionMergeTest, CombinedSelectionControlMask) { const std::string input = "OpSelectionMerge %1 Flatten|DontFlatten"; const uint32_t expected_mask = - uint32_t(spv::SelectionControlMask::Flatten | - spv::SelectionControlMask::DontFlatten); - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSelectionMerge, {1, expected_mask}))); + SpvSelectionControlFlattenMask | SpvSelectionControlDontFlattenMask; + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpSelectionMerge, {1, expected_mask}))); } TEST_F(OpSelectionMergeTest, WrongSelectionControl) { @@ -87,15 +85,15 @@ TEST_P(OpLoopMergeTest, AnySingleLoopControlMask) { input << "OpLoopMerge %merge %continue " << ctrl.name(); for (auto num : ctrl.operands()) input << " " << num; EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())), - Eq(MakeInstruction(spv::Op::OpLoopMerge, {1, 2, ctrl.value()}, + Eq(MakeInstruction(SpvOpLoopMerge, {1, 2, ctrl.value()}, ctrl.operands()))); } #define CASE(VALUE, NAME) \ - { int32_t(spv::LoopControlMask::VALUE), NAME } -#define CASE1(VALUE, NAME, PARM) \ - { \ - int32_t(spv::LoopControlMask::VALUE), NAME, { PARM } \ + { SpvLoopControl##VALUE, NAME } +#define CASE1(VALUE, NAME, PARM) \ + { \ + SpvLoopControl##VALUE, NAME, { PARM } \ } INSTANTIATE_TEST_SUITE_P( TextToBinaryLoopMerge, OpLoopMergeTest, @@ -103,8 +101,8 @@ INSTANTIATE_TEST_SUITE_P( ValuesIn(std::vector>{ // clang-format off CASE(MaskNone, "None"), - CASE(Unroll, "Unroll"), - CASE(DontUnroll, "DontUnroll"), + CASE(UnrollMask, "Unroll"), + CASE(DontUnrollMask, "DontUnroll"), // clang-format on }))); @@ -113,9 +111,9 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_1), ValuesIn(std::vector>{ // clang-format off - CASE(DependencyInfinite, "DependencyInfinite"), - CASE1(DependencyLength, "DependencyLength", 234), - {int32_t(spv::LoopControlMask::Unroll|spv::LoopControlMask::DependencyLength), + CASE(DependencyInfiniteMask, "DependencyInfinite"), + CASE1(DependencyLengthMask, "DependencyLength", 234), + {SpvLoopControlUnrollMask|SpvLoopControlDependencyLengthMask, "DependencyLength|Unroll", {33}}, // clang-format on }))); @@ -125,9 +123,9 @@ INSTANTIATE_TEST_SUITE_P( TEST_F(OpLoopMergeTest, CombinedLoopControlMask) { const std::string input = "OpLoopMerge %merge %continue Unroll|DontUnroll"; const uint32_t expected_mask = - uint32_t(spv::LoopControlMask::Unroll | spv::LoopControlMask::DontUnroll); + SpvLoopControlUnrollMask | SpvLoopControlDontUnrollMask; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpLoopMerge, {1, 2, expected_mask}))); + Eq(MakeInstruction(SpvOpLoopMerge, {1, 2, expected_mask}))); } TEST_F(OpLoopMergeTest, WrongLoopControl) { @@ -139,17 +137,16 @@ TEST_F(OpLoopMergeTest, WrongLoopControl) { TEST_F(TextToBinaryTest, SwitchGoodZeroTargets) { EXPECT_THAT(CompiledInstructions("OpSwitch %selector %default"), - Eq(MakeInstruction(spv::Op::OpSwitch, {1, 2}))); + Eq(MakeInstruction(SpvOpSwitch, {1, 2}))); } TEST_F(TextToBinaryTest, SwitchGoodOneTarget) { - EXPECT_THAT( - CompiledInstructions("%1 = OpTypeInt 32 0\n" - "%2 = OpConstant %1 52\n" - "OpSwitch %2 %default 12 %target0"), - Eq(Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 52}), - MakeInstruction(spv::Op::OpSwitch, {2, 3, 12, 4})}))); + EXPECT_THAT(CompiledInstructions("%1 = OpTypeInt 32 0\n" + "%2 = OpConstant %1 52\n" + "OpSwitch %2 %default 12 %target0"), + Eq(Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 52}), + MakeInstruction(SpvOpSwitch, {2, 3, 12, 4})}))); } TEST_F(TextToBinaryTest, SwitchGoodTwoTargets) { @@ -158,9 +155,9 @@ TEST_F(TextToBinaryTest, SwitchGoodTwoTargets) { "%2 = OpConstant %1 52\n" "OpSwitch %2 %default 12 %target0 42 %target1"), Eq(Concatenate({ - MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 52}), - MakeInstruction(spv::Op::OpSwitch, {2, 3, 12, 4, 42, 5}), + MakeInstruction(SpvOpTypeInt, {1, 32, 0}), + MakeInstruction(SpvOpConstant, {1, 2, 52}), + MakeInstruction(SpvOpSwitch, {2, 3, 12, 4, 42, 5}), }))); } @@ -249,11 +246,11 @@ SwitchTestCase MakeSwitchTestCase(uint32_t integer_width, constant_str, case_value_str, {Concatenate( - {MakeInstruction(spv::Op::OpTypeInt, + {MakeInstruction(SpvOpTypeInt, {1, integer_width, integer_signedness}), - MakeInstruction(spv::Op::OpConstant, + MakeInstruction(SpvOpConstant, Concatenate({{1, 2}, encoded_constant})), - MakeInstruction(spv::Op::OpSwitch, + MakeInstruction(SpvOpSwitch, Concatenate({{2, 3}, encoded_case_value, {4}}))})}}; } diff --git a/test/text_to_binary.debug_test.cpp b/test/text_to_binary.debug_test.cpp index 013107b3..39ba5c52 100644 --- a/test/text_to_binary.debug_test.cpp +++ b/test/text_to_binary.debug_test.cpp @@ -39,7 +39,7 @@ struct LanguageCase { return static_cast(language_value); } const char* language_name; - spv::SourceLanguage language_value; + SpvSourceLanguage language_value; uint32_t version; }; @@ -47,7 +47,7 @@ struct LanguageCase { // The list of OpSource cases to use. const LanguageCase kLanguageCases[] = { #define CASE(NAME, VERSION) \ - { #NAME, spv::SourceLanguage::NAME, VERSION } + { #NAME, SpvSourceLanguage##NAME, VERSION } CASE(Unknown, 0), CASE(Unknown, 999), CASE(ESSL, 310), @@ -69,10 +69,9 @@ TEST_P(OpSourceTest, AnyLanguage) { const std::string input = std::string("OpSource ") + GetParam().language_name + " " + std::to_string(GetParam().version); - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSource, {GetParam().get_language_value(), - GetParam().version}))); + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpSource, {GetParam().get_language_value(), + GetParam().version}))); } INSTANTIATE_TEST_SUITE_P(TextToBinaryTestDebug, OpSourceTest, @@ -88,8 +87,7 @@ TEST_F(TextToBinaryTest, OpSourceAcceptsOptionalFileId) { const std::string input = "OpSource GLSL 450 %file_id"; EXPECT_THAT( CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSource, - {uint32_t(spv::SourceLanguage::GLSL), 450, 1}))); + Eq(MakeInstruction(SpvOpSource, {SpvSourceLanguageGLSL, 450, 1}))); } TEST_F(TextToBinaryTest, OpSourceAcceptsOptionalSourceText) { @@ -97,8 +95,7 @@ TEST_F(TextToBinaryTest, OpSourceAcceptsOptionalSourceText) { const std::string input = "OpSource GLSL 450 %file_id \"" + fake_source + "\""; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSource, - {uint32_t(spv::SourceLanguage::GLSL), 450, 1}, + Eq(MakeInstruction(SpvOpSource, {SpvSourceLanguageGLSL, 450, 1}, MakeVector(fake_source)))); } @@ -113,7 +110,7 @@ TEST_P(OpSourceContinuedTest, AnyExtension) { std::string("OpSourceContinued \"") + GetParam() + "\""; EXPECT_THAT( CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSourceContinued, MakeVector(GetParam())))); + Eq(MakeInstruction(SpvOpSourceContinued, MakeVector(GetParam())))); } // TODO(dneto): utf-8, quoting, escaping @@ -132,7 +129,7 @@ TEST_P(OpSourceExtensionTest, AnyExtension) { std::string("OpSourceExtension \"") + GetParam() + "\""; EXPECT_THAT( CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpSourceExtension, MakeVector(GetParam())))); + Eq(MakeInstruction(SpvOpSourceExtension, MakeVector(GetParam())))); } // TODO(dneto): utf-8, quoting, escaping @@ -142,12 +139,12 @@ INSTANTIATE_TEST_SUITE_P(TextToBinaryTestDebug, OpSourceExtensionTest, TEST_F(TextToBinaryTest, OpLine) { EXPECT_THAT(CompiledInstructions("OpLine %srcfile 42 99"), - Eq(MakeInstruction(spv::Op::OpLine, {1, 42, 99}))); + Eq(MakeInstruction(SpvOpLine, {1, 42, 99}))); } TEST_F(TextToBinaryTest, OpNoLine) { EXPECT_THAT(CompiledInstructions("OpNoLine"), - Eq(MakeInstruction(spv::Op::OpNoLine, {}))); + Eq(MakeInstruction(SpvOpNoLine, {}))); } using OpStringTest = @@ -157,9 +154,8 @@ TEST_P(OpStringTest, AnyString) { // TODO(dneto): utf-8, quoting, escaping const std::string input = std::string("%result = OpString \"") + GetParam() + "\""; - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpString, {1}, MakeVector(GetParam())))); + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpString, {1}, MakeVector(GetParam())))); } // TODO(dneto): utf-8, quoting, escaping @@ -173,9 +169,8 @@ using OpNameTest = TEST_P(OpNameTest, AnyString) { const std::string input = std::string("OpName %target \"") + GetParam() + "\""; - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpName, {1}, MakeVector(GetParam())))); + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpName, {1}, MakeVector(GetParam())))); } // UTF-8, quoting, escaping, etc. are covered in the StringLiterals tests in @@ -190,9 +185,9 @@ TEST_P(OpMemberNameTest, AnyString) { // TODO(dneto): utf-8, quoting, escaping const std::string input = std::string("OpMemberName %type 42 \"") + GetParam() + "\""; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpMemberName, {1, 42}, - MakeVector(GetParam())))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpMemberName, {1, 42}, MakeVector(GetParam())))); } // TODO(dneto): utf-8, quoting, escaping @@ -210,7 +205,7 @@ TEST_P(OpModuleProcessedTest, AnyString) { std::string("OpModuleProcessed \"") + GetParam() + "\""; EXPECT_THAT( CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpModuleProcessed, MakeVector(GetParam())))); + Eq(MakeInstruction(SpvOpModuleProcessed, MakeVector(GetParam())))); } INSTANTIATE_TEST_SUITE_P(TextToBinaryTestDebug, OpModuleProcessedTest, diff --git a/test/text_to_binary.device_side_enqueue_test.cpp b/test/text_to_binary.device_side_enqueue_test.cpp index 7f424f37..2f4dd705 100644 --- a/test/text_to_binary.device_side_enqueue_test.cpp +++ b/test/text_to_binary.device_side_enqueue_test.cpp @@ -44,7 +44,7 @@ TEST_P(OpEnqueueKernelGood, Sample) { " %wait_events %ret_event %invoke %param %param_size %param_align " + GetParam().local_size_source; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpEnqueueKernel, + Eq(MakeInstruction(SpvOpEnqueueKernel, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, GetParam().local_size_operands))); } diff --git a/test/text_to_binary.extension_test.cpp b/test/text_to_binary.extension_test.cpp index 55f84666..cf4919ac 100644 --- a/test/text_to_binary.extension_test.cpp +++ b/test/text_to_binary.extension_test.cpp @@ -87,14 +87,12 @@ TEST_F(TextToBinaryTest, ExtInstFromTwoDifferentImports) { EXPECT_THAT( CompiledInstructions(input), Eq(Concatenate({ - MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("OpenCL.std")), - MakeInstruction(spv::Op::OpExtInstImport, {2}, - MakeVector("GLSL.std.450")), + MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("OpenCL.std")), + MakeInstruction(SpvOpExtInstImport, {2}, MakeVector("GLSL.std.450")), MakeInstruction( - spv::Op::OpExtInst, + SpvOpExtInst, {3, 4, 1, uint32_t(OpenCLLIB::Entrypoints::Native_sqrt), 5}), - MakeInstruction(spv::Op::OpExtInst, + MakeInstruction(SpvOpExtInst, {6, 7, 2, uint32_t(GLSLstd450MatrixInverse), 8}), }))); @@ -142,74 +140,62 @@ INSTANTIATE_TEST_SUITE_P( SPV_KHR_shader_ballot, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), - ValuesIn(std::vector{ - {"OpCapability SubgroupBallotKHR\n", - MakeInstruction(spv::Op::OpCapability, - {uint32_t(spv::Capability::SubgroupBallotKHR)})}, - {"%2 = OpSubgroupBallotKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupBallotKHR, {1, 2, 3})}, - {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupFirstInvocationKHR, {1, 2, 3})}, - {"OpDecorate %1 BuiltIn SubgroupEqMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupEqMaskKHR)})}, - {"OpDecorate %1 BuiltIn SubgroupGeMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupGeMaskKHR)})}, - {"OpDecorate %1 BuiltIn SubgroupGtMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupGtMaskKHR)})}, - {"OpDecorate %1 BuiltIn SubgroupLeMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupLeMaskKHR)})}, - {"OpDecorate %1 BuiltIn SubgroupLtMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupLtMaskKHR)})}, - }))); + Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_VULKAN_1_0), + ValuesIn(std::vector{ + {"OpCapability SubgroupBallotKHR\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilitySubgroupBallotKHR})}, + {"%2 = OpSubgroupBallotKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupBallotKHR, {1, 2, 3})}, + {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupFirstInvocationKHR, {1, 2, 3})}, + {"OpDecorate %1 BuiltIn SubgroupEqMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupEqMaskKHR})}, + {"OpDecorate %1 BuiltIn SubgroupGeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGeMaskKHR})}, + {"OpDecorate %1 BuiltIn SubgroupGtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGtMaskKHR})}, + {"OpDecorate %1 BuiltIn SubgroupLeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLeMaskKHR})}, + {"OpDecorate %1 BuiltIn SubgroupLtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLtMaskKHR})}, + }))); INSTANTIATE_TEST_SUITE_P( SPV_KHR_shader_ballot_vulkan_1_1, ExtensionRoundTripTest, // In SPIR-V 1.3 and Vulkan 1.1 we can drop the KHR suffix on the // builtin enums. - Combine( - Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), - ValuesIn(std::vector{ - {"OpCapability SubgroupBallotKHR\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::SubgroupBallotKHR})}, - {"%2 = OpSubgroupBallotKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupBallotKHR, {1, 2, 3})}, - {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupFirstInvocationKHR, {1, 2, 3})}, - {"OpDecorate %1 BuiltIn SubgroupEqMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupEqMask)})}, - {"OpDecorate %1 BuiltIn SubgroupGeMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupGeMask)})}, - {"OpDecorate %1 BuiltIn SubgroupGtMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupGtMask)})}, - {"OpDecorate %1 BuiltIn SubgroupLeMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupLeMask)})}, - {"OpDecorate %1 BuiltIn SubgroupLtMask\n", - MakeInstruction(spv::Op::OpDecorate, - {1, uint32_t(spv::Decoration::BuiltIn), - uint32_t(spv::BuiltIn::SubgroupLtMask)})}, - }))); + Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), + ValuesIn(std::vector{ + {"OpCapability SubgroupBallotKHR\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilitySubgroupBallotKHR})}, + {"%2 = OpSubgroupBallotKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupBallotKHR, {1, 2, 3})}, + {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupFirstInvocationKHR, {1, 2, 3})}, + {"OpDecorate %1 BuiltIn SubgroupEqMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupEqMask})}, + {"OpDecorate %1 BuiltIn SubgroupGeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGeMask})}, + {"OpDecorate %1 BuiltIn SubgroupGtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGtMask})}, + {"OpDecorate %1 BuiltIn SubgroupLeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLeMask})}, + {"OpDecorate %1 BuiltIn SubgroupLtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLtMask})}, + }))); // The old builtin names (with KHR suffix) still work in the assembler, and // map to the enums without the KHR. @@ -220,25 +206,20 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), ValuesIn(std::vector{ {"OpDecorate %1 BuiltIn SubgroupEqMaskKHR\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::SubgroupEqMask})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupEqMask})}, {"OpDecorate %1 BuiltIn SubgroupGeMaskKHR\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::SubgroupGeMask})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGeMask})}, {"OpDecorate %1 BuiltIn SubgroupGtMaskKHR\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::SubgroupGtMask})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGtMask})}, {"OpDecorate %1 BuiltIn SubgroupLeMaskKHR\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::SubgroupLeMask})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLeMask})}, {"OpDecorate %1 BuiltIn SubgroupLtMaskKHR\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::SubgroupLtMask})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLtMask})}, }))); // SPV_KHR_shader_draw_parameters @@ -247,24 +228,21 @@ INSTANTIATE_TEST_SUITE_P( SPV_KHR_shader_draw_parameters, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine(ValuesIn(CommonVulkanEnvs()), - ValuesIn(std::vector{ - {"OpCapability DrawParameters\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::DrawParameters})}, - {"OpDecorate %1 BuiltIn BaseVertex\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::BaseVertex})}, - {"OpDecorate %1 BuiltIn BaseInstance\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::BaseInstance})}, - {"OpDecorate %1 BuiltIn DrawIndex\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::DrawIndex})}, - }))); + Combine( + ValuesIn(CommonVulkanEnvs()), + ValuesIn(std::vector{ + {"OpCapability DrawParameters\n", + MakeInstruction(SpvOpCapability, {SpvCapabilityDrawParameters})}, + {"OpDecorate %1 BuiltIn BaseVertex\n", + MakeInstruction(SpvOpDecorate, + {1, SpvDecorationBuiltIn, SpvBuiltInBaseVertex})}, + {"OpDecorate %1 BuiltIn BaseInstance\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInBaseInstance})}, + {"OpDecorate %1 BuiltIn DrawIndex\n", + MakeInstruction(SpvOpDecorate, + {1, SpvDecorationBuiltIn, SpvBuiltInDrawIndex})}, + }))); // SPV_KHR_subgroup_vote @@ -275,14 +253,14 @@ INSTANTIATE_TEST_SUITE_P( Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability SubgroupVoteKHR\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::SubgroupVoteKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilitySubgroupVoteKHR})}, {"%2 = OpSubgroupAnyKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupAnyKHR, {1, 2, 3})}, + MakeInstruction(SpvOpSubgroupAnyKHR, {1, 2, 3})}, {"%2 = OpSubgroupAllKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupAllKHR, {1, 2, 3})}, + MakeInstruction(SpvOpSubgroupAllKHR, {1, 2, 3})}, {"%2 = OpSubgroupAllEqualKHR %1 %3\n", - MakeInstruction(spv::Op::OpSubgroupAllEqualKHR, {1, 2, 3})}, + MakeInstruction(SpvOpSubgroupAllEqualKHR, {1, 2, 3})}, }))); // SPV_KHR_16bit_storage @@ -291,50 +269,42 @@ INSTANTIATE_TEST_SUITE_P( SPV_KHR_16bit_storage, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine( - ValuesIn(CommonVulkanEnvs()), - ValuesIn(std::vector{ - {"OpCapability StorageBuffer16BitAccess\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageUniformBufferBlock16})}, - {"OpCapability StorageBuffer16BitAccess\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageBuffer16BitAccess})}, - {"OpCapability UniformAndStorageBuffer16BitAccess\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t) - spv::Capability::UniformAndStorageBuffer16BitAccess})}, - {"OpCapability UniformAndStorageBuffer16BitAccess\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageUniform16})}, - {"OpCapability StoragePushConstant16\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StoragePushConstant16})}, - {"OpCapability StorageInputOutput16\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageInputOutput16})}, - }))); + Combine(ValuesIn(CommonVulkanEnvs()), + ValuesIn(std::vector{ + {"OpCapability StorageBuffer16BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageUniformBufferBlock16})}, + {"OpCapability StorageBuffer16BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageBuffer16BitAccess})}, + {"OpCapability UniformAndStorageBuffer16BitAccess\n", + MakeInstruction( + SpvOpCapability, + {SpvCapabilityUniformAndStorageBuffer16BitAccess})}, + {"OpCapability UniformAndStorageBuffer16BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageUniform16})}, + {"OpCapability StoragePushConstant16\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStoragePushConstant16})}, + {"OpCapability StorageInputOutput16\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageInputOutput16})}, + }))); INSTANTIATE_TEST_SUITE_P( SPV_KHR_16bit_storage_alias_check, ExtensionAssemblyTest, - Combine( - ValuesIn(CommonVulkanEnvs()), - ValuesIn(std::vector{ - // The old name maps to the new enum. - {"OpCapability StorageUniformBufferBlock16\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageBuffer16BitAccess})}, - // The new name maps to the old enum. - {"OpCapability UniformAndStorageBuffer16BitAccess\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageUniform16})}, - }))); + Combine(ValuesIn(CommonVulkanEnvs()), + ValuesIn(std::vector{ + // The old name maps to the new enum. + {"OpCapability StorageUniformBufferBlock16\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageBuffer16BitAccess})}, + // The new name maps to the old enum. + {"OpCapability UniformAndStorageBuffer16BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageUniform16})}, + }))); // SPV_KHR_device_group @@ -345,12 +315,10 @@ INSTANTIATE_TEST_SUITE_P( Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability DeviceGroup\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::DeviceGroup})}, + MakeInstruction(SpvOpCapability, {SpvCapabilityDeviceGroup})}, {"OpDecorate %1 BuiltIn DeviceIndex\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::DeviceIndex})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInDeviceIndex})}, }))); // SPV_KHR_8bit_storage @@ -359,22 +327,19 @@ INSTANTIATE_TEST_SUITE_P( SPV_KHR_8bit_storage, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine(ValuesIn(CommonVulkanEnvs()), - ValuesIn(std::vector{ - {"OpCapability StorageBuffer8BitAccess\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StorageBuffer8BitAccess})}, - {"OpCapability UniformAndStorageBuffer8BitAccess\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t) - spv::Capability::UniformAndStorageBuffer8BitAccess})}, - {"OpCapability StoragePushConstant8\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::StoragePushConstant8})}, - }))); + Combine( + ValuesIn(CommonVulkanEnvs()), + ValuesIn(std::vector{ + {"OpCapability StorageBuffer8BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStorageBuffer8BitAccess})}, + {"OpCapability UniformAndStorageBuffer8BitAccess\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityUniformAndStorageBuffer8BitAccess})}, + {"OpCapability StoragePushConstant8\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityStoragePushConstant8})}, + }))); // SPV_KHR_multiview @@ -386,12 +351,10 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_0), ValuesIn(std::vector{ {"OpCapability MultiView\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::MultiView})}, + MakeInstruction(SpvOpCapability, {SpvCapabilityMultiView})}, {"OpDecorate %1 BuiltIn ViewIndex\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::ViewIndex})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInViewIndex})}, }))); // SPV_AMD_shader_explicit_vertex_parameter @@ -409,9 +372,9 @@ INSTANTIATE_TEST_SUITE_P( {PREAMBLE "%3 = OpExtInst %2 %1 InterpolateAtVertexAMD %4 %5\n", Concatenate( {MakeInstruction( - spv::Op::OpExtInstImport, {1}, + SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_explicit_vertex_parameter")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 1, 4, 5})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5})})}, }))); #undef PREAMBLE @@ -428,49 +391,49 @@ INSTANTIATE_TEST_SUITE_P( ValuesIn(std::vector{ {PREAMBLE "%3 = OpExtInst %2 %1 FMin3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 1, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 UMin3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 2, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 SMin3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 3, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 3, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 FMax3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 4, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 4, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 UMax3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 5, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 5, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 SMax3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 6, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 6, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 FMid3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 7, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 7, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 UMid3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 8, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 8, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 SMid3AMD %4 %5 %6\n", Concatenate( - {MakeInstruction(spv::Op::OpExtInstImport, {1}, + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_trinary_minmax")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 9, 4, 5, 6})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 9, 4, 5, 6})})}, }))); #undef PREAMBLE @@ -481,25 +444,22 @@ INSTANTIATE_TEST_SUITE_P( SPV_AMD_gcn_shader, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), - ValuesIn(std::vector{ - {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceIndexAMD %4\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("SPV_AMD_gcn_shader")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, 1, 4})})}, - {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceCoordAMD %4\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("SPV_AMD_gcn_shader")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, 2, 4})})}, - {PREAMBLE "%3 = OpExtInst %2 %1 TimeAMD\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, - MakeVector("SPV_AMD_gcn_shader")), - MakeInstruction(spv::Op::OpExtInst, {2, 3, 1, 3})})}, - }))); + Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_VULKAN_1_0), + ValuesIn(std::vector{ + {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceIndexAMD %4\n", + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, + MakeVector("SPV_AMD_gcn_shader")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4})})}, + {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceCoordAMD %4\n", + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, + MakeVector("SPV_AMD_gcn_shader")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4})})}, + {PREAMBLE "%3 = OpExtInst %2 %1 TimeAMD\n", + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, + MakeVector("SPV_AMD_gcn_shader")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, 3})})}, + }))); #undef PREAMBLE // SPV_AMD_shader_ballot @@ -514,26 +474,23 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_0), ValuesIn(std::vector{ {PREAMBLE "%3 = OpExtInst %2 %1 SwizzleInvocationsAMD %4 %5\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_ballot")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, 1, 4, 5})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5})})}, {PREAMBLE "%3 = OpExtInst %2 %1 SwizzleInvocationsMaskedAMD %4 %5\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_ballot")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, 2, 4, 5})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4, 5})})}, {PREAMBLE "%3 = OpExtInst %2 %1 WriteInvocationAMD %4 %5 %6\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_ballot")), - MakeInstruction(spv::Op::OpExtInst, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 3, 4, 5, 6})})}, {PREAMBLE "%3 = OpExtInst %2 %1 MbcntAMD %4\n", - Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1}, + Concatenate({MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("SPV_AMD_shader_ballot")), - MakeInstruction(spv::Op::OpExtInst, - {2, 3, 1, 4, 4})})}, + MakeInstruction(SpvOpExtInst, {2, 3, 1, 4, 4})})}, }))); #undef PREAMBLE @@ -543,18 +500,16 @@ INSTANTIATE_TEST_SUITE_P( SPV_KHR_variable_pointers, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), - ValuesIn(std::vector{ - {"OpCapability VariablePointers\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::VariablePointers})}, - {"OpCapability VariablePointersStorageBuffer\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::VariablePointersStorageBuffer})}, - }))); + Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_VULKAN_1_0), + ValuesIn(std::vector{ + {"OpCapability VariablePointers\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityVariablePointers})}, + {"OpCapability VariablePointersStorageBuffer\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilityVariablePointersStorageBuffer})}, + }))); // SPV_KHR_vulkan_memory_model @@ -573,145 +528,126 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1), ValuesIn(std::vector{ {"OpCapability VulkanMemoryModel\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::VulkanMemoryModelKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityVulkanMemoryModelKHR})}, {"OpCapability VulkanMemoryModelDeviceScope\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::VulkanMemoryModelDeviceScopeKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityVulkanMemoryModelDeviceScopeKHR})}, {"OpMemoryModel Logical Vulkan\n", - MakeInstruction(spv::Op::OpMemoryModel, - {(uint32_t)spv::AddressingModel::Logical, - (uint32_t)spv::MemoryModel::VulkanKHR})}, + MakeInstruction(SpvOpMemoryModel, {SpvAddressingModelLogical, + SpvMemoryModelVulkanKHR})}, {"OpStore %1 %2 MakePointerAvailable %3\n", - MakeInstruction( - spv::Op::OpStore, - {1, 2, - (uint32_t)spv::MemoryAccessMask::MakePointerAvailableKHR, - 3})}, + MakeInstruction(SpvOpStore, + {1, 2, SpvMemoryAccessMakePointerAvailableKHRMask, + 3})}, {"OpStore %1 %2 Volatile|MakePointerAvailable %3\n", - MakeInstruction( - spv::Op::OpStore, - {1, 2, - int(spv::MemoryAccessMask::MakePointerAvailableKHR) | - int(spv::MemoryAccessMask::Volatile), - 3})}, + MakeInstruction(SpvOpStore, + {1, 2, + int(SpvMemoryAccessMakePointerAvailableKHRMask) | + int(SpvMemoryAccessVolatileMask), + 3})}, {"OpStore %1 %2 Aligned|MakePointerAvailable 4 %3\n", - MakeInstruction( - spv::Op::OpStore, - {1, 2, - int(spv::MemoryAccessMask::MakePointerAvailableKHR) | - int(spv::MemoryAccessMask::Aligned), - 4, 3})}, + MakeInstruction(SpvOpStore, + {1, 2, + int(SpvMemoryAccessMakePointerAvailableKHRMask) | + int(SpvMemoryAccessAlignedMask), + 4, 3})}, {"OpStore %1 %2 MakePointerAvailable|NonPrivatePointer %3\n", - MakeInstruction( - spv::Op::OpStore, - {1, 2, - int(spv::MemoryAccessMask::MakePointerAvailableKHR) | - int(spv::MemoryAccessMask::NonPrivatePointerKHR), - 3})}, + MakeInstruction(SpvOpStore, + {1, 2, + int(SpvMemoryAccessMakePointerAvailableKHRMask) | + int(SpvMemoryAccessNonPrivatePointerKHRMask), + 3})}, {"%2 = OpLoad %1 %3 MakePointerVisible %4\n", - MakeInstruction( - spv::Op::OpLoad, - {1, 2, 3, - (uint32_t)spv::MemoryAccessMask::MakePointerVisibleKHR, 4})}, + MakeInstruction(SpvOpLoad, + {1, 2, 3, SpvMemoryAccessMakePointerVisibleKHRMask, + 4})}, {"%2 = OpLoad %1 %3 Volatile|MakePointerVisible %4\n", - MakeInstruction( - spv::Op::OpLoad, - {1, 2, 3, - int(spv::MemoryAccessMask::MakePointerVisibleKHR) | - int(spv::MemoryAccessMask::Volatile), - 4})}, + MakeInstruction(SpvOpLoad, + {1, 2, 3, + int(SpvMemoryAccessMakePointerVisibleKHRMask) | + int(SpvMemoryAccessVolatileMask), + 4})}, {"%2 = OpLoad %1 %3 Aligned|MakePointerVisible 8 %4\n", - MakeInstruction( - spv::Op::OpLoad, - {1, 2, 3, - int(spv::MemoryAccessMask::MakePointerVisibleKHR) | - int(spv::MemoryAccessMask::Aligned), - 8, 4})}, + MakeInstruction(SpvOpLoad, + {1, 2, 3, + int(SpvMemoryAccessMakePointerVisibleKHRMask) | + int(SpvMemoryAccessAlignedMask), + 8, 4})}, {"%2 = OpLoad %1 %3 MakePointerVisible|NonPrivatePointer " "%4\n", - MakeInstruction( - spv::Op::OpLoad, - {1, 2, 3, - int(spv::MemoryAccessMask::MakePointerVisibleKHR) | - int(spv::MemoryAccessMask::NonPrivatePointerKHR), - 4})}, + MakeInstruction(SpvOpLoad, + {1, 2, 3, + int(SpvMemoryAccessMakePointerVisibleKHRMask) | + int(SpvMemoryAccessNonPrivatePointerKHRMask), + 4})}, {"OpCopyMemory %1 %2 " "MakePointerAvailable|" "MakePointerVisible|" "NonPrivatePointer " "%3 %4\n", - MakeInstruction( - spv::Op::OpCopyMemory, - {1, 2, - (int(spv::MemoryAccessMask::MakePointerVisibleKHR) | - int(spv::MemoryAccessMask::MakePointerAvailableKHR) | - int(spv::MemoryAccessMask::NonPrivatePointerKHR)), - 3, 4})}, + MakeInstruction(SpvOpCopyMemory, + {1, 2, + (int(SpvMemoryAccessMakePointerVisibleKHRMask) | + int(SpvMemoryAccessMakePointerAvailableKHRMask) | + int(SpvMemoryAccessNonPrivatePointerKHRMask)), + 3, 4})}, {"OpCopyMemorySized %1 %2 %3 " "MakePointerAvailable|" "MakePointerVisible|" "NonPrivatePointer " "%4 %5\n", - MakeInstruction( - spv::Op::OpCopyMemorySized, - {1, 2, 3, - (int(spv::MemoryAccessMask::MakePointerVisibleKHR) | - int(spv::MemoryAccessMask::MakePointerAvailableKHR) | - int(spv::MemoryAccessMask::NonPrivatePointerKHR)), - 4, 5})}, + MakeInstruction(SpvOpCopyMemorySized, + {1, 2, 3, + (int(SpvMemoryAccessMakePointerVisibleKHRMask) | + int(SpvMemoryAccessMakePointerAvailableKHRMask) | + int(SpvMemoryAccessNonPrivatePointerKHRMask)), + 4, 5})}, // Image operands {"OpImageWrite %1 %2 %3 MakeTexelAvailable " "%4\n", MakeInstruction( - spv::Op::OpImageWrite, - {1, 2, 3, int(spv::ImageOperandsMask::MakeTexelAvailableKHR), - 4})}, + SpvOpImageWrite, + {1, 2, 3, int(SpvImageOperandsMakeTexelAvailableKHRMask), 4})}, {"OpImageWrite %1 %2 %3 MakeTexelAvailable|NonPrivateTexel " "%4\n", - MakeInstruction( - spv::Op::OpImageWrite, - {1, 2, 3, - int(spv::ImageOperandsMask::MakeTexelAvailableKHR) | - int(spv::ImageOperandsMask::NonPrivateTexelKHR), - 4})}, + MakeInstruction(SpvOpImageWrite, + {1, 2, 3, + int(SpvImageOperandsMakeTexelAvailableKHRMask) | + int(SpvImageOperandsNonPrivateTexelKHRMask), + 4})}, {"OpImageWrite %1 %2 %3 " "MakeTexelAvailable|NonPrivateTexel|VolatileTexel " "%4\n", - MakeInstruction( - spv::Op::OpImageWrite, - {1, 2, 3, - int(spv::ImageOperandsMask::MakeTexelAvailableKHR) | - int(spv::ImageOperandsMask::NonPrivateTexelKHR) | - int(spv::ImageOperandsMask::VolatileTexelKHR), - 4})}, + MakeInstruction(SpvOpImageWrite, + {1, 2, 3, + int(SpvImageOperandsMakeTexelAvailableKHRMask) | + int(SpvImageOperandsNonPrivateTexelKHRMask) | + int(SpvImageOperandsVolatileTexelKHRMask), + 4})}, {"%2 = OpImageRead %1 %3 %4 MakeTexelVisible " "%5\n", - MakeInstruction(spv::Op::OpImageRead, + MakeInstruction(SpvOpImageRead, {1, 2, 3, 4, - int(spv::ImageOperandsMask::MakeTexelVisibleKHR), + int(SpvImageOperandsMakeTexelVisibleKHRMask), 5})}, {"%2 = OpImageRead %1 %3 %4 " "MakeTexelVisible|NonPrivateTexel " "%5\n", - MakeInstruction( - spv::Op::OpImageRead, - {1, 2, 3, 4, - int(spv::ImageOperandsMask::MakeTexelVisibleKHR) | - int(spv::ImageOperandsMask::NonPrivateTexelKHR), - 5})}, + MakeInstruction(SpvOpImageRead, + {1, 2, 3, 4, + int(SpvImageOperandsMakeTexelVisibleKHRMask) | + int(SpvImageOperandsNonPrivateTexelKHRMask), + 5})}, {"%2 = OpImageRead %1 %3 %4 " "MakeTexelVisible|NonPrivateTexel|VolatileTexel " "%5\n", - MakeInstruction( - spv::Op::OpImageRead, - {1, 2, 3, 4, - int(spv::ImageOperandsMask::MakeTexelVisibleKHR) | - int(spv::ImageOperandsMask::NonPrivateTexelKHR) | - int(spv::ImageOperandsMask::VolatileTexelKHR), - 5})}, + MakeInstruction(SpvOpImageRead, + {1, 2, 3, 4, + int(SpvImageOperandsMakeTexelVisibleKHRMask) | + int(SpvImageOperandsNonPrivateTexelKHRMask) | + int(SpvImageOperandsVolatileTexelKHRMask), + 5})}, // Memory semantics ID values are numbers put into a SPIR-V // constant integer referenced by Id. There is no token for @@ -734,20 +670,20 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0), ValuesIn(std::vector{ {"OpDecorateString %1 UserSemantic \"ABC\"\n", - MakeInstruction(spv::Op::OpDecorateStringGOOGLE, - {1, (uint32_t)spv::Decoration::HlslSemanticGOOGLE}, + MakeInstruction(SpvOpDecorateStringGOOGLE, + {1, SpvDecorationHlslSemanticGOOGLE}, MakeVector("ABC"))}, {"OpDecorateString %1 UserSemantic \"ABC\"\n", - MakeInstruction(spv::Op::OpDecorateString, - {1, (uint32_t)spv::Decoration::UserSemantic}, + MakeInstruction(SpvOpDecorateString, + {1, SpvDecorationUserSemantic}, MakeVector("ABC"))}, {"OpMemberDecorateString %1 3 UserSemantic \"DEF\"\n", - MakeInstruction(spv::Op::OpMemberDecorateStringGOOGLE, - {1, 3, (uint32_t)spv::Decoration::UserSemantic}, + MakeInstruction(SpvOpMemberDecorateStringGOOGLE, + {1, 3, SpvDecorationUserSemantic}, MakeVector("DEF"))}, {"OpMemberDecorateString %1 3 UserSemantic \"DEF\"\n", - MakeInstruction(spv::Op::OpMemberDecorateString, - {1, 3, (uint32_t)spv::Decoration::UserSemantic}, + MakeInstruction(SpvOpMemberDecorateString, + {1, 3, SpvDecorationUserSemantic}, MakeVector("DEF"))}, }))); @@ -760,13 +696,12 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0), ValuesIn(std::vector{ {"OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE \"ABC\"\n", - MakeInstruction(spv::Op::OpDecorateStringGOOGLE, - {1, (uint32_t)spv::Decoration::HlslSemanticGOOGLE}, + MakeInstruction(SpvOpDecorateStringGOOGLE, + {1, SpvDecorationHlslSemanticGOOGLE}, MakeVector("ABC"))}, {"OpMemberDecorateStringGOOGLE %1 3 HlslSemanticGOOGLE \"DEF\"\n", - MakeInstruction(spv::Op::OpMemberDecorateStringGOOGLE, - {1, 3, - (uint32_t)spv::Decoration::HlslSemanticGOOGLE}, + MakeInstruction(SpvOpMemberDecorateStringGOOGLE, + {1, 3, SpvDecorationHlslSemanticGOOGLE}, MakeVector("DEF"))}, }))); @@ -786,12 +721,11 @@ INSTANTIATE_TEST_SUITE_P( // they are coupled together. ValuesIn(std::vector{ {"OpDecorateId %1 CounterBuffer %2\n", - MakeInstruction( - spv::Op::OpDecorateId, - {1, (uint32_t)spv::Decoration::HlslCounterBufferGOOGLE, 2})}, + MakeInstruction(SpvOpDecorateId, + {1, SpvDecorationHlslCounterBufferGOOGLE, 2})}, {"OpDecorateId %1 CounterBuffer %2\n", - MakeInstruction(spv::Op::OpDecorateId, - {1, (uint32_t)spv::Decoration::CounterBuffer, 2})}, + MakeInstruction(SpvOpDecorateId, + {1, SpvDecorationCounterBuffer, 2})}, }))); INSTANTIATE_TEST_SUITE_P( @@ -805,9 +739,8 @@ INSTANTIATE_TEST_SUITE_P( // they are coupled together. ValuesIn(std::vector{ {"OpDecorateId %1 HlslCounterBufferGOOGLE %2\n", - MakeInstruction( - spv::Op::OpDecorateId, - {1, (uint32_t)spv::Decoration::HlslCounterBufferGOOGLE, 2})}, + MakeInstruction(SpvOpDecorateId, + {1, SpvDecorationHlslCounterBufferGOOGLE, 2})}, }))); // SPV_NV_viewport_array2 @@ -819,26 +752,23 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1), ValuesIn(std::vector{ {"OpExtension \"SPV_NV_viewport_array2\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_NV_viewport_array2"))}, // The EXT and NV extensions have the same token number for this // capability. {"OpCapability ShaderViewportIndexLayerEXT\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::ShaderViewportIndexLayerNV})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityShaderViewportIndexLayerNV})}, // Check the new capability's token number {"OpCapability ShaderViewportIndexLayerEXT\n", - MakeInstruction(spv::Op::OpCapability, {5254})}, + MakeInstruction(SpvOpCapability, {5254})}, // Decorations {"OpDecorate %1 ViewportRelativeNV\n", - MakeInstruction( - spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::ViewportRelativeNV})}, + MakeInstruction(SpvOpDecorate, + {1, SpvDecorationViewportRelativeNV})}, {"OpDecorate %1 BuiltIn ViewportMaskNV\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::BuiltIn, - (uint32_t)spv::BuiltIn::ViewportMaskNV})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInViewportMaskNV})}, }))); // SPV_NV_shader_subgroup_partitioned @@ -849,44 +779,38 @@ INSTANTIATE_TEST_SUITE_P( Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), ValuesIn(std::vector{ {"OpExtension \"SPV_NV_shader_subgroup_partitioned\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_NV_shader_subgroup_partitioned"))}, {"OpCapability GroupNonUniformPartitionedNV\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::GroupNonUniformPartitionedNV})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityGroupNonUniformPartitionedNV})}, // Check the new capability's token number {"OpCapability GroupNonUniformPartitionedNV\n", - MakeInstruction(spv::Op::OpCapability, {5297})}, + MakeInstruction(SpvOpCapability, {5297})}, {"%2 = OpGroupNonUniformPartitionNV %1 %3\n", - MakeInstruction(spv::Op::OpGroupNonUniformPartitionNV, {1, 2, 3})}, + MakeInstruction(SpvOpGroupNonUniformPartitionNV, {1, 2, 3})}, // Check the new instruction's token number {"%2 = OpGroupNonUniformPartitionNV %1 %3\n", - MakeInstruction(static_cast(5296), {1, 2, 3})}, + MakeInstruction(static_cast(5296), {1, 2, 3})}, // Check the new group operations {"%2 = OpGroupIAdd %1 %3 PartitionedReduceNV %4\n", - MakeInstruction( - spv::Op::OpGroupIAdd, - {1, 2, 3, (uint32_t)spv::GroupOperation::PartitionedReduceNV, - 4})}, + MakeInstruction(SpvOpGroupIAdd, + {1, 2, 3, SpvGroupOperationPartitionedReduceNV, + 4})}, {"%2 = OpGroupIAdd %1 %3 PartitionedReduceNV %4\n", - MakeInstruction(spv::Op::OpGroupIAdd, {1, 2, 3, 6, 4})}, + MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 6, 4})}, {"%2 = OpGroupIAdd %1 %3 PartitionedInclusiveScanNV %4\n", - MakeInstruction( - spv::Op::OpGroupIAdd, - {1, 2, 3, - (uint32_t)spv::GroupOperation::PartitionedInclusiveScanNV, - 4})}, + MakeInstruction(SpvOpGroupIAdd, + {1, 2, 3, + SpvGroupOperationPartitionedInclusiveScanNV, 4})}, {"%2 = OpGroupIAdd %1 %3 PartitionedInclusiveScanNV %4\n", - MakeInstruction(spv::Op::OpGroupIAdd, {1, 2, 3, 7, 4})}, + MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 7, 4})}, {"%2 = OpGroupIAdd %1 %3 PartitionedExclusiveScanNV %4\n", - MakeInstruction( - spv::Op::OpGroupIAdd, - {1, 2, 3, - (uint32_t)spv::GroupOperation::PartitionedExclusiveScanNV, - 4})}, + MakeInstruction(SpvOpGroupIAdd, + {1, 2, 3, + SpvGroupOperationPartitionedExclusiveScanNV, 4})}, {"%2 = OpGroupIAdd %1 %3 PartitionedExclusiveScanNV %4\n", - MakeInstruction(spv::Op::OpGroupIAdd, {1, 2, 3, 8, 4})}, + MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 8, 4})}, }))); // SPV_EXT_descriptor_indexing @@ -899,90 +823,86 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_1), ValuesIn(std::vector{ {"OpExtension \"SPV_EXT_descriptor_indexing\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_EXT_descriptor_indexing"))}, // Check capabilities, by name {"OpCapability ShaderNonUniform\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::ShaderNonUniformEXT})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityShaderNonUniformEXT})}, {"OpCapability RuntimeDescriptorArray\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::RuntimeDescriptorArrayEXT})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityRuntimeDescriptorArrayEXT})}, {"OpCapability InputAttachmentArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - InputAttachmentArrayDynamicIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityInputAttachmentArrayDynamicIndexingEXT})}, {"OpCapability UniformTexelBufferArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - UniformTexelBufferArrayDynamicIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT})}, {"OpCapability StorageTexelBufferArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - StorageTexelBufferArrayDynamicIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT})}, {"OpCapability UniformBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - UniformBufferArrayNonUniformIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityUniformBufferArrayNonUniformIndexingEXT})}, {"OpCapability SampledImageArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - SampledImageArrayNonUniformIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilitySampledImageArrayNonUniformIndexingEXT})}, {"OpCapability StorageBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - StorageBufferArrayNonUniformIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityStorageBufferArrayNonUniformIndexingEXT})}, {"OpCapability StorageImageArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - StorageImageArrayNonUniformIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityStorageImageArrayNonUniformIndexingEXT})}, {"OpCapability InputAttachmentArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - InputAttachmentArrayNonUniformIndexingEXT})}, + MakeInstruction( + SpvOpCapability, + {SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT})}, {"OpCapability UniformTexelBufferArrayNonUniformIndexing\n", MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - UniformTexelBufferArrayNonUniformIndexingEXT})}, + SpvOpCapability, + {SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT})}, {"OpCapability StorageTexelBufferArrayNonUniformIndexing\n", MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability:: - StorageTexelBufferArrayNonUniformIndexingEXT})}, + SpvOpCapability, + {SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT})}, // Check capabilities, by number {"OpCapability ShaderNonUniform\n", - MakeInstruction(spv::Op::OpCapability, {5301})}, + MakeInstruction(SpvOpCapability, {5301})}, {"OpCapability RuntimeDescriptorArray\n", - MakeInstruction(spv::Op::OpCapability, {5302})}, + MakeInstruction(SpvOpCapability, {5302})}, {"OpCapability InputAttachmentArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5303})}, + MakeInstruction(SpvOpCapability, {5303})}, {"OpCapability UniformTexelBufferArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5304})}, + MakeInstruction(SpvOpCapability, {5304})}, {"OpCapability StorageTexelBufferArrayDynamicIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5305})}, + MakeInstruction(SpvOpCapability, {5305})}, {"OpCapability UniformBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5306})}, + MakeInstruction(SpvOpCapability, {5306})}, {"OpCapability SampledImageArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5307})}, + MakeInstruction(SpvOpCapability, {5307})}, {"OpCapability StorageBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5308})}, + MakeInstruction(SpvOpCapability, {5308})}, {"OpCapability StorageImageArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5309})}, + MakeInstruction(SpvOpCapability, {5309})}, {"OpCapability InputAttachmentArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5310})}, + MakeInstruction(SpvOpCapability, {5310})}, {"OpCapability UniformTexelBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5311})}, + MakeInstruction(SpvOpCapability, {5311})}, {"OpCapability StorageTexelBufferArrayNonUniformIndexing\n", - MakeInstruction(spv::Op::OpCapability, {5312})}, + MakeInstruction(SpvOpCapability, {5312})}, // Check the decoration token {"OpDecorate %1 NonUniform\n", - MakeInstruction(spv::Op::OpDecorate, - {1, (uint32_t)spv::Decoration::NonUniformEXT})}, + MakeInstruction(SpvOpDecorate, {1, SpvDecorationNonUniformEXT})}, {"OpDecorate %1 NonUniform\n", - MakeInstruction(spv::Op::OpDecorate, {1, 5300})}, + MakeInstruction(SpvOpDecorate, {1, 5300})}, }))); // SPV_KHR_linkonce_odr @@ -994,14 +914,13 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_linkonce_odr\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_linkonce_odr"))}, {"OpDecorate %1 LinkageAttributes \"foobar\" LinkOnceODR\n", - MakeInstruction( - spv::Op::OpDecorate, - Concatenate({{1, (uint32_t)spv::Decoration::LinkageAttributes}, - MakeVector("foobar"), - {(uint32_t)spv::LinkageType::LinkOnceODR}}))}, + MakeInstruction(SpvOpDecorate, + Concatenate({{1, SpvDecorationLinkageAttributes}, + MakeVector("foobar"), + {SpvLinkageTypeLinkOnceODR}}))}, }))); // SPV_KHR_expect_assume @@ -1012,10 +931,10 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_expect_assume\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_expect_assume"))}, {"OpAssumeTrueKHR %1\n", - MakeInstruction(spv::Op::OpAssumeTrueKHR, {1})}}))); + MakeInstruction(SpvOpAssumeTrueKHR, {1})}}))); // SPV_KHR_subgroup_uniform_control_flow INSTANTIATE_TEST_SUITE_P( @@ -1025,12 +944,12 @@ INSTANTIATE_TEST_SUITE_P( ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_subgroup_uniform_control_flow\"\n", MakeInstruction( - spv::Op::OpExtension, + SpvOpExtension, MakeVector("SPV_KHR_subgroup_uniform_control_flow"))}, {"OpExecutionMode %1 SubgroupUniformControlFlowKHR\n", - MakeInstruction(spv::Op::OpExecutionMode, - {1, (uint32_t)spv::ExecutionMode:: - SubgroupUniformControlFlowKHR})}, + MakeInstruction( + SpvOpExecutionMode, + {1, SpvExecutionModeSubgroupUniformControlFlowKHR})}, }))); // SPV_KHR_integer_dot_product @@ -1043,71 +962,61 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_integer_dot_product\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_integer_dot_product"))}, {"OpCapability DotProductInputAll\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::DotProductInputAllKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityDotProductInputAllKHR})}, {"OpCapability DotProductInput4x8Bit\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::DotProductInput4x8BitKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityDotProductInput4x8BitKHR})}, {"OpCapability DotProductInput4x8BitPacked\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::DotProductInput4x8BitPackedKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityDotProductInput4x8BitPackedKHR})}, {"OpCapability DotProduct\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::DotProductKHR})}, + MakeInstruction(SpvOpCapability, {SpvCapabilityDotProductKHR})}, {"%2 = OpSDot %1 %3 %4\n", - MakeInstruction(spv::Op::OpSDotKHR, {1, 2, 3, 4})}, + MakeInstruction(SpvOpSDotKHR, {1, 2, 3, 4})}, {"%2 = OpSDot %1 %3 %4 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpSDotKHR, + SpvOpSDotKHR, {1, 2, 3, 4, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, {"%2 = OpUDot %1 %3 %4\n", - MakeInstruction(spv::Op::OpUDotKHR, {1, 2, 3, 4})}, + MakeInstruction(SpvOpUDotKHR, {1, 2, 3, 4})}, {"%2 = OpUDot %1 %3 %4 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpUDotKHR, + SpvOpUDotKHR, {1, 2, 3, 4, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, {"%2 = OpSUDot %1 %3 %4\n", - MakeInstruction(spv::Op::OpSUDotKHR, {1, 2, 3, 4})}, + MakeInstruction(SpvOpSUDotKHR, {1, 2, 3, 4})}, {"%2 = OpSUDot %1 %3 %4 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpSUDotKHR, + SpvOpSUDotKHR, {1, 2, 3, 4, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, {"%2 = OpSDotAccSat %1 %3 %4 %5\n", - MakeInstruction(spv::Op::OpSDotAccSatKHR, {1, 2, 3, 4, 5})}, + MakeInstruction(SpvOpSDotAccSatKHR, {1, 2, 3, 4, 5})}, {"%2 = OpSDotAccSat %1 %3 %4 %5 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpSDotAccSatKHR, + SpvOpSDotAccSatKHR, {1, 2, 3, 4, 5, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, {"%2 = OpUDotAccSat %1 %3 %4 %5\n", - MakeInstruction(spv::Op::OpUDotAccSatKHR, {1, 2, 3, 4, 5})}, + MakeInstruction(SpvOpUDotAccSatKHR, {1, 2, 3, 4, 5})}, {"%2 = OpUDotAccSat %1 %3 %4 %5 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpUDotAccSatKHR, + SpvOpUDotAccSatKHR, {1, 2, 3, 4, 5, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, {"%2 = OpSUDotAccSat %1 %3 %4 %5\n", - MakeInstruction(spv::Op::OpSUDotAccSatKHR, {1, 2, 3, 4, 5})}, + MakeInstruction(SpvOpSUDotAccSatKHR, {1, 2, 3, 4, 5})}, {"%2 = OpSUDotAccSat %1 %3 %4 %5 PackedVectorFormat4x8Bit\n", MakeInstruction( - spv::Op::OpSUDotAccSatKHR, + SpvOpSUDotAccSatKHR, {1, 2, 3, 4, 5, - (uint32_t) - spv::PackedVectorFormat::PackedVectorFormat4x8BitKHR})}, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR})}, }))); // SPV_KHR_bit_instructions @@ -1118,11 +1027,11 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_bit_instructions\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_bit_instructions"))}, {"OpCapability BitInstructions\n", - MakeInstruction(spv::Op::OpCapability, - {(uint32_t)spv::Capability::BitInstructions})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityBitInstructions})}, }))); // SPV_KHR_uniform_group_instructions @@ -1135,44 +1044,35 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_uniform_group_instructions\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_uniform_group_instructions"))}, {"OpCapability GroupUniformArithmeticKHR\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::GroupUniformArithmeticKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityGroupUniformArithmeticKHR})}, {"%2 = OpGroupIMulKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupIMulKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupIMulKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupFMulKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupFMulKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupFMulKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupBitwiseAndKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupBitwiseAndKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupBitwiseAndKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupBitwiseOrKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupBitwiseOrKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupBitwiseOrKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupBitwiseXorKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupBitwiseXorKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupBitwiseXorKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupLogicalAndKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupLogicalAndKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupLogicalAndKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupLogicalOrKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupLogicalOrKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupLogicalOrKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, {"%2 = OpGroupLogicalXorKHR %1 %3 Reduce %4\n", - MakeInstruction(spv::Op::OpGroupLogicalXorKHR, - {1, 2, 3, (uint32_t)spv::GroupOperation::Reduce, - 4})}, + MakeInstruction(SpvOpGroupLogicalXorKHR, + {1, 2, 3, SpvGroupOperationReduce, 4})}, }))); // SPV_KHR_subgroup_rotate @@ -1184,68 +1084,18 @@ INSTANTIATE_TEST_SUITE_P( SPV_ENV_VULKAN_1_3, SPV_ENV_OPENCL_2_1), ValuesIn(std::vector{ {"OpExtension \"SPV_KHR_subgroup_rotate\"\n", - MakeInstruction(spv::Op::OpExtension, + MakeInstruction(SpvOpExtension, MakeVector("SPV_KHR_subgroup_rotate"))}, {"OpCapability GroupNonUniformRotateKHR\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::GroupNonUniformRotateKHR})}, + MakeInstruction(SpvOpCapability, + {SpvCapabilityGroupNonUniformRotateKHR})}, {"%2 = OpGroupNonUniformRotateKHR %1 %3 %4 %5\n", - MakeInstruction(spv::Op::OpGroupNonUniformRotateKHR, + MakeInstruction(SpvOpGroupNonUniformRotateKHR, {1, 2, 3, 4, 5})}, {"%2 = OpGroupNonUniformRotateKHR %1 %3 %4 %5 %6\n", - MakeInstruction(spv::Op::OpGroupNonUniformRotateKHR, + MakeInstruction(SpvOpGroupNonUniformRotateKHR, {1, 2, 3, 4, 5, 6})}, }))); -// SPV_EXT_shader_tile_image - -INSTANTIATE_TEST_SUITE_P( - SPV_EXT_shader_tile_image, ExtensionRoundTripTest, - Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_0, - SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3), - ValuesIn(std::vector{ - {"OpExtension \"SPV_EXT_shader_tile_image\"\n", - MakeInstruction(spv::Op::OpExtension, - MakeVector("SPV_EXT_shader_tile_image"))}, - {"OpCapability TileImageColorReadAccessEXT\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::TileImageColorReadAccessEXT})}, - {"OpCapability TileImageDepthReadAccessEXT\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::TileImageDepthReadAccessEXT})}, - {"OpCapability TileImageStencilReadAccessEXT\n", - MakeInstruction( - spv::Op::OpCapability, - {(uint32_t)spv::Capability::TileImageStencilReadAccessEXT})}, - {"OpExecutionMode %1 NonCoherentColorAttachmentReadEXT\n", - MakeInstruction(spv::Op::OpExecutionMode, - {1, (uint32_t)spv::ExecutionMode:: - NonCoherentColorAttachmentReadEXT})}, - {"OpExecutionMode %1 NonCoherentDepthAttachmentReadEXT\n", - MakeInstruction(spv::Op::OpExecutionMode, - {1, (uint32_t)spv::ExecutionMode:: - NonCoherentDepthAttachmentReadEXT})}, - {"OpExecutionMode %1 NonCoherentStencilAttachmentReadEXT\n", - MakeInstruction(spv::Op::OpExecutionMode, - {1, (uint32_t)spv::ExecutionMode:: - NonCoherentStencilAttachmentReadEXT})}, - {"%2 = OpColorAttachmentReadEXT %1 %3\n", - MakeInstruction(spv::Op::OpColorAttachmentReadEXT, {1, 2, 3})}, - {"%2 = OpColorAttachmentReadEXT %1 %3 %4\n", - MakeInstruction(spv::Op::OpColorAttachmentReadEXT, {1, 2, 3, 4})}, - {"%2 = OpDepthAttachmentReadEXT %1\n", - MakeInstruction(spv::Op::OpDepthAttachmentReadEXT, {1, 2})}, - {"%2 = OpDepthAttachmentReadEXT %1 %3\n", - MakeInstruction(spv::Op::OpDepthAttachmentReadEXT, {1, 2, 3})}, - {"%2 = OpStencilAttachmentReadEXT %1\n", - MakeInstruction(spv::Op::OpStencilAttachmentReadEXT, {1, 2})}, - {"%2 = OpStencilAttachmentReadEXT %1 %3\n", - MakeInstruction(spv::Op::OpStencilAttachmentReadEXT, {1, 2, 3})}, - }))); - } // namespace } // namespace spvtools diff --git a/test/text_to_binary.function_test.cpp b/test/text_to_binary.function_test.cpp index 9361d6c6..55a8e6ce 100644 --- a/test/text_to_binary.function_test.cpp +++ b/test/text_to_binary.function_test.cpp @@ -33,25 +33,25 @@ using ::testing::Eq; // Test OpFunction using OpFunctionControlTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(OpFunctionControlTest, AnySingleFunctionControlMask) { const std::string input = "%result_id = OpFunction %result_type " + GetParam().name() + " %function_type "; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpFunction, - {1, 2, (uint32_t)GetParam().value(), 3}))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpFunction, {1, 2, GetParam().value(), 3}))); } // clang-format off -#define CASE(VALUE,NAME) { spv::FunctionControlMask::VALUE, NAME } +#define CASE(VALUE,NAME) { SpvFunctionControl##VALUE, NAME } INSTANTIATE_TEST_SUITE_P(TextToBinaryFunctionTest, OpFunctionControlTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(MaskNone, "None"), - CASE(Inline, "Inline"), - CASE(DontInline, "DontInline"), - CASE(Pure, "Pure"), - CASE(Const, "Const"), + CASE(InlineMask, "Inline"), + CASE(DontInlineMask, "DontInline"), + CASE(PureMask, "Pure"), + CASE(ConstMask, "Const"), })); #undef CASE // clang-format on @@ -61,12 +61,11 @@ TEST_F(OpFunctionControlTest, CombinedFunctionControlMask) { // the instruction parsing logic with spvTextParseMask. const std::string input = "%result_id = OpFunction %result_type Inline|Pure|Const %function_type"; - const uint32_t expected_mask = uint32_t(spv::FunctionControlMask::Inline | - spv::FunctionControlMask::Pure | - spv::FunctionControlMask::Const); - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpFunction, {1, 2, expected_mask, 3}))); + const uint32_t expected_mask = SpvFunctionControlInlineMask | + SpvFunctionControlPureMask | + SpvFunctionControlConstMask; + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpFunction, {1, 2, expected_mask, 3}))); } TEST_F(OpFunctionControlTest, WrongFunctionControl) { diff --git a/test/text_to_binary.group_test.cpp b/test/text_to_binary.group_test.cpp index 606e00e9..becc3aa6 100644 --- a/test/text_to_binary.group_test.cpp +++ b/test/text_to_binary.group_test.cpp @@ -32,20 +32,20 @@ using ::testing::Eq; // Test GroupOperation enum using GroupOperationTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(GroupOperationTest, AnyGroupOperation) { const std::string input = "%result = OpGroupIAdd %type %scope " + GetParam().name() + " %x"; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpGroupIAdd, - {1, 2, 3, (uint32_t)GetParam().value(), 4}))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, GetParam().value(), 4}))); } // clang-format off -#define CASE(NAME) { spv::GroupOperation::NAME, #NAME} +#define CASE(NAME) { SpvGroupOperation##NAME, #NAME} INSTANTIATE_TEST_SUITE_P(TextToBinaryGroupOperation, GroupOperationTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(Reduce), CASE(InclusiveScan), CASE(ExclusiveScan), diff --git a/test/text_to_binary.image_test.cpp b/test/text_to_binary.image_test.cpp index 3e7a560a..8d8ff432 100644 --- a/test/text_to_binary.image_test.cpp +++ b/test/text_to_binary.image_test.cpp @@ -45,11 +45,11 @@ TEST_P(ImageOperandsTest, Sample) { const std::string input = "%2 = OpImageFetch %1 %3 %4" + GetParam().image_operands + "\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpImageFetch, {1, 2, 3, 4}, + Eq(MakeInstruction(SpvOpImageFetch, {1, 2, 3, 4}, GetParam().expected_mask_and_operands))); } -#define MASK(NAME) uint32_t(spv::ImageOperandsMask::NAME) +#define MASK(NAME) SpvImageOperands##NAME##Mask INSTANTIATE_TEST_SUITE_P( TextToBinaryImageOperandsAny, ImageOperandsTest, ::testing::ValuesIn(std::vector{ @@ -68,7 +68,7 @@ INSTANTIATE_TEST_SUITE_P( {" MinLod %5", {MASK(MinLod), 5}}, })); #undef MASK -#define MASK(NAME) static_cast(spv::ImageOperandsMask::NAME) +#define MASK(NAME) static_cast(SpvImageOperands##NAME##Mask) INSTANTIATE_TEST_SUITE_P( TextToBinaryImageOperandsCombination, ImageOperandsTest, ::testing::ValuesIn(std::vector{ @@ -110,7 +110,7 @@ using OpImageTest = TextToBinaryTest; TEST_F(OpImageTest, Valid) { const std::string input = "%2 = OpImage %1 %3\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpImage, {1, 2, 3}))); + Eq(MakeInstruction(SpvOpImage, {1, 2, 3}))); // Test the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input); @@ -153,7 +153,7 @@ using OpImageSparseReadTest = TextToBinaryTest; TEST_F(OpImageSparseReadTest, OnlyRequiredOperands) { const std::string input = "%2 = OpImageSparseRead %1 %3 %4\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpImageSparseRead, {1, 2, 3, 4}))); + Eq(MakeInstruction(SpvOpImageSparseRead, {1, 2, 3, 4}))); // Test the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input); } @@ -167,13 +167,13 @@ TEST_P(ImageSparseReadImageOperandsTest, Sample) { const std::string input = "%2 = OpImageSparseRead %1 %3 %4" + GetParam().image_operands + "\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpImageSparseRead, {1, 2, 3, 4}, + Eq(MakeInstruction(SpvOpImageSparseRead, {1, 2, 3, 4}, GetParam().expected_mask_and_operands))); // Test the disassembler. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input); } -#define MASK(NAME) uint32_t(spv::ImageOperandsMask::NAME) +#define MASK(NAME) SpvImageOperands##NAME##Mask INSTANTIATE_TEST_SUITE_P(ImageSparseReadImageOperandsAny, ImageSparseReadImageOperandsTest, ::testing::ValuesIn(std::vector{ @@ -190,7 +190,7 @@ INSTANTIATE_TEST_SUITE_P(ImageSparseReadImageOperandsAny, {" MinLod %5", {MASK(MinLod), 5}}, })); #undef MASK -#define MASK(NAME) static_cast(spv::ImageOperandsMask::NAME) +#define MASK(NAME) static_cast(SpvImageOperands##NAME##Mask) INSTANTIATE_TEST_SUITE_P( ImageSparseReadImageOperandsCombination, ImageSparseReadImageOperandsTest, ::testing::ValuesIn(std::vector{ diff --git a/test/text_to_binary.memory_test.cpp b/test/text_to_binary.memory_test.cpp index 629ab661..f94c134a 100644 --- a/test/text_to_binary.memory_test.cpp +++ b/test/text_to_binary.memory_test.cpp @@ -35,53 +35,51 @@ using ::testing::HasSubstr; // Test assembly of Memory Access masks using MemoryAccessTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(MemoryAccessTest, AnySingleMemoryAccessMask) { std::stringstream input; input << "OpStore %ptr %value " << GetParam().name(); for (auto operand : GetParam().operands()) input << " " << operand; - EXPECT_THAT( - CompiledInstructions(input.str()), - Eq(MakeInstruction(spv::Op::OpStore, {1, 2, (uint32_t)GetParam().value()}, - GetParam().operands()))); + EXPECT_THAT(CompiledInstructions(input.str()), + Eq(MakeInstruction(SpvOpStore, {1, 2, GetParam().value()}, + GetParam().operands()))); } INSTANTIATE_TEST_SUITE_P( TextToBinaryMemoryAccessTest, MemoryAccessTest, - ::testing::ValuesIn(std::vector>{ - {spv::MemoryAccessMask::MaskNone, "None", {}}, - {spv::MemoryAccessMask::Volatile, "Volatile", {}}, - {spv::MemoryAccessMask::Aligned, "Aligned", {16}}, - {spv::MemoryAccessMask::Nontemporal, "Nontemporal", {}}, + ::testing::ValuesIn(std::vector>{ + {SpvMemoryAccessMaskNone, "None", {}}, + {SpvMemoryAccessVolatileMask, "Volatile", {}}, + {SpvMemoryAccessAlignedMask, "Aligned", {16}}, + {SpvMemoryAccessNontemporalMask, "Nontemporal", {}}, })); TEST_F(TextToBinaryTest, CombinedMemoryAccessMask) { const std::string input = "OpStore %ptr %value Volatile|Aligned 16"; - const uint32_t expected_mask = uint32_t(spv::MemoryAccessMask::Volatile | - spv::MemoryAccessMask::Aligned); + const uint32_t expected_mask = + SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask; EXPECT_THAT(expected_mask, Eq(3u)); EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpStore, {1, 2, expected_mask, 16}))); + Eq(MakeInstruction(SpvOpStore, {1, 2, expected_mask, 16}))); } // Test Storage Class enum values using StorageClassTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(StorageClassTest, AnyStorageClass) { const std::string input = "%1 = OpVariable %2 " + GetParam().name(); EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpVariable, - {1, 2, (uint32_t)GetParam().value()}))); + Eq(MakeInstruction(SpvOpVariable, {1, 2, GetParam().value()}))); } // clang-format off -#define CASE(NAME) { spv::StorageClass::NAME, #NAME, {} } +#define CASE(NAME) { SpvStorageClass##NAME, #NAME, {} } INSTANTIATE_TEST_SUITE_P( TextToBinaryStorageClassTest, StorageClassTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(UniformConstant), CASE(Input), CASE(Uniform), @@ -105,7 +103,7 @@ using MemoryRoundTripTest = RoundTripTest; TEST_F(MemoryRoundTripTest, OpPtrEqualGood) { std::string spirv = "%2 = OpPtrEqual %1 %3 %4\n"; EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), - Eq(MakeInstruction(spv::Op::OpPtrEqual, {1, 2, 3, 4}))); + Eq(MakeInstruction(SpvOpPtrEqual, {1, 2, 3, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully( spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); EXPECT_THAT(disassembly, Eq(spirv)); @@ -122,7 +120,7 @@ TEST_F(MemoryRoundTripTest, OpPtrEqualV13Bad) { TEST_F(MemoryRoundTripTest, OpPtrNotEqualGood) { std::string spirv = "%2 = OpPtrNotEqual %1 %3 %4\n"; EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), - Eq(MakeInstruction(spv::Op::OpPtrNotEqual, {1, 2, 3, 4}))); + Eq(MakeInstruction(SpvOpPtrNotEqual, {1, 2, 3, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully( spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); EXPECT_THAT(disassembly, Eq(spirv)); @@ -139,7 +137,7 @@ TEST_F(MemoryRoundTripTest, OpPtrNotEqualV13Bad) { TEST_F(MemoryRoundTripTest, OpPtrDiffGood) { std::string spirv = "%2 = OpPtrDiff %1 %3 %4\n"; EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), - Eq(MakeInstruction(spv::Op::OpPtrDiff, {1, 2, 3, 4}))); + Eq(MakeInstruction(SpvOpPtrDiff, {1, 2, 3, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully( spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); EXPECT_THAT(disassembly, Eq(spirv)); @@ -159,7 +157,7 @@ TEST_F(MemoryRoundTripTest, OpPtrDiffV13Good) { TEST_F(MemoryRoundTripTest, OpCopyMemoryNoMemAccessGood) { std::string spirv = "OpCopyMemory %1 %2\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -181,7 +179,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTooManyArgsBad) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNoneGood) { std::string spirv = "OpCopyMemory %1 %2 None\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 0}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 0}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -190,7 +188,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNoneGood) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVolatileGood) { std::string spirv = "OpCopyMemory %1 %2 Volatile\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -199,7 +197,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVolatileGood) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAligned8Good) { std::string spirv = "OpCopyMemory %1 %2 Aligned 8\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 2, 8}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 2, 8}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -208,7 +206,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAligned8Good) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) { std::string spirv = "OpCopyMemory %1 %2 Nontemporal\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 4}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -217,7 +215,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) { std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailable %3\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 8, 3}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 8, 3}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -226,7 +224,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) { std::string spirv = "OpCopyMemory %1 %2 MakePointerVisible %3\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 16, 3}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 16, 3}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -235,7 +233,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) { TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) { std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointer\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 32}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 32}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -247,7 +245,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessMixedGood) { "Volatile|Aligned|Nontemporal|MakePointerAvailable|" "MakePointerVisible|NonPrivatePointer 16 %3 %4\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 63, 16, 3, 4}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 63, 16, 3, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -257,7 +255,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV13Good) { std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n"; // Note: This will assemble but should not validate for SPIR-V 1.3 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -266,7 +264,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV13Good) { TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV14Good) { std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n"; EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1}))); + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -277,9 +275,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) { "OpCopyMemory %1 %2 Volatile|Nontemporal|" "MakePointerVisible %3 " "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4\n"; - EXPECT_THAT( - CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 21, 3, 42, 16, 4}))); + EXPECT_THAT(CompiledInstructions(spirv), + Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 21, 3, 42, 16, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -290,7 +287,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedNoMemAccessGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -312,7 +309,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooManyArgsBad) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNoneGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 None\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 0}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 0}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -321,7 +318,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNoneGood) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVolatileGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -330,7 +327,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVolatileGood) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAligned8Good) { std::string spirv = "OpCopyMemorySized %1 %2 %3 Aligned 8\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 2, 8}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 2, 8}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -339,7 +336,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAligned8Good) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 Nontemporal\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 4}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -348,7 +345,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailable %4\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 8, 4}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 8, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -356,9 +353,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisible %4\n"; - EXPECT_THAT( - CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 16, 4}))); + EXPECT_THAT(CompiledInstructions(spirv), + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 16, 4}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -367,7 +363,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) { std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointer\n"; EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 32}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 32}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -380,7 +376,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessMixedGood) { "MakePointerVisible|NonPrivatePointer 16 %4 %5\n"; EXPECT_THAT( CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -390,7 +386,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV13Good) { std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n"; // Note: This will assemble but should not validate for SPIR-V 1.3 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -399,7 +395,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV13Good) { TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV14Good) { std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n"; EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1}))); + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1, 1}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); @@ -410,9 +406,9 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessMixedV14Good) { "OpCopyMemorySized %1 %2 %3 Volatile|Nontemporal|" "MakePointerVisible %4 " "Aligned|MakePointerAvailable|NonPrivatePointer 16 %5\n"; - EXPECT_THAT(CompiledInstructions(spirv), - Eq(MakeInstruction(spv::Op::OpCopyMemorySized, - {1, 2, 3, 21, 4, 42, 16, 5}))); + EXPECT_THAT( + CompiledInstructions(spirv), + Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 21, 4, 42, 16, 5}))); std::string disassembly = EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); EXPECT_THAT(disassembly, Eq(spirv)); diff --git a/test/text_to_binary.misc_test.cpp b/test/text_to_binary.misc_test.cpp index 9ee425a1..03b1e091 100644 --- a/test/text_to_binary.misc_test.cpp +++ b/test/text_to_binary.misc_test.cpp @@ -29,8 +29,7 @@ using ::testing::Eq; using TextToBinaryMisc = spvtest::TextToBinaryTest; TEST_F(TextToBinaryMisc, OpNop) { - EXPECT_THAT(CompiledInstructions("OpNop"), - Eq(MakeInstruction(spv::Op::OpNop, {}))); + EXPECT_THAT(CompiledInstructions("OpNop"), Eq(MakeInstruction(SpvOpNop, {}))); } TEST_F(TextToBinaryMisc, OpUndef) { @@ -38,8 +37,7 @@ TEST_F(TextToBinaryMisc, OpUndef) { %u = OpUndef %f32)"); const uint32_t typeID = 1; EXPECT_THAT(code[1], Eq(typeID)); - EXPECT_THAT(Subvector(code, 3), - Eq(MakeInstruction(spv::Op::OpUndef, {typeID, 2}))); + EXPECT_THAT(Subvector(code, 3), Eq(MakeInstruction(SpvOpUndef, {typeID, 2}))); } TEST_F(TextToBinaryMisc, OpWrong) { diff --git a/test/text_to_binary.mode_setting_test.cpp b/test/text_to_binary.mode_setting_test.cpp index c62ba3eb..7f15c8b4 100644 --- a/test/text_to_binary.mode_setting_test.cpp +++ b/test/text_to_binary.mode_setting_test.cpp @@ -46,9 +46,9 @@ struct MemoryModelCase { uint32_t get_memory_value() const { return static_cast(memory_value); } - spv::AddressingModel addressing_value; + SpvAddressingModel addressing_value; std::string addressing_name; - spv::MemoryModel memory_value; + SpvMemoryModel memory_value; std::string memory_name; }; @@ -58,16 +58,16 @@ using OpMemoryModelTest = TEST_P(OpMemoryModelTest, AnyMemoryModelCase) { const std::string input = "OpMemoryModel " + GetParam().addressing_name + " " + GetParam().memory_name; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpMemoryModel, - {GetParam().get_addressing_value(), - GetParam().get_memory_value()}))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpMemoryModel, {GetParam().get_addressing_value(), + GetParam().get_memory_value()}))); } -#define CASE(ADDRESSING, MEMORY) \ - { \ - spv::AddressingModel::ADDRESSING, #ADDRESSING, spv::MemoryModel::MEMORY, \ - #MEMORY \ +#define CASE(ADDRESSING, MEMORY) \ + { \ + SpvAddressingModel##ADDRESSING, #ADDRESSING, SpvMemoryModel##MEMORY, \ + #MEMORY \ } // clang-format off INSTANTIATE_TEST_SUITE_P(TextToBinaryMemoryModel, OpMemoryModelTest, @@ -97,7 +97,7 @@ struct EntryPointCase { uint32_t get_execution_value() const { return static_cast(execution_value); } - spv::ExecutionModel execution_value; + SpvExecutionModel execution_value; std::string execution_name; std::string entry_point_name; }; @@ -109,14 +109,14 @@ TEST_P(OpEntryPointTest, AnyEntryPointCase) { // TODO(dneto): utf-8, escaping, quoting cases for entry point name. const std::string input = "OpEntryPoint " + GetParam().execution_name + " %1 \"" + GetParam().entry_point_name + "\""; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpEntryPoint, - {GetParam().get_execution_value(), 1}, - MakeVector(GetParam().entry_point_name)))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpEntryPoint, {GetParam().get_execution_value(), 1}, + MakeVector(GetParam().entry_point_name)))); } // clang-format off -#define CASE(NAME) spv::ExecutionModel::NAME, #NAME +#define CASE(NAME) SpvExecutionModel##NAME, #NAME INSTANTIATE_TEST_SUITE_P(TextToBinaryEntryPoint, OpEntryPointTest, ValuesIn(std::vector{ { CASE(Vertex), "" }, @@ -137,7 +137,7 @@ TEST_F(OpEntryPointTest, WrongModel) { // Test OpExecutionMode using OpExecutionModeTest = spvtest::TextToBinaryTestBase< - TestWithParam>>>; + TestWithParam>>>; TEST_P(OpExecutionModeTest, AnyExecutionMode) { // This string should assemble, but should not validate. @@ -146,16 +146,16 @@ TEST_P(OpExecutionModeTest, AnyExecutionMode) { for (auto operand : std::get<1>(GetParam()).operands()) input << " " << operand; EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())), - Eq(MakeInstruction(spv::Op::OpExecutionMode, + Eq(MakeInstruction(SpvOpExecutionMode, {1, std::get<1>(GetParam()).value()}, std::get<1>(GetParam()).operands()))); } -#define CASE(NAME) spv::ExecutionMode::NAME, #NAME +#define CASE(NAME) SpvExecutionMode##NAME, #NAME INSTANTIATE_TEST_SUITE_P( TextToBinaryExecutionMode, OpExecutionModeTest, Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ // The operand literal values are arbitrarily chosen, // but there are the right number of them. {CASE(Invocations), {101}}, @@ -195,7 +195,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( TextToBinaryExecutionModeV11, OpExecutionModeTest, Combine(Values(SPV_ENV_UNIVERSAL_1_1), - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ {CASE(Initializer)}, {CASE(Finalizer)}, {CASE(SubgroupSize), {12}}, @@ -216,18 +216,18 @@ TEST_F(OpExecutionModeTest, TooManyModes) { // Test OpCapability using OpCapabilityTest = - spvtest::TextToBinaryTestBase>>; + spvtest::TextToBinaryTestBase>>; TEST_P(OpCapabilityTest, AnyCapability) { const std::string input = "OpCapability " + GetParam().name(); EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpCapability, {GetParam().value()}))); + Eq(MakeInstruction(SpvOpCapability, {GetParam().value()}))); } // clang-format off -#define CASE(NAME) { spv::Capability::NAME, #NAME } +#define CASE(NAME) { SpvCapability##NAME, #NAME } INSTANTIATE_TEST_SUITE_P(TextToBinaryCapability, OpCapabilityTest, - ValuesIn(std::vector>{ + ValuesIn(std::vector>{ CASE(Matrix), CASE(Shader), CASE(Geometry), diff --git a/test/text_to_binary.pipe_storage_test.cpp b/test/text_to_binary.pipe_storage_test.cpp index ef899a27..955f5ef8 100644 --- a/test/text_to_binary.pipe_storage_test.cpp +++ b/test/text_to_binary.pipe_storage_test.cpp @@ -28,7 +28,7 @@ using OpTypePipeStorageTest = spvtest::TextToBinaryTest; TEST_F(OpTypePipeStorageTest, OpcodeAssemblesInV10) { EXPECT_THAT( CompiledInstructions("%res = OpTypePipeStorage", SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpTypePipeStorage, {1}))); + Eq(MakeInstruction(SpvOpTypePipeStorage, {1}))); } TEST_F(OpTypePipeStorageTest, ArgumentCount) { @@ -38,19 +38,18 @@ TEST_F(OpTypePipeStorageTest, ArgumentCount) { "'OpTypePipeStorage'.")); EXPECT_THAT( CompiledInstructions("%res = OpTypePipeStorage", SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpTypePipeStorage, {1}))); + Eq(MakeInstruction(SpvOpTypePipeStorage, {1}))); EXPECT_THAT(CompileFailure("%res = OpTypePipeStorage %1 %2 %3 %4 %5", SPV_ENV_UNIVERSAL_1_1), - Eq("'=' expected after result id but found '%2'.")); + Eq("'=' expected after result id.")); } using OpConstantPipeStorageTest = spvtest::TextToBinaryTest; TEST_F(OpConstantPipeStorageTest, OpcodeAssemblesInV10) { - EXPECT_THAT( - CompiledInstructions("%1 = OpConstantPipeStorage %2 3 4 5", - SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpConstantPipeStorage, {1, 2, 3, 4, 5}))); + EXPECT_THAT(CompiledInstructions("%1 = OpConstantPipeStorage %2 3 4 5", + SPV_ENV_UNIVERSAL_1_0), + Eq(MakeInstruction(SpvOpConstantPipeStorage, {1, 2, 3, 4, 5}))); } TEST_F(OpConstantPipeStorageTest, ArgumentCount) { @@ -66,13 +65,12 @@ TEST_F(OpConstantPipeStorageTest, ArgumentCount) { SPV_ENV_UNIVERSAL_1_1), Eq("Expected operand for OpConstantPipeStorage instruction, but " "found the end of the stream.")); - EXPECT_THAT( - CompiledInstructions("%1 = OpConstantPipeStorage %2 3 4 5", - SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpConstantPipeStorage, {1, 2, 3, 4, 5}))); + EXPECT_THAT(CompiledInstructions("%1 = OpConstantPipeStorage %2 3 4 5", + SPV_ENV_UNIVERSAL_1_1), + Eq(MakeInstruction(SpvOpConstantPipeStorage, {1, 2, 3, 4, 5}))); EXPECT_THAT(CompileFailure("%1 = OpConstantPipeStorage %2 3 4 5 %6 %7", SPV_ENV_UNIVERSAL_1_1), - Eq("'=' expected after result id but found '%7'.")); + Eq("'=' expected after result id.")); } TEST_F(OpConstantPipeStorageTest, ArgumentTypes) { @@ -93,10 +91,9 @@ TEST_F(OpConstantPipeStorageTest, ArgumentTypes) { using OpCreatePipeFromPipeStorageTest = spvtest::TextToBinaryTest; TEST_F(OpCreatePipeFromPipeStorageTest, OpcodeAssemblesInV10) { - EXPECT_THAT( - CompiledInstructions("%1 = OpCreatePipeFromPipeStorage %2 %3", - SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpCreatePipeFromPipeStorage, {1, 2, 3}))); + EXPECT_THAT(CompiledInstructions("%1 = OpCreatePipeFromPipeStorage %2 %3", + SPV_ENV_UNIVERSAL_1_0), + Eq(MakeInstruction(SpvOpCreatePipeFromPipeStorage, {1, 2, 3}))); } TEST_F(OpCreatePipeFromPipeStorageTest, ArgumentCount) { @@ -112,13 +109,12 @@ TEST_F(OpCreatePipeFromPipeStorageTest, ArgumentCount) { SPV_ENV_UNIVERSAL_1_1), Eq("Expected operand for OpCreatePipeFromPipeStorage " "instruction, but found the next instruction instead.")); - EXPECT_THAT( - CompiledInstructions("%1 = OpCreatePipeFromPipeStorage %2 %3", - SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpCreatePipeFromPipeStorage, {1, 2, 3}))); + EXPECT_THAT(CompiledInstructions("%1 = OpCreatePipeFromPipeStorage %2 %3", + SPV_ENV_UNIVERSAL_1_1), + Eq(MakeInstruction(SpvOpCreatePipeFromPipeStorage, {1, 2, 3}))); EXPECT_THAT(CompileFailure("%1 = OpCreatePipeFromPipeStorage %2 %3 %4 %5", SPV_ENV_UNIVERSAL_1_1), - Eq("'=' expected after result id but found '%5'.")); + Eq("'=' expected after result id.")); } TEST_F(OpCreatePipeFromPipeStorageTest, ArgumentTypes) { diff --git a/test/text_to_binary.reserved_sampling_test.cpp b/test/text_to_binary.reserved_sampling_test.cpp index abc16672..42e4e2ae 100644 --- a/test/text_to_binary.reserved_sampling_test.cpp +++ b/test/text_to_binary.reserved_sampling_test.cpp @@ -30,36 +30,33 @@ using ReservedSamplingInstTest = RoundTripTest; TEST_F(ReservedSamplingInstTest, OpImageSparseSampleProjImplicitLod) { std::string input = "%2 = OpImageSparseSampleProjImplicitLod %1 %3 %4\n"; - EXPECT_THAT(CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpImageSparseSampleProjImplicitLod, - {1, 2, 3, 4}))); + EXPECT_THAT( + CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), + Eq(MakeInstruction(SpvOpImageSparseSampleProjImplicitLod, {1, 2, 3, 4}))); } TEST_F(ReservedSamplingInstTest, OpImageSparseSampleProjExplicitLod) { std::string input = "%2 = OpImageSparseSampleProjExplicitLod %1 %3 %4 Lod %5\n"; EXPECT_THAT(CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction( - spv::Op::OpImageSparseSampleProjExplicitLod, - {1, 2, 3, 4, (uint32_t)spv::ImageOperandsMask::Lod, 5}))); + Eq(MakeInstruction(SpvOpImageSparseSampleProjExplicitLod, + {1, 2, 3, 4, SpvImageOperandsLodMask, 5}))); } TEST_F(ReservedSamplingInstTest, OpImageSparseSampleProjDrefImplicitLod) { std::string input = "%2 = OpImageSparseSampleProjDrefImplicitLod %1 %3 %4 %5\n"; - EXPECT_THAT( - CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpImageSparseSampleProjDrefImplicitLod, - {1, 2, 3, 4, 5}))); + EXPECT_THAT(CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), + Eq(MakeInstruction(SpvOpImageSparseSampleProjDrefImplicitLod, + {1, 2, 3, 4, 5}))); } TEST_F(ReservedSamplingInstTest, OpImageSparseSampleProjDrefExplicitLod) { std::string input = "%2 = OpImageSparseSampleProjDrefExplicitLod %1 %3 %4 %5 Lod %6\n"; EXPECT_THAT(CompiledInstructions(input, SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction( - spv::Op::OpImageSparseSampleProjDrefExplicitLod, - {1, 2, 3, 4, 5, (uint32_t)spv::ImageOperandsMask::Lod, 6}))); + Eq(MakeInstruction(SpvOpImageSparseSampleProjDrefExplicitLod, + {1, 2, 3, 4, 5, SpvImageOperandsLodMask, 6}))); } } // namespace diff --git a/test/text_to_binary.subgroup_dispatch_test.cpp b/test/text_to_binary.subgroup_dispatch_test.cpp index 45d77806..8c404457 100644 --- a/test/text_to_binary.subgroup_dispatch_test.cpp +++ b/test/text_to_binary.subgroup_dispatch_test.cpp @@ -35,7 +35,7 @@ TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, OpcodeAssemblesInV10) { CompiledInstructions("%res = OpGetKernelLocalSizeForSubgroupCount %type " "%sgcount %invoke %param %param_size %param_align", SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpGetKernelLocalSizeForSubgroupCount, + Eq(MakeInstruction(SpvOpGetKernelLocalSizeForSubgroupCount, {1, 2, 3, 4, 5, 6, 7}))); } @@ -57,7 +57,7 @@ TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, ArgumentCount) { CompiledInstructions("%res = OpGetKernelLocalSizeForSubgroupCount %type " "%sgcount %invoke %param %param_size %param_align", SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpGetKernelLocalSizeForSubgroupCount, + Eq(MakeInstruction(SpvOpGetKernelLocalSizeForSubgroupCount, {1, 2, 3, 4, 5, 6, 7}))); EXPECT_THAT( CompileFailure("%res = OpGetKernelLocalSizeForSubgroupCount %type " @@ -81,11 +81,11 @@ TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, ArgumentTypes) { using OpGetKernelMaxNumSubgroupsTest = spvtest::TextToBinaryTest; TEST_F(OpGetKernelMaxNumSubgroupsTest, OpcodeAssemblesInV10) { - EXPECT_THAT(CompiledInstructions("%res = OpGetKernelMaxNumSubgroups %type " - "%invoke %param %param_size %param_align", - SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpGetKernelMaxNumSubgroups, - {1, 2, 3, 4, 5, 6}))); + EXPECT_THAT( + CompiledInstructions("%res = OpGetKernelMaxNumSubgroups %type " + "%invoke %param %param_size %param_align", + SPV_ENV_UNIVERSAL_1_0), + Eq(MakeInstruction(SpvOpGetKernelMaxNumSubgroups, {1, 2, 3, 4, 5, 6}))); } TEST_F(OpGetKernelMaxNumSubgroupsTest, ArgumentCount) { @@ -101,11 +101,11 @@ TEST_F(OpGetKernelMaxNumSubgroupsTest, ArgumentCount) { SPV_ENV_UNIVERSAL_1_1), Eq("Expected operand for OpGetKernelMaxNumSubgroups instruction, " "but found the end of the stream.")); - EXPECT_THAT(CompiledInstructions("%res = OpGetKernelMaxNumSubgroups %type " - "%invoke %param %param_size %param_align", - SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpGetKernelMaxNumSubgroups, - {1, 2, 3, 4, 5, 6}))); + EXPECT_THAT( + CompiledInstructions("%res = OpGetKernelMaxNumSubgroups %type " + "%invoke %param %param_size %param_align", + SPV_ENV_UNIVERSAL_1_1), + Eq(MakeInstruction(SpvOpGetKernelMaxNumSubgroups, {1, 2, 3, 4, 5, 6}))); EXPECT_THAT(CompileFailure("%res = OpGetKernelMaxNumSubgroups %type %invoke " "%param %param_size %param_align %extra", SPV_ENV_UNIVERSAL_1_1), diff --git a/test/text_to_binary.type_declaration_test.cpp b/test/text_to_binary.type_declaration_test.cpp index 770f298b..65a23554 100644 --- a/test/text_to_binary.type_declaration_test.cpp +++ b/test/text_to_binary.type_declaration_test.cpp @@ -32,34 +32,32 @@ using ::testing::Eq; // Test Dim enums via OpTypeImage using DimTest = - spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; + spvtest::TextToBinaryTestBase<::testing::TestWithParam>>; TEST_P(DimTest, AnyDim) { const std::string input = "%1 = OpTypeImage %2 " + GetParam().name() + " 2 3 0 4 Rgba8\n"; - EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpTypeImage, - {1, 2, (uint32_t)GetParam().value(), 2, 3, 0, - 4, (uint32_t)spv::ImageFormat::Rgba8}))); + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(SpvOpTypeImage, {1, 2, GetParam().value(), 2, 3, 0, 4, + SpvImageFormatRgba8}))); // Check the disassembler as well. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); } // clang-format off -#define CASE(NAME) {spv::Dim::NAME, #NAME} -#define CASE1(DIM, NAME) {spv::Dim::DIM, #NAME} +#define CASE(NAME) {SpvDim##NAME, #NAME} INSTANTIATE_TEST_SUITE_P( TextToBinaryDim, DimTest, - ::testing::ValuesIn(std::vector>{ - CASE1(Dim1D, 1D), - CASE1(Dim2D, 2D), - CASE1(Dim3D, 3D), + ::testing::ValuesIn(std::vector>{ + CASE(1D), + CASE(2D), + CASE(3D), CASE(Cube), CASE(Rect), CASE(Buffer), CASE(SubpassData), - CASE(TileImageDataEXT), })); #undef CASE // clang-format on @@ -72,24 +70,23 @@ TEST_F(DimTest, WrongDim) { // Test ImageFormat enums via OpTypeImage using ImageFormatTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(ImageFormatTest, AnyImageFormatAndNoAccessQualifier) { const std::string input = "%1 = OpTypeImage %2 1D 2 3 0 4 " + GetParam().name() + "\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpTypeImage, - {1, 2, (uint32_t)spv::Dim::Dim1D, 2, 3, 0, 4, - GetParam().value()}))); + Eq(MakeInstruction(SpvOpTypeImage, {1, 2, SpvDim1D, 2, 3, 0, 4, + GetParam().value()}))); // Check the disassembler as well. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); } // clang-format off -#define CASE(NAME) {spv::ImageFormat::NAME, #NAME} +#define CASE(NAME) {SpvImageFormat##NAME, #NAME} INSTANTIATE_TEST_SUITE_P( TextToBinaryImageFormat, ImageFormatTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(Unknown), CASE(Rgba32f), CASE(Rgba16f), @@ -141,25 +138,24 @@ TEST_F(ImageFormatTest, WrongFormat) { // Test AccessQualifier enums via OpTypeImage. using ImageAccessQualifierTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(ImageAccessQualifierTest, AnyAccessQualifier) { const std::string input = "%1 = OpTypeImage %2 1D 2 3 0 4 Rgba8 " + GetParam().name() + "\n"; EXPECT_THAT(CompiledInstructions(input), - Eq(MakeInstruction( - spv::Op::OpTypeImage, - {1, 2, (uint32_t)spv::Dim::Dim1D, 2, 3, 0, 4, - (uint32_t)spv::ImageFormat::Rgba8, GetParam().value()}))); + Eq(MakeInstruction(SpvOpTypeImage, + {1, 2, SpvDim1D, 2, 3, 0, 4, + SpvImageFormatRgba8, GetParam().value()}))); // Check the disassembler as well. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); } // clang-format off -#define CASE(NAME) {spv::AccessQualifier::NAME, #NAME} +#define CASE(NAME) {SpvAccessQualifier##NAME, #NAME} INSTANTIATE_TEST_SUITE_P( AccessQualifier, ImageAccessQualifierTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(ReadOnly), CASE(WriteOnly), CASE(ReadWrite), @@ -170,22 +166,21 @@ INSTANTIATE_TEST_SUITE_P( // Test AccessQualifier enums via OpTypePipe. using OpTypePipeTest = spvtest::TextToBinaryTestBase< - ::testing::TestWithParam>>; + ::testing::TestWithParam>>; TEST_P(OpTypePipeTest, AnyAccessQualifier) { const std::string input = "%1 = OpTypePipe " + GetParam().name() + "\n"; - EXPECT_THAT( - CompiledInstructions(input), - Eq(MakeInstruction(spv::Op::OpTypePipe, {1, GetParam().value()}))); + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(SpvOpTypePipe, {1, GetParam().value()}))); // Check the disassembler as well. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input)); } // clang-format off -#define CASE(NAME) {spv::AccessQualifier::NAME, #NAME} +#define CASE(NAME) {SpvAccessQualifier##NAME, #NAME} INSTANTIATE_TEST_SUITE_P( TextToBinaryTypePipe, OpTypePipeTest, - ::testing::ValuesIn(std::vector>{ + ::testing::ValuesIn(std::vector>{ CASE(ReadOnly), CASE(WriteOnly), CASE(ReadWrite), @@ -200,12 +195,12 @@ TEST_F(OpTypePipeTest, WrongAccessQualifier) { using OpTypeForwardPointerTest = spvtest::TextToBinaryTest; -#define CASE(storage_class) \ - do { \ - EXPECT_THAT( \ - CompiledInstructions("OpTypeForwardPointer %pt " #storage_class), \ - Eq(MakeInstruction(spv::Op::OpTypeForwardPointer, \ - {1, (uint32_t)spv::StorageClass::storage_class}))); \ +#define CASE(storage_class) \ + do { \ + EXPECT_THAT( \ + CompiledInstructions("OpTypeForwardPointer %pt " #storage_class), \ + Eq(MakeInstruction(SpvOpTypeForwardPointer, \ + {1, SpvStorageClass##storage_class}))); \ } while (0) TEST_F(OpTypeForwardPointerTest, ValidStorageClass) { @@ -222,7 +217,6 @@ TEST_F(OpTypeForwardPointerTest, ValidStorageClass) { CASE(AtomicCounter); CASE(Image); CASE(StorageBuffer); - CASE(TileImageEXT); } #undef CASE @@ -251,7 +245,7 @@ using OpSizeOfTest = spvtest::TextToBinaryTest; TEST_F(OpSizeOfTest, OpcodeAssemblesInV10) { EXPECT_THAT( CompiledInstructions("%1 = OpSizeOf %2 %3", SPV_ENV_UNIVERSAL_1_0), - Eq(MakeInstruction(spv::Op::OpSizeOf, {1, 2, 3}))); + Eq(MakeInstruction(SpvOpSizeOf, {1, 2, 3}))); } TEST_F(OpSizeOfTest, ArgumentCount) { @@ -264,7 +258,7 @@ TEST_F(OpSizeOfTest, ArgumentCount) { "next instruction instead.")); EXPECT_THAT( CompiledInstructions("%1 = OpSizeOf %2 %3", SPV_ENV_UNIVERSAL_1_1), - Eq(MakeInstruction(spv::Op::OpSizeOf, {1, 2, 3}))); + Eq(MakeInstruction(SpvOpSizeOf, {1, 2, 3}))); EXPECT_THAT( CompileFailure("%1 = OpSizeOf %2 %3 44 55 ", SPV_ENV_UNIVERSAL_1_1), Eq("Expected or at the beginning of an instruction, " diff --git a/test/text_to_binary_test.cpp b/test/text_to_binary_test.cpp index a9580972..0b348e87 100644 --- a/test/text_to_binary_test.cpp +++ b/test/text_to_binary_test.cpp @@ -180,10 +180,9 @@ TEST_F(TextToBinaryTest, WrongOpCode) { TEST_F(TextToBinaryTest, CRLF) { const std::string input = "%i32 = OpTypeInt 32 1\r\n%c = OpConstant %i32 123\r\n"; - EXPECT_THAT( - CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), - MakeInstruction(spv::Op::OpConstant, {1, 2, 123})}))); + EXPECT_THAT(CompiledInstructions(input), + Eq(Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}), + MakeInstruction(SpvOpConstant, {1, 2, 123})}))); } using TextToBinaryFloatValueTest = spvtest::TextToBinaryTestBase< @@ -193,8 +192,8 @@ TEST_P(TextToBinaryFloatValueTest, Samples) { const std::string input = "%1 = OpTypeFloat 32\n%2 = OpConstant %1 " + GetParam().first; EXPECT_THAT(CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), - MakeInstruction(spv::Op::OpConstant, + Eq(Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 32}), + MakeInstruction(SpvOpConstant, {1, 2, GetParam().second})}))); } @@ -223,8 +222,8 @@ TEST_P(TextToBinaryHalfValueTest, Samples) { const std::string input = "%1 = OpTypeFloat 16\n%2 = OpConstant %1 " + GetParam().first; EXPECT_THAT(CompiledInstructions(input), - Eq(Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 16}), - MakeInstruction(spv::Op::OpConstant, + Eq(Concatenate({MakeInstruction(SpvOpTypeFloat, {1, 16}), + MakeInstruction(SpvOpConstant, {1, 2, GetParam().second})}))); } diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 37fe2b97..99f9780c 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -13,19 +13,9 @@ # limitations under the License. add_test(NAME spirv-tools_expect_unittests - COMMAND Python3::Interpreter -m unittest expect_unittest.py + COMMAND ${PYTHON_EXECUTABLE} -m unittest expect_unittest.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) add_test(NAME spirv-tools_spirv_test_framework_unittests - COMMAND Python3::Interpreter -m unittest spirv_test_framework_unittest.py + COMMAND ${PYTHON_EXECUTABLE} -m unittest spirv_test_framework_unittest.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - -add_spvtools_unittest( - TARGET spirv_unit_test_tools_util - SRCS flags_test.cpp ${spirv-tools_SOURCE_DIR}/tools/util/flags.cpp - LIBS ${SPIRV_TOOLS_FULL_VISIBILITY} - DEFINES TESTING=1) - add_subdirectory(opt) -if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Android")) - add_subdirectory(objdump) -endif () diff --git a/test/tools/flags_test.cpp b/test/tools/flags_test.cpp deleted file mode 100755 index 43db9967..00000000 --- a/test/tools/flags_test.cpp +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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 "tools/util/flags.h" - -#include "gmock/gmock.h" - -#ifdef UTIL_FLAGS_FLAG -#undef UTIL_FLAGS_FLAG -#define UTIL_FLAGS_FLAG(Type, Prefix, Name, Default, Required, IsShort) \ - flags::Flag Name(Default); \ - flags::FlagRegistration Name##_registration(Name, Prefix #Name, Required, \ - IsShort) -#else -#error \ - "UTIL_FLAGS_FLAG is not defined. Either flags.h is not included of the flag name changed." -#endif - -class FlagTest : public ::testing::Test { - protected: - void SetUp() override { flags::FlagList::reset(); } -}; - -TEST_F(FlagTest, NoFlags) { - const char* argv[] = {"binary", nullptr}; - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, DashIsPositional) { - const char* argv[] = {"binary", "-", nullptr}; - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(flags::positional_arguments.size(), 1); - EXPECT_EQ(flags::positional_arguments[0], "-"); -} - -TEST_F(FlagTest, Positional) { - const char* argv[] = {"binary", "A", "BCD", nullptr}; - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(flags::positional_arguments.size(), 2); - EXPECT_EQ(flags::positional_arguments[0], "A"); - EXPECT_EQ(flags::positional_arguments[1], "BCD"); -} - -TEST_F(FlagTest, MissingRequired) { - FLAG_SHORT_bool(g, false, true); - - const char* argv[] = {"binary", nullptr}; - EXPECT_FALSE(flags::Parse(argv)); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, BooleanShortValue) { - FLAG_SHORT_bool(g, false, false); - const char* argv[] = {"binary", "-g", nullptr}; - EXPECT_FALSE(g.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(g.value()); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, BooleanShortDefaultValue) { - FLAG_SHORT_bool(g, true, false); - const char* argv[] = {"binary", nullptr}; - EXPECT_TRUE(g.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(g.value()); -} - -TEST_F(FlagTest, BooleanLongValueNotParsed) { - FLAG_SHORT_bool(g, false, false); - const char* argv[] = {"binary", "-g", "false", nullptr}; - EXPECT_FALSE(g.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(g.value()); - EXPECT_EQ(flags::positional_arguments.size(), 1); - EXPECT_EQ(flags::positional_arguments[0], "false"); -} - -TEST_F(FlagTest, BooleanLongSplitNotParsed) { - FLAG_LONG_bool(foo, false, false); - const char* argv[] = {"binary", "--foo", "true", nullptr}; - EXPECT_FALSE(foo.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(foo.value()); - EXPECT_EQ(flags::positional_arguments.size(), 1); - EXPECT_EQ(flags::positional_arguments[0], "true"); -} - -TEST_F(FlagTest, BooleanLongExplicitTrue) { - FLAG_LONG_bool(foo, false, false); - const char* argv[] = {"binary", "--foo=true", nullptr}; - EXPECT_FALSE(foo.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(foo.value()); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, BooleanLongExplicitFalse) { - FLAG_LONG_bool(foo, false, false); - const char* argv[] = {"binary", "--foo=false", nullptr}; - EXPECT_FALSE(foo.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_FALSE(foo.value()); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, BooleanLongDefaultValue) { - FLAG_LONG_bool(foo, true, false); - const char* argv[] = {"binary", nullptr}; - EXPECT_TRUE(foo.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_TRUE(foo.value()); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, BooleanLongDefaultValueCancelled) { - FLAG_LONG_bool(foo, true, false); - const char* argv[] = {"binary", "--foo=false", nullptr}; - EXPECT_TRUE(foo.value()); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_FALSE(foo.value()); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringFlagDefaultValue) { - FLAG_SHORT_string(f, "default", false); - const char* argv[] = {"binary", nullptr}; - EXPECT_EQ(f.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(f.value(), "default"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringFlagShortMissingString) { - FLAG_SHORT_string(f, "default", false); - const char* argv[] = {"binary", "-f", nullptr}; - EXPECT_EQ(f.value(), "default"); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, StringFlagDefault) { - FLAG_SHORT_string(f, "default", false); - const char* argv[] = {"binary", nullptr}; - EXPECT_EQ(f.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(f.value(), "default"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringFlagSet) { - FLAG_SHORT_string(f, "default", false); - const char* argv[] = {"binary", "-f", "toto", nullptr}; - EXPECT_EQ(f.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(f.value(), "toto"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringLongFlagSetSplit) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--foo", "toto", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), "toto"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringLongFlagSetUnified) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--foo=toto", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), "toto"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, StringLongFlagSetEmpty) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--foo=", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), ""); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, AllPositionalAfterDoubleDash) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--", "--foo=toto", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), "default"); - EXPECT_EQ(flags::positional_arguments.size(), 1); - EXPECT_EQ(flags::positional_arguments[0], "--foo=toto"); -} - -TEST_F(FlagTest, NothingAfterDoubleDash) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), "default"); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, FlagDoubleSetNotAllowed) { - FLAG_LONG_string(foo, "default", false); - const char* argv[] = {"binary", "--foo=abc", "--foo=def", nullptr}; - EXPECT_EQ(foo.value(), "default"); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, MultipleFlags) { - FLAG_LONG_string(foo, "default foo", false); - FLAG_LONG_string(bar, "default_bar", false); - const char* argv[] = {"binary", "--foo", "abc", "--bar=def", nullptr}; - EXPECT_EQ(foo.value(), "default foo"); - EXPECT_EQ(bar.value(), "default_bar"); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(foo.value(), "abc"); - EXPECT_EQ(bar.value(), "def"); -} - -TEST_F(FlagTest, MixedStringAndBool) { - FLAG_LONG_string(foo, "default foo", false); - FLAG_LONG_string(bar, "default_bar", false); - FLAG_SHORT_bool(g, false, false); - const char* argv[] = {"binary", "--foo", "abc", "-g", "--bar=def", nullptr}; - EXPECT_EQ(foo.value(), "default foo"); - EXPECT_EQ(bar.value(), "default_bar"); - EXPECT_FALSE(g.value()); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(foo.value(), "abc"); - EXPECT_EQ(bar.value(), "def"); - EXPECT_TRUE(g.value()); -} - -TEST_F(FlagTest, UintFlagDefaultValue) { - FLAG_SHORT_uint(f, 18, false); - const char* argv[] = {"binary", nullptr}; - EXPECT_EQ(f.value(), 18); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(f.value(), 18); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, UintFlagShortMissingValue) { - FLAG_SHORT_uint(f, 19, false); - const char* argv[] = {"binary", "-f", nullptr}; - EXPECT_EQ(f.value(), 19); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintFlagSet) { - FLAG_SHORT_uint(f, 20, false); - const char* argv[] = {"binary", "-f", "21", nullptr}; - EXPECT_EQ(f.value(), 20); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(f.value(), 21); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, UintLongFlagSetSplit) { - FLAG_LONG_uint(foo, 22, false); - const char* argv[] = {"binary", "--foo", "23", nullptr}; - EXPECT_EQ(foo.value(), 22); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), 23); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, UintLongFlagSetUnified) { - FLAG_LONG_uint(foo, 24, false); - const char* argv[] = {"binary", "--foo=25", nullptr}; - EXPECT_EQ(foo.value(), 24); - - EXPECT_TRUE(flags::Parse(argv)); - - EXPECT_EQ(foo.value(), 25); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, UintLongFlagSetEmptyIsWrong) { - FLAG_LONG_uint(foo, 26, false); - const char* argv[] = {"binary", "--foo=", nullptr}; - EXPECT_EQ(foo.value(), 26); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagSetNegativeFails) { - FLAG_LONG_uint(foo, 26, false); - const char* argv[] = {"binary", "--foo=-2", nullptr}; - EXPECT_EQ(foo.value(), 26); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagSetOverflowFails) { - FLAG_LONG_uint(foo, 27, false); - const char* argv[] = { - "binary", "--foo=99999999999999999999999999999999999999999999999999999", - nullptr}; - EXPECT_EQ(foo.value(), 27); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagSetInvalidCharTrailing) { - FLAG_LONG_uint(foo, 28, false); - const char* argv[] = {"binary", "--foo=12A", nullptr}; - EXPECT_EQ(foo.value(), 28); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagSetSpaces) { - FLAG_LONG_uint(foo, 29, false); - const char* argv[] = {"binary", "--foo= 12", nullptr}; - EXPECT_EQ(foo.value(), 29); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(foo.value(), 12); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} - -TEST_F(FlagTest, UintLongFlagSpacesOnly) { - FLAG_LONG_uint(foo, 30, false); - const char* argv[] = {"binary", "--foo= ", nullptr}; - EXPECT_EQ(foo.value(), 30); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagSplitNumber) { - FLAG_LONG_uint(foo, 31, false); - const char* argv[] = {"binary", "--foo= 2 2", nullptr}; - EXPECT_EQ(foo.value(), 31); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagHex) { - FLAG_LONG_uint(foo, 32, false); - const char* argv[] = {"binary", "--foo=0xA", nullptr}; - EXPECT_EQ(foo.value(), 32); - - EXPECT_FALSE(flags::Parse(argv)); -} - -TEST_F(FlagTest, UintLongFlagZeros) { - FLAG_LONG_uint(foo, 33, false); - const char* argv[] = {"binary", "--foo=0000", nullptr}; - EXPECT_EQ(foo.value(), 33); - - EXPECT_TRUE(flags::Parse(argv)); - EXPECT_EQ(foo.value(), 0); - EXPECT_EQ(flags::positional_arguments.size(), 0); -} diff --git a/test/tools/objdump/CMakeLists.txt b/test/tools/objdump/CMakeLists.txt deleted file mode 100755 index 46fae21a..00000000 --- a/test/tools/objdump/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2023 Google LLC. -# -# 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. - -add_spvtools_unittest( - TARGET spirv_unit_test_tools_objdump - SRCS - extract_source_test.cpp - ${spirv-tools_SOURCE_DIR}/tools/util/flags.cpp - ${spirv-tools_SOURCE_DIR}/tools/util/cli_consumer.cpp - ${spirv-tools_SOURCE_DIR}/tools/objdump/extract_source.cpp - LIBS ${SPIRV_TOOLS_FULL_VISIBILITY} SPIRV-Tools-opt - DEFINES TESTING=1) diff --git a/test/tools/objdump/extract_source_test.cpp b/test/tools/objdump/extract_source_test.cpp deleted file mode 100755 index 0b81caa4..00000000 --- a/test/tools/objdump/extract_source_test.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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 "tools/objdump/extract_source.h" - -#include - -#include - -#include "source/opt/build_module.h" -#include "source/opt/ir_context.h" -#include "spirv-tools/libspirv.hpp" -#include "tools/util/cli_consumer.h" - -namespace { - -constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; - -std::pair> ExtractSource( - const std::string& spv_source) { - std::unique_ptr ctx = spvtools::BuildModule( - kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, spv_source, - spvtools::SpirvTools::kDefaultAssembleOption | - SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - std::vector binary; - ctx->module()->ToBinary(&binary, /* skip_nop = */ false); - std::unordered_map output; - bool result = ExtractSourceFromModule(binary, &output); - return std::make_pair(result, std::move(output)); -} - -} // namespace - -TEST(ExtractSourceTest, no_debug) { - std::string source = R"( - OpCapability Shader - OpCapability Linkage - OpMemoryModel Logical GLSL450 - %void = OpTypeVoid - %2 = OpTypeFunction %void - %bool = OpTypeBool - %4 = OpUndef %bool - %5 = OpFunction %void None %2 - %6 = OpLabel - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 0); -} - -TEST(ExtractSourceTest, SimpleSource) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 "[numthreads(1, 1, 1)] void compute_1(){ }" - OpName %1 "compute_1" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 1 41 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == - "[numthreads(1, 1, 1)] void compute_1(){ }"); -} - -TEST(ExtractSourceTest, SourceContinued) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 "[numthreads(1, 1, 1)] " - OpSourceContinued "void compute_1(){ }" - OpName %1 "compute_1" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 1 41 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == - "[numthreads(1, 1, 1)] void compute_1(){ }"); -} - -TEST(ExtractSourceTest, OnlyFilename) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 - OpName %1 "compute_1" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 1 41 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == ""); -} - -TEST(ExtractSourceTest, MultipleFiles) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute1.hlsl" - %3 = OpString "compute2.hlsl" - OpSource HLSL 660 %2 "some instruction" - OpSource HLSL 660 %3 "some other instruction" - OpName %1 "compute_1" - %4 = OpTypeVoid - %5 = OpTypeFunction %4 - %1 = OpFunction %4 None %5 - %6 = OpLabel - OpLine %2 1 41 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 2); - ASSERT_TRUE(result["compute1.hlsl"] == "some instruction"); - ASSERT_TRUE(result["compute2.hlsl"] == "some other instruction"); -} - -TEST(ExtractSourceTest, MultilineCode) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 "[numthreads(1, 1, 1)] -void compute_1() { -} -" - OpName %1 "compute_1" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 3 1 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == - "[numthreads(1, 1, 1)]\nvoid compute_1() {\n}\n"); -} - -TEST(ExtractSourceTest, EmptyFilename) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute_1" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "" - OpSource HLSL 660 %2 "void compute(){}" - OpName %1 "compute_1" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 3 1 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["unnamed-0.hlsl"] == "void compute(){}"); -} - -TEST(ExtractSourceTest, EscapeEscaped) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 "// check \" escape removed" - OpName %1 "compute" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 6 1 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == "// check \" escape removed"); -} - -TEST(ExtractSourceTest, OpSourceWithNoSource) { - std::string source = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %1 "compute" - OpExecutionMode %1 LocalSize 1 1 1 - %2 = OpString "compute.hlsl" - OpSource HLSL 660 %2 - OpName %1 "compute" - %3 = OpTypeVoid - %4 = OpTypeFunction %3 - %1 = OpFunction %3 None %4 - %5 = OpLabel - OpLine %2 6 1 - OpReturn - OpFunctionEnd - )"; - - auto[success, result] = ExtractSource(source); - ASSERT_TRUE(success); - ASSERT_TRUE(result.size() == 1); - ASSERT_TRUE(result["compute.hlsl"] == ""); -} diff --git a/test/tools/opt/CMakeLists.txt b/test/tools/opt/CMakeLists.txt index 966ffbb5..21aa247f 100644 --- a/test/tools/opt/CMakeLists.txt +++ b/test/tools/opt/CMakeLists.txt @@ -13,9 +13,9 @@ # limitations under the License. if(NOT ${SPIRV_SKIP_TESTS}) - if(${Python3_Interpreter_FOUND}) + if(${PYTHONINTERP_FOUND}) add_test(NAME spirv_opt_cli_tools_tests - COMMAND Python3::Interpreter + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../spirv_test_framework.py $ $ $ --test-dir ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/test/unit_spirv.h b/test/unit_spirv.h index 9e7074cb..f0a2958d 100644 --- a/test/unit_spirv.h +++ b/test/unit_spirv.h @@ -105,7 +105,7 @@ inline void PrintTo(const WordVector& words, ::std::ostream* os) { // Returns a vector of words representing a single instruction with the // given opcode and operand words as a vector. inline std::vector MakeInstruction( - spv::Op opcode, const std::vector& args) { + SpvOp opcode, const std::vector& args) { std::vector result{ spvOpcodeMake(uint16_t(args.size() + 1), opcode)}; result.insert(result.end(), args.begin(), args.end()); @@ -116,7 +116,7 @@ inline std::vector MakeInstruction( // given opcode and whose operands are the concatenation of the two given // argument lists. inline std::vector MakeInstruction( - spv::Op opcode, std::vector args, + SpvOp opcode, std::vector args, const std::vector& extra_args) { args.insert(args.end(), extra_args.begin(), extra_args.end()); return MakeInstruction(opcode, args); @@ -200,10 +200,11 @@ inline std::vector AllTargetEnvironments() { } // Returns the capabilities in a CapabilitySet as an ordered vector. -inline std::vector ElementsIn( +inline std::vector ElementsIn( const spvtools::CapabilitySet& capabilities) { - return std::vector(capabilities.cbegin(), - capabilities.cend()); + std::vector result; + capabilities.ForEach([&result](SpvCapability c) { result.push_back(c); }); + return result; } } // namespace spvtest diff --git a/test/val/CMakeLists.txt b/test/val/CMakeLists.txt index 62d93bdd..de89b93f 100644 --- a/test/val/CMakeLists.txt +++ b/test/val/CMakeLists.txt @@ -93,7 +93,6 @@ add_spvtools_unittest(TARGET val_rstuvw SRCS val_ray_query_test.cpp val_ray_tracing_test.cpp - val_ray_tracing_reorder_test.cpp val_small_type_uses_test.cpp val_ssa_test.cpp val_state_test.cpp diff --git a/test/val/val_annotation_test.cpp b/test/val/val_annotation_test.cpp index 9f85a30b..bb30de0a 100644 --- a/test/val/val_annotation_test.cpp +++ b/test/val/val_annotation_test.cpp @@ -18,6 +18,7 @@ #include #include "gmock/gmock.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_code_generator.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_arithmetics_test.cpp b/test/val/val_arithmetics_test.cpp index 58ac4423..631375ef 100644 --- a/test/val/val_arithmetics_test.cpp +++ b/test/val/val_arithmetics_test.cpp @@ -1318,7 +1318,7 @@ TEST_F(ValidateArithmetics, CoopMatComponentTypeNotScalarNumeric) { CompileSuccessfully(GenerateCoopMatCode(types, "").c_str()); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpTypeCooperativeMatrix Component Type " + HasSubstr("OpTypeCooperativeMatrixNV Component Type " "'4[%bool]' is not a scalar numerical type.")); } @@ -1331,7 +1331,7 @@ TEST_F(ValidateArithmetics, CoopMatScopeNotConstantInt) { EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr("OpTypeCooperativeMatrix Scope '17[%float_1]' is not a " + HasSubstr("OpTypeCooperativeMatrixNV Scope '17[%float_1]' is not a " "constant instruction with scalar integer type.")); } @@ -1344,7 +1344,7 @@ TEST_F(ValidateArithmetics, CoopMatRowsNotConstantInt) { EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr("OpTypeCooperativeMatrix Rows '17[%float_1]' is not a " + HasSubstr("OpTypeCooperativeMatrixNV Rows '17[%float_1]' is not a " "constant instruction with scalar integer type.")); } @@ -1357,7 +1357,7 @@ TEST_F(ValidateArithmetics, CoopMatColumnsNotConstantInt) { EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr("OpTypeCooperativeMatrix Cols '17[%float_1]' is not a " + HasSubstr("OpTypeCooperativeMatrixNV Cols '17[%float_1]' is not a " "constant instruction with scalar integer type.")); } @@ -1469,149 +1469,6 @@ TEST_F(ValidateArithmetics, SMulExtendedResultTypeMembersNotIdentical) { "SMulExtended")); } -std::string GenerateCoopMatKHRCode(const std::string& extra_types, - const std::string& main_body) { - const std::string prefix = R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u32 = OpTypeInt 32 0 -%s32 = OpTypeInt 32 1 - -%u32_16 = OpConstant %u32 16 -%u32_4 = OpConstant %u32 4 -%subgroup = OpConstant %u32 3 -%useA = OpConstant %u32 0 -%useB = OpConstant %u32 1 -%useC = OpConstant %u32 2 - -%f16matA = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA -%u32matA = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useA -%s32matA = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useA - -%f16matB = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useB -%u32matB = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useB -%s32matB = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useB - -%f16matC = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useC -%f32matC = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_16 %u32_16 %useC -%u32matC = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useC -%s32matC = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useC - -%f16_1 = OpConstant %f16 1 -%f32_1 = OpConstant %f32 1 -%u32_1 = OpConstant %u32 1 -%s32_1 = OpConstant %s32 1 - -%f16mat_A_1 = OpConstantComposite %f16matA %f16_1 -%u32mat_A_1 = OpConstantComposite %u32matA %u32_1 -%s32mat_A_1 = OpConstantComposite %s32matA %s32_1 - -%f16mat_B_1 = OpConstantComposite %f16matB %f16_1 -%u32mat_B_1 = OpConstantComposite %u32matB %u32_1 -%s32mat_B_1 = OpConstantComposite %s32matB %s32_1 - -%f16mat_C_1 = OpConstantComposite %f16matC %f16_1 -%u32mat_C_1 = OpConstantComposite %u32matC %u32_1 -%s32mat_C_1 = OpConstantComposite %s32matC %s32_1 - -)"; - - const std::string func_begin = R"( -%main = OpFunction %void None %func -%main_entry = OpLabel)"; - - const std::string suffix = R"( -OpReturn -OpFunctionEnd)"; - - return prefix + extra_types + func_begin + main_body + suffix; -} - -TEST_F(ValidateArithmetics, CoopMatKHRSuccess) { - const std::string body = R"( -%val1 = OpFAdd %f16matA %f16mat_A_1 %f16mat_A_1 -%val2 = OpFSub %f16matA %f16mat_A_1 %f16mat_A_1 -%val3 = OpFMul %f16matA %f16mat_A_1 %f16mat_A_1 -%val4 = OpFDiv %f16matA %f16mat_A_1 %f16mat_A_1 -%val5 = OpFNegate %f16matA %f16mat_A_1 -%val6 = OpIAdd %u32matA %u32mat_A_1 %u32mat_A_1 -%val7 = OpISub %u32matA %u32mat_A_1 %u32mat_A_1 -%val8 = OpUDiv %u32matA %u32mat_A_1 %u32mat_A_1 -%val9 = OpIAdd %s32matA %s32mat_A_1 %s32mat_A_1 -%val10 = OpISub %s32matA %s32mat_A_1 %s32mat_A_1 -%val11 = OpSDiv %s32matA %s32mat_A_1 %s32mat_A_1 -%val12 = OpSNegate %s32matA %s32mat_A_1 -%val13 = OpMatrixTimesScalar %f16matA %f16mat_A_1 %f16_1 -%val14 = OpMatrixTimesScalar %u32matA %u32mat_A_1 %u32_1 -%val15 = OpMatrixTimesScalar %s32matA %s32mat_A_1 %s32_1 -%val16 = OpCooperativeMatrixMulAddKHR %f32matC %f16mat_A_1 %f16mat_B_1 %f16mat_C_1 -%val17 = OpCooperativeMatrixMulAddKHR %s32matC %s32mat_A_1 %s32mat_B_1 %s32mat_C_1 - MatrixASignedComponentsKHR|MatrixBSignedComponentsKHR|MatrixCSignedComponentsKHR|MatrixResultSignedComponentsKHR -%val18 = OpCooperativeMatrixMulAddKHR %u32matC %u32mat_A_1 %u32mat_B_1 %u32mat_C_1 -)"; - - CompileSuccessfully(GenerateCoopMatKHRCode("", body).c_str()); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); -} - -TEST_F(ValidateArithmetics, CoopMatMatrixKHRTimesScalarMismatchFail) { - const std::string body = R"( -%val1 = OpMatrixTimesScalar %f16matA %f16mat_A_1 %f32_1 -)"; - - CompileSuccessfully(GenerateCoopMatKHRCode("", body).c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected scalar operand type to be equal to the component " - "type of the matrix operand: MatrixTimesScalar")); -} - -TEST_F(ValidateArithmetics, CoopMatKHRScopeFail) { - const std::string types = R"( -%workgroup = OpConstant %u32 2 -%mat16x16_wg = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %useC -%f16matwg_16x16_1 = OpConstantComposite %mat16x16_wg %f16_1 -)"; - - const std::string body = R"( -%val1 = OpFAdd %f16matA %f16matwg_16x16_1 %f16mat_A_1 -)"; - - CompileSuccessfully(GenerateCoopMatKHRCode(types, body).c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected scopes of Matrix and Result Type to be identical")); -} - -TEST_F(ValidateArithmetics, CoopMatKHRDimFail) { - const std::string types = R"( -%mat16x4 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_4 %useC -%mat16x4_C_1 = OpConstantComposite %mat16x4 %f16_1 -)"; - - const std::string body = R"( -%val1 = OpCooperativeMatrixMulAddKHR %mat16x4 %f16mat_A_1 %f16mat_B_1 %mat16x4_C_1 -)"; - - CompileSuccessfully(GenerateCoopMatKHRCode(types, body).c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Cooperative matrix 'N' mismatch: CooperativeMatrixMulAddKHR")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_barriers_test.cpp b/test/val/val_barriers_test.cpp index f1609040..c86cdc13 100644 --- a/test/val/val_barriers_test.cpp +++ b/test/val/val_barriers_test.cpp @@ -361,7 +361,7 @@ OpControlBarrier %subgroup %subgroup %none CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-07951")); + AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-06997")); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -775,7 +775,7 @@ OpMemoryBarrier %subgroup %acquire_release_uniform_workgroup CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-07951")); + AnyVUID("VUID-StandaloneSpirv-SubgroupVoteKHR-06997")); EXPECT_THAT( getDiagnosticString(), HasSubstr( diff --git a/test/val/val_bitwise_test.cpp b/test/val/val_bitwise_test.cpp index b849e7b7..bebaa84f 100644 --- a/test/val/val_bitwise_test.cpp +++ b/test/val/val_bitwise_test.cpp @@ -643,32 +643,6 @@ TEST_F(ValidateBitwise, OpBitCountNot32Vulkan) { HasSubstr("Expected 32-bit int type for Base operand: BitCount")); } -TEST_F(ValidateBitwise, OpBitCountPointer) { - const std::string body = R"( -OpCapability Shader -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%ptr_int = OpTypePointer Function %int -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%var = OpVariable %ptr_int Function -%count = OpBitCount %int %var -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(body); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Expected int scalar or vector type for Base operand: BitCount")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index 3953057e..a4d14441 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -16,12 +16,14 @@ #include #include +#include #include #include #include #include #include "gmock/gmock.h" +#include "source/diagnostic.h" #include "source/spirv_target_env.h" #include "source/val/validate.h" #include "test/test_fixture.h" @@ -35,7 +37,7 @@ namespace { using ::testing::HasSubstr; using ::testing::MatchesRegex; -using ValidateCFG = spvtest::ValidateBase; +using ValidateCFG = spvtest::ValidateBase; using spvtest::ScopedContext; std::string nameOps() { return ""; } @@ -56,7 +58,7 @@ std::string nameOps(std::string head, Args... names) { class Block { std::string label_; std::string body_; - spv::Op type_; + SpvOp type_; std::vector successors_; public: @@ -64,7 +66,7 @@ class Block { /// /// @param[in]: label the label id of the block /// @param[in]: type the branch instruction that ends the block - explicit Block(std::string label, spv::Op type = spv::Op::OpBranch) + explicit Block(std::string label, SpvOp type = SpvOpBranch) : label_(label), body_(), type_(type), successors_() {} /// Sets the instructions which will appear in the body of the block @@ -87,13 +89,13 @@ class Block { } switch (type_) { - case spv::Op::OpBranchConditional: + case SpvOpBranchConditional: out << "OpBranchConditional %cond "; for (Block& b : successors_) { out << "%" + b.label_ + " "; } break; - case spv::Op::OpSwitch: { + case SpvOpSwitch: { out << "OpSwitch %one %" + successors_.front().label_; std::stringstream ss; for (size_t i = 1; i < successors_.size(); i++) { @@ -101,25 +103,25 @@ class Block { } out << ss.str(); } break; - case spv::Op::OpLoopMerge: { + case SpvOpLoopMerge: { assert(successors_.size() == 2); out << "OpLoopMerge %" + successors_[0].label_ + " %" + successors_[0].label_ + "None"; } break; - case spv::Op::OpReturn: + case SpvOpReturn: assert(successors_.size() == 0); out << "OpReturn\n"; break; - case spv::Op::OpUnreachable: + case SpvOpUnreachable: assert(successors_.size() == 0); out << "OpUnreachable\n"; break; - case spv::Op::OpBranch: + case SpvOpBranch: assert(successors_.size() == 1); out << "OpBranch %" + successors_.front().label_; break; - case spv::Op::OpKill: + case SpvOpKill: assert(successors_.size() == 0); out << "OpKill\n"; break; @@ -136,9 +138,9 @@ class Block { /// Assigns the successors for the Block on the lhs Block& operator>>(Block& lhs, std::vector successors) { - if (lhs.type_ == spv::Op::OpBranchConditional) { + if (lhs.type_ == SpvOpBranchConditional) { assert(successors.size() == 2); - } else if (lhs.type_ == spv::Op::OpSwitch) { + } else if (lhs.type_ == SpvOpSwitch) { assert(successors.size() > 1); } lhs.successors_ = successors; @@ -147,12 +149,12 @@ Block& operator>>(Block& lhs, std::vector successors) { /// Assigns the successor for the Block on the lhs Block& operator>>(Block& lhs, Block& successor) { - assert(lhs.type_ == spv::Op::OpBranch); + assert(lhs.type_ == SpvOpBranch); lhs.successors_.push_back(successor); return lhs; } -const std::string& GetDefaultHeader(spv::Capability cap) { +const std::string& GetDefaultHeader(SpvCapability cap) { static const std::string shader_header = "OpCapability Shader\n" "OpCapability Linkage\n" @@ -163,7 +165,7 @@ const std::string& GetDefaultHeader(spv::Capability cap) { "OpCapability Linkage\n" "OpMemoryModel Logical OpenCL\n"; - return (cap == spv::Capability::Shader) ? shader_header : kernel_header; + return (cap == SpvCapabilityShader) ? shader_header : kernel_header; } const std::string& types_consts() { @@ -179,8 +181,8 @@ const std::string& types_consts() { } INSTANTIATE_TEST_SUITE_P(StructuredControlFlow, ValidateCFG, - ::testing::Values(spv::Capability::Shader, - spv::Capability::Kernel)); + ::testing::Values(SpvCapabilityShader, + SpvCapabilityKernel)); TEST_P(ValidateCFG, LoopReachableFromEntryButNeverLeadingToReturn) { // In this case, the loop is reachable from a node without a predecessor, @@ -266,11 +268,11 @@ TEST_P(ValidateCFG, LoopUnreachableFromEntryButLeadingToReturn) { } TEST_P(ValidateCFG, Simple) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); + Block loop("loop", SpvOpBranchConditional); Block cont("cont"); - Block merge("merge", spv::Op::OpReturn); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -296,7 +298,7 @@ TEST_P(ValidateCFG, Simple) { TEST_P(ValidateCFG, Variable) { Block entry("entry"); Block cont("cont"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%var = OpVariable %ptrt Function\n"); @@ -315,7 +317,7 @@ TEST_P(ValidateCFG, Variable) { TEST_P(ValidateCFG, VariableNotInFirstBlockBad) { Block entry("entry"); Block cont("cont"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); // This operation should only be performed in the entry block cont.SetBody("%var = OpVariable %ptrt Function\n"); @@ -337,10 +339,10 @@ TEST_P(ValidateCFG, VariableNotInFirstBlockBad) { } TEST_P(ValidateCFG, BlockSelfLoopIsOk) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block loop("loop", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody("OpLoopMerge %merge %loop None\n"); @@ -361,11 +363,11 @@ TEST_P(ValidateCFG, BlockSelfLoopIsOk) { } TEST_P(ValidateCFG, BlockAppearsBeforeDominatorBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); Block cont("cont"); - Block branch("branch", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block branch("branch", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) branch.SetBody("OpSelectionMerge %merge None\n"); @@ -390,11 +392,11 @@ TEST_P(ValidateCFG, BlockAppearsBeforeDominatorBad) { } TEST_P(ValidateCFG, MergeBlockTargetedByMultipleHeaderBlocksBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); Block loop("loop"); - Block selection("selection", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block selection("selection", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody(" OpLoopMerge %merge %loop None\n"); @@ -426,11 +428,11 @@ TEST_P(ValidateCFG, MergeBlockTargetedByMultipleHeaderBlocksBad) { } TEST_P(ValidateCFG, MergeBlockTargetedByMultipleHeaderBlocksSelectionBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block selection("selection", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block loop("loop", SpvOpBranchConditional); + Block selection("selection", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) selection.SetBody(" OpSelectionMerge %merge None\n"); @@ -464,7 +466,7 @@ TEST_P(ValidateCFG, MergeBlockTargetedByMultipleHeaderBlocksSelectionBad) { TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceEntryBlock) { Block entry("entry"); Block bad("bad"); - Block end("end", spv::Op::OpReturn); + Block end("end", SpvOpReturn); std::string str = GetDefaultHeader(GetParam()) + nameOps("entry", "bad", std::make_pair("func", "Main")) + types_consts() + @@ -487,7 +489,7 @@ TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceValue) { Block entry("entry"); entry.SetBody("%undef = OpUndef %boolt\n"); Block bad("bad"); - Block end("end", spv::Op::OpReturn); + Block end("end", SpvOpReturn); Block badvalue("undef"); // This references the OpUndef. std::string str = GetDefaultHeader(GetParam()) + nameOps("entry", "bad", std::make_pair("func", "Main")) + @@ -509,8 +511,8 @@ TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceValue) { TEST_P(ValidateCFG, BranchConditionalTrueTargetFirstBlockBad) { Block entry("entry"); - Block bad("bad", spv::Op::OpBranchConditional); - Block exit("exit", spv::Op::OpReturn); + Block bad("bad", SpvOpBranchConditional); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); bad.SetBody(" OpLoopMerge %entry %exit None\n"); @@ -536,10 +538,10 @@ TEST_P(ValidateCFG, BranchConditionalTrueTargetFirstBlockBad) { TEST_P(ValidateCFG, BranchConditionalFalseTargetFirstBlockBad) { Block entry("entry"); - Block bad("bad", spv::Op::OpBranchConditional); + Block bad("bad", SpvOpBranchConditional); Block t("t"); Block merge("merge"); - Block end("end", spv::Op::OpReturn); + Block end("end", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); bad.SetBody("OpLoopMerge %merge %cont None\n"); @@ -566,13 +568,13 @@ TEST_P(ValidateCFG, BranchConditionalFalseTargetFirstBlockBad) { TEST_P(ValidateCFG, SwitchTargetFirstBlockBad) { Block entry("entry"); - Block bad("bad", spv::Op::OpSwitch); + Block bad("bad", SpvOpSwitch); Block block1("block1"); Block block2("block2"); Block block3("block3"); Block def("def"); // default block Block merge("merge"); - Block end("end", spv::Op::OpReturn); + Block end("end", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); bad.SetBody("OpSelectionMerge %merge None\n"); @@ -603,15 +605,15 @@ TEST_P(ValidateCFG, SwitchTargetFirstBlockBad) { TEST_P(ValidateCFG, BranchToBlockInOtherFunctionBad) { Block entry("entry"); - Block middle("middle", spv::Op::OpBranchConditional); - Block end("end", spv::Op::OpReturn); + Block middle("middle", SpvOpBranchConditional); + Block end("end", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); middle.SetBody("OpSelectionMerge %end None\n"); Block entry2("entry2"); Block middle2("middle2"); - Block end2("end2", spv::Op::OpReturn); + Block end2("end2", SpvOpReturn); std::string str = GetDefaultHeader(GetParam()) + nameOps("middle2", std::make_pair("func", "Main")) + @@ -641,9 +643,9 @@ TEST_P(ValidateCFG, BranchToBlockInOtherFunctionBad) { TEST_P(ValidateCFG, HeaderDoesntStrictlyDominateMergeBad) { // If a merge block is reachable, then it must be strictly dominated by // its header block. - bool is_shader = GetParam() == spv::Capability::Shader; - Block head("head", spv::Op::OpBranchConditional); - Block exit("exit", spv::Op::OpReturn); + bool is_shader = GetParam() == SpvCapabilityShader; + Block head("head", SpvOpBranchConditional); + Block exit("exit", SpvOpReturn); head.SetBody("%cond = OpSLessThan %boolt %one %two\n"); @@ -673,16 +675,16 @@ TEST_P(ValidateCFG, HeaderDoesntStrictlyDominateMergeBad) { } } -std::string GetUnreachableMergeNoMergeInst(spv::Capability cap) { +std::string GetUnreachableMergeNoMergeInst(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); - Block merge("merge", spv::Op::OpReturn); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); std::string str = header; @@ -703,18 +705,18 @@ TEST_P(ValidateCFG, UnreachableMergeNoMergeInst) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeTerminatedBy(spv::Capability cap, spv::Op op) { +std::string GetUnreachableMergeTerminatedBy(SpvCapability cap, SpvOp op) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); Block merge("merge", op); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); str += nameOps("branch", "merge", std::make_pair("func", "Main")); @@ -732,35 +734,33 @@ std::string GetUnreachableMergeTerminatedBy(spv::Capability cap, spv::Op op) { TEST_P(ValidateCFG, UnreachableMergeTerminatedByOpUnreachable) { CompileSuccessfully( - GetUnreachableMergeTerminatedBy(GetParam(), spv::Op::OpUnreachable)); + GetUnreachableMergeTerminatedBy(GetParam(), SpvOpUnreachable)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_F(ValidateCFG, UnreachableMergeTerminatedByOpKill) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy(spv::Capability::Shader, - spv::Op::OpKill)); + CompileSuccessfully( + GetUnreachableMergeTerminatedBy(SpvCapabilityShader, SpvOpKill)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_P(ValidateCFG, UnreachableMergeTerminatedByOpReturn) { - CompileSuccessfully( - GetUnreachableMergeTerminatedBy(GetParam(), spv::Op::OpReturn)); + CompileSuccessfully(GetUnreachableMergeTerminatedBy(GetParam(), SpvOpReturn)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableContinueTerminatedBy(spv::Capability cap, - spv::Op op) { +std::string GetUnreachableContinueTerminatedBy(SpvCapability cap, SpvOp op) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); Block target("target", op); - if (op == spv::Op::OpBranch) target >> branch; + if (op == SpvOpBranch) target >> branch; std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); @@ -775,10 +775,10 @@ std::string GetUnreachableContinueTerminatedBy(spv::Capability cap, return str; } -TEST_P(ValidateCFG, UnreachableContinueTerminatedByOpUnreachable) { +TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpUnreachable) { CompileSuccessfully( - GetUnreachableContinueTerminatedBy(GetParam(), spv::Op::OpUnreachable)); - if (GetParam() == spv::Capability::Shader) { + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpUnreachable)); + if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("targeted by 0 back-edge blocks")); @@ -787,18 +787,18 @@ TEST_P(ValidateCFG, UnreachableContinueTerminatedByOpUnreachable) { } } -TEST_F(ValidateCFG, UnreachableContinueTerminatedByOpKill) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - spv::Capability::Shader, spv::Op::OpKill)); +TEST_F(ValidateCFG, UnreachableContinueTerminatedBySpvOpKill) { + CompileSuccessfully( + GetUnreachableContinueTerminatedBy(SpvCapabilityShader, SpvOpKill)); ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("targeted by 0 back-edge blocks")); } -TEST_P(ValidateCFG, UnreachableContinueTerminatedByOpReturn) { +TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpReturn) { CompileSuccessfully( - GetUnreachableContinueTerminatedBy(GetParam(), spv::Op::OpReturn)); - if (GetParam() == spv::Capability::Shader) { + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpReturn)); + if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("targeted by 0 back-edge blocks")); @@ -807,25 +807,25 @@ TEST_P(ValidateCFG, UnreachableContinueTerminatedByOpReturn) { } } -TEST_P(ValidateCFG, UnreachableContinueTerminatedByOpBranch) { +TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpBranch) { CompileSuccessfully( - GetUnreachableContinueTerminatedBy(GetParam(), spv::Op::OpBranch)); + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpBranch)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeUnreachableMergeInst(spv::Capability cap) { +std::string GetUnreachableMergeUnreachableMergeInst(SpvCapability cap) { std::string header = GetDefaultHeader(cap); - Block body("body", spv::Op::OpReturn); + Block body("body", SpvOpReturn); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); - Block merge("merge", spv::Op::OpUnreachable); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); + Block merge("merge", SpvOpUnreachable); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); str += nameOps("branch", "merge", std::make_pair("func", "Main")); @@ -847,19 +847,19 @@ TEST_P(ValidateCFG, UnreachableMergeUnreachableMergeInst) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableContinueUnreachableLoopInst(spv::Capability cap) { +std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap) { std::string header = GetDefaultHeader(cap); - Block body("body", spv::Op::OpReturn); + Block body("body", SpvOpReturn); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); - Block target("target", spv::Op::OpBranch); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); + Block target("target", SpvOpBranch); target >> branch; std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); @@ -880,21 +880,21 @@ TEST_P(ValidateCFG, UnreachableContinueUnreachableLoopInst) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeWithComplexBody(spv::Capability cap) { +std::string GetUnreachableMergeWithComplexBody(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); - Block merge("merge", spv::Op::OpUnreachable); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); + Block merge("merge", SpvOpUnreachable); entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); merge.AppendBody("OpStore %placeholder %one\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); str += nameOps("branch", "merge", std::make_pair("func", "Main")); @@ -916,13 +916,13 @@ TEST_P(ValidateCFG, UnreachableMergeWithComplexBody) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableContinueWithComplexBody(spv::Capability cap) { +std::string GetUnreachableContinueWithComplexBody(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); - Block target("target", spv::Op::OpBranch); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); + Block target("target", SpvOpBranch); target >> branch; @@ -930,7 +930,7 @@ std::string GetUnreachableContinueWithComplexBody(spv::Capability cap) { target.AppendBody("OpStore %placeholder %one\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); @@ -951,19 +951,19 @@ TEST_P(ValidateCFG, UnreachableContinueWithComplexBody) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeWithBranchUse(spv::Capability cap) { +std::string GetUnreachableMergeWithBranchUse(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpBranch); - Block f("f", spv::Op::OpReturn); - Block merge("merge", spv::Op::OpUnreachable); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpBranch); + Block f("f", SpvOpReturn); + Block merge("merge", SpvOpUnreachable); entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); str += nameOps("branch", "merge", std::make_pair("func", "Main")); @@ -984,20 +984,20 @@ TEST_P(ValidateCFG, UnreachableMergeWithBranchUse) { EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeWithMultipleUses(spv::Capability cap) { +std::string GetUnreachableMergeWithMultipleUses(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); - Block merge("merge", spv::Op::OpUnreachable); - Block duplicate("duplicate", spv::Op::OpBranchConditional); + Block branch("branch", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); + Block merge("merge", SpvOpUnreachable); + Block duplicate("duplicate", SpvOpBranchConditional); entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (cap == spv::Capability::Shader) { + if (cap == SpvCapabilityShader) { branch.AppendBody("OpSelectionMerge %merge None\n"); duplicate.AppendBody("OpSelectionMerge %merge None\n"); } @@ -1018,7 +1018,7 @@ std::string GetUnreachableMergeWithMultipleUses(spv::Capability cap) { TEST_P(ValidateCFG, UnreachableMergeWithMultipleUses) { CompileSuccessfully(GetUnreachableMergeWithMultipleUses(GetParam())); - if (GetParam() == spv::Capability::Shader) { + if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("is already a merge block for another header")); @@ -1027,20 +1027,20 @@ TEST_P(ValidateCFG, UnreachableMergeWithMultipleUses) { } } -std::string GetUnreachableContinueWithBranchUse(spv::Capability cap) { +std::string GetUnreachableContinueWithBranchUse(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); - Block target("target", spv::Op::OpBranch); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); + Block target("target", SpvOpBranch); target >> branch; entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); std::string str = header; - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); @@ -1061,16 +1061,16 @@ TEST_P(ValidateCFG, UnreachableContinueWithBranchUse) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetReachableMergeAndContinue(spv::Capability cap) { +std::string GetReachableMergeAndContinue(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); - Block target("target", spv::Op::OpBranch); - Block body("body", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpBranch); - Block f("f", spv::Op::OpBranch); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); + Block target("target", SpvOpBranch); + Block body("body", SpvOpBranchConditional); + Block t("t", SpvOpBranch); + Block f("f", SpvOpBranch); target >> branch; body.SetBody("%cond = OpSLessThan %boolt %one %two\n"); @@ -1078,7 +1078,7 @@ std::string GetReachableMergeAndContinue(spv::Capability cap) { f >> target; std::string str = header; - if (cap == spv::Capability::Shader) { + if (cap == SpvCapabilityShader) { branch.AppendBody("OpLoopMerge %merge %target None\n"); body.AppendBody("OpSelectionMerge %f None\n"); } @@ -1104,23 +1104,23 @@ TEST_P(ValidateCFG, ReachableMergeAndContinue) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeAndContinue(spv::Capability cap) { +std::string GetUnreachableMergeAndContinue(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block branch("branch", spv::Op::OpBranch); - Block merge("merge", spv::Op::OpReturn); - Block target("target", spv::Op::OpBranch); - Block body("body", spv::Op::OpBranchConditional); - Block t("t", spv::Op::OpReturn); - Block f("f", spv::Op::OpReturn); - Block pre_target("pre_target", spv::Op::OpBranch); + Block branch("branch", SpvOpBranch); + Block merge("merge", SpvOpReturn); + Block target("target", SpvOpBranch); + Block body("body", SpvOpBranchConditional); + Block t("t", SpvOpReturn); + Block f("f", SpvOpReturn); + Block pre_target("pre_target", SpvOpBranch); target >> branch; body.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (cap == spv::Capability::Shader) { + if (cap == SpvCapabilityShader) { branch.AppendBody("OpLoopMerge %merge %target None\n"); body.AppendBody("OpSelectionMerge %pre_target None\n"); } @@ -1147,12 +1147,12 @@ TEST_P(ValidateCFG, UnreachableMergeAndContinue) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableBlock(spv::Capability cap) { +std::string GetUnreachableBlock(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); Block unreachable("unreachable"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); std::string str = header; str += nameOps("unreachable", "exit", std::make_pair("func", "Main")); @@ -1171,18 +1171,18 @@ TEST_P(ValidateCFG, UnreachableBlock) { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableBranch(spv::Capability cap) { +std::string GetUnreachableBranch(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block unreachable("unreachable", spv::Op::OpBranchConditional); + Block unreachable("unreachable", SpvOpBranchConditional); Block unreachablechildt("unreachablechildt"); Block unreachablechildf("unreachablechildf"); Block merge("merge"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); unreachable.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - if (cap == spv::Capability::Shader) + if (cap == SpvCapabilityShader) unreachable.AppendBody("OpSelectionMerge %merge None\n"); std::string str = header; @@ -1219,10 +1219,10 @@ TEST_P(ValidateCFG, EmptyFunction) { } TEST_P(ValidateCFG, SingleBlockLoop) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block exit("exit", spv::Op::OpReturn); + Block loop("loop", SpvOpBranchConditional); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.AppendBody("OpLoopMerge %exit %loop None\n"); @@ -1240,15 +1240,15 @@ TEST_P(ValidateCFG, SingleBlockLoop) { } TEST_P(ValidateCFG, NestedLoops) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); Block loop1("loop1"); Block loop1_cont_break_block("loop1_cont_break_block", - spv::Op::OpBranchConditional); - Block loop2("loop2", spv::Op::OpBranchConditional); + SpvOpBranchConditional); + Block loop2("loop2", SpvOpBranchConditional); Block loop2_merge("loop2_merge"); Block loop1_merge("loop1_merge"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -1275,7 +1275,7 @@ TEST_P(ValidateCFG, NestedLoops) { } TEST_P(ValidateCFG, NestedSelection) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); const int N = 256; std::vector if_blocks; @@ -1284,18 +1284,18 @@ TEST_P(ValidateCFG, NestedSelection) { entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - if_blocks.emplace_back("if0", spv::Op::OpBranchConditional); + if_blocks.emplace_back("if0", SpvOpBranchConditional); if (is_shader) if_blocks[0].SetBody("OpSelectionMerge %if_merge0 None\n"); - merge_blocks.emplace_back("if_merge0", spv::Op::OpReturn); + merge_blocks.emplace_back("if_merge0", SpvOpReturn); for (int i = 1; i < N; i++) { std::stringstream ss; ss << i; - if_blocks.emplace_back("if" + ss.str(), spv::Op::OpBranchConditional); + if_blocks.emplace_back("if" + ss.str(), SpvOpBranchConditional); if (is_shader) if_blocks[i].SetBody("OpSelectionMerge %if_merge" + ss.str() + " None\n"); - merge_blocks.emplace_back("if_merge" + ss.str(), spv::Op::OpBranch); + merge_blocks.emplace_back("if_merge" + ss.str(), SpvOpBranch); } std::string str = GetDefaultHeader(GetParam()) + std::string(types_consts()) + "%func = OpFunction %voidt None %funct\n"; @@ -1318,14 +1318,14 @@ TEST_P(ValidateCFG, NestedSelection) { } TEST_P(ValidateCFG, BackEdgeBlockDoesntPostDominateContinueTargetBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop1("loop1", spv::Op::OpBranchConditional); - Block loop2("loop2", spv::Op::OpBranchConditional); + Block loop1("loop1", SpvOpBranchConditional); + Block loop2("loop2", SpvOpBranchConditional); Block loop2_merge("loop2_merge"); - Block loop1_cont("loop1_cont", spv::Op::OpBranchConditional); + Block loop1_cont("loop1_cont", SpvOpBranchConditional); Block be_block("be_block"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -1348,7 +1348,7 @@ TEST_P(ValidateCFG, BackEdgeBlockDoesntPostDominateContinueTargetBad) { str += "OpFunctionEnd"; CompileSuccessfully(str); - if (GetParam() == spv::Capability::Shader) { + if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), @@ -1363,12 +1363,12 @@ TEST_P(ValidateCFG, BackEdgeBlockDoesntPostDominateContinueTargetBad) { } TEST_P(ValidateCFG, BranchingToNonLoopHeaderBlockBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block split("split", spv::Op::OpBranchConditional); + Block split("split", SpvOpBranchConditional); Block t("t"); Block f("f"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) split.SetBody("OpSelectionMerge %exit None\n"); @@ -1398,10 +1398,10 @@ TEST_P(ValidateCFG, BranchingToNonLoopHeaderBlockBad) { } TEST_P(ValidateCFG, BranchingToSameNonLoopHeaderBlockBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block split("split", spv::Op::OpBranchConditional); - Block exit("exit", spv::Op::OpReturn); + Block split("split", SpvOpBranchConditional); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) split.SetBody("OpSelectionMerge %exit None\n"); @@ -1429,12 +1429,12 @@ TEST_P(ValidateCFG, BranchingToSameNonLoopHeaderBlockBad) { } TEST_P(ValidateCFG, MultipleBackEdgeBlocksToLoopHeaderBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); + Block loop("loop", SpvOpBranchConditional); Block back0("back0"); Block back1("back1"); - Block merge("merge", spv::Op::OpReturn); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody("OpLoopMerge %merge %back0 None\n"); @@ -1465,13 +1465,13 @@ TEST_P(ValidateCFG, MultipleBackEdgeBlocksToLoopHeaderBad) { } TEST_P(ValidateCFG, ContinueTargetMustBePostDominatedByBackEdge) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block cheader("cheader", spv::Op::OpBranchConditional); + Block loop("loop", SpvOpBranchConditional); + Block cheader("cheader", SpvOpBranchConditional); Block be_block("be_block"); - Block merge("merge", spv::Op::OpReturn); - Block exit("exit", spv::Op::OpReturn); + Block merge("merge", SpvOpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody("OpLoopMerge %merge %cheader None\n"); @@ -1504,11 +1504,11 @@ TEST_P(ValidateCFG, ContinueTargetMustBePostDominatedByBackEdge) { } TEST_P(ValidateCFG, BranchOutOfConstructToMergeBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block cont("cont", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block loop("loop", SpvOpBranchConditional); + Block cont("cont", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody("OpLoopMerge %merge %loop None\n"); @@ -1539,12 +1539,12 @@ TEST_P(ValidateCFG, BranchOutOfConstructToMergeBad) { } TEST_P(ValidateCFG, BranchOutOfConstructBad) { - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block cont("cont", spv::Op::OpBranchConditional); + Block loop("loop", SpvOpBranchConditional); + Block cont("cont", SpvOpBranchConditional); Block merge("merge"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) loop.SetBody("OpLoopMerge %merge %loop None\n"); @@ -1575,12 +1575,12 @@ TEST_P(ValidateCFG, BranchOutOfConstructBad) { } TEST_F(ValidateCFG, OpSwitchToUnreachableBlock) { - Block entry("entry", spv::Op::OpSwitch); + Block entry("entry", SpvOpSwitch); Block case0("case0"); Block case1("case1"); Block case2("case2"); - Block def("default", spv::Op::OpUnreachable); - Block phi("phi", spv::Op::OpReturn); + Block def("default", SpvOpUnreachable); + Block phi("phi", SpvOpReturn); std::string str = R"( OpCapability Shader @@ -1687,13 +1687,13 @@ TEST_P(ValidateCFG, // The nested construct has an unreachable merge block. In the // augmented CFG that merge block // we still determine that the - bool is_shader = GetParam() == spv::Capability::Shader; - Block entry("entry", spv::Op::OpBranchConditional); - Block inner_head("inner_head", spv::Op::OpBranchConditional); - Block inner_true("inner_true", spv::Op::OpReturn); - Block inner_false("inner_false", spv::Op::OpReturn); + bool is_shader = GetParam() == SpvCapabilityShader; + Block entry("entry", SpvOpBranchConditional); + Block inner_head("inner_head", SpvOpBranchConditional); + Block inner_true("inner_true", SpvOpReturn); + Block inner_false("inner_false", SpvOpReturn); Block inner_merge("inner_merge"); - Block exit("exit", spv::Op::OpReturn); + Block exit("exit", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -1721,13 +1721,13 @@ TEST_P(ValidateCFG, ContinueTargetCanBeMergeBlockForNestedStructure) { // The continue construct cannot be the merge target of a nested selection // because the loop construct must contain "if_merge" because it contains // "if_head". - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); Block loop("loop"); - Block if_head("if_head", spv::Op::OpBranchConditional); + Block if_head("if_head", SpvOpBranchConditional); Block if_true("if_true"); - Block if_merge("if_merge", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block if_merge("if_merge", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -1765,11 +1765,11 @@ TEST_P(ValidateCFG, ContinueTargetCanBeMergeBlockForNestedStructure) { TEST_P(ValidateCFG, SingleLatchBlockMultipleBranchesToLoopHeader) { // This test case ensures we allow both branches of a loop latch block // to go back to the loop header. It still counts as a single back edge. - bool is_shader = GetParam() == spv::Capability::Shader; + bool is_shader = GetParam() == SpvCapabilityShader; Block entry("entry"); - Block loop("loop", spv::Op::OpBranchConditional); - Block latch("latch", spv::Op::OpBranchConditional); - Block merge("merge", spv::Op::OpReturn); + Block loop("loop", SpvOpBranchConditional); + Block latch("latch", SpvOpBranchConditional); + Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); if (is_shader) { @@ -2062,106 +2062,6 @@ OpFunctionEnd ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, OpSwitchTargetCannotBeOuterLoopMergeBlock) { - std::string text = R"( -OpCapability Shader -OpCapability Linkage -OpMemoryModel Logical GLSL450 - -%1 = OpTypeVoid -%2 = OpTypeFunction %1 -%3 = OpTypeBool -%4 = OpUndef %3 -%5 = OpTypeInt 32 0 -%6 = OpConstant %5 0 - -%7 = OpFunction %1 None %2 - -%8 = OpLabel -OpBranch %9 - -%9 = OpLabel -OpLoopMerge %10 %11 None -OpBranch %12 - -%12 = OpLabel -OpSelectionMerge %13 None -OpSwitch %6 %13 0 %10 1 %14 - -%14 = OpLabel -OpBranch %13 - -%13 = OpLabel -OpBranch %11 - -%11 = OpLabel -OpBranch %9 - -%10 = OpLabel -OpReturn - -OpFunctionEnd -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Switch header '12[%12]' does not structurally dominate its case construct '10[%10]'\n" - " %12 = OpLabel")); -} - -TEST_F(ValidateCFG, OpSwitchTargetCannotBeOuterLoopContinueBlock) { - std::string text = R"( -OpCapability Shader -OpCapability Linkage -OpMemoryModel Logical GLSL450 - -%1 = OpTypeVoid -%2 = OpTypeFunction %1 -%3 = OpTypeBool -%4 = OpUndef %3 -%5 = OpTypeInt 32 0 -%6 = OpConstant %5 0 - -%7 = OpFunction %1 None %2 - -%8 = OpLabel -OpBranch %9 - -%9 = OpLabel -OpLoopMerge %10 %11 None -OpBranch %12 - -%12 = OpLabel -OpSelectionMerge %13 None -OpSwitch %6 %13 0 %11 1 %14 - -%14 = OpLabel -OpBranch %13 - -%13 = OpLabel -OpBranch %11 - -%11 = OpLabel -OpBranch %9 - -%10 = OpLabel -OpReturn - -OpFunctionEnd -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Switch header '12[%12]' does not structurally dominate its case construct '11[%11]'\n" - " %12 = OpLabel")); -} - TEST_F(ValidateCFG, WrongOperandList) { std::string text = R"( OpCapability Shader @@ -3544,37 +3444,6 @@ OpFunctionEnd EXPECT_THAT(getDiagnosticString(), HasSubstr("Selection must be structured")); } -TEST_F(ValidateCFG, LoopConditionalBranchWithoutExitBad) { - const std::string text = R"( -OpCapability Shader -OpCapability Linkage -OpMemoryModel Logical GLSL450 -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%bool = OpTypeBool -%undef = OpUndef %bool -%func = OpFunction %void None %void_fn -%entry = OpLabel -OpBranch %loop -%loop = OpLabel -OpLoopMerge %exit %continue None -OpBranchConditional %undef %then %else -%then = OpLabel -OpBranch %continue -%else = OpLabel -OpBranch %exit -%continue = OpLabel -OpBranch %loop -%exit = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(text); - EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Selection must be structured")); -} - TEST_F(ValidateCFG, MissingMergeSwitchBad) { const std::string text = R"( OpCapability Shader @@ -4732,77 +4601,6 @@ OpFunctionEnd "does not structurally dominate the back-edge block '8[%8]'")); } -TEST_F(ValidateCFG, BadLoop) { - const std::string text = R"( -OpCapability Shader -OpMemoryModel Logical Simple -OpEntryPoint Fragment %2 " " -OpExecutionMode %2 OriginUpperLeft -OpName %49 "loop" -%void = OpTypeVoid -%12 = OpTypeFunction %void -%2 = OpFunction %void None %12 -%33 = OpLabel -OpBranch %49 -%50 = OpLabel -OpBranch %49 -%49 = OpLabel -OpLoopMerge %33 %50 Unroll -OpBranch %49 -OpFunctionEnd -)"; - - CompileSuccessfully(text); - EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Loop header '2[%loop]' is targeted by 2 back-edge " - "blocks but the standard requires exactly one")); -} - -TEST_F(ValidateCFG, BadSwitch) { - const std::string text = R"( - OpCapability StorageImageExtendedFormats - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "blah" %58 - OpExecutionMode %2 OriginUpperLeft - OpName %BAD "BAD" - %11 = OpTypeVoid - %12 = OpTypeFunction %11 - %19 = OpTypeInt 32 1 - %21 = OpConstant %19 555758549 - %2 = OpFunction %11 None %12 - %4 = OpLabel - OpBranch %33 - %33 = OpLabel - OpLoopMerge %34 %35 None - OpBranch %55 - %BAD = OpLabel - OpSelectionMerge %53 None - OpSwitch %21 %34 196153896 %53 20856160 %34 33570306 %34 593494531 %52 - %55 = OpLabel - OpLoopMerge %52 %58 DontUnroll - OpBranch %35 - %58 = OpLabel - OpSelectionMerge %58 None - OpSwitch %21 %52 178168 %55 608223677 %34 604111047 %34 -553516825 %34 -106432813 %BAD 6946864 %55 1257373689 %55 973090296 %35 -113180668 %55 537002232 %BAD 13762553 %BAD 1030172152 %35 -553516825 %55 -262137 %35 -1091822332 %BAD 131320 %52 131321 %35 131320 %52 131321 %35 -1091822332 %BAD - %53 = OpLabel - OpBranch %35 - %52 = OpLabel - OpBranch %34 - %35 = OpLabel - OpBranch %33 - %34 = OpLabel - OpKill - OpFunctionEnd -)"; - - CompileSuccessfully(text); - EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("exits the selection headed by '3[%BAD]', but not " - "via a structured exit")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_composites_test.cpp b/test/val/val_composites_test.cpp index 6e0d7c03..0fd1ed65 100644 --- a/test/val/val_composites_test.cpp +++ b/test/val/val_composites_test.cpp @@ -1486,7 +1486,8 @@ OpFunctionEnd } TEST_F(ValidateComposites, CoopMatConstantCompositeMismatchFail) { - const std::string body = R"( + const std::string body = + R"( OpCapability Shader OpCapability Float16 OpCapability CooperativeMatrixNV @@ -1524,7 +1525,8 @@ OpFunctionEnd)"; } TEST_F(ValidateComposites, CoopMatCompositeConstructMismatchFail) { - const std::string body = R"( + const std::string body = + R"( OpCapability Shader OpCapability Float16 OpCapability CooperativeMatrixNV @@ -1560,86 +1562,6 @@ OpFunctionEnd)"; HasSubstr("Expected Constituent type to be equal to the component type")); } -TEST_F(ValidateComposites, CoopMatKHRConstantCompositeMismatchFail) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u32 = OpTypeInt 32 0 - -%u32_16 = OpConstant %u32 16 -%useA = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA - -%f32_1 = OpConstant %f32 1 - -%f16mat_1 = OpConstantComposite %f16mat %f32_1 - -%main = OpFunction %void None %func -%main_entry = OpLabel - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "OpConstantComposite Constituent '12[%float_1]' type " - "does not match the Result Type '11[%11]'s component type.")); -} - -TEST_F(ValidateComposites, CoopMatKHRCompositeConstructMismatchFail) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u32 = OpTypeInt 32 0 - -%u32_16 = OpConstant %u32 16 -%useA = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA - -%f32_1 = OpConstant %f32 1 - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%f16mat_1 = OpCompositeConstruct %f16mat %f32_1 - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected Constituent type to be equal to the component type")); -} - TEST_F(ValidateComposites, ExtractDynamicLabelIndex) { const std::string spirv = R"( OpCapability Shader diff --git a/test/val/val_constants_test.cpp b/test/val/val_constants_test.cpp index 47278777..301539d9 100644 --- a/test/val/val_constants_test.cpp +++ b/test/val/val_constants_test.cpp @@ -478,22 +478,6 @@ OpName %ptr "ptr" "a null value")); } -TEST_F(ValidateConstant, VectorMismatchedConstituents) { - std::string spirv = kShaderPreamble kBasicTypes R"( -%int = OpTypeInt 32 1 -%int_0 = OpConstantNull %int -%const_vector = OpConstantComposite %uint2 %uint_0 %int_0 -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "OpConstantComposite Constituent '13[%13]'s type " - "does not match Result Type '3[%v2uint]'s vector element type")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_conversion_test.cpp b/test/val/val_conversion_test.cpp index 0128aa1f..1f8c4265 100644 --- a/test/val/val_conversion_test.cpp +++ b/test/val/val_conversion_test.cpp @@ -1149,7 +1149,8 @@ OpFunctionEnd)"; } TEST_F(ValidateConversion, CoopMatConversionShapesMismatchPass) { - const std::string body = R"( + const std::string body = + R"( OpCapability Shader OpCapability Float16 OpCapability Int16 @@ -1190,179 +1191,6 @@ OpFunctionEnd)"; ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateConversion, CoopMatKHRConversionSuccess) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability Int16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u16 = OpTypeInt 16 0 -%u32 = OpTypeInt 32 0 -%s16 = OpTypeInt 16 1 -%s32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%use_A = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A -%f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A -%u16mat = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_A -%u32mat = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_A -%s16mat = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_A -%s32mat = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_A - -%f16_1 = OpConstant %f16 1 -%f32_1 = OpConstant %f32 1 -%u16_1 = OpConstant %u16 1 -%u32_1 = OpConstant %u32 1 -%s16_1 = OpConstant %s16 1 -%s32_1 = OpConstant %s32 1 - -%f16mat_1 = OpConstantComposite %f16mat %f16_1 -%f32mat_1 = OpConstantComposite %f32mat %f32_1 -%u16mat_1 = OpConstantComposite %u16mat %u16_1 -%u32mat_1 = OpConstantComposite %u32mat %u32_1 -%s16mat_1 = OpConstantComposite %s16mat %s16_1 -%s32mat_1 = OpConstantComposite %s32mat %s32_1 - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%val11 = OpConvertFToU %u16mat %f16mat_1 -%val12 = OpConvertFToU %u32mat %f16mat_1 -%val13 = OpConvertFToS %s16mat %f16mat_1 -%val14 = OpConvertFToS %s32mat %f16mat_1 -%val15 = OpFConvert %f32mat %f16mat_1 - -%val21 = OpConvertFToU %u16mat %f32mat_1 -%val22 = OpConvertFToU %u32mat %f32mat_1 -%val23 = OpConvertFToS %s16mat %f32mat_1 -%val24 = OpConvertFToS %s32mat %f32mat_1 -%val25 = OpFConvert %f16mat %f32mat_1 - -%val31 = OpConvertUToF %f16mat %u16mat_1 -%val32 = OpConvertUToF %f32mat %u16mat_1 -%val33 = OpUConvert %u32mat %u16mat_1 -%val34 = OpSConvert %s32mat %u16mat_1 - -%val41 = OpConvertSToF %f16mat %s16mat_1 -%val42 = OpConvertSToF %f32mat %s16mat_1 -%val43 = OpUConvert %u32mat %s16mat_1 -%val44 = OpSConvert %s32mat %s16mat_1 - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); -} - -TEST_F(ValidateConversion, CoopMatKHRConversionUseMismatchFail) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability Int16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u16 = OpTypeInt 16 0 -%u32 = OpTypeInt 32 0 -%s16 = OpTypeInt 16 1 -%s32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%u32_4 = OpConstant %u32 4 -%subgroup = OpConstant %u32 3 -%use_A = OpConstant %u32 0 -%use_B = OpConstant %u32 1 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A -%f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_B - -%f16_1 = OpConstant %f16 1 - -%f16mat_1 = OpConstantComposite %f16mat %f16_1 - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%val1 = OpFConvert %f32mat %f16mat_1 - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected Use of Matrix type and Result Type to be identical")); -} - -TEST_F(ValidateConversion, CoopMatKHRConversionScopeMismatchFail) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability Int16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f16 = OpTypeFloat 16 -%f32 = OpTypeFloat 32 -%u16 = OpTypeInt 16 0 -%u32 = OpTypeInt 32 0 -%s16 = OpTypeInt 16 1 -%s32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%u32_4 = OpConstant %u32 4 -%subgroup = OpConstant %u32 3 -%workgroup = OpConstant %u32 2 -%use_A = OpConstant %u32 0 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A -%f32mat = OpTypeCooperativeMatrixKHR %f32 %workgroup %u32_8 %u32_8 %use_A - -%f16_1 = OpConstant %f16 1 - -%f16mat_1 = OpConstantComposite %f16mat %f16_1 - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%val1 = OpFConvert %f32mat %f16mat_1 - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Expected scopes of Matrix and Result Type to be identical")); -} - TEST_F(ValidateConversion, BitcastSuccess) { const std::string body = R"( %ptr = OpVariable %f32ptr_func Function diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp index 349e5e9e..6a7f243f 100644 --- a/test/val/val_data_test.cpp +++ b/test/val/val_data_test.cpp @@ -14,6 +14,7 @@ // Validation tests for Data Rules. +#include #include #include diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp index e32e237a..28ee970a 100644 --- a/test/val/val_decoration_test.cpp +++ b/test/val/val_decoration_test.cpp @@ -19,6 +19,7 @@ #include "gmock/gmock.h" #include "source/val/decoration.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_code_generator.h" #include "test/val/val_fixtures.h" @@ -61,10 +62,9 @@ TEST_F(ValidateDecorations, ValidateOpDecorateRegistration) { CompileSuccessfully(spirv); EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); // Must have 2 decorations. - EXPECT_THAT( - vstate_->id_decorations(id), - Eq(std::set{Decoration(spv::Decoration::Location, {4}), - Decoration(spv::Decoration::Centroid)})); + EXPECT_THAT(vstate_->id_decorations(id), + Eq(std::set{Decoration(SpvDecorationLocation, {4}), + Decoration(SpvDecorationCentroid)})); } TEST_F(ValidateDecorations, ValidateOpMemberDecorateRegistration) { @@ -89,15 +89,15 @@ TEST_F(ValidateDecorations, ValidateOpMemberDecorateRegistration) { const uint32_t arr_id = 1; EXPECT_THAT( vstate_->id_decorations(arr_id), - Eq(std::set{Decoration(spv::Decoration::ArrayStride, {4})})); + Eq(std::set{Decoration(SpvDecorationArrayStride, {4})})); // The struct must have 3 decorations. const uint32_t struct_id = 2; EXPECT_THAT( vstate_->id_decorations(struct_id), - Eq(std::set{Decoration(spv::Decoration::NonReadable, {}, 2), - Decoration(spv::Decoration::Offset, {2}, 2), - Decoration(spv::Decoration::BufferBlock)})); + Eq(std::set{Decoration(SpvDecorationNonReadable, {}, 2), + Decoration(SpvDecorationOffset, {2}, 2), + Decoration(SpvDecorationBufferBlock)})); } TEST_F(ValidateDecorations, ValidateOpMemberDecorateOutOfBound) { @@ -152,9 +152,9 @@ TEST_F(ValidateDecorations, ValidateGroupDecorateRegistration) { // Decoration group has 3 decorations. auto expected_decorations = - std::set{Decoration(spv::Decoration::DescriptorSet, {0}), - Decoration(spv::Decoration::RelaxedPrecision), - Decoration(spv::Decoration::Restrict)}; + std::set{Decoration(SpvDecorationDescriptorSet, {0}), + Decoration(SpvDecorationRelaxedPrecision), + Decoration(SpvDecorationRestrict)}; // Decoration group is applied to id 1, 2, 3, and 4. Note that id 1 (which is // the decoration group id) also has all the decorations. @@ -182,7 +182,7 @@ TEST_F(ValidateDecorations, ValidateGroupMemberDecorateRegistration) { EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); // Decoration group has 1 decoration. auto expected_decorations = - std::set{Decoration(spv::Decoration::Offset, {3}, 3)}; + std::set{Decoration(SpvDecorationOffset, {3}, 3)}; // Decoration group is applied to id 2, 3, and 4. EXPECT_THAT(vstate_->id_decorations(2), Eq(expected_decorations)); @@ -1218,14 +1218,9 @@ TEST_F(ValidateDecorations, BlockGLSLSharedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLShared' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLShared decoration")); } TEST_F(ValidateDecorations, BufferBlockGLSLSharedBad) { @@ -1252,14 +1247,9 @@ TEST_F(ValidateDecorations, BufferBlockGLSLSharedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLShared' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLShared decoration")); } TEST_F(ValidateDecorations, BlockNestedStructGLSLSharedBad) { @@ -1292,14 +1282,9 @@ TEST_F(ValidateDecorations, BlockNestedStructGLSLSharedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLShared' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLShared decoration")); } TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLSharedBad) { @@ -1332,14 +1317,9 @@ TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLSharedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLShared' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLShared decoration")); } TEST_F(ValidateDecorations, BlockGLSLPackedBad) { @@ -1366,14 +1346,9 @@ TEST_F(ValidateDecorations, BlockGLSLPackedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLPacked' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLPacked decoration")); } TEST_F(ValidateDecorations, BufferBlockGLSLPackedBad) { @@ -1400,14 +1375,9 @@ TEST_F(ValidateDecorations, BufferBlockGLSLPackedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLPacked' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLPacked decoration")); } TEST_F(ValidateDecorations, BlockNestedStructGLSLPackedBad) { @@ -1440,14 +1410,9 @@ TEST_F(ValidateDecorations, BlockNestedStructGLSLPackedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLPacked' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLPacked decoration")); } TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLPackedBad) { @@ -1480,14 +1445,9 @@ TEST_F(ValidateDecorations, BufferBlockNestedStructGLSLPackedBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "'GLSLPacked' is not valid for the Vulkan execution environment")); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("[VUID-StandaloneSpirv-GLSLShared-04669]")); + HasSubstr("must not use GLSLPacked decoration")); } TEST_F(ValidateDecorations, BlockMissingArrayStrideBad) { @@ -1888,8 +1848,7 @@ TEST_F(ValidateDecorations, BlockStandardUniformBufferLayout) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); } TEST_F(ValidateDecorations, BlockLayoutPermitsTightVec3ScalarPackingGood) { @@ -1918,7 +1877,7 @@ TEST_F(ValidateDecorations, BlockLayoutPermitsTightVec3ScalarPackingGood) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -2100,8 +2059,7 @@ TEST_F(ValidateDecorations, BlockLayoutForbidsTightScalarVec3PackingBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr("Structure id 2 decorated as Block for variable in Uniform " @@ -2509,8 +2467,7 @@ TEST_F(ValidateDecorations, BufferBlock16bitStandardStorageBufferLayout) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); } TEST_F(ValidateDecorations, BlockArrayExtendedAlignmentGood) { @@ -2574,8 +2531,7 @@ TEST_F(ValidateDecorations, BlockArrayBaseAlignmentBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -2772,7 +2728,7 @@ TEST_F(ValidateDecorations, PushConstantArrayBaseAlignmentGood) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -2804,8 +2760,7 @@ TEST_F(ValidateDecorations, PushConstantArrayBadAlignmentBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -2839,7 +2794,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -2868,8 +2823,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -3721,7 +3675,7 @@ TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBaseAlignmentGood) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -3756,8 +3710,7 @@ TEST_F(ValidateDecorations, StorageBufferStorageClassArrayBadAlignmentBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -3824,8 +3777,7 @@ TEST_F(ValidateDecorations, BufferBlockStandardStorageBufferLayout) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); } TEST_F(ValidateDecorations, @@ -3856,7 +3808,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -3888,8 +3840,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -3957,8 +3908,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr("Structure id 6 decorated as Block for variable in Uniform " @@ -4025,8 +3975,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr("Structure id 8 decorated as Block for variable in Uniform " @@ -4092,8 +4041,7 @@ TEST_F(ValidateDecorations, BlockUniformBufferLayoutIncorrectArrayStrideBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -4129,8 +4077,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr("Structure id 3 decorated as BufferBlock for variable in " @@ -4169,8 +4116,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -4186,7 +4132,6 @@ TEST_F(ValidateDecorations, OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %1 "main" - OpExecutionMode %1 LocalSize 1 1 1 OpMemberDecorate %_struct_6 0 Offset 0 OpMemberDecorate %_struct_2 0 Offset 0 OpMemberDecorate %_struct_2 1 Offset 4 @@ -4205,8 +4150,7 @@ TEST_F(ValidateDecorations, )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -4331,8 +4275,7 @@ TEST_F(ValidateDecorations, BlockLayoutOffsetOverlapBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -4462,7 +4405,7 @@ TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixTightPackingGood) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)) + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()) << getDiagnosticString(); } @@ -4506,8 +4449,7 @@ TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixNextMemberOverlapsBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -4519,48 +4461,6 @@ TEST_F(ValidateDecorations, ArrayArrayRowMajorMatrixNextMemberOverlapsBad) { TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGood) { // Original GLSL - // #version 450 - // layout (set=0,binding=0) buffer S { - // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12 - // uint i; // Can't have offset 60 = 3x16 + 12 - // } B; - // void main() {} - - std::string spirv = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %1 "main" - OpDecorate %_arr_v3uint_uint_2 ArrayStride 16 - OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32 - OpMemberDecorate %_struct_4 0 Offset 0 - OpMemberDecorate %_struct_4 1 Offset 64 - OpDecorate %_struct_4 BufferBlock - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 0 - %void = OpTypeVoid - %7 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v3uint = OpTypeVector %uint 3 - %uint_2 = OpConstant %uint 2 -%_arr_v3uint_uint_2 = OpTypeArray %v3uint %uint_2 -%_arr__arr_v3uint_uint_2_uint_2 = OpTypeArray %_arr_v3uint_uint_2 %uint_2 - %_struct_4 = OpTypeStruct %_arr__arr_v3uint_uint_2_uint_2 %uint -%_ptr_Uniform__struct_4 = OpTypePointer Uniform %_struct_4 - %5 = OpVariable %_ptr_Uniform__struct_4 Uniform - %1 = OpFunction %void None %7 - %12 = OpLabel - OpReturn - OpFunctionEnd - )"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); -} - -TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGoodScalar) { - // Original GLSL - // #version 450 // layout (set=0,binding=0) buffer S { // uvec3 arr[2][2]; // first 3 elements are 16 bytes, last is 12 @@ -4595,10 +4495,8 @@ TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackGoodScalar) { OpFunctionEnd )"; - options_->scalar_block_layout = true; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); } TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackBad) { @@ -4611,7 +4509,7 @@ TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackBad) { OpDecorate %_arr_v3uint_uint_2 ArrayStride 16 OpDecorate %_arr__arr_v3uint_uint_2_uint_2 ArrayStride 32 OpMemberDecorate %_struct_4 0 Offset 0 - OpMemberDecorate %_struct_4 1 Offset 60 + OpMemberDecorate %_struct_4 1 Offset 56 OpDecorate %_struct_4 BufferBlock OpDecorate %5 DescriptorSet 0 OpDecorate %5 Binding 0 @@ -4632,13 +4530,12 @@ TEST_F(ValidateDecorations, StorageBufferArraySizeCalculationPackBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT(getDiagnosticString(), HasSubstr("Structure id 4 decorated as BufferBlock for variable " "in Uniform storage class must follow standard storage " - "buffer layout rules: member 1 at offset 60 overlaps " - "previous member ending at offset 63")); + "buffer layout rules: member 1 at offset 56 overlaps " + "previous member ending at offset 59")); } TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackGood) { @@ -4673,8 +4570,7 @@ TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackGood) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); } TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackBad) { @@ -4708,8 +4604,7 @@ TEST_F(ValidateDecorations, UniformBufferArraySizeCalculationPackBad) { )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -5247,10 +5142,8 @@ OpGroupDecorate %1 %2 %1 TEST_F(ValidateDecorations, RecurseThroughRuntimeArray) { const std::string spirv = R"( OpCapability Shader -OpExtension "SPV_KHR_storage_buffer_storage_class" +OpCapability Linkage OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -OpExecutionMode %main LocalSize 1 1 1 OpDecorate %outer Block OpMemberDecorate %inner 0 Offset 0 OpMemberDecorate %inner 1 Offset 1 @@ -5260,55 +5153,17 @@ OpMemberDecorate %outer 0 Offset 0 %inner = OpTypeStruct %int %int %runtime = OpTypeRuntimeArray %inner %outer = OpTypeStruct %runtime -%outer_ptr = OpTypePointer StorageBuffer %outer -%var = OpVariable %outer_ptr StorageBuffer -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd +%outer_ptr = OpTypePointer Uniform %outer +%var = OpVariable %outer_ptr Uniform )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), - HasSubstr( - "Structure id 3 decorated as Block for variable in StorageBuffer " - "storage class must follow standard storage buffer layout " - "rules: member 1 at offset 1 is not aligned to 4")); -} - -TEST_F(ValidateDecorations, VulkanStructWithoutDecorationWithRuntimeArray) { - std::string str = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft - OpDecorate %array_t ArrayStride 4 - OpMemberDecorate %struct_t 0 Offset 0 - OpMemberDecorate %struct_t 1 Offset 4 - %uint_t = OpTypeInt 32 0 - %array_t = OpTypeRuntimeArray %uint_t - %struct_t = OpTypeStruct %uint_t %array_t -%struct_ptr = OpTypePointer StorageBuffer %struct_t - %2 = OpVariable %struct_ptr StorageBuffer - %void = OpTypeVoid - %func_t = OpTypeFunction %void - %func = OpFunction %void None %func_t - %1 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(str.c_str(), SPV_ENV_VULKAN_1_1); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Vulkan, OpTypeStruct containing an OpTypeRuntimeArray " - "must be decorated with Block or BufferBlock.")); + HasSubstr("Structure id 2 decorated as Block for variable in Uniform " + "storage class must follow standard uniform buffer layout " + "rules: member 1 at offset 1 is not aligned to 4")); } TEST_F(ValidateDecorations, EmptyStructAtNonZeroOffsetGood) { @@ -7029,8 +6884,6 @@ OpFunctionEnd CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04924")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Component decoration specified for type")); EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a scalar or vector")); @@ -7040,7 +6893,6 @@ std::string ShaderWithComponentDecoration(const std::string& type, const std::string& decoration) { return R"( OpCapability Shader -OpCapability Int64 OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %entryPointOutput OpExecutionMode %main OriginUpperLeft @@ -7053,9 +6905,6 @@ OpDecorate %entryPointOutput )" + %v3float = OpTypeVector %float 3 %v4float = OpTypeVector %float 4 %uint = OpTypeInt 32 0 -%uint64 = OpTypeInt 64 0 -%v2uint64 = OpTypeVector %uint64 2 -%v3uint64 = OpTypeVector %uint64 3 %uint_2 = OpConstant %uint 2 %arr_v3float_uint_2 = OpTypeArray %v3float %uint_2 %float_0 = OpConstant %float 0 @@ -7111,10 +6960,8 @@ TEST_F(ValidateDecorations, ComponentDecorationIntBad4Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04920")); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Component decoration value must not be greater than 3")); + HasSubstr("Sequence of components starting with 4 " + "and ending with 4 gets larger than 3")); } TEST_F(ValidateDecorations, ComponentDecorationVector3GoodVulkan) { @@ -7141,8 +6988,6 @@ TEST_F(ValidateDecorations, ComponentDecorationVector4Bad1Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04921")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 1 " "and ending with 4 gets larger than 3")); @@ -7154,8 +6999,6 @@ TEST_F(ValidateDecorations, ComponentDecorationVector4Bad3Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04921")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 3 " "and ending with 6 gets larger than 3")); @@ -7178,102 +7021,11 @@ TEST_F(ValidateDecorations, ComponentDecorationArrayBadVulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04921")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 2 " "and ending with 4 gets larger than 3")); } -TEST_F(ValidateDecorations, ComponentDecoration64ScalarGoodVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("uint64", "Component 0"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Scalar1BadVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("uint64", "Component 1"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04923")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Component decoration value must not be 1 or 3 for " - "64-bit data types")); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Scalar2GoodVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("uint64", "Component 2"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Scalar3BadVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("uint64", "Component 3"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04923")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Component decoration value must not be 1 or 3 for " - "64-bit data types")); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Vec0GoodVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 0"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Vec1BadVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 1"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04923")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Component decoration value must not be 1 or 3 for " - "64-bit data types")); -} - -TEST_F(ValidateDecorations, ComponentDecoration64Vec2BadVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 2"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04922")); - HasSubstr( - "Sequence of components starting with 2 " - "and ending with 6 gets larger than 3"); -} - -TEST_F(ValidateDecorations, ComponentDecoration64VecWideBadVulkan) { - const spv_target_env env = SPV_ENV_VULKAN_1_0; - std::string spirv = ShaderWithComponentDecoration("v3uint64", "Component 0"); - - CompileSuccessfully(spirv, env); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-07703")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Component decoration only allowed on 64-bit scalar " - "and 2-component vector")); -} - TEST_F(ValidateDecorations, ComponentDecorationBlockGood) { std::string spirv = R"( OpCapability Shader @@ -7344,8 +7096,6 @@ OpFunctionEnd CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Component-04921")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 2 " "and ending with 4 gets larger than 3")); @@ -8003,7 +7753,6 @@ TEST_F(ValidateDecorations, WorkgroupBlockVariableWith16BitType) { OpCapability Shader OpCapability Float16 OpCapability Int16 - OpCapability WorkgroupMemoryExplicitLayoutKHR OpCapability WorkgroupMemoryExplicitLayout16BitAccessKHR OpExtension "SPV_KHR_workgroup_memory_explicit_layout" OpMemoryModel Logical GLSL450 @@ -8223,7 +7972,7 @@ TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableMissingLayout) { CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4)); + ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT( getDiagnosticString(), HasSubstr("Block must be explicitly laid out with Offset decorations")); @@ -8258,43 +8007,13 @@ TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableBadLayout) { CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); EXPECT_EQ(SPV_ERROR_INVALID_ID, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Block for variable in Workgroup storage class must follow " - "relaxed storage buffer layout rules: " - "member 0 at offset 1 is not aligned to 4")); -} - -TEST_F(ValidateDecorations, WorkgroupBlockNoCapability) { - std::string spirv = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" %_ - OpExecutionMode %main LocalSize 1 1 1 - OpMemberDecorate %struct 0 Offset 0 - OpMemberDecorate %struct 1 Offset 4 - OpDecorate %struct Block - %void = OpTypeVoid - %3 = OpTypeFunction %void - %int = OpTypeInt 32 1 - %struct = OpTypeStruct %int %int -%ptr_workgroup = OpTypePointer Workgroup %struct - %_ = OpVariable %ptr_workgroup Workgroup - %main = OpFunction %void None %3 - %5 = OpLabel - OpReturn - OpFunctionEnd - )"; - - CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, - ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4)); + ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_4)); EXPECT_THAT( getDiagnosticString(), HasSubstr( - "Workgroup Storage Class variables can't be decorated with Block " - "unless declaring the WorkgroupMemoryExplicitLayoutKHR capability")); + "Block for variable in Workgroup storage class must follow " + "standard storage buffer layout rules: " + "member 0 at offset 1 is not aligned to 4")); } TEST_F(ValidateDecorations, BadMatrixStrideUniform) { @@ -8324,7 +8043,7 @@ OpFunctionEnd )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -8361,7 +8080,7 @@ OpFunctionEnd )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -8380,6 +8099,8 @@ OpDecorate %block Block OpMemberDecorate %block 0 Offset 0 OpMemberDecorate %block 0 MatrixStride 3 OpMemberDecorate %block 0 ColMajor +OpDecorate %var DescriptorSet 0 +OpDecorate %var Binding 0 %void = OpTypeVoid %float = OpTypeFloat 32 %float4 = OpTypeVector %float 4 @@ -8395,7 +8116,7 @@ OpFunctionEnd )"; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -8433,7 +8154,7 @@ OpFunctionEnd options_->scalar_block_layout = true; CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr( @@ -8932,8 +8653,9 @@ TEST_P(ValidateDecorationString, VulkanOutputInvalidInterface) { AnyVUID("VUID-StandaloneSpirv-Flat-06201")); EXPECT_THAT( getDiagnosticString(), - HasSubstr("decorated variable must not be used in fragment execution " - "model as an Output storage class for Entry Point id 2.")); + HasSubstr( + "OpEntryPoint interfaces variable must not be fragment execution " + "model with an output storage class for Entry Point id 2.")); } TEST_P(ValidateDecorationString, VulkanVertexInputInvalidInterface) { @@ -8971,8 +8693,8 @@ TEST_P(ValidateDecorationString, VulkanVertexInputInvalidInterface) { AnyVUID("VUID-StandaloneSpirv-Flat-06202")); EXPECT_THAT( getDiagnosticString(), - HasSubstr("decorated variable must not be used in vertex execution model " - "as an Input storage class for Entry Point id 2.")); + HasSubstr("OpEntryPoint interfaces variable must not be vertex execution " + "model with an input storage class for Entry Point id 2.")); } INSTANTIATE_TEST_SUITE_P(FragmentInputInterface, ValidateDecorationString, @@ -9284,124 +9006,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); } -TEST_F(ValidateDecorations, PhysicalStorageBufferWithOffset) { - const std::string spirv = R"( -OpCapability Shader -OpCapability Int64 -OpCapability PhysicalStorageBufferAddresses -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint GLCompute %main "main" %pc -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %pc_block Block -OpMemberDecorate %pc_block 0 Offset 0 -OpMemberDecorate %pssbo_struct 0 Offset 0 -%void = OpTypeVoid -%long = OpTypeInt 64 0 -%float = OpTypeFloat 32 -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%pc_block = OpTypeStruct %long -%pc_block_ptr = OpTypePointer PushConstant %pc_block -%pc_long_ptr = OpTypePointer PushConstant %long -%pc = OpVariable %pc_block_ptr PushConstant -%pssbo_struct = OpTypeStruct %float -%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0 -%addr = OpLoad %long %pc_gep -%ptr = OpConvertUToPtr %pssbo_ptr %addr -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3)); -} - -TEST_F(ValidateDecorations, PhysicalStorageBufferMissingOffset) { - const std::string spirv = R"( -OpCapability Shader -OpCapability Int64 -OpCapability PhysicalStorageBufferAddresses -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint GLCompute %main "main" %pc -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %pc_block Block -OpMemberDecorate %pc_block 0 Offset 0 -%void = OpTypeVoid -%long = OpTypeInt 64 0 -%float = OpTypeFloat 32 -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%pc_block = OpTypeStruct %long -%pc_block_ptr = OpTypePointer PushConstant %pc_block -%pc_long_ptr = OpTypePointer PushConstant %long -%pc = OpVariable %pc_block_ptr PushConstant -%pssbo_struct = OpTypeStruct %float -%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0 -%addr = OpLoad %long %pc_gep -%ptr = OpConvertUToPtr %pssbo_ptr %addr -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("decorated as Block for variable in PhysicalStorageBuffer " - "storage class must follow relaxed storage buffer layout " - "rules: member 0 is missing an Offset decoration")); -} - -TEST_F(ValidateDecorations, PhysicalStorageBufferMissingArrayStride) { - const std::string spirv = R"( -OpCapability Shader -OpCapability Int64 -OpCapability PhysicalStorageBufferAddresses -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint GLCompute %main "main" %pc -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %pc_block Block -OpMemberDecorate %pc_block 0 Offset 0 -%void = OpTypeVoid -%long = OpTypeInt 64 0 -%float = OpTypeFloat 32 -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_4 = OpConstant %int 4 -%pc_block = OpTypeStruct %long -%pc_block_ptr = OpTypePointer PushConstant %pc_block -%pc_long_ptr = OpTypePointer PushConstant %long -%pc = OpVariable %pc_block_ptr PushConstant -%pssbo_array = OpTypeArray %float %int_4 -%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_array -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0 -%addr = OpLoad %long %pc_gep -%ptr = OpConvertUToPtr %pssbo_ptr %addr -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "decorated as Block for variable in PhysicalStorageBuffer storage " - "class must follow relaxed storage buffer layout rules: member 0 " - "contains an array with stride 0, but with an element size of 4")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_entry_point.cpp b/test/val/val_entry_point.cpp new file mode 100644 index 00000000..f28cf5d1 --- /dev/null +++ b/test/val/val_entry_point.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2019 Samsung Inc +// +// 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 "gmock/gmock.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace { + +using ::testing::Eq; +using ::testing::HasSubstr; + +using ValidateEntryPoints = spvtest::ValidateBase; + +TEST_F(ValidateEntryPoints, DuplicateEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Entry points cannot share the same name")); +} + +TEST_F(ValidateEntryPoints, UniqueEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo2" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +} // namespace +} // namespace spvtools diff --git a/test/val/val_ext_inst_debug_test.cpp b/test/val/val_ext_inst_debug_test.cpp index 8f0da42d..554e78b0 100644 --- a/test/val/val_ext_inst_debug_test.cpp +++ b/test/val/val_ext_inst_debug_test.cpp @@ -1012,9 +1012,9 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) { CompileSuccessfully(GenerateShaderCodeForDebugInfo( src, size_const, dbg_inst_header, "", extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("expected operand Base Type is not a valid debug type")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("expected operand Base Type must be a result id of " + "DebugTypeBasic")); } TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) { @@ -1077,9 +1077,9 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) { CompileSuccessfully(GenerateShaderCodeForDebugInfo( src, size_const, dbg_inst_header, "", extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("expected operand Base Type is not a valid debug type")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("expected operand Base Type must be a result id of " + "DebugTypeBasic")); } TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifier) { const std::string src = R"( @@ -1147,9 +1147,9 @@ OpExtension "SPV_KHR_non_semantic_info" CompileSuccessfully(GenerateShaderCodeForDebugInfo( src, constants, dbg_inst_header, "", extension, "Vertex")); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("expected operand Base Type is not a valid debug type")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("expected operand Base Type must be a result id of " + "DebugTypeBasic")); } TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) { diff --git a/test/val/val_ext_inst_test.cpp b/test/val/val_ext_inst_test.cpp index 8f0bcce1..e685acde 100644 --- a/test/val/val_ext_inst_test.cpp +++ b/test/val/val_ext_inst_test.cpp @@ -6239,197 +6239,6 @@ OpFunctionEnd HasSubstr("Name must match an entry-point for Kernel")); } -TEST_F(ValidateClspvReflection, KernelArgumentsVersionGood) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_1 = OpConstant %int 1 -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1 -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); -} - -TEST_F(ValidateClspvReflection, KernelArgumentsVersionBad) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.4" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_1 = OpConstant %int 1 -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %int_1 -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Version 4 of the Kernel instruction can only have 2 " - "additional operands")); -} - -TEST_F(ValidateClspvReflection, KernelNumArgumentsNotInt) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %float_0 -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant")); -} - -TEST_F(ValidateClspvReflection, KernelNumArgumentsNotConstant) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%null = OpConstantNull %int -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %null -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("NumArguments must be a 32-bit unsigned integer OpConstant")); -} - -TEST_F(ValidateClspvReflection, KernelFlagsNotInt) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %float_0 -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Flags must be a 32-bit unsigned integer OpConstant")); -} - -TEST_F(ValidateClspvReflection, KernelFlagsNotConstant) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%null = OpConstantNull %int -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %null -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Flags must be a 32-bit unsigned integer OpConstant")); -} - -TEST_F(ValidateClspvReflection, KernelAttributesNotString) { - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%void = OpTypeVoid -%void_fn = OpTypeFunction %void -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name %int_0 %int_0 %int_0 -)"; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Attributes must be an OpString")); -} - using ArgumentBasics = spvtest::ValidateBase>; @@ -6445,11 +6254,7 @@ INSTANTIATE_TEST_SUITE_P( std::make_pair("ArgumentSampledImage", "%int_0 %int_0"), std::make_pair("ArgumentStorageImage", "%int_0 %int_0"), std::make_pair("ArgumentSampler", "%int_0 %int_0"), - std::make_pair("ArgumentWorkgroup", "%int_0 %int_0"), - std::make_pair("ArgumentPointerPushConstant", "%int_0 %int_4"), - std::make_pair("ArgumentPointerUniform", "%int_0 %int_0 %int_0 %int_4"), - std::make_pair("ArgumentStorageTexelBuffer", "%int_0 %int_0"), - std::make_pair("ArgumentUniformTexelBuffer", "%int_0 %int_0")})); + std::make_pair("ArgumentWorkgroup", "%int_0 %int_0")})); TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) { const std::string ext_inst = std::get<0>(GetParam()); @@ -6457,7 +6262,7 @@ TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6486,8 +6291,8 @@ TEST_P(ArgumentBasics, KernelFromDifferentImport) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -%ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" +%ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6518,7 +6323,7 @@ TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6548,7 +6353,7 @@ TEST_P(ArgumentBasics, ArgumentInfo) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6578,7 +6383,7 @@ TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6609,8 +6414,8 @@ TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -%ext2 = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" +%ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -6854,269 +6659,7 @@ INSTANTIATE_TEST_SUITE_P( std::make_pair( "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"), std::make_pair( - "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z"), - std::make_pair("SpecConstantSubgroupMaxSize %float_0", "Size"), - std::make_pair("SpecConstantSubgroupMaxSize %null", "Size"), - std::make_pair( - "ArgumentPointerPushConstant %decl %float_0 %int_0 %int_0", - "Ordinal"), - std::make_pair("ArgumentPointerPushConstant %decl %null %int_0 %int_0", - "Ordinal"), - std::make_pair( - "ArgumentPointerPushConstant %decl %int_0 %float_0 %int_0", - "Offset"), - std::make_pair("ArgumentPointerPushConstant %decl %int_0 %null %int_0", - "Offset"), - std::make_pair( - "ArgumentPointerPushConstant %decl %int_0 %int_0 %float_0", "Size"), - std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %null", - "Size"), - std::make_pair( - "ArgumentPointerUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair( - "ArgumentPointerUniform %decl %null %int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %null %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4", - "Binding"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %null %int_0 %int_4", - "Binding"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4", - "Offset"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %null %int_4", - "Offset"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0", - "Size"), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %null", - "Size"), - std::make_pair( - "ProgramScopeVariablesStorageBuffer %float_0 %int_0 %data", - "DescriptorSet"), - std::make_pair("ProgramScopeVariablesStorageBuffer %null %int_0 %data", - "DescriptorSet"), - std::make_pair( - "ProgramScopeVariablesStorageBuffer %int_0 %float_0 %data", - "Binding"), - std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %null %data", - "Binding"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %float_0 %int_0 %int_4", - "ObjectOffset"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %null %int_0 %int_4", - "ObjectOffset"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %int_0 %float_0 %int_4", - "PointerOffset"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %int_0 %null %int_4", - "PointerOffset"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %int_0 %int_0 %float_0", - "PointerSize"), - std::make_pair( - "ProgramScopeVariablePointerRelocation %int_0 %int_0 %null", - "PointerSize"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl " - "%float_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %null " - "%int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " - "%float_0 %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " - "%null %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " - "%int_0 %float_0", - "Size"), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " - "%int_0 %null", - "Size"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%float_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%null %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%int_0 %float_0 %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%int_0 %null %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%int_0 %int_0 %float_0", - "Size"), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%int_0 %int_0 %null", - "Size"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %float_0 " - "%int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %null " - "%int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%float_0 %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%null %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %float_0 %int_0 %int_4", - "Binding"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %null %int_0 %int_4", - "Binding"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %int_0 %float_0 %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %int_0 %null %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %float_0", - "Size"), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %null", - "Size"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %float_0 " - "%int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %null " - "%int_0 %int_0 %int_0 %int_4", - "Ordinal"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%float_0 %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%null %int_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %float_0 %int_0 %int_4", - "Binding"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %null %int_0 %int_4", - "Binding"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %int_0 %float_0 %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %int_0 %null %int_4", - "Offset"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %float_0", - "Size"), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %null", - "Size"), - std::make_pair( - "ArgumentStorageTexelBuffer %decl %float_0 %int_0 %int_0", - "Ordinal"), - std::make_pair("ArgumentStorageTexelBuffer %decl %null %int_0 %int_0", - "Ordinal"), - std::make_pair( - "ArgumentStorageTexelBuffer %decl %int_0 %float_0 %int_0", - "DescriptorSet"), - std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %null %int_0", - "DescriptorSet"), - std::make_pair( - "ArgumentStorageTexelBuffer %decl %int_0 %int_0 %float_0", - "Binding"), - std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %null", - "Binding"), - std::make_pair( - "ArgumentUniformTexelBuffer %decl %float_0 %int_0 %int_0", - "Ordinal"), - std::make_pair("ArgumentUniformTexelBuffer %decl %null %int_0 %int_0", - "Ordinal"), - std::make_pair( - "ArgumentUniformTexelBuffer %decl %int_0 %float_0 %int_0", - "DescriptorSet"), - std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %null %int_0", - "DescriptorSet"), - std::make_pair( - "ArgumentUniformTexelBuffer %decl %int_0 %int_0 %float_0", - "Binding"), - std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %null", - "Binding"), - std::make_pair("ConstantDataPointerPushConstant %float_0 %int_4 %data", - "Offset"), - std::make_pair("ConstantDataPointerPushConstant %null %int_4 %data", - "Offset"), - std::make_pair("ConstantDataPointerPushConstant %int_0 %float_0 %data", - "Size"), - std::make_pair("ConstantDataPointerPushConstant %int_0 %null %data", - "Size"), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %float_0 %int_4 %data", - "Offset"), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %null %int_4 %data", - "Offset"), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %int_0 %float_0 %data", - "Size"), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %int_0 %null %data", - "Size"), - std::make_pair("PrintfInfo %float_0 %data %int_0 %int_0 %int_0", - "PrintfID"), - std::make_pair("PrintfInfo %null %data %int_0 %int_0 %int_0", - "PrintfID"), - std::make_pair("PrintfInfo %int_0 %data %float_0 %int_0 %int_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %null %int_0 %int_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0 %int_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %null %int_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %null", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %int_0 %float_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %float_0", - "ArgumentSizes"), - std::make_pair("PrintfInfo %int_0 %data %int_0 %null", "ArgumentSizes"), - std::make_pair("PrintfBufferStorageBuffer %float_0 %int_0 %int_4", - "DescriptorSet"), - std::make_pair("PrintfBufferStorageBuffer %null %int_0 %int_4", - "DescriptorSet"), - std::make_pair("PrintfBufferStorageBuffer %int_0 %float_0 %int_4", - "Binding"), - std::make_pair("PrintfBufferStorageBuffer %int_0 %null %int_4", - "Binding"), - std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %float_0", - "Size"), - std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %null", "Size"), - std::make_pair("PrintfBufferPointerPushConstant %float_0 %int_0 %int_4", - "Offset"), - std::make_pair("PrintfBufferPointerPushConstant %null %int_0 %int_4", - "Offset"), - std::make_pair("PrintfBufferPointerPushConstant %int_0 %float_0 %int_4", - "Size"), - std::make_pair("PrintfBufferPointerPushConstant %int_0 %null %int_4", - "Size"), - std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %float_0", - "BufferSize"), - std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %null", - "BufferSize")})); + "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z")})); TEST_P(Uint32Constant, Invalid) { const std::string ext_inst = std::get<0>(GetParam()); @@ -7124,7 +6667,7 @@ TEST_P(Uint32Constant, Invalid) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" +%ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" OpExecutionMode %foo LocalSize 1 1 1 @@ -7162,15 +6705,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(std::vector>{ std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0", "Data"), - std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data"), - std::make_pair( - "ProgramScopeVariablesStorageBuffer %int_0 %int_0 %int_0", "Data"), - std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %int_0", - "Data"), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %int_0", - "Data"), - std::make_pair("PrintfInfo %int_0 %int_0", "FormatString")})); + std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data")})); TEST_P(StringOperand, Invalid) { const std::string ext_inst = std::get<0>(GetParam()); @@ -7178,106 +6713,6 @@ TEST_P(StringOperand, Invalid) { const std::string text = R"( OpCapability Shader OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%data = OpString "1234" -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_1 = OpConstant %int 1 -%int_4 = OpConstant %int 4 -%null = OpConstantNull %int -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%void_fn = OpTypeFunction %void -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name -%inst = OpExtInst %void %ext )" + - ext_inst; - - CompileSuccessfully(text); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString")); -} - -using VersionCheck = spvtest::ValidateBase>; - -INSTANTIATE_TEST_SUITE_P( - ValidateClspvReflectionVersionCheck, VersionCheck, - ::testing::ValuesIn(std::vector>{ - std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentUniform %decl %int_0 %int_0 %int_0", 1), - std::make_pair( - "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %int_0", - 1), - std::make_pair( - "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentSampler %decl %int_0 %int_0 %int_0", 1), - std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %int_0", 1), - std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %int_0", 1), - std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %int_0", 1), - std::make_pair("SpecConstantWorkDim %int_0", 1), - std::make_pair("PushConstantGlobalOffset %int_0 %int_0", 1), - std::make_pair("PushConstantEnqueuedLocalSize %int_0 %int_0", 1), - std::make_pair("PushConstantGlobalSize %int_0 %int_0", 1), - std::make_pair("PushConstantRegionOffset %int_0 %int_0", 1), - std::make_pair("PushConstantNumWorkgroups %int_0 %int_0", 1), - std::make_pair("PushConstantRegionGroupOffset %int_0 %int_0", 1), - std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %data", 1), - std::make_pair("ConstantDataUniform %int_0 %int_0 %data", 1), - std::make_pair("LiteralSampler %int_0 %int_0 %int_0", 1), - std::make_pair( - "PropertyRequiredWorkgroupSize %decl %int_0 %int_0 %int_0", 1), - std::make_pair("SpecConstantSubgroupMaxSize %int_0", 2), - std::make_pair("ArgumentPointerPushConstant %decl %int_0 %int_0 %int_0", - 3), - std::make_pair( - "ArgumentPointerUniform %decl %int_0 %int_0 %int_0 %int_0 %int_0", - 3), - std::make_pair("ProgramScopeVariablesStorageBuffer %int_0 %int_0 %data", - 3), - std::make_pair( - "ProgramScopeVariablePointerRelocation %int_0 %int_0 %int_0", 3), - std::make_pair("ImageArgumentInfoChannelOrderPushConstant %decl %int_0 " - "%int_0 %int_0", - 3), - std::make_pair("ImageArgumentInfoChannelDataTypePushConstant %decl " - "%int_0 %int_0 %int_0", - 3), - std::make_pair("ImageArgumentInfoChannelOrderUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %int_0", - 3), - std::make_pair("ImageArgumentInfoChannelDataTypeUniform %decl %int_0 " - "%int_0 %int_0 %int_0 %int_0", - 3), - std::make_pair("ArgumentStorageTexelBuffer %decl %int_0 %int_0 %int_0", - 4), - std::make_pair("ArgumentUniformTexelBuffer %decl %int_0 %int_0 %int_0", - 4), - std::make_pair("ConstantDataPointerPushConstant %int_0 %int_0 %data", - 5), - std::make_pair( - "ProgramScopeVariablePointerPushConstant %int_0 %int_0 %data", 5), - std::make_pair("PrintfInfo %int_0 %data", 5), - std::make_pair("PrintfBufferStorageBuffer %int_0 %int_0 %int_0", 5), - std::make_pair("PrintfBufferPointerPushConstant %int_0 %int_0 %int_0", - 5)})); - -TEST_P(VersionCheck, V1) { - const std::string ext_inst = std::get<0>(GetParam()); - const uint32_t version = std::get<1>(GetParam()); - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" %ext = OpExtInstImport "NonSemantic.ClspvReflection.1" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %foo "foo" @@ -7302,174 +6737,8 @@ OpFunctionEnd ext_inst; CompileSuccessfully(text); - if (version <= 1) { - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); - } else { - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("requires version " + std::to_string(version) + - ", but parsed version is 1")); - } -} - -TEST_P(VersionCheck, V2) { - const std::string ext_inst = std::get<0>(GetParam()); - const uint32_t version = std::get<1>(GetParam()); - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.2" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%data = OpString "1234" -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_1 = OpConstant %int 1 -%int_4 = OpConstant %int 4 -%null = OpConstantNull %int -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%void_fn = OpTypeFunction %void -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name -%inst = OpExtInst %void %ext )" + - ext_inst; - - CompileSuccessfully(text); - if (version <= 2) { - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); - } else { - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("requires version " + std::to_string(version) + - ", but parsed version is 2")); - } -} - -TEST_P(VersionCheck, V3) { - const std::string ext_inst = std::get<0>(GetParam()); - const uint32_t version = std::get<1>(GetParam()); - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.3" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%data = OpString "1234" -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_1 = OpConstant %int 1 -%int_4 = OpConstant %int 4 -%null = OpConstantNull %int -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%void_fn = OpTypeFunction %void -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name -%inst = OpExtInst %void %ext )" + - ext_inst; - - CompileSuccessfully(text); - if (version <= 3) { - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); - } else { - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("requires version " + std::to_string(version) + - ", but parsed version is 3")); - } -} - -TEST_P(VersionCheck, V4) { - const std::string ext_inst = std::get<0>(GetParam()); - const uint32_t version = std::get<1>(GetParam()); - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.4" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%data = OpString "1234" -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_1 = OpConstant %int 1 -%int_4 = OpConstant %int 4 -%null = OpConstantNull %int -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%void_fn = OpTypeFunction %void -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name -%inst = OpExtInst %void %ext )" + - ext_inst; - - CompileSuccessfully(text); - if (version <= 4) { - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); - } else { - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("requires version " + std::to_string(version) + - ", but parsed version is 4")); - } -} - -TEST_P(VersionCheck, V5) { - const std::string ext_inst = std::get<0>(GetParam()); - const uint32_t version = std::get<1>(GetParam()); - const std::string text = R"( -OpCapability Shader -OpExtension "SPV_KHR_non_semantic_info" -%ext = OpExtInstImport "NonSemantic.ClspvReflection.5" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %foo "foo" -OpExecutionMode %foo LocalSize 1 1 1 -%foo_name = OpString "foo" -%data = OpString "1234" -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%int_1 = OpConstant %int 1 -%int_4 = OpConstant %int 4 -%null = OpConstantNull %int -%float = OpTypeFloat 32 -%float_0 = OpConstant %float 0 -%void_fn = OpTypeFunction %void -%foo = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -%decl = OpExtInst %void %ext Kernel %foo %foo_name -%inst = OpExtInst %void %ext )" + - ext_inst; - - CompileSuccessfully(text); - if (version <= 5) { - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); - } else { - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("requires version " + std::to_string(version) + - ", but parsed version is 1")); - } + ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString")); } } // namespace diff --git a/test/val/val_extension_spv_khr_bit_instructions_test.cpp b/test/val/val_extension_spv_khr_bit_instructions_test.cpp index d23b9b6f..0e926716 100644 --- a/test/val/val_extension_spv_khr_bit_instructions_test.cpp +++ b/test/val/val_extension_spv_khr_bit_instructions_test.cpp @@ -18,7 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_extension_spv_khr_expect_assume.cpp b/test/val/val_extension_spv_khr_expect_assume.cpp new file mode 100644 index 00000000..6ece15d1 --- /dev/null +++ b/test/val/val_extension_spv_khr_expect_assume.cpp @@ -0,0 +1,310 @@ +// Copyright (c) 2020 Google Inc. +// +// 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. + +// Tests for OpExtension validator rules. + +#include +#include + +#include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/spirv_target_env.h" +#include "test/test_fixture.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace val { +namespace { + +using ::testing::HasSubstr; +using ::testing::Values; +using ::testing::ValuesIn; + +using ValidateSpvExpectAssumeKHR = spvtest::ValidateBase; + +TEST_F(ValidateSpvExpectAssumeKHR, Valid) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %bool = OpTypeBool + %true = OpConstantTrue %bool + %undef = OpUndef %bool + + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + + %v2bool = OpTypeVector %bool 2 + %v2uint = OpTypeVector %uint 2 + + %null_v2bool = OpConstantNull %v2bool + %null_v2uint = OpConstantNull %v2uint + + %main = OpFunction %void None %voidfn + %entry = OpLabel + OpAssumeTrueKHR %true + OpAssumeTrueKHR %undef ; probably undefined behaviour + %bool_val = OpExpectKHR %bool %true %true + %uint_val = OpExpectKHR %uint %uint_1 %uint_2 ; a bad expectation + %v2bool_val = OpExpectKHR %v2bool %null_v2bool %null_v2bool + %v2uint_val = OpExpectKHR %v2uint %null_v2uint %null_v2uint + OpReturn + OpFunctionEnd + +)"; + CompileSuccessfully(str.c_str()); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateSpvExpectAssumeKHR, RequiresExtension) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %bool = OpTypeBool + %true = OpConstantTrue %bool + %undef = OpUndef %bool + + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + OpAssumeTrueKHR %true + OpAssumeTrueKHR %undef ; probably undefined behaviour + %val = OpExpectKHR %uint %uint_1 %uint_2 ; a bad expectation + OpReturn + OpFunctionEnd + +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Capability: operand ExpectAssumeKHR(5629) requires " + "one of these extensions: SPV_KHR_expect_assume")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, + AssumeTrueKHR_RequiresExpectAssumeCapability) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %bool = OpTypeBool + %true = OpConstantTrue %bool + %undef = OpUndef %bool + + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + OpAssumeTrueKHR %true + OpAssumeTrueKHR %undef ; probably undefined behaviour + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Opcode AssumeTrueKHR requires one of these " + "capabilities: ExpectAssumeKHR \n" + " OpAssumeTrueKHR %true\n")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, AssumeTrueKHR_OperandMustBeBool) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %bool = OpTypeBool + %true = OpConstantTrue %bool + %undef = OpUndef %bool + + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + OpAssumeTrueKHR %uint_1 ; bad type + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("Value operand of OpAssumeTrueKHR must be a boolean scalar\n" + " OpAssumeTrueKHR %uint_1\n")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, ExpectKHR_RequiresExpectAssumeCapability) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %bool = OpTypeBool + %true = OpConstantTrue %bool + %undef = OpUndef %bool + + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + %val = OpExpectKHR %uint %uint_1 %uint_2 ; a bad expectation + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Opcode ExpectKHR requires one of these capabilities: " + "ExpectAssumeKHR \n" + " %11 = OpExpectKHR %uint %uint_1 %uint_2\n")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, ExpectKHR_ResultMustBeBoolOrIntScalar) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %float = OpTypeFloat 32 + + %float_0 = OpConstant %float 0 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + %val = OpExpectKHR %float %float_0 %float_0 + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Result of OpExpectKHR must be a scalar or vector of " + "integer type or boolean type\n" + " %7 = OpExpectKHR %float %float_0 %float_0\n")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, ExpectKHR_Value0MustMatchResultType) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %uint = OpTypeInt 32 0 + %float = OpTypeFloat 32 + %float_0 = OpConstant %float 0 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + %val = OpExpectKHR %uint %float_0 %float_0 + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Type of Value operand of OpExpectKHR does not match " + "the result type \n" + " %8 = OpExpectKHR %uint %float_0 %float_0\n")); +} + +TEST_F(ValidateSpvExpectAssumeKHR, ExpectKHR_Value1MustMatchResultType) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + OpMemoryModel Physical32 OpenCL + + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 + %float = OpTypeFloat 32 + %float_0 = OpConstant %float 0 + + %main = OpFunction %void None %voidfn + %entry = OpLabel + %val = OpExpectKHR %uint %uint_0 %float_0 + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Type of ExpectedValue operand of OpExpectKHR does not " + "match the result type \n" + " %9 = OpExpectKHR %uint %uint_0 %float_0\n")); +} + +} // namespace +} // namespace val +} // namespace spvtools diff --git a/test/val/val_extension_spv_khr_expect_assume_test.cpp b/test/val/val_extension_spv_khr_expect_assume_test.cpp index 85a484aa..6ece15d1 100644 --- a/test/val/val_extension_spv_khr_expect_assume_test.cpp +++ b/test/val/val_extension_spv_khr_expect_assume_test.cpp @@ -18,7 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_extension_spv_khr_integer_dot_product_test.cpp b/test/val/val_extension_spv_khr_integer_dot_product_test.cpp index 5b3a3096..e0e6896c 100644 --- a/test/val/val_extension_spv_khr_integer_dot_product_test.cpp +++ b/test/val/val_extension_spv_khr_integer_dot_product_test.cpp @@ -14,12 +14,15 @@ // limitations under the License. #include +#include #include #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" #include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" @@ -128,7 +131,7 @@ std::string AssemblyForCase(const Case& c) { %char_0 = OpConstant %char 0 %char_1 = OpConstant %char 1 - %v4uchar_0 = OpConstantComposite %v4uchar %uchar_0 %uchar_0 %uchar_0 %uchar_0 + %v4uchar_0 = OpConstantComposite %v4uchar %uchar_0 %uint_0 %uchar_0 %uchar_0 %v4uchar_1 = OpConstantComposite %v4uchar %uchar_1 %uchar_1 %uchar_1 %uchar_1 %v4char_0 = OpConstantComposite %v4char %char_0 %char_0 %char_0 %char_0 %v4char_1 = OpConstantComposite %v4char %char_1 %char_1 %char_1 %char_1 diff --git a/test/val/val_extension_spv_khr_linkonce_odr.cpp b/test/val/val_extension_spv_khr_linkonce_odr.cpp new file mode 100644 index 00000000..ac15558b --- /dev/null +++ b/test/val/val_extension_spv_khr_linkonce_odr.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2020 Google Inc. +// +// 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. + +// Tests for OpExtension validator rules. + +#include +#include + +#include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/spirv_target_env.h" +#include "test/test_fixture.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace val { +namespace { + +using ::testing::HasSubstr; +using ::testing::Values; +using ::testing::ValuesIn; + +using ValidateSpvKHRLinkOnceODR = spvtest::ValidateBase; + +TEST_F(ValidateSpvKHRLinkOnceODR, Valid) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpExtension "SPV_KHR_linkonce_odr" + OpMemoryModel Physical32 OpenCL + OpDecorate %var LinkageAttributes "foobar" LinkOnceODR + + %uint = OpTypeInt 32 0 + %ptr = OpTypePointer CrossWorkgroup %uint + %var = OpVariable %ptr CrossWorkgroup + +)"; + CompileSuccessfully(str.c_str()); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateSpvKHRLinkOnceODR, RequiresExtension) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpCapability Linkage + OpMemoryModel Physical32 OpenCL + OpDecorate %var LinkageAttributes "foobar" LinkOnceODR + + %uint = OpTypeInt 32 0 + %ptr = OpTypePointer CrossWorkgroup %uint + %var = OpVariable %ptr CrossWorkgroup +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("4th operand of Decorate: operand LinkOnceODR(2) requires one " + "of these extensions: SPV_KHR_linkonce_odr \n" + " OpDecorate %1 LinkageAttributes \"foobar\" LinkOnceODR\n")); +} + +TEST_F(ValidateSpvKHRLinkOnceODR, RequiresLinkageCapability) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpExtension "SPV_KHR_linkonce_odr" + OpMemoryModel Physical32 OpenCL + OpDecorate %var LinkageAttributes "foobar" LinkOnceODR + + %uint = OpTypeInt 32 0 + %ptr = OpTypePointer CrossWorkgroup %uint + %var = OpVariable %ptr CrossWorkgroup +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "Operand 2 of Decorate requires one of these capabilities: Linkage \n" + " OpDecorate %1 LinkageAttributes \"foobar\" LinkOnceODR")); +} + +} // namespace +} // namespace val +} // namespace spvtools diff --git a/test/val/val_extension_spv_khr_linkonce_odr_test.cpp b/test/val/val_extension_spv_khr_linkonce_odr_test.cpp index ed3fb8a1..ac15558b 100644 --- a/test/val/val_extension_spv_khr_linkonce_odr_test.cpp +++ b/test/val/val_extension_spv_khr_linkonce_odr_test.cpp @@ -18,7 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_extension_spv_khr_subgroup_uniform_control_flow_test.cpp b/test/val/val_extension_spv_khr_subgroup_uniform_control_flow_test.cpp index 80d57533..f528cb9e 100644 --- a/test/val/val_extension_spv_khr_subgroup_uniform_control_flow_test.cpp +++ b/test/val/val_extension_spv_khr_subgroup_uniform_control_flow_test.cpp @@ -18,7 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_extension_spv_khr_terminate_invocation.cpp b/test/val/val_extension_spv_khr_terminate_invocation.cpp new file mode 100644 index 00000000..4cabf9e2 --- /dev/null +++ b/test/val/val_extension_spv_khr_terminate_invocation.cpp @@ -0,0 +1,150 @@ +// Copyright (c) 2020 Google LLC +// +// 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. + +// Tests for OpExtension validator rules. + +#include +#include + +#include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" +#include "source/spirv_target_env.h" +#include "test/test_fixture.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace val { +namespace { + +using ::testing::HasSubstr; +using ::testing::Values; +using ::testing::ValuesIn; + +using ValidateSpvKHRTerminateInvocation = spvtest::ValidateBase; + +TEST_F(ValidateSpvKHRTerminateInvocation, Valid) { + const std::string str = R"( + OpCapability Shader + OpExtension "SPV_KHR_terminate_invocation" + OpMemoryModel Logical Simple + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + + %void = OpTypeVoid + %void_fn = OpTypeFunction %void + + %main = OpFunction %void None %void_fn + %entry = OpLabel + OpTerminateInvocation + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +TEST_F(ValidateSpvKHRTerminateInvocation, RequiresExtension) { + const std::string str = R"( + OpCapability Shader + OpMemoryModel Logical Simple + OpEntryPoint Fragment %main "main" + OpExecutionMode %main OriginUpperLeft + + %void = OpTypeVoid + %void_fn = OpTypeFunction %void + + %main = OpFunction %void None %void_fn + %entry = OpLabel + OpTerminateInvocation + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("TerminateInvocation requires one of the following " + "extensions: SPV_KHR_terminate_invocation")); +} + +TEST_F(ValidateSpvKHRTerminateInvocation, RequiresShaderCapability) { + const std::string str = R"( + OpCapability Kernel + OpCapability Addresses + OpExtension "SPV_KHR_terminate_invocation" + OpMemoryModel Physical32 OpenCL + OpEntryPoint Kernel %main "main" + + %void = OpTypeVoid + %void_fn = OpTypeFunction %void + + %main = OpFunction %void None %void_fn + %entry = OpLabel + OpTerminateInvocation + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "TerminateInvocation requires one of these capabilities: Shader \n")); +} + +TEST_F(ValidateSpvKHRTerminateInvocation, RequiresFragmentShader) { + const std::string str = R"( + OpCapability Shader + OpExtension "SPV_KHR_terminate_invocation" + OpMemoryModel Logical Simple + OpEntryPoint GLCompute %main "main" + + %void = OpTypeVoid + %void_fn = OpTypeFunction %void + + %main = OpFunction %void None %void_fn + %entry = OpLabel + OpTerminateInvocation + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpTerminateInvocation requires Fragment execution model")); +} + +TEST_F(ValidateSpvKHRTerminateInvocation, IsTerminatorInstruction) { + const std::string str = R"( + OpCapability Shader + OpExtension "SPV_KHR_terminate_invocation" + OpMemoryModel Logical Simple + OpEntryPoint GLCompute %main "main" + + %void = OpTypeVoid + %void_fn = OpTypeFunction %void + + %main = OpFunction %void None %void_fn + %entry = OpLabel + OpTerminateInvocation + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(str.c_str()); + EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Return must appear in a block")); +} + +} // namespace +} // namespace val +} // namespace spvtools diff --git a/test/val/val_extension_spv_khr_terminate_invocation_test.cpp b/test/val/val_extension_spv_khr_terminate_invocation_test.cpp index 4d3e4d6a..8d924149 100644 --- a/test/val/val_extension_spv_khr_terminate_invocation_test.cpp +++ b/test/val/val_extension_spv_khr_terminate_invocation_test.cpp @@ -18,7 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" +#include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_extensions_test.cpp b/test/val/val_extensions_test.cpp index 0ab8c6e3..491a8085 100644 --- a/test/val/val_extensions_test.cpp +++ b/test/val/val_extensions_test.cpp @@ -18,8 +18,10 @@ #include #include "gmock/gmock.h" +#include "source/enum_string_mapping.h" #include "source/extensions.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_function_test.cpp b/test/val/val_function_test.cpp index 24b52638..e7d5cd7e 100644 --- a/test/val/val_function_test.cpp +++ b/test/val/val_function_test.cpp @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include "gmock/gmock.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index 7acac563..dd040b33 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -203,12 +203,11 @@ std::string ValidateIdWithMessage::make_message(const char* msg) { // Parse 'num[%name]' size_t open_quote = message.find('\'', next); + // Copy up to the first quote + result.write(msg + next, open_quote - next); if (open_quote == std::string::npos) { break; } - - // Copy up to the first quote - result.write(msg + next, open_quote - next); // Handle apostrophes if (!isdigit(message[open_quote + 1])) { result << '\''; @@ -2317,7 +2316,7 @@ OpFunctionEnd "be used with non-externally visible shader Storage Classes: " "Workgroup, CrossWorkgroup, Private, Function, Input, Output, " "RayPayloadKHR, IncomingRayPayloadKHR, HitAttributeKHR, " - "CallableDataKHR, IncomingCallableDataKHR, or UniformConstant"))); + "CallableDataKHR, or IncomingCallableDataKHR"))); } TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPrivateGood) { @@ -2339,25 +2338,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_P(ValidateIdWithMessage, OpVariableContainsBoolUniformConstantGood) { - std::string spirv = kGLSL450MemoryModel + R"( -%bool = OpTypeBool -%int = OpTypeInt 32 0 -%block = OpTypeStruct %bool %int -%_ptr_UniformConstant_block = OpTypePointer UniformConstant %block -%var = OpVariable %_ptr_UniformConstant_block UniformConstant -%void = OpTypeVoid -%fnty = OpTypeFunction %void -%main = OpFunction %void None %fnty -%entry = OpLabel -%load = OpLoad %block %var -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str()); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); -} - TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPointerGood) { std::string spirv = kGLSL450MemoryModel + R"( %bool = OpTypeBool @@ -4001,11 +3981,8 @@ OpFunctionEnd TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesGood) { const std::string instr = GetParam(); const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : ""; - const std::string arrayStride = - " OpDecorate %_ptr_Uniform_deep_struct ArrayStride 8 "; int depth = 255; - std::string header = - kGLSL450MemoryModel + arrayStride + kDeeplyNestedStructureSetup; + std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup; header.erase(header.find("%func")); std::ostringstream spirv; spirv << header << "\n"; @@ -4067,11 +4044,8 @@ TEST_P(AccessChainInstructionTest, AccessChainTooManyIndexesBad) { TEST_P(AccessChainInstructionTest, CustomizedAccessChainTooManyIndexesGood) { const std::string instr = GetParam(); const std::string elem = AccessChainRequiresElemId(instr) ? " %int_0 " : ""; - const std::string arrayStride = - " OpDecorate %_ptr_Uniform_deep_struct ArrayStride 8 "; int depth = 10; - std::string header = - kGLSL450MemoryModel + arrayStride + kDeeplyNestedStructureSetup; + std::string header = kGLSL450MemoryModel + kDeeplyNestedStructureSetup; header.erase(header.find("%func")); std::ostringstream spirv; spirv << header << "\n"; @@ -4243,11 +4217,8 @@ TEST_P(AccessChainInstructionTest, AccessChainIndexIntoAllTypesGood) { // 0 will select the element at the index 0 of the vector. (which is a float). const std::string instr = GetParam(); const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : ""; - const std::string arrayStride = - " OpDecorate %_ptr_Uniform_blockName ArrayStride 8 "; std::ostringstream spirv; - spirv << kGLSL450MemoryModel << arrayStride << kDeeplyNestedStructureSetup - << std::endl; + spirv << kGLSL450MemoryModel << kDeeplyNestedStructureSetup << std::endl; spirv << "%ss = " << instr << " %_ptr_Uniform_struct_s %blockName_var " << elem << "%int_0" << std::endl; spirv << "%sa = " << instr << " %_ptr_Uniform_array5_mat4x3 %blockName_var " @@ -4270,12 +4241,9 @@ OpFunctionEnd TEST_P(AccessChainInstructionTest, AccessChainIndexIntoRuntimeArrayGood) { const std::string instr = GetParam(); const std::string elem = AccessChainRequiresElemId(instr) ? "%int_0 " : ""; - const std::string arrayStride = - " OpDecorate %_ptr_Uniform_blockName ArrayStride 8 "; - std::string spirv = kGLSL450MemoryModel + arrayStride + - kDeeplyNestedStructureSetup + R"( -%runtime_arr_entry = )" + instr + - R"( %_ptr_Uniform_float %blockName_var )" + elem + + std::string spirv = kGLSL450MemoryModel + kDeeplyNestedStructureSetup + R"( +%runtime_arr_entry = )" + + instr + R"( %_ptr_Uniform_float %blockName_var )" + elem + R"(%int_2 %int_0 OpReturn OpFunctionEnd @@ -5663,7 +5631,6 @@ TEST_P(ValidateIdWithMessage, StgBufOpPtrAccessChainGood) { OpExtension "SPV_KHR_variable_pointers" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %3 "" - OpDecorate %ptr ArrayStride 8 %int = OpTypeInt 32 0 %int_2 = OpConstant %int 2 %int_4 = OpConstant %int 4 diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index 9a704098..a97ef7cb 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -356,8 +356,7 @@ OpFunctionEnd)"; std::string GenerateKernelCode( const std::string& body, - const std::string& capabilities_and_extensions = "", - const std::string& declarations = "") { + const std::string& capabilities_and_extensions = "") { std::ostringstream ss; ss << R"( OpCapability Addresses @@ -437,11 +436,7 @@ OpMemoryModel Physical32 OpenCL %type_sampler = OpTypeSampler %ptr_sampler = OpTypePointer UniformConstant %type_sampler %uniform_sampler = OpVariable %ptr_sampler UniformConstant -)"; - ss << declarations; - - ss << R"( %main = OpFunction %void None %func %main_entry = OpLabel )"; @@ -485,10 +480,10 @@ OpCapability Int64 OpCapability Float64 )"; - if (!include_entry_point) { - ss << "OpCapability Linkage\n"; - } ss << capabilities_and_extensions; + if (!include_entry_point) { + ss << "OpCapability Linkage"; + } ss << R"( OpMemoryModel Logical GLSL450 @@ -786,279 +781,6 @@ TEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) { HasSubstr("Dim SubpassData requires Arrayed to be 0")); } -TEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %void TileImageDataEXT 0 0 0 2 Unknown -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Dim TileImageDataEXT requires Sampled Type to be not OpTypeVoid")); -} - -TEST_F(ValidateImage, TypeImageWrongSampledForTileImageDataEXT) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 1 Unknown -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Dim TileImageDataEXT requires Sampled to be 2")); -} - -TEST_F(ValidateImage, TypeImageWrongFormatForTileImageDataEXT) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Rgba32f -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Dim TileImageDataEXT requires format Unknown")); -} - -TEST_F(ValidateImage, TypeImageWrongDepthForTileImageDataEXT) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %f32 TileImageDataEXT 1 0 0 2 Unknown -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Dim TileImageDataEXT requires Depth to be 0")); -} - -TEST_F(ValidateImage, TypeImageWrongArrayedForTileImageDataEXT) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %f32 TileImageDataEXT 0 1 0 2 Unknown -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Dim TileImageDataEXT requires Arrayed to be 0")); -} - -TEST_F(ValidateImage, TypeSampledImage_TileImageDataEXT_Error) { - const std::string code = GetShaderHeader( - "OpCapability TileImageColorReadAccessEXT\n" - "OpExtension \"SPV_EXT_shader_tile_image\"\n", - false) + - R"( -%img_type = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%simg_type = OpTypeSampledImage %img_type -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Sampled image type requires an image type with " - "\"Sampled\" operand set to 0 or 1")); -} - -TEST_F(ValidateImage, ImageTexelPointerImageDimTileImageDataEXTBad) { - const std::string body = R"( -%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %tile_image_u32_tid_0002 %u32_0 %u32_0 -%sum = OpAtomicIAdd %u32 %texel_ptr %u32_1 %u32_0 %u32_1 -)"; - const std::string decl = R"( -%type_image_u32_tid_0002 = OpTypeImage %u32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_u32_tid_0002 = OpTypePointer TileImageEXT %type_image_u32_tid_0002 -%tile_image_u32_tid_0002 = OpVariable %ptr_image_u32_tid_0002 TileImageEXT -)"; - - const std::string extra = R"( -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", - SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl) - .c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Image Dim TileImageDataEXT cannot be used with " - "OpImageTexelPointer")); -} - -TEST_F(ValidateImage, ReadTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -%res1 = OpImageRead %f32vec4 %img %u32vec2_01 -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability StorageImageReadWithoutFormat -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", - SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl) - .c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Image Dim TileImageDataEXT cannot be used with ImageRead")); -} - -TEST_F(ValidateImage, WriteTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -OpImageWrite %img %u32vec2_01 %f32vec4_0000 -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", - SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl) - .c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Image 'Dim' cannot be TileImageDataEXT")); -} - -TEST_F(ValidateImage, QueryFormatTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -%res1 = OpImageQueryFormat %u32 %img -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str()); - - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Image 'Dim' cannot be TileImageDataEXT")); -} - -TEST_F(ValidateImage, QueryOrderTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -%res1 = OpImageQueryOrder %u32 %img -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateKernelCode(body, extra, decl).c_str()); - - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Image 'Dim' cannot be TileImageDataEXT")); -} - -TEST_F(ValidateImage, SparseFetchTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -%res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01 -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability StorageImageReadWithoutFormat -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", - SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl) - .c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Expected Image 'Sampled' parameter to be 1")); -} - -TEST_F(ValidateImage, SparseReadTileImageDataEXT) { - const std::string body = R"( -%img = OpLoad %type_image_f32_tid_0002 %uniform_image_f32_tid_0002 -%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01 -)"; - - const std::string decl = R"( -%type_image_f32_tid_0002 = OpTypeImage %f32 TileImageDataEXT 0 0 0 2 Unknown -%ptr_image_f32_tid_0002 = OpTypePointer UniformConstant %type_image_f32_tid_0002 -%uniform_image_f32_tid_0002 = OpVariable %ptr_image_f32_tid_0002 UniformConstant -)"; - - const std::string extra = R"( -OpCapability StorageImageReadWithoutFormat -OpCapability TileImageColorReadAccessEXT -OpExtension "SPV_EXT_shader_tile_image" -)"; - - CompileSuccessfully(GenerateShaderCode(body, extra, "Fragment", "", - SPV_ENV_UNIVERSAL_1_5, "GLSL450", decl) - .c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Image Dim TileImageDataEXT cannot be used with ImageSparseRead")); -} - TEST_F(ValidateImage, TypeImage_OpenCL_Sampled0_OK) { const std::string code = GetKernelHeader() + R"( %img_type = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly @@ -2177,6 +1899,8 @@ TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) { CompileSuccessfully( GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Offset-04662")); EXPECT_THAT( getDiagnosticString(), HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets " @@ -5852,12 +5576,10 @@ TEST_F(ValidateImage, SignExtendV13Bad) { %res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend )"; - CompileSuccessfully( - GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3)); - ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later")); + EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "", + SPV_ENV_UNIVERSAL_1_3), + SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION), + HasSubstr("Invalid image operand 'SignExtend'")); } TEST_F(ValidateImage, ZeroExtendV13Bad) { @@ -5866,12 +5588,10 @@ TEST_F(ValidateImage, ZeroExtendV13Bad) { %res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend )"; - CompileSuccessfully( - GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3)); - ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later")); + EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "", + SPV_ENV_UNIVERSAL_1_3), + SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION), + HasSubstr("Invalid image operand 'ZeroExtend'")); } TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) { @@ -6677,1375 +6397,6 @@ TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) { HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32")); } -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 1 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 3 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 2 - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_4 = OpConstant %uint 4 - %17 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %19 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeSampler -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 - %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant - %23 = OpTypeSampledImage %19 - %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - %26 = OpLoad %19 %4 - %27 = OpLoad %21 %5 - %28 = OpSampledImage %23 %26 %27 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %19 %6 - %31 = OpLoad %21 %5 - %32 = OpSampledImage %23 %30 %31 - %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29 - OpStore %3 %33 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 1 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 3 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 2 - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_4 = OpConstant %uint 4 - %17 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %19 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeSampler -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 - %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant - %23 = OpTypeSampledImage %19 - %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - %26 = OpLoad %19 %4 - %27 = OpLoad %21 %5 - %28 = OpSampledImage %23 %26 %27 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %19 %6 - %31 = OpLoad %21 %5 - %32 = OpSampledImage %23 %30 %31 - %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29 - OpStore %3 %33 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 4 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - %void = OpTypeVoid - %7 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown - %19 = OpTypeSampledImage %18 -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %7 - %22 = OpLabel - %23 = OpVariable %_ptr_Function_v2uint Function - %24 = OpLoad %19 %4 - %25 = OpLoad %v2uint %23 - %26 = OpLoad %19 %5 - %27 = OpLoad %v2uint %23 - %28 = OpLoad %v2uint %23 - %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28 - OpStore %3 %29 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 4 - OpDecorate %4 BlockMatchTextureQCOM - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 5 - %void = OpTypeVoid - %7 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown - %19 = OpTypeSampledImage %18 -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %7 - %22 = OpLabel - %23 = OpVariable %_ptr_Function_v2uint Function - %24 = OpLoad %19 %4 - %25 = OpLoad %v2uint %23 - %26 = OpLoad %19 %5 - %27 = OpLoad %v2uint %23 - %28 = OpLoad %v2uint %23 - %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28 - OpStore %3 %29 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 1 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 3 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 2 - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_4 = OpConstant %uint 4 - %17 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %19 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeSampler -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 - %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant - %23 = OpTypeSampledImage %19 - %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - %26 = OpLoad %19 %4 - %27 = OpLoad %21 %5 - %28 = OpSampledImage %23 %26 %27 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %19 %6 - %31 = OpLoad %21 %5 - %32 = OpSampledImage %23 %30 %31 - %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29 - OpStore %3 %33 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 1 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 3 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 2 - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 -%v4float = OpTypeVector %float 4 -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_4 = OpConstant %uint 4 - %17 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %19 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeSampler -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 - %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant - %23 = OpTypeSampledImage %19 - %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - %26 = OpLoad %19 %4 - %27 = OpLoad %21 %5 - %28 = OpSampledImage %23 %26 %27 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %19 %6 - %31 = OpLoad %21 %5 - %32 = OpSampledImage %23 %30 %31 - %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29 - OpStore %3 %33 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 4 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - %void = OpTypeVoid - %7 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown - %19 = OpTypeSampledImage %18 -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %7 - %22 = OpLabel - %23 = OpVariable %_ptr_Function_v2uint Function - %24 = OpLoad %19 %4 - %25 = OpLoad %v2uint %23 - %26 = OpLoad %19 %5 - %27 = OpLoad %v2uint %23 - %28 = OpLoad %v2uint %23 - %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28 - OpStore %3 %29 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 4 - OpDecorate %4 BlockMatchTextureQCOM - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 5 - %void = OpTypeVoid - %7 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float -%_ptr_Input_float = OpTypePointer Input %float -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown - %19 = OpTypeSampledImage %18 -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %21 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %7 - %22 = OpLabel - %23 = OpVariable %_ptr_Function_v2uint Function - %24 = OpLoad %19 %4 - %25 = OpLoad %v2uint %23 - %26 = OpLoad %19 %5 - %27 = OpLoad %v2uint %23 - %28 = OpLoad %v2uint %23 - %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28 - OpStore %3 %29 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) { - std::string text = R"( - OpCapability Shader - OpCapability TextureSampleWeightedQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 DescriptorSet 0 - OpDecorate %4 Binding 1 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 3 - OpDecorate %6 Location 0 - OpDecorate %7 DescriptorSet 0 - OpDecorate %7 Binding 0 - %void = OpTypeVoid - %9 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %13 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 - %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant - %15 = OpTypeSampler -%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 - %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant - %17 = OpTypeSampledImage %13 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %6 = OpVariable %_ptr_Input_v4float Input - %v2float = OpTypeVector %float 2 - %20 = OpTypeImage %float 2D 0 1 0 1 Unknown -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %22 = OpTypeSampledImage %20 -%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17 - %2 = OpFunction %void None %9 - %24 = OpLabel - %25 = OpLoad %13 %4 - %26 = OpLoad %15 %5 - %27 = OpSampledImage %17 %25 %26 - %28 = OpLoad %v4float %6 - %29 = OpVectorShuffle %v2float %28 %28 0 1 - %30 = OpLoad %20 %7 - %31 = OpLoad %15 %5 - %32 = OpSampledImage %22 %30 %31 - %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32 - OpStore %3 %33 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) { - std::string text = R"( - OpCapability Shader - OpCapability TextureSampleWeightedQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - %void = OpTypeVoid - %8 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %12 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 - %14 = OpTypeSampler -%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 - %16 = OpTypeSampledImage %12 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %4 = OpVariable %_ptr_Input_v4float Input - %v2float = OpTypeVector %float 2 - %19 = OpTypeImage %float 2D 0 1 0 1 Unknown -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %21 = OpTypeSampledImage %19 -%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16 - %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 - %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpLoad %16 %5 - %26 = OpLoad %v4float %4 - %27 = OpVectorShuffle %v2float %26 %26 0 1 - %28 = OpLoad %21 %6 - %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28 - OpStore %3 %29 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseA) { - std::string text = R"( -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 11 -; Bound: 79 -; Schema: 0 - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104 - OpExecutionMode %main OriginUpperLeft - OpDecorate %100 Location 0 - OpDecorate %101 Location 0 - OpDecorate %102 DescriptorSet 0 - OpDecorate %102 Binding 1 - OpDecorate %103 DescriptorSet 0 - OpDecorate %103 Binding 3 - OpDecorate %104 DescriptorSet 0 - OpDecorate %104 Binding 2 - OpDecorate %102 BlockMatchTextureQCOM - OpDecorate %104 BlockMatchTextureQCOM - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %100 = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float - %101 = OpVariable %_ptr_Output_v4float Output - %42 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42 - %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %46 = OpTypeSampler -%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 - %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant - %50 = OpTypeSampledImage %42 - %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %v2float = OpTypeVector %float 2 - %main = OpFunction %void None %3 - %5 = OpLabel - %15 = OpVariable %_ptr_Function_v2uint Function - %45 = OpLoad %42 %102 - %49 = OpLoad %46 %103 - %51 = OpSampledImage %50 %45 %49 - %52 = OpLoad %v2uint %15 - %54 = OpLoad %42 %104 - %55 = OpLoad %46 %103 - %56 = OpSampledImage %50 %54 %55 - %57 = OpLoad %v2uint %15 - %58 = OpLoad %v2uint %15 - %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58 - OpStore %101 %59 - %69 = OpLoad %42 %102 - %70 = OpLoad %46 %103 - %71 = OpSampledImage %50 %69 %70 - %73 = OpLoad %v4float %100 - %74 = OpVectorShuffle %v2float %73 %73 0 0 - %75 = OpImageSampleImplicitLod %v4float %71 %74 - OpStore %101 %75 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) { - std::string text = R"( -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 11 -; Bound: 79 -; Schema: 0 - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104 - OpExecutionMode %main OriginUpperLeft - OpDecorate %100 Location 0 - OpDecorate %101 Location 0 - OpDecorate %102 DescriptorSet 0 - OpDecorate %102 Binding 1 - OpDecorate %103 DescriptorSet 0 - OpDecorate %103 Binding 3 - OpDecorate %104 DescriptorSet 0 - OpDecorate %104 Binding 2 - OpDecorate %102 BlockMatchTextureQCOM - OpDecorate %104 BlockMatchTextureQCOM - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %100 = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float - %101 = OpVariable %_ptr_Output_v4float Output - %42 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42 - %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %46 = OpTypeSampler -%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 - %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant - %50 = OpTypeSampledImage %42 - %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %v2float = OpTypeVector %float 2 - %main = OpFunction %void None %3 - %5 = OpLabel - %15 = OpVariable %_ptr_Function_v2uint Function - %45 = OpLoad %42 %102 - %49 = OpLoad %46 %103 - %51 = OpSampledImage %50 %45 %49 - %52 = OpLoad %v2uint %15 - %54 = OpLoad %42 %104 - %55 = OpLoad %46 %103 - %56 = OpSampledImage %50 %54 %55 - %57 = OpLoad %v2uint %15 - %58 = OpLoad %v2uint %15 - %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58 - OpStore %101 %59 - %69 = OpLoad %42 %104 - %70 = OpLoad %46 %103 - %71 = OpSampledImage %50 %69 %70 - %73 = OpLoad %v4float %100 - %74 = OpVectorShuffle %v2float %73 %73 0 0 - %75 = OpImageSampleImplicitLod %v4float %71 %74 - OpStore %101 %75 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %3 = OpVariable %_ptr_Input_v4float Input - %uint_4 = OpConstant %uint 4 - %16 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %4 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 - %20 = OpTypeSampledImage %18 -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %v2float = OpTypeVector %float 2 - %23 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - OpStore %25 %16 - %26 = OpLoad %20 %5 - %27 = OpLoad %v2uint %25 - %28 = OpLoad %20 %6 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %v2uint %25 - %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30 - OpStore %4 %31 - %32 = OpLoad %20 %5 - %33 = OpLoad %v4float %3 - %34 = OpVectorShuffle %v2float %33 %33 0 2 - %35 = OpImageSampleImplicitLod %v4float %32 %34 - OpStore %4 %35 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %3 = OpVariable %_ptr_Input_v4float Input - %uint_4 = OpConstant %uint 4 - %16 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %4 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 - %20 = OpTypeSampledImage %18 -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %v2float = OpTypeVector %float 2 - %23 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - OpStore %25 %16 - %26 = OpLoad %20 %5 - %27 = OpLoad %v2uint %25 - %28 = OpLoad %20 %6 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %v2uint %25 - %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30 - OpStore %4 %31 - %32 = OpLoad %20 %6 - %33 = OpLoad %v4float %3 - %34 = OpVectorShuffle %v2float %33 %33 0 2 - %35 = OpImageSampleImplicitLod %v4float %32 %34 - OpStore %4 %35 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) { - std::string text = R"( -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 11 -; Bound: 79 -; Schema: 0 - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104 - OpExecutionMode %main OriginUpperLeft - OpDecorate %100 Location 0 - OpDecorate %101 Location 0 - OpDecorate %102 DescriptorSet 0 - OpDecorate %102 Binding 1 - OpDecorate %103 DescriptorSet 0 - OpDecorate %103 Binding 3 - OpDecorate %104 DescriptorSet 0 - OpDecorate %104 Binding 2 - OpDecorate %102 BlockMatchTextureQCOM - OpDecorate %104 BlockMatchTextureQCOM - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %100 = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float - %101 = OpVariable %_ptr_Output_v4float Output - %42 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42 - %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %46 = OpTypeSampler -%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 - %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant - %50 = OpTypeSampledImage %42 - %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %v2float = OpTypeVector %float 2 - %main = OpFunction %void None %3 - %5 = OpLabel - %15 = OpVariable %_ptr_Function_v2uint Function - %45 = OpLoad %42 %102 - %49 = OpLoad %46 %103 - %51 = OpSampledImage %50 %45 %49 - %52 = OpLoad %v2uint %15 - %54 = OpLoad %42 %104 - %55 = OpLoad %46 %103 - %56 = OpSampledImage %50 %54 %55 - %57 = OpLoad %v2uint %15 - %58 = OpLoad %v2uint %15 - %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58 - OpStore %101 %59 - %69 = OpLoad %42 %102 - %70 = OpLoad %46 %103 - %71 = OpSampledImage %50 %69 %70 - %73 = OpLoad %v4float %100 - %74 = OpVectorShuffle %v2float %73 %73 0 0 - %75 = OpImageSampleImplicitLod %v4float %71 %74 - OpStore %101 %75 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) { - std::string text = R"( -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 11 -; Bound: 79 -; Schema: 0 - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104 - OpExecutionMode %main OriginUpperLeft - OpDecorate %100 Location 0 - OpDecorate %101 Location 0 - OpDecorate %102 DescriptorSet 0 - OpDecorate %102 Binding 1 - OpDecorate %103 DescriptorSet 0 - OpDecorate %103 Binding 3 - OpDecorate %104 DescriptorSet 0 - OpDecorate %104 Binding 2 - OpDecorate %102 BlockMatchTextureQCOM - OpDecorate %104 BlockMatchTextureQCOM - %void = OpTypeVoid - %3 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %100 = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float - %101 = OpVariable %_ptr_Output_v4float Output - %42 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42 - %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %46 = OpTypeSampler -%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46 - %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant - %50 = OpTypeSampledImage %42 - %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant - %v2float = OpTypeVector %float 2 - %main = OpFunction %void None %3 - %5 = OpLabel - %15 = OpVariable %_ptr_Function_v2uint Function - %45 = OpLoad %42 %102 - %49 = OpLoad %46 %103 - %51 = OpSampledImage %50 %45 %49 - %52 = OpLoad %v2uint %15 - %54 = OpLoad %42 %104 - %55 = OpLoad %46 %103 - %56 = OpSampledImage %50 %54 %55 - %57 = OpLoad %v2uint %15 - %58 = OpLoad %v2uint %15 - %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58 - OpStore %101 %59 - %69 = OpLoad %42 %104 - %70 = OpLoad %46 %103 - %71 = OpSampledImage %50 %69 %70 - %73 = OpLoad %v4float %100 - %74 = OpVectorShuffle %v2float %73 %73 0 0 - %75 = OpImageSampleImplicitLod %v4float %71 %74 - OpStore %101 %75 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %3 = OpVariable %_ptr_Input_v4float Input - %uint_4 = OpConstant %uint 4 - %16 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %4 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 - %20 = OpTypeSampledImage %18 -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %v2float = OpTypeVector %float 2 - %23 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - OpStore %25 %16 - %26 = OpLoad %20 %5 - %27 = OpLoad %v2uint %25 - %28 = OpLoad %20 %6 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %v2uint %25 - %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30 - OpStore %4 %31 - %32 = OpLoad %20 %5 - %33 = OpLoad %v4float %3 - %34 = OpVectorShuffle %v2float %33 %33 0 2 - %35 = OpImageSampleImplicitLod %v4float %32 %34 - OpStore %4 %35 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) { - std::string text = R"( - OpCapability Shader - OpCapability TextureBlockMatchQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - OpDecorate %5 BlockMatchTextureQCOM - OpDecorate %6 BlockMatchTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 -%_ptr_Function_v2uint = OpTypePointer Function %v2uint - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %3 = OpVariable %_ptr_Input_v4float Input - %uint_4 = OpConstant %uint 4 - %16 = OpConstantComposite %v2uint %uint_4 %uint_4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %4 = OpVariable %_ptr_Output_v4float Output - %18 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 - %20 = OpTypeSampledImage %18 -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %v2float = OpTypeVector %float 2 - %23 = OpTypeImage %float 2D 0 1 0 1 Unknown - %2 = OpFunction %void None %8 - %24 = OpLabel - %25 = OpVariable %_ptr_Function_v2uint Function - OpStore %25 %16 - %26 = OpLoad %20 %5 - %27 = OpLoad %v2uint %25 - %28 = OpLoad %20 %6 - %29 = OpLoad %v2uint %25 - %30 = OpLoad %v2uint %25 - %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30 - OpStore %4 %31 - %32 = OpLoad %20 %6 - %33 = OpLoad %v4float %3 - %34 = OpVectorShuffle %v2float %33 %33 0 2 - %35 = OpImageSampleImplicitLod %v4float %32 %34 - OpStore %4 %35 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) { - std::string text = R"( - OpCapability Shader - OpCapability TextureSampleWeightedQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %4 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 4 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 5 - OpDecorate %6 WeightTextureQCOM - %void = OpTypeVoid - %8 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %12 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 - %14 = OpTypeSampledImage %12 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %4 = OpVariable %_ptr_Input_v4float Input - %v2float = OpTypeVector %float 2 - %17 = OpTypeImage %float 2D 0 1 0 1 Unknown -%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17 - %19 = OpTypeSampledImage %17 -%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 - %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant -%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19 - %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant - %v3float = OpTypeVector %float 3 - %2 = OpFunction %void None %8 - %23 = OpLabel - %24 = OpLoad %v4float %4 - %25 = OpVectorShuffle %v2float %24 %24 0 1 - %26 = OpLoad %14 %5 - %27 = OpLoad %v4float %4 - %28 = OpVectorShuffle %v2float %27 %27 0 1 - %29 = OpLoad %19 %6 - %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29 - OpStore %3 %30 - %31 = OpLoad %19 %6 - %32 = OpLoad %v4float %4 - %33 = OpVectorShuffle %v3float %32 %32 0 1 0 - %34 = OpCompositeExtract %float %33 0 - %35 = OpCompositeExtract %float %33 1 - %36 = OpCompositeExtract %float %33 2 - %37 = OpCompositeConstruct %v3float %34 %35 %36 - %38 = OpImageSampleImplicitLod %v4float %31 %37 - OpStore %3 %38 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) { - std::string text = R"( - OpCapability Shader - OpCapability TextureSampleWeightedQCOM - OpExtension "SPV_QCOM_image_processing" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7 - OpExecutionMode %2 OriginUpperLeft - OpDecorate %3 Location 0 - OpDecorate %5 DescriptorSet 0 - OpDecorate %5 Binding 1 - OpDecorate %6 DescriptorSet 0 - OpDecorate %6 Binding 3 - OpDecorate %4 Location 0 - OpDecorate %7 DescriptorSet 0 - OpDecorate %7 Binding 0 - OpDecorate %7 WeightTextureQCOM - %void = OpTypeVoid - %9 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 -%_ptr_Output_v4float = OpTypePointer Output %v4float - %3 = OpVariable %_ptr_Output_v4float Output - %13 = OpTypeImage %float 2D 0 0 0 1 Unknown -%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 - %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant - %15 = OpTypeSampler -%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 - %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant - %17 = OpTypeSampledImage %13 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %4 = OpVariable %_ptr_Input_v4float Input - %v2float = OpTypeVector %float 2 - %20 = OpTypeImage %float 2D 0 1 0 1 Unknown -%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20 - %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant - %22 = OpTypeSampledImage %20 - %v3float = OpTypeVector %float 3 - %2 = OpFunction %void None %9 - %24 = OpLabel - %25 = OpLoad %13 %5 - %26 = OpLoad %15 %6 - %27 = OpSampledImage %17 %25 %26 - %28 = OpLoad %v4float %4 - %29 = OpVectorShuffle %v2float %28 %28 0 1 - %30 = OpLoad %20 %7 - %31 = OpLoad %15 %6 - %32 = OpSampledImage %22 %30 %31 - %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32 - OpStore %3 %33 - %34 = OpLoad %20 %7 - %35 = OpLoad %15 %6 - %36 = OpSampledImage %22 %34 %35 - %37 = OpLoad %v4float %4 - %38 = OpVectorShuffle %v3float %37 %37 0 1 0 - %39 = OpCompositeExtract %float %38 0 - %40 = OpCompositeExtract %float %38 1 - %41 = OpCompositeExtract %float %38 2 - %42 = OpCompositeConstruct %v3float %39 %40 %41 - %43 = OpImageSampleImplicitLod %v4float %36 %42 - OpStore %3 %43 - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Illegal use of QCOM image processing decorated texture")); -} - -TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) { - const std::string code = R"( - OpCapability Shader - OpCapability StorageImageMultisample - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v2uint = OpTypeVector %u32 2 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 1 1 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v2uint %uint_1 %uint_2 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 Sample %uint_2 - OpReturn - OpFunctionEnd -)"; - - const spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(code, env); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability ImageMSArray is required to access storage image")); -} - -TEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) { - const std::string code = R"( - OpCapability Shader - OpCapability StorageImageMultisample - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v2uint = OpTypeVector %u32 2 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 0 1 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v2uint %uint_1 %uint_2 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 Sample %uint_2 - OpReturn - OpFunctionEnd -)"; - - const spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(code, env); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env)); - EXPECT_THAT(getDiagnosticString(), Eq("")); -} - -TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) { - const std::string code = R"( - OpCapability Shader - OpCapability StorageImageReadWithoutFormat - OpMemoryModel Logical GLSL450 - OpEntryPoint Fragment %main "main" - OpExecutionMode %main OriginUpperLeft - OpDecorate %var_image DescriptorSet 0 - OpDecorate %var_image Binding 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %uint_3 = OpConstant %u32 3 - %uint_2 = OpConstant %u32 2 - %uint_1 = OpConstant %u32 1 - %v3uint = OpTypeVector %u32 3 - %v4float = OpTypeVector %f32 4 - %image = OpTypeImage %f32 2D 2 1 0 2 Unknown -%ptr_image = OpTypePointer UniformConstant %image - %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3 -%var_image = OpVariable %ptr_image UniformConstant - %main = OpFunction %void None %func - %main_lab = OpLabel - %18 = OpLoad %image %var_image - %19 = OpImageRead %v4float %18 %10 - OpReturn - OpFunctionEnd -)"; - - const spv_target_env env = SPV_ENV_VULKAN_1_0; - CompileSuccessfully(code, env); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env)); - EXPECT_THAT(getDiagnosticString(), Eq("")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_interfaces_test.cpp b/test/val/val_interfaces_test.cpp index d75c20cf..22a0e7c3 100644 --- a/test/val/val_interfaces_test.cpp +++ b/test/val/val_interfaces_test.cpp @@ -583,8 +583,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 0")); @@ -613,8 +611,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); EXPECT_THAT( getDiagnosticString(), HasSubstr("Entry-point has conflicting output location assignment " @@ -702,8 +698,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1")); @@ -737,8 +731,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1")); @@ -769,8 +761,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1")); @@ -801,8 +791,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 2")); @@ -833,8 +821,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 3")); @@ -867,8 +853,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1")); @@ -901,8 +885,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 5")); @@ -935,8 +917,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 7")); @@ -969,8 +949,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1")); @@ -1003,8 +981,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 3")); @@ -1039,8 +1015,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 15")); @@ -1100,8 +1074,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting input location assignment " "at location 1, component 1")); @@ -1217,8 +1189,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); EXPECT_THAT( getDiagnosticString(), HasSubstr("Entry-point has conflicting output location assignment " @@ -1388,8 +1358,6 @@ OpFunctionEnd CompileSuccessfully(text, SPV_ENV_VULKAN_1_0); EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722")); EXPECT_THAT(getDiagnosticString(), HasSubstr("Entry-point has conflicting output location " "assignment at location 1, component 1")); @@ -1488,7 +1456,7 @@ OpDecorate %struct Block OpMemberDecorate %struct 0 Location 0 OpMemberDecorate %struct 0 Component 0 OpMemberDecorate %struct 1 Location 0 -OpMemberDecorate %struct 1 Component 2 +OpMemberDecorate %struct 1 Component 1 %void = OpTypeVoid %void_fn = OpTypeFunction %void %float = OpTypeFloat 32 @@ -1570,58 +1538,6 @@ OpFunctionEnd "Interface struct has no Block decoration but has BuiltIn members.")); } -TEST_F(ValidateInterfacesTest, InvalidLocationTypePointer) { - const std::string text = R"( - OpCapability Shader - OpMemoryModel Logical Simple - OpEntryPoint Vertex %1 "Aiqn0" %2 %3 - OpDecorate %2 Location 0 - %void = OpTypeVoid - %5 = OpTypeFunction %void - %float = OpTypeFloat 32 -%_ptr_Private_void = OpTypePointer Private %void - %uint = OpTypeInt 32 0 -%uint_4278132784 = OpConstant %uint 4278132784 -%_arr__ptr_Private_void_uint_4278132784 = OpTypeArray %_ptr_Private_void %uint_4278132784 -%_ptr_Output__arr__ptr_Private_void_uint_4278132784 = OpTypePointer Output %_arr__ptr_Private_void_uint_4278132784 - %2 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output -%_ptr_Output__ptr_Private_void = OpTypePointer Output %_ptr_Private_void - %3 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output - %1 = OpFunction %void None %5 - %15 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(text, SPV_ENV_VULKAN_1_1); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Invalid type to assign a location")); -} - -TEST_F(ValidateInterfacesTest, ValidLocationTypePhysicalStorageBufferPointer) { - const std::string text = R"( -OpCapability Shader -OpCapability PhysicalStorageBufferAddresses -OpMemoryModel PhysicalStorageBuffer64 GLSL450 -OpEntryPoint Vertex %main "main" %var -OpDecorate %var Location 0 -OpDecorate %var RestrictPointer -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%ptr = OpTypePointer PhysicalStorageBuffer %int -%ptr2 = OpTypePointer Input %ptr -%var = OpVariable %ptr2 Input -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(text, SPV_ENV_VULKAN_1_3); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3)); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp index e809abf8..8cca96f5 100644 --- a/test/val/val_layout_test.cpp +++ b/test/val/val_layout_test.cpp @@ -14,7 +14,9 @@ // Validation tests for Logical Layout +#include #include +#include #include #include #include @@ -55,6 +57,13 @@ struct Range { bool inverse_; }; +template +spv_result_t InvalidSet(int order) { + for (spv_result_t val : {T(true)(order)...}) + if (val != SPV_SUCCESS) return val; + return SPV_SUCCESS; +} + // SPIRV source used to test the logical layout const std::vector& getInstructions() { // clang-format off diff --git a/test/val/val_limits_test.cpp b/test/val/val_limits_test.cpp index 66a6ff7f..364d514e 100644 --- a/test/val/val_limits_test.cpp +++ b/test/val/val_limits_test.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "gmock/gmock.h" #include "test/unit_spirv.h" diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index 8d0a94d2..4299eda9 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -23,14 +23,12 @@ #include "test/val/val_fixtures.h" // For pretty-printing tuples with spv_target_env. -std::ostream& operator<<(std::ostream& stream, spv_target_env target) { +std::ostream& operator<<(std::ostream& stream, spv_target_env target) +{ switch (target) { - case SPV_ENV_UNIVERSAL_1_3: - return stream << "SPV_ENV_UNIVERSAL_1_3"; - case SPV_ENV_UNIVERSAL_1_4: - return stream << "SPV_ENV_UNIVERSAL_1_4"; - default: - return stream << (unsigned)target; + case SPV_ENV_UNIVERSAL_1_3: return stream << "SPV_ENV_UNIVERSAL_1_3"; + case SPV_ENV_UNIVERSAL_1_4: return stream << "SPV_ENV_UNIVERSAL_1_4"; + default: return stream << (unsigned)target; } } @@ -2348,186 +2346,6 @@ OpFunctionEnd)"; EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateMemory, CoopMatKHRLoadStoreSuccess) { - std::string spirv = - GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR", - "MakePointerVisibleKHR|NonPrivatePointerKHR"); - - CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); -} - -TEST_F(ValidateMemory, CoopMatKHRStoreMemoryAccessFail) { - std::string spirv = - GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR", - "MakePointerVisibleKHR|NonPrivatePointerKHR"); - - CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("MakePointerVisibleKHR cannot be used with OpStore")); -} - -TEST_F(ValidateMemory, CoopMatKHRLoadMemoryAccessFail) { - std::string spirv = - GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR", - "MakePointerAvailableKHR|NonPrivatePointerKHR"); - - CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad")); -} - -TEST_F(ValidateMemory, CoopMatKHRInvalidStorageClassFail) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%f16 = OpTypeFloat 16 -%u32 = OpTypeInt 32 0 - -%u32_8 = OpConstant %u32 8 -%use_A = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A - -%str = OpTypeStruct %f16mat -%str_ptr = OpTypePointer Workgroup %str -%sh = OpVariable %str_ptr Workgroup - -%main = OpFunction %void None %func -%main_entry = OpLabel - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Cooperative matrix types (or types containing them) can only be " - "allocated in Function or Private storage classes or as function " - "parameters")); -} - -TEST_F(ValidateMemory, CoopMatMatrixKHRLengthResultTypeBad) { - const std::string body = R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%f16 = OpTypeFloat 16 -%u32 = OpTypeInt 32 0 -%i32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%use_A = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%1 = OpCooperativeMatrixLengthKHR %i32 %f16mat - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("The Result Type of OpCooperativeMatrixLengthKHR " - "'12[%12]' must be OpTypeInt with width 32 and signedness 0")); -} - -TEST_F(ValidateMemory, CoopMatMatrixKHRLengthOperandTypeBad) { - const std::string body = - R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%f16 = OpTypeFloat 16 -%u32 = OpTypeInt 32 0 -%i32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%use_A = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%1 = OpCooperativeMatrixLengthKHR %u32 %u32 - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("The type in OpCooperativeMatrixLengthKHR '5[%uint]' " - "must be OpTypeCooperativeMatrixKHR")); -} - -TEST_F(ValidateMemory, CoopMatMatrixKHRLengthGood) { - const std::string body = - R"( -OpCapability Shader -OpCapability Float16 -OpCapability CooperativeMatrixKHR -OpExtension "SPV_KHR_cooperative_matrix" -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%func = OpTypeFunction %void -%f16 = OpTypeFloat 16 -%u32 = OpTypeInt 32 0 -%i32 = OpTypeInt 32 1 - -%u32_8 = OpConstant %u32 8 -%use_A = OpConstant %u32 0 -%subgroup = OpConstant %u32 3 - -%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A - -%main = OpFunction %void None %func -%main_entry = OpLabel - -%1 = OpCooperativeMatrixLengthKHR %u32 %f16mat - -OpReturn -OpFunctionEnd)"; - - CompileSuccessfully(body.c_str()); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); -} - TEST_F(ValidateMemory, VulkanRTAOutsideOfStructBad) { std::string spirv = R"( OpCapability Shader @@ -2657,7 +2475,6 @@ OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %func "func" OpExecutionMode %func OriginUpperLeft -OpDecorate %struct_t Block %uint_t = OpTypeInt 32 0 %array_t = OpTypeRuntimeArray %uint_t %struct_t = OpTypeStruct %array_t @@ -2681,7 +2498,7 @@ OpFunctionEnd "For Vulkan, OpTypeStruct variables containing OpTypeRuntimeArray " "must have storage class of StorageBuffer, PhysicalStorageBuffer, or " "Uniform.\n %6 = " - "OpVariable %_ptr_Workgroup__struct_2 Workgroup\n")); + "OpVariable %_ptr_Workgroup__struct_4 Workgroup\n")); } TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) { @@ -2690,7 +2507,6 @@ OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %func "func" OpExecutionMode %func OriginUpperLeft -OpDecorate %struct_t BufferBlock %uint_t = OpTypeInt 32 0 %array_t = OpTypeRuntimeArray %uint_t %struct_t = OpTypeStruct %array_t @@ -2713,7 +2529,7 @@ OpFunctionEnd "OpTypeRuntimeArray must be decorated with Block if it " "has storage class StorageBuffer or " "PhysicalStorageBuffer.\n %6 = OpVariable " - "%_ptr_StorageBuffer__struct_2 StorageBuffer\n")); + "%_ptr_StorageBuffer__struct_4 StorageBuffer\n")); } TEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) { @@ -2748,7 +2564,6 @@ OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %func "func" OpExecutionMode %func OriginUpperLeft -OpDecorate %struct_t Block %uint_t = OpTypeInt 32 0 %array_t = OpTypeRuntimeArray %uint_t %struct_t = OpTypeStruct %array_t @@ -2770,7 +2585,7 @@ OpFunctionEnd HasSubstr("For Vulkan, an OpTypeStruct variable containing an " "OpTypeRuntimeArray must be decorated with BufferBlock " "if it has storage class Uniform.\n %6 = OpVariable " - "%_ptr_Uniform__struct_2 Uniform\n")); + "%_ptr_Uniform__struct_4 Uniform\n")); } TEST_F(ValidateMemory, VulkanRTAInsideRTABad) { @@ -3947,8 +3762,9 @@ OpFunctionEnd HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks")); } -using ValidateSizedVariable = spvtest::ValidateBase< - std::tuple>; +using ValidateSizedVariable = + spvtest::ValidateBase>; CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) { CodeGenerator generator; @@ -3958,8 +3774,7 @@ CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) { "\"SPV_KHR_8bit_storage\"\n"; generator.memory_model_ = "OpMemoryModel Logical GLSL450\n"; if (is_8bit) { - generator.before_types_ = - "OpMemberDecorate %char_buffer_block 0 Offset 0\n"; + generator.before_types_ = "OpMemberDecorate %char_buffer_block 0 Offset 0\n"; if (buffer_block) generator.before_types_ += "OpDecorate %char_buffer_block BufferBlock\n"; @@ -4897,224 +4712,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateMemory, PtrAccessChainArrayStrideBad) { - const std::string spirv = R"( - OpCapability Shader - OpCapability VariablePointersStorageBuffer - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - OpDecorate %var DescriptorSet 0 - OpDecorate %var Binding 0 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 - %ptr = OpTypePointer StorageBuffer %uint - %void = OpTypeVoid - %func = OpTypeFunction %void - %var = OpVariable %ptr StorageBuffer - %main = OpFunction %void None %func - %label = OpLabel - %access = OpAccessChain %ptr %var - %ptr_access = OpPtrAccessChain %ptr %access %uint_1 - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpPtrAccessChain must have a Base whose type is " - "decorated with ArrayStride")); -} - -TEST_F(ValidateMemory, PtrAccessChainArrayStrideSuccess) { - const std::string spirv = R"( - OpCapability Shader - OpCapability VariablePointersStorageBuffer - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - OpDecorate %var DescriptorSet 0 - OpDecorate %var Binding 00 - OpDecorate %ptr ArrayStride 4 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 - %ptr = OpTypePointer StorageBuffer %uint - %void = OpTypeVoid - %func = OpTypeFunction %void - %var = OpVariable %ptr StorageBuffer - %main = OpFunction %void None %func - %label = OpLabel - %access = OpAccessChain %ptr %var - %ptr_access = OpPtrAccessChain %ptr %access %uint_1 - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); -} - -TEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferSuccess) { - const std::string spirv = R"( - OpCapability Shader - OpCapability VariablePointersStorageBuffer - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - OpDecorate %_runtimearr_uint ArrayStride 4 - OpMemberDecorate %_struct_10 0 Offset 0 - OpDecorate %_struct_10 Block - OpDecorate %var DescriptorSet 0 - OpDecorate %var Binding 0 - OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 -%_runtimearr_uint = OpTypeRuntimeArray %uint - %_struct_10 = OpTypeStruct %_runtimearr_uint -%_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10 -%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint - %void = OpTypeVoid - %func2 = OpTypeFunction %void %_ptr_StorageBuffer_uint - %func1 = OpTypeFunction %void - %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer - %called = OpFunction %void None %func2 - %param = OpFunctionParameter %_ptr_StorageBuffer_uint - %label2 = OpLabel - %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %param %uint_1 - OpReturn - OpFunctionEnd - %main = OpFunction %void None %func1 - %label1 = OpLabel - %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0 - %call = OpFunctionCall %void %called %access - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferCapability) { - const std::string spirv = R"( - OpCapability Shader - OpCapability PhysicalStorageBufferAddresses - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel PhysicalStorageBuffer64 GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - OpDecorate %_runtimearr_uint ArrayStride 4 - OpMemberDecorate %_struct_10 0 Offset 0 - OpDecorate %_struct_10 Block - OpDecorate %var DescriptorSet 0 - OpDecorate %var Binding 0 - OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 -%_runtimearr_uint = OpTypeRuntimeArray %uint - %_struct_10 = OpTypeStruct %_runtimearr_uint -%_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10 -%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint - %void = OpTypeVoid - %func = OpTypeFunction %void - %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer - %main = OpFunction %void None %func - %label = OpLabel - %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0 - %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %access %uint_1 - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Base-07652")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpPtrAccessChain Base operand pointing to " - "StorageBuffer storage class must use VariablePointers " - "or VariablePointersStorageBuffer capability")); -} - -TEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupCapability) { - const std::string spirv = R"( - OpCapability Shader - OpCapability VariablePointersStorageBuffer - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - OpDecorate %_ptr_Workgroup_uint ArrayStride 4 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 -%_arr_uint = OpTypeArray %uint %uint_1 -%_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %void = OpTypeVoid - %func = OpTypeFunction %void - %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup - %main = OpFunction %void None %func - %label = OpLabel - %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0 - %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1 - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2)); - EXPECT_THAT(getDiagnosticString(), - AnyVUID("VUID-StandaloneSpirv-Base-07651")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpPtrAccessChain Base operand pointing to Workgroup " - "storage class must use VariablePointers capability")); -} - -TEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupNoArrayStrideSuccess) { - const std::string spirv = R"( - OpCapability Shader - OpCapability VariablePointers - OpExtension "SPV_KHR_storage_buffer_storage_class" - OpExtension "SPV_KHR_variable_pointers" - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "foo" %var - OpExecutionMode %main LocalSize 1 1 1 - %uint = OpTypeInt 32 0 - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 -%_arr_uint = OpTypeArray %uint %uint_1 -%_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %void = OpTypeVoid - %func = OpTypeFunction %void - %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup - %main = OpFunction %void None %func - %label = OpLabel - %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0 - %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1 - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_mesh_shading_test.cpp b/test/val/val_mesh_shading_test.cpp index a7b96a4e..ce6999dc 100644 --- a/test/val/val_mesh_shading_test.cpp +++ b/test/val/val_mesh_shading_test.cpp @@ -14,6 +14,7 @@ // Tests instructions from SPV_EXT_mesh_shader +#include #include #include "gmock/gmock.h" diff --git a/test/val/val_modes_test.cpp b/test/val/val_modes_test.cpp index 8dc0fbc5..689f0baa 100644 --- a/test/val/val_modes_test.cpp +++ b/test/val/val_modes_test.cpp @@ -18,6 +18,7 @@ #include "gmock/gmock.h" #include "source/spirv_target_env.h" +#include "test/test_fixture.h" #include "test/unit_spirv.h" #include "test/val/val_fixtures.h" @@ -578,11 +579,6 @@ TEST_P(ValidateModeExecution, ExecutionMode) { sstr << "OpCapability Kernel\n"; if (env == SPV_ENV_UNIVERSAL_1_3) { sstr << "OpCapability SubgroupDispatch\n"; - } else if (env == SPV_ENV_UNIVERSAL_1_5) { - sstr << "OpCapability TileImageColorReadAccessEXT\n"; - sstr << "OpCapability TileImageDepthReadAccessEXT\n"; - sstr << "OpCapability TileImageStencilReadAccessEXT\n"; - sstr << "OpExtension \"SPV_EXT_shader_tile_image\"\n"; } } sstr << "OpMemoryModel Logical GLSL450\n"; @@ -706,27 +702,6 @@ INSTANTIATE_TEST_SUITE_P( "DepthLess", "DepthUnchanged"), Values(SPV_ENV_UNIVERSAL_1_0))); -INSTANTIATE_TEST_SUITE_P(ValidateModeFragmentOnlyGoodSpv15, - ValidateModeExecution, - Combine(Values(SPV_SUCCESS), Values(""), - Values("Fragment"), - Values("NonCoherentColorAttachmentReadEXT", - "NonCoherentDepthAttachmentReadEXT", - "NonCoherentStencilAttachmentReadEXT"), - Values(SPV_ENV_UNIVERSAL_1_5))); - -INSTANTIATE_TEST_SUITE_P( - ValidateModeFragmentOnlyBadSpv15, ValidateModeExecution, - Combine(Values(SPV_ERROR_INVALID_DATA), - Values("Execution mode can only be used with the Fragment " - "execution model."), - Values("Geometry", "TessellationControl", "TessellationEvaluation", - "GLCompute", "Vertex", "Kernel"), - Values("NonCoherentColorAttachmentReadEXT", - "NonCoherentDepthAttachmentReadEXT", - "NonCoherentStencilAttachmentReadEXT"), - Values(SPV_ENV_UNIVERSAL_1_5))); - INSTANTIATE_TEST_SUITE_P(ValidateModeKernelOnlyGoodSpv13, ValidateModeExecution, Combine(Values(SPV_SUCCESS), Values(""), Values("Kernel"), diff --git a/test/val/val_non_uniform_test.cpp b/test/val/val_non_uniform_test.cpp index a020500d..3840eec6 100644 --- a/test/val/val_non_uniform_test.cpp +++ b/test/val/val_non_uniform_test.cpp @@ -44,8 +44,6 @@ OpCapability GroupNonUniformShuffleRelative OpCapability GroupNonUniformArithmetic OpCapability GroupNonUniformClustered OpCapability GroupNonUniformQuad -OpCapability GroupNonUniformPartitionedNV -OpExtension "SPV_NV_shader_subgroup_partitioned" )"; ss << capabilities_and_extensions; @@ -64,27 +62,16 @@ OpExtension "SPV_NV_shader_subgroup_partitioned" %float = OpTypeFloat 32 %u32vec4 = OpTypeVector %u32 4 %u32vec3 = OpTypeVector %u32 3 -%v2bool = OpTypeVector %bool 2 -%v4float = OpTypeVector %float 4 -%struct = OpTypeStruct %int -%v4int = OpTypeVector %int 4 %true = OpConstantTrue %bool %false = OpConstantFalse %bool %u32_0 = OpConstant %u32 0 -%int_0 = OpConstant %int 0 %float_0 = OpConstant %float 0 %u32vec4_null = OpConstantComposite %u32vec4 %u32_0 %u32_0 %u32_0 %u32_0 %u32vec3_null = OpConstantComposite %u32vec3 %u32_0 %u32_0 %u32_0 -%v2bool_false = OpConstantNull %v2bool -%v4float_null = OpConstantNull %v4float -%struct_null = OpConstantNull %struct -%v4int_null = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 - -%u32_undef = OpUndef %u32 %cross_device = OpConstant %u32 0 %device = OpConstant %u32 1 @@ -110,71 +97,37 @@ OpFunctionEnd)"; return ss.str(); } -spv::Scope scopes[] = {spv::Scope::CrossDevice, spv::Scope::Device, - spv::Scope::Workgroup, spv::Scope::Subgroup, - spv::Scope::Invocation}; +SpvScope scopes[] = {SpvScopeCrossDevice, SpvScopeDevice, SpvScopeWorkgroup, + SpvScopeSubgroup, SpvScopeInvocation}; using ValidateGroupNonUniform = spvtest::ValidateBase; using GroupNonUniform = spvtest::ValidateBase< - std::tuple>; + std::tuple>; -std::string ConvertScope(spv::Scope scope) { +std::string ConvertScope(SpvScope scope) { switch (scope) { - case spv::Scope::CrossDevice: + case SpvScopeCrossDevice: return "%cross_device"; - case spv::Scope::Device: + case SpvScopeDevice: return "%device"; - case spv::Scope::Workgroup: + case SpvScopeWorkgroup: return "%workgroup"; - case spv::Scope::Subgroup: + case SpvScopeSubgroup: return "%subgroup"; - case spv::Scope::Invocation: + case SpvScopeInvocation: return "%invocation"; default: return ""; } } -std::string ConvertMatch(const std::string& type) { - if (type == "%bool") { - return "%true"; - } else if (type == "%u32") { - return "%u32_0"; - } else if (type == "%int") { - return "%int_0"; - } else if (type == "%float") { - return "%float_0"; - } else if (type == "%u32vec4") { - return "%u32vec4_null"; - } else if (type == "%u32vec3") { - return "%u32vec3_null"; - } else if (type == "%v2bool") { - return "%v2bool_false"; - } else if (type == "%v4float") { - return "%v4float_null"; - } else if (type == "%struct") { - return "%struct_null"; - } else if (type == "%v4int") { - return "%v4int_null"; - } - - return "INVALID"; -} - TEST_P(GroupNonUniform, Vulkan1p1) { std::string opcode = std::get<0>(GetParam()); std::string type = std::get<1>(GetParam()); - spv::Scope execution_scope = std::get<2>(GetParam()); + SpvScope execution_scope = std::get<2>(GetParam()); std::string args = std::get<3>(GetParam()); std::string error = std::get<4>(GetParam()); - const std::string match = "match_res"; - size_t pos = std::string::npos; - while ((pos = args.find(match)) != std::string::npos) { - const std::string replace = ConvertMatch(type); - args = args.substr(0, pos) + replace + args.substr(pos + match.size()); - } - std::ostringstream sstr; sstr << "%result = " << opcode << " "; sstr << type << " "; @@ -184,7 +137,7 @@ TEST_P(GroupNonUniform, Vulkan1p1) { CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_VULKAN_1_1); spv_result_t result = ValidateInstructions(SPV_ENV_VULKAN_1_1); if (error == "") { - if (execution_scope == spv::Scope::Subgroup) { + if (execution_scope == SpvScopeSubgroup) { EXPECT_EQ(SPV_SUCCESS, result); } else { EXPECT_EQ(SPV_ERROR_INVALID_DATA, result); @@ -204,17 +157,10 @@ TEST_P(GroupNonUniform, Vulkan1p1) { TEST_P(GroupNonUniform, Spirv1p3) { std::string opcode = std::get<0>(GetParam()); std::string type = std::get<1>(GetParam()); - spv::Scope execution_scope = std::get<2>(GetParam()); + SpvScope execution_scope = std::get<2>(GetParam()); std::string args = std::get<3>(GetParam()); std::string error = std::get<4>(GetParam()); - const std::string match = "match_res"; - size_t pos = std::string::npos; - while ((pos = args.find(match)) != std::string::npos) { - const std::string replace = ConvertMatch(type); - args = args.substr(0, pos) + replace + args.substr(pos + match.size()); - } - std::ostringstream sstr; sstr << "%result = " << opcode << " "; sstr << type << " "; @@ -224,8 +170,8 @@ TEST_P(GroupNonUniform, Spirv1p3) { CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_UNIVERSAL_1_3); spv_result_t result = ValidateInstructions(SPV_ENV_UNIVERSAL_1_3); if (error == "") { - if (execution_scope == spv::Scope::Subgroup || - execution_scope == spv::Scope::Workgroup) { + if (execution_scope == SpvScopeSubgroup || + execution_scope == SpvScopeWorkgroup) { EXPECT_EQ(SPV_SUCCESS, result); } else { EXPECT_EQ(SPV_ERROR_INVALID_DATA, result); @@ -334,541 +280,17 @@ INSTANTIATE_TEST_SUITE_P( GroupNonUniformBallotBitCountBadResultType, GroupNonUniform, Combine( Values("OpGroupNonUniformBallotBitCount"), Values("%float", "%int"), - Values(spv::Scope::Subgroup), Values("Reduce %u32vec4_null"), + Values(SpvScopeSubgroup), Values("Reduce %u32vec4_null"), Values("Expected Result Type to be an unsigned integer type scalar."))); INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitCountBadValue, GroupNonUniform, Combine(Values("OpGroupNonUniformBallotBitCount"), - Values("%u32"), Values(spv::Scope::Subgroup), + Values("%u32"), Values(SpvScopeSubgroup), Values("Reduce %u32vec3_null", "Reduce %u32_0", "Reduce %float_0"), Values("Expected Value to be a vector of four " "components of integer type scalar"))); -INSTANTIATE_TEST_SUITE_P(GroupNonUniformElectGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformElect"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values(""), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformElectBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformElect"), - Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct"), - Values(spv::Scope::Subgroup), Values(""), - Values("Result must be a boolean scalar type"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformAnyAllGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformAny", - "OpGroupNonUniformAll"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%true", "%false"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformAnyAllBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"), - Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct"), - Values(spv::Scope::Subgroup), Values("%true"), - Values("Result must be a boolean scalar type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformAnyAllBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null", - "%u32vec3_null", "%v2bool_false", "%v4float_null", - "%struct_null"), - Values("Predicate must be a boolean scalar type"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformAllEqualGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformAllEqual"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%true", "%false"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformAllEqualBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformAllEqual"), - Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct"), - Values(spv::Scope::Subgroup), Values("%true"), - Values("Result must be a boolean scalar type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformAllEqualBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformAllEqual"), Values("%bool"), - Values(spv::Scope::Subgroup), Values("%struct_null"), - Values("Value must be a scalar or vector of integer, " - "floating-point, or boolean type"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcast", - "OpGroupNonUniformQuadBroadcast", - "OpGroupNonUniformQuadSwap"), - Values("%bool", "%u32", "%int", "%float", - "%u32vec4", "%u32vec3", "%v2bool", - "%v4float", "%v4int"), - Values(spv::Scope::Subgroup), - Values("match_res %u32_0"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBroadcastShuffleBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle", - "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp", - "OpGroupNonUniformShuffleDown", - "OpGroupNonUniformQuadBroadcast", - "OpGroupNonUniformQuadSwap"), - Values("%void", "%struct"), Values(spv::Scope::Subgroup), - Values("%u32_0 %u32_0"), - Values("Result must be a scalar or vector of integer, " - "floating-point, or boolean type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBroadcastShuffleBadOperand1, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle", - "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp", - "OpGroupNonUniformShuffleDown", - "OpGroupNonUniformQuadBroadcast", - "OpGroupNonUniformQuadSwap"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%u32_0 %u32_0", "%int_0 %u32_0", "%float_0 %u32_0", - "%u32vec4_null %u32_0", "%u32vec3_null %u32_0", - "%v2bool_false %u32_0", "%v4float_null %u32_0", - "%struct_null %u32_0", "%v4int_null %u32_0"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBroadcastShuffleBadOperand2, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle", - "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp", - "OpGroupNonUniformShuffleDown", - "OpGroupNonUniformQuadBroadcast", - "OpGroupNonUniformQuadSwap"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%true %true", "%true %int_0", "%true %float_0", - "%true %u32vec4_null", "%true %u32vec3_null", - "%true %v4float_null", "%true %v2bool_false", - "%true %struct_null", "%true %v4int_null"), - Values("must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastShuffleOperand2NotConstant, - GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcast", - "OpGroupNonUniformQuadBroadcast", - "OpGroupNonUniformQuadSwap"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%true %u32_undef"), - Values("must be a constant instruction"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastFirstGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcastFirst"), - Values("%bool", "%u32", "%int", "%float", - "%u32vec4", "%u32vec3", "%v2bool", - "%v4float", "%v4int"), - Values(spv::Scope::Subgroup), - Values("match_res"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBroadcasFirsttBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcastFirst"), - Values("%void", "%struct"), Values(spv::Scope::Subgroup), - Values("%u32_0"), - Values("Result must be a scalar or vector of integer, " - "floating-point, or boolean type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBroadcastBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformBroadcastFirst"), Values("%bool"), - Values(spv::Scope::Subgroup), - Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null", - "%u32vec3_null", "%v2bool_false", "%v4float_null", - "%struct_null", "%v4int_null"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallot"), - Values("%u32vec4"), - Values(spv::Scope::Subgroup), - Values("%true", "%false"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallot"), - Values("%void", "%bool", "%u32", "%int", "%float", "%u32vec3", - "%v2bool", "%v4float", "%struct", "%v4int"), - Values(spv::Scope::Subgroup), Values("%true", "%false"), - Values("Result must be a 4-component unsigned integer vector"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallot"), - Values("%u32vec4"), - Values(spv::Scope::Subgroup), - Values("%u32_0", "%int_0", "%float_0", - "%u32vec4_null", "%u32vec3_null", - "%v2bool_false", "%v4float_null", - "%struct_null", "%v4int_null"), - Values("Predicate must be a boolean scalar"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformInverseBallotGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformInverseBallot"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%u32vec4_null"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformInverseBallotBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformInverseBallot"), - Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct", "%v4int"), - Values(spv::Scope::Subgroup), Values("%u32vec4_null"), - Values("Result must be a boolean scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformInverseBallotBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformInverseBallot"), Values("%bool"), - Values(spv::Scope::Subgroup), - Values("%true", "%false", "%u32_0", "%int_0", "%float_0", - "%u32vec3_null", "%v2bool_false", "%v4float_null", - "%struct_null", "%v4int_null"), - Values("Value must be a 4-component unsigned integer vector"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitExtractGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotBitExtract"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("%u32vec4_null %u32_0"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotBitExtractBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotBitExtract"), - Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct", "%v4int"), - Values(spv::Scope::Subgroup), Values("%u32vec4_null %u32_0"), - Values("Result must be a boolean scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotBitExtractBadOperand1, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"), - Values(spv::Scope::Subgroup), - Values("%true %u32_0", "%false %u32_0", "%u32_0 %u32_0", - "%int_0 %u32_0", "%float_0 %u32_0", "%u32vec3_null %u32_0", - "%v2bool_false %u32_0", "%v4float_null %u32_0", - "%struct_null %u32_0", "%v4int_null %u32_0"), - Values("Value must be a 4-component unsigned integer vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotBitExtractBadOperand2, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"), - Values(spv::Scope::Subgroup), - Values("%u32vec4_null %true", "%u32vec4_null %false", - "%u32vec4_null %int_0", "%u32vec4_null %float_0", - "%u32vec4_null %u32vec3_null", "%u32vec4_null %v2bool_false", - "%u32vec4_null %v4float_null", "%u32vec4_null %struct_null", - "%u32vec4_null %v4int_null"), - Values("Id must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotFindGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotFindLSB", - "OpGroupNonUniformBallotFindMSB"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("%u32vec4_null"), Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotFindBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotFindLSB", - "OpGroupNonUniformBallotFindMSB"), - Values("%void", "%bool", "%int", "%float", "%u32vec4", "%u32vec3", - "%v2bool", "%v4float", "%struct", "%v4int"), - Values(spv::Scope::Subgroup), Values("%u32vec4_null"), - Values("Result must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBallotFindBadOperand, GroupNonUniform, - Combine(Values("OpGroupNonUniformBallotFindLSB", - "OpGroupNonUniformBallotFindMSB"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("%true", "%false", "%u32_0", "%int_0", "%float_0", - "%u32vec3_null", "%v2bool_false", "%v4float_null", - "%struct_null", "%v4int_null"), - Values("Value must be a 4-component unsigned integer vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformSMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32", "%int", "%u32vec4", "%u32vec3", "%v4int"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0", - "PartitionedReduceNV match_res %u32vec4_null", - "PartitionedInclusiveScanNV match_res %u32vec4_null", - "PartitionedExclusiveScanNV match_res %v4int_null"), - Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformSMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%bool", "%float", "%v4float", "%struct"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values("Result must be an integer scalar or vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticBadValue, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformSMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%int", "%u32vec4", "%u32vec3", "%v4int"), - Values(spv::Scope::Subgroup), - Values("Reduce %u32_0", "InclusiveScan %u32_0", - "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticMissingClusterSize, GroupNonUniform, - Combine( - Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformUMin", - "OpGroupNonUniformSMax", "OpGroupNonUniformUMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res"), - Values( - "ClusterSize must be present when Operation is ClusteredReduce"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticMissingBallot, GroupNonUniform, - Combine( - Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformUMin", - "OpGroupNonUniformSMax", "OpGroupNonUniformUMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("PartitionedReduceNV match_res", - "PartitionedInclusiveScanNV match_res", - "PartitionedExclusiveScanNV match_res"), - Values("Ballot must be present when Operation is PartitionedReduceNV, " - "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticBadClusterSizeType, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformUMin", - "OpGroupNonUniformSMax", "OpGroupNonUniformUMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %true", - "ClusteredReduce match_res %false", - "ClusteredReduce match_res %int_0", - "ClusteredReduce match_res %float_0", - "ClusteredReduce match_res %u32vec4_null", - "ClusteredReduce match_res %u32vec3_null", - "ClusteredReduce match_res %v2bool_false", - "ClusteredReduce match_res %v4float_null", - "ClusteredReduce match_res %struct_null", - "ClusteredReduce match_res %v4int_null"), - Values("ClusterSize must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticBadBallotType, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformUMin", - "OpGroupNonUniformSMax", "OpGroupNonUniformUMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("PartitionedReduceNV match_res %true", - "PartitionedReduceNV match_res %false", - "PartitionedReduceNV match_res %int_0", - "PartitionedReduceNV match_res %float_0", - "PartitionedReduceNV match_res %u32_0", - "PartitionedReduceNV match_res %u32vec3_null", - "PartitionedReduceNV match_res %v2bool_false", - "PartitionedReduceNV match_res %v4float_null", - "PartitionedReduceNV match_res %struct_null"), - Values("Ballot must be a 4-component integer vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformIntegerArithmeticClusterSizeNotConstant, GroupNonUniform, - Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul", - "OpGroupNonUniformSMin", "OpGroupNonUniformUMin", - "OpGroupNonUniformSMax", "OpGroupNonUniformUMax", - "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr", - "OpGroupNonUniformBitwiseXor"), - Values("%u32"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %u32_undef"), - Values("ClusterSize must be a constant instruction"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformUnsignedIntegerArithmeticGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"), - Values("%u32", "%u32vec4", "%u32vec3"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformUnsignedIntegerArithmeticBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"), - Values("%bool", "%int", "%float", "%v4float", "%struct", "%v4int"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values("Result must be an unsigned integer scalar or vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformUnsignedIntegerArithmeticBadValue, GroupNonUniform, - Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"), - Values("%u32vec4", "%u32vec3"), Values(spv::Scope::Subgroup), - Values("Reduce %u32_0", "InclusiveScan %u32_0", - "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%float", "%v4float"), Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%bool", "%u32", "%int", "%u32vec4", "%u32vec3", "%struct", - "%v4int"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values("Result must be a floating-point scalar or vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticBadValue, GroupNonUniform, - Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%v4float"), Values(spv::Scope::Subgroup), - Values("Reduce %float_0", "InclusiveScan %float_0", - "ExclusiveScan %float_0", "ClusteredReduce %float_0 %u32_0"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticMissingClusterSize, GroupNonUniform, - Combine( - Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%float"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res"), - Values( - "ClusterSize must be present when Operation is ClusteredReduce"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticBadClusterSizeType, GroupNonUniform, - Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%float"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %true", - "ClusteredReduce match_res %false", - "ClusteredReduce match_res %int_0", - "ClusteredReduce match_res %float_0", - "ClusteredReduce match_res %u32vec4_null", - "ClusteredReduce match_res %u32vec3_null", - "ClusteredReduce match_res %v2bool_false", - "ClusteredReduce match_res %v4float_null", - "ClusteredReduce match_res %struct_null", - "ClusteredReduce match_res %v4int_null"), - Values("ClusterSize must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformFloatArithmeticClusterSizeNotConstant, GroupNonUniform, - Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul", - "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"), - Values("%float"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %u32_undef"), - Values("ClusterSize must be a constant instruction"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticGood, GroupNonUniform, - Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%bool", "%v2bool"), Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values(""))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticBadResultType, GroupNonUniform, - Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%u32", "%int", "%float", "%u32vec4", "%u32vec3", "%struct", - "%v4float", "%v4int"), - Values(spv::Scope::Subgroup), - Values("Reduce match_res", "InclusiveScan match_res", - "ExclusiveScan match_res", - "ClusteredReduce match_res %u32_0"), - Values("Result must be a boolean scalar or vector"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticBadValue, GroupNonUniform, - Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%v2bool"), Values(spv::Scope::Subgroup), - Values("Reduce %true", "InclusiveScan %true", - "ExclusiveScan %false", "ClusteredReduce %false %u32_0"), - Values("The type of Value must match the Result type"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticMissingClusterSize, GroupNonUniform, - Combine( - Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res"), - Values( - "ClusterSize must be present when Operation is ClusteredReduce"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticBadClusterSizeType, GroupNonUniform, - Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %true", - "ClusteredReduce match_res %false", - "ClusteredReduce match_res %int_0", - "ClusteredReduce match_res %float_0", - "ClusteredReduce match_res %u32vec4_null", - "ClusteredReduce match_res %u32vec3_null", - "ClusteredReduce match_res %v2bool_false", - "ClusteredReduce match_res %v4float_null", - "ClusteredReduce match_res %struct_null", - "ClusteredReduce match_res %v4int_null"), - Values("ClusterSize must be an unsigned integer scalar"))); - -INSTANTIATE_TEST_SUITE_P( - GroupNonUniformBooleanArithmeticClusterSizeNotConstant, GroupNonUniform, - Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr", - "OpGroupNonUniformLogicalXor"), - Values("%bool"), Values(spv::Scope::Subgroup), - Values("ClusteredReduce match_res %u32_undef"), - Values("ClusterSize must be a constant instruction"))); - TEST_F(ValidateGroupNonUniform, VulkanGroupNonUniformBallotBitCountOperation) { std::string test = R"( OpCapability Shader @@ -904,146 +326,6 @@ OpFunctionEnd "be only: Reduce, InclusiveScan, or ExclusiveScan.")); } -TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p4) { - const std::string text = R"( -OpCapability Shader -OpCapability GroupNonUniformBallot -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" %var -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %var DescriptorSet 0 -OpDecorate %var Binding 0 -OpDecorate %struct Block -OpMemberDecorate %struct 0 Offset 0 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%subgroup = OpConstant %int 3 -%struct = OpTypeStruct %int -%ptr_struct = OpTypePointer StorageBuffer %struct -%ptr_int = OpTypePointer StorageBuffer %int -%var = OpVariable %ptr_struct StorageBuffer -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%gep = OpAccessChain %ptr_int %var %int_0 -%ld = OpLoad %int %gep -%broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Before SPIR-V 1.5, Id must be a constant instruction")); -} - -TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p5) { - const std::string text = R"( -OpCapability Shader -OpCapability GroupNonUniformBallot -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" %var -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %var DescriptorSet 0 -OpDecorate %var Binding 0 -OpDecorate %struct Block -OpMemberDecorate %struct 0 Offset 0 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%subgroup = OpConstant %int 3 -%struct = OpTypeStruct %int -%ptr_struct = OpTypePointer StorageBuffer %struct -%ptr_int = OpTypePointer StorageBuffer %int -%var = OpVariable %ptr_struct StorageBuffer -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%gep = OpAccessChain %ptr_int %var %int_0 -%ld = OpLoad %int %gep -%broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); -} - -TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p4) { - const std::string text = R"( -OpCapability Shader -OpCapability GroupNonUniformQuad -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" %var -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %var DescriptorSet 0 -OpDecorate %var Binding 0 -OpDecorate %struct Block -OpMemberDecorate %struct 0 Offset 0 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%subgroup = OpConstant %int 3 -%struct = OpTypeStruct %int -%ptr_struct = OpTypePointer StorageBuffer %struct -%ptr_int = OpTypePointer StorageBuffer %int -%var = OpVariable %ptr_struct StorageBuffer -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%gep = OpAccessChain %ptr_int %var %int_0 -%ld = OpLoad %int %gep -%broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, - ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Before SPIR-V 1.5, Index must be a constant instruction")); -} - -TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p5) { - const std::string text = R"( -OpCapability Shader -OpCapability GroupNonUniformQuad -OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %main "main" %var -OpExecutionMode %main LocalSize 1 1 1 -OpDecorate %var DescriptorSet 0 -OpDecorate %var Binding 0 -OpDecorate %struct Block -OpMemberDecorate %struct 0 Offset 0 -%void = OpTypeVoid -%int = OpTypeInt 32 0 -%int_0 = OpConstant %int 0 -%subgroup = OpConstant %int 3 -%struct = OpTypeStruct %int -%ptr_struct = OpTypePointer StorageBuffer %struct -%ptr_int = OpTypePointer StorageBuffer %int -%var = OpVariable %ptr_struct StorageBuffer -%void_fn = OpTypeFunction %void -%main = OpFunction %void None %void_fn -%entry = OpLabel -%gep = OpAccessChain %ptr_int %var %int_0 -%ld = OpLoad %int %gep -%broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_ray_tracing_reorder_test.cpp b/test/val/val_ray_tracing_reorder_test.cpp deleted file mode 100755 index 6038c383..00000000 --- a/test/val/val_ray_tracing_reorder_test.cpp +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright (c) 2022 The Khronos Group Inc. -// -// 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. - -// Tests instructions from SPV_NV_shader_invocation_reorder. - -#include -#include - -#include "gmock/gmock.h" -#include "test/val/val_fixtures.h" - -namespace spvtools { -namespace val { -namespace { - -using ::testing::HasSubstr; -using ::testing::Values; - -using ValidateRayTracingReorderNV = spvtest::ValidateBase; - -std::string GenerateReorderThreadCode(const std::string& body = "", - const std::string& declarations = "") { - std::ostringstream ss; - ss << R"( - OpCapability RayTracingKHR - OpCapability ShaderInvocationReorderNV - OpExtension "SPV_KHR_ray_tracing" - OpExtension "SPV_NV_shader_invocation_reorder" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint RayGenerationNV %main "main" %hObj - OpSourceExtension "GL_EXT_ray_tracing" - OpSourceExtension "GL_NV_shader_invocation_reorder" - OpName %main "main" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %6 = OpTypeHitObjectNV -%_ptr_Private_6 = OpTypePointer Private %6 - %hObj = OpVariable %_ptr_Private_6 Private - )"; - ss << declarations; - - ss << R"( - %main = OpFunction %void None %3 - %5 = OpLabel - )"; - - ss << body; - - ss << R"( - OpReturn - OpFunctionEnd - )"; - return ss.str(); -} - -TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHintNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 - )"; - - const std::string body = R"( - OpReorderThreadWithHintNV %uint_4 %uint_4 - )"; - - CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHitObjectNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 - %uint_2 = OpConstant %uint 2 - )"; - - const std::string body = R"( - OpReorderThreadWithHitObjectNV %hObj - OpReorderThreadWithHitObjectNV %hObj %uint_4 %uint_2 - )"; - - CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -std::string GenerateReorderShaderCode( - const std::string& body = "", const std::string& declarations = "", - const std::string execution_model = "RayGenerationKHR") { - std::ostringstream ss; - ss << R"( - OpCapability RayTracingKHR - OpCapability ShaderInvocationReorderNV - OpExtension "SPV_KHR_ray_tracing" - OpExtension "SPV_NV_shader_invocation_reorder" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint )" - << execution_model - << R"( %main "main" %attr %_ %hObj %payload %__0 %as %__1 - OpSource GLSL 460 - OpSourceExtension "GL_EXT_ray_tracing" - OpSourceExtension "GL_NV_shader_invocation_reorder" - OpName %main "main" - OpName %attr "attr" - OpName %hBlock "hBlock" - OpMemberName %hBlock 0 "attrval" - OpName %_ "" - OpName %hObj "hObj" - OpName %payload "payload" - OpName %pBlock "pBlock" - OpMemberName %pBlock 0 "val1" - OpMemberName %pBlock 1 "val2" - OpName %__0 "" - OpName %as "as" - OpName %block "block" - OpMemberName %block 0 "op" - OpName %__1 "" - OpDecorate %hBlock Block - OpDecorate %pBlock Block - OpDecorate %as DescriptorSet 0 - OpDecorate %as Binding 0 - OpMemberDecorate %block 0 Offset 0 - OpDecorate %block Block - OpDecorate %__1 DescriptorSet 0 - OpDecorate %__1 Binding 1 - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v2float = OpTypeVector %float 2 -%_ptr_HitObjectAttributeNV_v2float = OpTypePointer HitObjectAttributeNV %v2float - %attr = OpVariable %_ptr_HitObjectAttributeNV_v2float HitObjectAttributeNV - %float_1 = OpConstant %float 1 - %11 = OpConstantComposite %v2float %float_1 %float_1 - %hBlock = OpTypeStruct %float -%_ptr_HitObjectAttributeNV_hBlock = OpTypePointer HitObjectAttributeNV %hBlock - %_ = OpVariable %_ptr_HitObjectAttributeNV_hBlock HitObjectAttributeNV - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 - %float_2 = OpConstant %float 2 -%_ptr_HitObjectAttributeNV_float = OpTypePointer HitObjectAttributeNV %float - %20 = OpTypeHitObjectNV - %_ptr_Private_20 = OpTypePointer Private %20 - %hObj = OpVariable %_ptr_Private_20 Private - %23 = OpTypeAccelerationStructureKHR - %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23 - %as = OpVariable %_ptr_UniformConstant_23 UniformConstant - %v4float = OpTypeVector %float 4 -%_ptr_RayPayloadNV_v4float = OpTypePointer RayPayloadNV %v4float - %payload = OpVariable %_ptr_RayPayloadNV_v4float RayPayloadNV - %pBlock = OpTypeStruct %v2float %v2float -%_ptr_RayPayloadNV_pBlock = OpTypePointer RayPayloadNV %pBlock - %__0 = OpVariable %_ptr_RayPayloadNV_pBlock RayPayloadNV - %block = OpTypeStruct %float -%_ptr_StorageBuffer_block = OpTypePointer StorageBuffer %block - %__1 = OpVariable %_ptr_StorageBuffer_block StorageBuffer - )"; - - ss << declarations; - - ss << R"( - %main = OpFunction %void None %3 - %5 = OpLabel - )"; - - ss << body; - - ss << R"( - OpReturn - OpFunctionEnd)"; - return ss.str(); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %v3float = OpTypeVector %float 3 - %float_0_5 = OpConstant %float 0.5 - %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 - %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1 - %int_1 = OpConstant %int 1 - )"; - - const std::string body = R"( - OpStore %attr %11 - %26 = OpLoad %23 %as - OpHitObjectTraceRayNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %payload - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayMotionNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %v3float = OpTypeVector %float 3 - %float_0_5 = OpConstant %float 0.5 - %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 - %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1 - %float_10 = OpConstant %float 10 - %int_2 = OpConstant %int 2 - )"; - - const std::string body = R"( - OpStore %attr %11 - %26 = OpLoad %23 %as - OpHitObjectTraceRayMotionNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %float_10 %__0 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitNV) { - const std::string declarations = R"( - %int_1 = OpConstant %int 1 - %uint = OpTypeInt 32 0 - %uint_2 = OpConstant %uint 2 - %v3float = OpTypeVector %float 3 - %float_0_5 = OpConstant %float 0.5 - %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 - %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1 - %float_10 = OpConstant %float 10 - %int_2 = OpConstant %int 2 - )"; - - const std::string body = R"( - OpStore %attr %11 - %26 = OpLoad %23 %as - OpHitObjectRecordHitNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %attr - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitWithIndexNV) { - const std::string declarations = R"( - %int_1 = OpConstant %int 1 - %uint = OpTypeInt 32 0 - %uint_2 = OpConstant %uint 2 - %v3float = OpTypeVector %float 3 - %float_0_5 = OpConstant %float 0.5 - %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 - %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1 - %float_10 = OpConstant %float 10 - %int_2 = OpConstant %int 2 - )"; - - const std::string body = R"( - OpStore %attr %11 - %26 = OpLoad %23 %as - OpHitObjectRecordHitWithIndexNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %_ - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectRecordEmptyNV) { - const std::string body = R"( - OpHitObjectRecordEmptyNV %hObj - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectRecordMissNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %uint_1 = OpConstant %uint 1 - %v3float = OpTypeVector %float 3 - %float_0_5 = OpConstant %float 0.5 - %29 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 - %float_1_5 = OpConstant %float 1.5 - %31 = OpConstantComposite %v3float %float_1_5 %float_1_5 %float_1_5 - %float_5 = OpConstant %float 5 - )"; - - const std::string body = R"( - OpHitObjectRecordMissNV %hObj %uint_1 %29 %float_2 %31 %float_5 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectIsHitNV) { - const std::string declarations = R"( - %bool = OpTypeBool - %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float - )"; - - const std::string body = R"( - %26 = OpHitObjectIsHitNV %bool %hObj - OpSelectionMerge %28 None - OpBranchConditional %26 %27 %28 - %27 = OpLabel - %33 = OpAccessChain %_ptr_StorageBuffer_float %__1 %int_0 - OpStore %33 %float_1 - OpBranch %28 - %28 = OpLabel - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMaxNV) { - const std::string declarations = R"( - %_ptr_Function_float = OpTypePointer Function %float - )"; - - const std::string body = R"( - %tmin = OpVariable %_ptr_Function_float Function - %12 = OpHitObjectGetRayTMaxNV %float %hObj - OpStore %tmin %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMinNV) { - const std::string declarations = R"( - %_ptr_Function_float = OpTypePointer Function %float - )"; - - const std::string body = R"( - %tmin = OpVariable %_ptr_Function_float Function - %12 = OpHitObjectGetRayTMinNV %float %hObj - OpStore %tmin %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayOriginNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %_ptr_Function_v3float = OpTypePointer Function %v3float - )"; - - const std::string body = R"( - %orig = OpVariable %_ptr_Function_v3float Function - %13 = OpHitObjectGetWorldRayOriginNV %v3float %hObj - OpStore %orig %13 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayOriginNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %_ptr_Function_v3float = OpTypePointer Function %v3float - )"; - - const std::string body = R"( - %oorig = OpVariable %_ptr_Function_v3float Function - %13 = OpHitObjectGetObjectRayOriginNV %v3float %hObj - OpStore %oorig %13 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayDirectionNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %_ptr_Function_v3float = OpTypePointer Function %v3float - )"; - - const std::string body = R"( - %dir = OpVariable %_ptr_Function_v3float Function - %13 = OpHitObjectGetWorldRayDirectionNV %v3float %hObj - OpStore %dir %13 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayDirectionNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %_ptr_Function_v3float = OpTypePointer Function %v3float - )"; - - const std::string body = R"( - %odir = OpVariable %_ptr_Function_v3float Function - %13 = OpHitObjectGetObjectRayDirectionNV %v3float %hObj - OpStore %odir %13 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectToWorldNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %mat4v3float = OpTypeMatrix %v3float 4 - %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float - )"; - - const std::string body = R"( - %otw = OpVariable %_ptr_Function_mat4v3float Function - %14 = OpHitObjectGetObjectToWorldNV %mat4v3float %hObj - OpStore %otw %14 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldToObjectNV) { - const std::string declarations = R"( - %v3float = OpTypeVector %float 3 - %mat4v3float = OpTypeMatrix %v3float 4 - %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float - )"; - - const std::string body = R"( - %wto = OpVariable %_ptr_Function_mat4v3float Function - %14 = OpHitObjectGetWorldToObjectNV %mat4v3float %hObj - OpStore %wto %14 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceCustomIndexNV) { - const std::string declarations = R"( - %_ptr_Function_int = OpTypePointer Function %int - )"; - - const std::string body = R"( - %id = OpVariable %_ptr_Function_int Function - %12 = OpHitObjectGetInstanceCustomIndexNV %int %hObj - OpStore %id %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceIdNV) { - const std::string declarations = R"( - %_ptr_Function_int = OpTypePointer Function %int - )"; - - const std::string body = R"( - %id = OpVariable %_ptr_Function_int Function - %12 = OpHitObjectGetInstanceIdNV %int %hObj - OpStore %id %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetPrimitiveIndexNV) { - const std::string declarations = R"( - %_ptr_Function_int = OpTypePointer Function %int - )"; - - const std::string body = R"( - %id = OpVariable %_ptr_Function_int Function - %12 = OpHitObjectGetPrimitiveIndexNV %int %hObj - OpStore %id %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetGeometryIndexNV) { - const std::string declarations = R"( - %_ptr_Function_int = OpTypePointer Function %int - )"; - - const std::string body = R"( - %id = OpVariable %_ptr_Function_int Function - %12 = OpHitObjectGetGeometryIndexNV %int %hObj - OpStore %id %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetHitKindNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %_ptr_Function_uint = OpTypePointer Function %uint - )"; - - const std::string body = R"( - %uid = OpVariable %_ptr_Function_uint Function - %12 = OpHitObjectGetHitKindNV %uint %hObj - OpStore %uid %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetAttributesNV) { - const std::string body = R"( - OpHitObjectGetAttributesNV %hObj %attr - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, HitObjectGetShaderRecordBufferHandleNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 - %_ptr_Function_v2uint = OpTypePointer Function %v2uint - )"; - - const std::string body = R"( - %handle = OpVariable %_ptr_Function_v2uint Function - %13 = OpHitObjectGetShaderRecordBufferHandleNV %v2uint %hObj - OpStore %handle %13 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -TEST_F(ValidateRayTracingReorderNV, - HitObjectGetShaderBindingTableRecordIndexNV) { - const std::string declarations = R"( - %uint = OpTypeInt 32 0 - %_ptr_Function_uint = OpTypePointer Function %uint - )"; - - const std::string body = R"( - %rid = OpVariable %_ptr_Function_uint Function - %12 = OpHitObjectGetShaderBindingTableRecordIndexNV %uint %hObj - OpStore %rid %12 - )"; - - CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(), - SPV_ENV_VULKAN_1_2); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); -} - -} // namespace -} // namespace val -} // namespace spvtools diff --git a/test/val/val_state_test.cpp b/test/val/val_state_test.cpp index 51064abd..65cb1c3a 100644 --- a/test/val/val_state_test.cpp +++ b/test/val/val_state_test.cpp @@ -18,10 +18,14 @@ #include #include "gtest/gtest.h" +#include "source/latest_version_spirv_header.h" + #include "source/enum_set.h" #include "source/extensions.h" -#include "source/latest_version_spirv_header.h" #include "source/spirv_validator_options.h" +#include "source/val/construct.h" +#include "source/val/function.h" +#include "source/val/validate.h" #include "source/val/validation_state.h" namespace spvtools { @@ -55,41 +59,40 @@ using ValidationState_HasAnyOfCapabilities = ValidationStateTest; TEST_F(ValidationState_HasAnyOfCapabilities, EmptyMask) { EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::Matrix); + state_.RegisterCapability(SpvCapabilityMatrix); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::ImageMipmap); + state_.RegisterCapability(SpvCapabilityImageMipmap); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::Pipes); + state_.RegisterCapability(SpvCapabilityPipes); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::StorageImageArrayDynamicIndexing); + state_.RegisterCapability(SpvCapabilityStorageImageArrayDynamicIndexing); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::ClipDistance); + state_.RegisterCapability(SpvCapabilityClipDistance); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); - state_.RegisterCapability(spv::Capability::StorageImageWriteWithoutFormat); + state_.RegisterCapability(SpvCapabilityStorageImageWriteWithoutFormat); EXPECT_TRUE(state_.HasAnyOfCapabilities({})); } TEST_F(ValidationState_HasAnyOfCapabilities, SingleCapMask) { - EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::Matrix})); - EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap})); - state_.RegisterCapability(spv::Capability::Matrix); - EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::Matrix})); - EXPECT_FALSE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap})); - state_.RegisterCapability(spv::Capability::ImageMipmap); - EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::Matrix})); - EXPECT_TRUE(state_.HasAnyOfCapabilities({spv::Capability::ImageMipmap})); + EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix})); + EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap})); + state_.RegisterCapability(SpvCapabilityMatrix); + EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix})); + EXPECT_FALSE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap})); + state_.RegisterCapability(SpvCapabilityImageMipmap); + EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityMatrix})); + EXPECT_TRUE(state_.HasAnyOfCapabilities({SpvCapabilityImageMipmap})); } TEST_F(ValidationState_HasAnyOfCapabilities, MultiCapMask) { const auto set1 = - CapabilitySet{spv::Capability::SampledRect, spv::Capability::ImageBuffer}; - const auto set2 = - CapabilitySet{spv::Capability::StorageImageWriteWithoutFormat, - spv::Capability::StorageImageReadWithoutFormat, - spv::Capability::GeometryStreams}; + CapabilitySet{SpvCapabilitySampledRect, SpvCapabilityImageBuffer}; + const auto set2 = CapabilitySet{SpvCapabilityStorageImageWriteWithoutFormat, + SpvCapabilityStorageImageReadWithoutFormat, + SpvCapabilityGeometryStreams}; EXPECT_FALSE(state_.HasAnyOfCapabilities(set1)); EXPECT_FALSE(state_.HasAnyOfCapabilities(set2)); - state_.RegisterCapability(spv::Capability::ImageBuffer); + state_.RegisterCapability(SpvCapabilityImageBuffer); EXPECT_TRUE(state_.HasAnyOfCapabilities(set1)); EXPECT_FALSE(state_.HasAnyOfCapabilities(set2)); } @@ -136,52 +139,50 @@ using ValidationState_InLayoutState = ValidationStateTest; TEST_F(ValidationState_InLayoutState, Variable) { state_.SetCurrentLayoutSectionForTesting(kLayoutTypes); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpVariable)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpVariable)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpVariable)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpVariable)); } TEST_F(ValidationState_InLayoutState, ExtInst) { state_.SetCurrentLayoutSectionForTesting(kLayoutTypes); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpExtInst)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpExtInst)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpExtInst)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpExtInst)); } TEST_F(ValidationState_InLayoutState, Undef) { state_.SetCurrentLayoutSectionForTesting(kLayoutTypes); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpUndef)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpUndef)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpUndef)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpUndef)); } TEST_F(ValidationState_InLayoutState, Function) { state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunction)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunction)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunction)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunction)); } TEST_F(ValidationState_InLayoutState, FunctionParameter) { state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations); - EXPECT_TRUE( - state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionParameter)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionParameter)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE( - state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionParameter)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionParameter)); } TEST_F(ValidationState_InLayoutState, FunctionEnd) { state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDeclarations); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionEnd)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionEnd)); state_.SetCurrentLayoutSectionForTesting(kLayoutFunctionDefinitions); - EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(spv::Op::OpFunctionEnd)); + EXPECT_TRUE(state_.IsOpcodeInCurrentLayoutSection(SpvOpFunctionEnd)); } } // namespace diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp index 6a3e4bdb..8693e803 100644 --- a/test/val/val_storage_test.cpp +++ b/test/val/val_storage_test.cpp @@ -28,6 +28,8 @@ namespace { using ::testing::HasSubstr; using ::testing::Values; using ValidateStorage = spvtest::ValidateBase; +using ValidateStorageClass = + spvtest::ValidateBase>; using ValidateStorageExecutionModel = spvtest::ValidateBase; TEST_F(ValidateStorage, FunctionStorageInsideFunction) { diff --git a/test/val/val_type_unique_test.cpp b/test/val/val_type_unique_test.cpp index 31ad3a65..45a4d504 100644 --- a/test/val/val_type_unique_test.cpp +++ b/test/val/val_type_unique_test.cpp @@ -90,7 +90,7 @@ OpFunctionEnd // Returns expected error string if |opcode| produces a duplicate type // declaration. -std::string GetErrorString(spv::Op opcode) { +std::string GetErrorString(SpvOp opcode) { return "Duplicate non-aggregate type declarations are not allowed. Opcode: " + std::string(spvOpcodeString(opcode)); } @@ -107,8 +107,7 @@ TEST_F(ValidateTypeUnique, duplicate_void) { )" + GetBody(); CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeVoid))); + EXPECT_THAT(getDiagnosticString(), HasSubstr(GetErrorString(SpvOpTypeVoid))); } TEST_F(ValidateTypeUnique, duplicate_bool) { @@ -117,8 +116,7 @@ TEST_F(ValidateTypeUnique, duplicate_bool) { )" + GetBody(); CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeBool))); + EXPECT_THAT(getDiagnosticString(), HasSubstr(GetErrorString(SpvOpTypeBool))); } TEST_F(ValidateTypeUnique, duplicate_int) { @@ -127,8 +125,7 @@ TEST_F(ValidateTypeUnique, duplicate_int) { )" + GetBody(); CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeInt))); + EXPECT_THAT(getDiagnosticString(), HasSubstr(GetErrorString(SpvOpTypeInt))); } TEST_F(ValidateTypeUnique, duplicate_float) { @@ -137,8 +134,7 @@ TEST_F(ValidateTypeUnique, duplicate_float) { )" + GetBody(); CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeFloat))); + EXPECT_THAT(getDiagnosticString(), HasSubstr(GetErrorString(SpvOpTypeFloat))); } TEST_F(ValidateTypeUnique, duplicate_vec3) { @@ -148,7 +144,7 @@ TEST_F(ValidateTypeUnique, duplicate_vec3) { CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeVector))); + HasSubstr(GetErrorString(SpvOpTypeVector))); } TEST_F(ValidateTypeUnique, duplicate_mat33) { @@ -158,7 +154,7 @@ TEST_F(ValidateTypeUnique, duplicate_mat33) { CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeMatrix))); + HasSubstr(GetErrorString(SpvOpTypeMatrix))); } TEST_F(ValidateTypeUnique, duplicate_vfunc) { @@ -168,7 +164,7 @@ TEST_F(ValidateTypeUnique, duplicate_vfunc) { CompileSuccessfully(str.c_str()); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeFunction))); + HasSubstr(GetErrorString(SpvOpTypeFunction))); } TEST_F(ValidateTypeUnique, duplicate_pipe_storage) { @@ -185,7 +181,7 @@ OpMemoryModel Physical32 OpenCL CompileSuccessfully(str.c_str(), SPV_ENV_UNIVERSAL_1_1); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypePipeStorage))); + HasSubstr(GetErrorString(SpvOpTypePipeStorage))); } TEST_F(ValidateTypeUnique, duplicate_named_barrier) { @@ -201,7 +197,7 @@ OpMemoryModel Physical32 OpenCL CompileSuccessfully(str.c_str(), SPV_ENV_UNIVERSAL_1_1); ASSERT_EQ(kDuplicateTypeError, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1)); EXPECT_THAT(getDiagnosticString(), - HasSubstr(GetErrorString(spv::Op::OpTypeNamedBarrier))); + HasSubstr(GetErrorString(SpvOpTypeNamedBarrier))); } TEST_F(ValidateTypeUnique, duplicate_forward_pointer) { @@ -238,7 +234,7 @@ OpMemoryModel Physical32 OpenCL CompileSuccessfully(str.c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - Not(HasSubstr(GetErrorString(spv::Op::OpTypeVoid)))); + Not(HasSubstr(GetErrorString(SpvOpTypeVoid)))); } TEST_F(ValidateTypeUnique, DuplicatePointerTypesNoExtension) { @@ -267,7 +263,7 @@ OpMemoryModel Logical GLSL450 CompileSuccessfully(str.c_str()); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - Not(HasSubstr(GetErrorString(spv::Op::OpTypePointer)))); + Not(HasSubstr(GetErrorString(SpvOpTypePointer)))); } } // namespace diff --git a/test/val/val_validation_state_test.cpp b/test/val/val_validation_state_test.cpp index a5e88dea..3dd9e64a 100644 --- a/test/val/val_validation_state_test.cpp +++ b/test/val/val_validation_state_test.cpp @@ -180,7 +180,7 @@ TEST_F(ValidationStateTest, CheckEntryPoints) { CompileSuccessfully(spirv); EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState()); EXPECT_EQ(size_t(1), vstate_->entry_points().size()); - EXPECT_EQ(spv::Op::OpFunction, + EXPECT_EQ(SpvOpFunction, vstate_->FindDef(vstate_->entry_points()[0])->opcode()); } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index a93f6404..86d0bc46 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -39,47 +39,26 @@ function(add_spvtools_tool) set_property(TARGET ${ARG_TARGET} PROPERTY FOLDER "SPIRV-Tools executables") endfunction() -set(COMMON_TOOLS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/util/flags.cpp") - if (NOT ${SPIRV_SKIP_EXECUTABLES}) - add_spvtools_tool(TARGET spirv-diff SRCS ${COMMON_TOOLS_SRCS} diff/diff.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-dis SRCS ${COMMON_TOOLS_SRCS} dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-val SRCS ${COMMON_TOOLS_SRCS} val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-opt SRCS ${COMMON_TOOLS_SRCS} opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-as SRCS as/as.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-diff SRCS diff/diff.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-diff SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-dis SRCS dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-val SRCS val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-opt SRCS opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")) # iOS does not allow std::system calls which spirv-reduce requires - add_spvtools_tool(TARGET spirv-reduce SRCS ${COMMON_TOOLS_SRCS} reduce/reduce.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-reduce SRCS reduce/reduce.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY}) endif() - add_spvtools_tool(TARGET spirv-link SRCS ${COMMON_TOOLS_SRCS} link/linker.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-lint SRCS ${COMMON_TOOLS_SRCS} lint/lint.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) - add_spvtools_tool(TARGET spirv-as - SRCS as/as.cpp - ${COMMON_TOOLS_SRCS} - LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - target_include_directories(spirv-as PRIVATE ${spirv-tools_SOURCE_DIR} - ${SPIRV_HEADER_INCLUDE_DIR}) + add_spvtools_tool(TARGET spirv-link SRCS link/linker.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY}) + add_spvtools_tool(TARGET spirv-lint SRCS lint/lint.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY}) add_spvtools_tool(TARGET spirv-cfg SRCS cfg/cfg.cpp cfg/bin_to_dot.h cfg/bin_to_dot.cpp - ${COMMON_TOOLS_SRCS} LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR} ${SPIRV_HEADER_INCLUDE_DIR}) set(SPIRV_INSTALL_TARGETS spirv-as spirv-dis spirv-val spirv-opt spirv-cfg spirv-link spirv-lint) - - if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Android")) - add_spvtools_tool(TARGET spirv-objdump - SRCS objdump/objdump.cpp - objdump/extract_source.cpp - util/cli_consumer.cpp - ${COMMON_TOOLS_SRCS} - LIBS ${SPIRV_TOOLS_FULL_VISIBILITY}) - target_include_directories(spirv-objdump PRIVATE ${spirv-tools_SOURCE_DIR} - ${SPIRV_HEADER_INCLUDE_DIR}) - set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-objdump) - endif() - if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")) set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-reduce) endif() @@ -90,19 +69,6 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) endif(SPIRV_BUILD_FUZZER) if(ENABLE_SPIRV_TOOLS_INSTALL) - install(TARGETS ${SPIRV_INSTALL_TARGETS} EXPORT SPIRV-Tools-toolsTargets) - export(EXPORT SPIRV-Tools-toolsTargets FILE SPIRV-Tools-toolsTargets.cmake) - - spvtools_config_package_dir(SPIRV-Tools-tools PACKAGE_DIR) - install(EXPORT SPIRV-Tools-toolsTargets FILE SPIRV-Tools-toolsTargets.cmake - DESTINATION ${PACKAGE_DIR}) - - file(WRITE ${CMAKE_BINARY_DIR}/SPIRV-Tools-toolsConfig.cmake - "include(CMakeFindDependencyMacro)\n" - "find_dependency(${SPIRV_TOOLS})\n" - "include(\${CMAKE_CURRENT_LIST_DIR}/SPIRV-Tools-toolsTargets.cmake)\n" - ) - - install(FILES ${CMAKE_BINARY_DIR}/SPIRV-Tools-toolsConfig.cmake DESTINATION ${PACKAGE_DIR}) + install(TARGETS ${SPIRV_INSTALL_TARGETS} DESTINATION ${CMAKE_INSTALL_BINDIR}) endif(ENABLE_SPIRV_TOOLS_INSTALL) endif() diff --git a/tools/as/as.cpp b/tools/as/as.cpp index 2a000cf0..506b0585 100644 --- a/tools/as/as.cpp +++ b/tools/as/as.cpp @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include #include @@ -20,11 +19,11 @@ #include "source/spirv_target_env.h" #include "spirv-tools/libspirv.h" #include "tools/io.h" -#include "tools/util/flags.h" -static const auto kDefaultEnvironment = "spv1.6"; -static const std::string kHelpText = - R"(%s - Create a SPIR-V binary module from SPIR-V assembly text +void print_usage(char* argv0) { + std::string target_env_list = spvTargetEnvList(19, 80); + printf( + R"(%s - Create a SPIR-V binary module from SPIR-V assembly text Usage: %s [options] [] @@ -43,70 +42,94 @@ Options: Numeric IDs in the binary will have the same values as in the source. Non-numeric IDs are allocated by filling in the gaps, starting with 1 and going up. - --target-env %s + --target-env {%s} Use specified environment. -)"; +)", + argv0, argv0, target_env_list.c_str()); +} -// clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( preserve_numeric_ids, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_string(o, /* default_value= */ "", /* required= */ false); -FLAG_LONG_string( target_env, /* default_value= */ kDefaultEnvironment, /* required= */ false); -// clang-format on +static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; -int main(int, const char** argv) { - if (!flags::Parse(argv)) { - return 1; - } - - if (flags::h.value() || flags::help.value()) { - const std::string target_env_list = spvTargetEnvList(19, 80); - printf(kHelpText.c_str(), argv[0], argv[0], target_env_list.c_str()); - return 0; - } - - if (flags::version.value()) { - spv_target_env target_env; - bool success = spvParseTargetEnv(kDefaultEnvironment, &target_env); - assert(success && "Default environment should always parse."); - if (!success) { - fprintf(stderr, - "error: invalid default target environment. Please report this " - "issue."); - return 1; +int main(int argc, char** argv) { + const char* inFile = nullptr; + const char* outFile = nullptr; + uint32_t options = 0; + spv_target_env target_env = kDefaultEnvironment; + for (int argi = 1; argi < argc; ++argi) { + if ('-' == argv[argi][0]) { + switch (argv[argi][1]) { + case 'h': { + print_usage(argv[0]); + return 0; + } + case 'o': { + if (!outFile && argi + 1 < argc) { + outFile = argv[++argi]; + } else { + print_usage(argv[0]); + return 1; + } + } break; + case 0: { + // Setting a filename of "-" to indicate stdin. + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } + } break; + case '-': { + // Long options + if (0 == strcmp(argv[argi], "--version")) { + printf("%s\n", spvSoftwareVersionDetailsString()); + printf("Target: %s\n", + spvTargetEnvDescription(kDefaultEnvironment)); + return 0; + } else if (0 == strcmp(argv[argi], "--help")) { + print_usage(argv[0]); + return 0; + } else if (0 == strcmp(argv[argi], "--preserve-numeric-ids")) { + options |= SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS; + } else if (0 == strcmp(argv[argi], "--target-env")) { + if (argi + 1 < argc) { + const auto env_str = argv[++argi]; + if (!spvParseTargetEnv(env_str, &target_env)) { + fprintf(stderr, "error: Unrecognized target env: %s\n", + env_str); + return 1; + } + } else { + fprintf(stderr, "error: Missing argument to --target-env\n"); + return 1; + } + } else { + fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]); + print_usage(argv[0]); + return 1; + } + } break; + default: + fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]); + print_usage(argv[0]); + return 1; + } + } else { + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } } - printf("%s\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(target_env)); - return 0; } - std::string outFile = flags::o.value(); - if (outFile.empty()) { + if (!outFile) { outFile = "out.spv"; } - uint32_t options = 0; - if (flags::preserve_numeric_ids.value()) { - options |= SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS; - } - - spv_target_env target_env; - if (!spvParseTargetEnv(flags::target_env.value().c_str(), &target_env)) { - fprintf(stderr, "error: Unrecognized target env: %s\n", - flags::target_env.value().c_str()); - return 1; - } - - if (flags::positional_arguments.size() != 1) { - fprintf(stderr, "error: exactly one input file must be specified.\n"); - return 1; - } - std::string inFile = flags::positional_arguments[0]; - std::vector contents; - if (!ReadTextFile(inFile.c_str(), &contents)) return 1; + if (!ReadTextFile(inFile, &contents)) return 1; spv_binary binary; spv_diagnostic diagnostic = nullptr; @@ -120,8 +143,7 @@ int main(int, const char** argv) { return error; } - if (!WriteFile(outFile.c_str(), "wb", binary->code, - binary->wordCount)) { + if (!WriteFile(outFile, "wb", binary->code, binary->wordCount)) { spvBinaryDestroy(binary); return 1; } diff --git a/tools/cfg/bin_to_dot.cpp b/tools/cfg/bin_to_dot.cpp index 40a7dc4d..72e7693a 100644 --- a/tools/cfg/bin_to_dot.cpp +++ b/tools/cfg/bin_to_dot.cpp @@ -81,26 +81,26 @@ class DotConverter { spv_result_t DotConverter::HandleInstruction( const spv_parsed_instruction_t& inst) { - switch (spv::Op(inst.opcode)) { - case spv::Op::OpFunction: + switch (inst.opcode) { + case SpvOpFunction: current_function_id_ = inst.result_id; seen_function_entry_block_ = false; break; - case spv::Op::OpFunctionEnd: + case SpvOpFunctionEnd: current_function_id_ = 0; break; - case spv::Op::OpLabel: + case SpvOpLabel: current_block_id_ = inst.result_id; break; - case spv::Op::OpBranch: + case SpvOpBranch: FlushBlock({inst.words[1]}); break; - case spv::Op::OpBranchConditional: + case SpvOpBranchConditional: FlushBlock({inst.words[2], inst.words[3]}); break; - case spv::Op::OpSwitch: { + case SpvOpSwitch: { std::vector successors{inst.words[2]}; for (size_t i = 3; i < inst.num_operands; i += 2) { successors.push_back(inst.words[inst.operands[i].offset]); @@ -108,18 +108,18 @@ spv_result_t DotConverter::HandleInstruction( FlushBlock(successors); } break; - case spv::Op::OpKill: - case spv::Op::OpReturn: - case spv::Op::OpUnreachable: - case spv::Op::OpReturnValue: + case SpvOpKill: + case SpvOpReturn: + case SpvOpUnreachable: + case SpvOpReturnValue: FlushBlock({}); break; - case spv::Op::OpLoopMerge: + case SpvOpLoopMerge: merge_ = inst.words[1]; continue_target_ = inst.words[2]; break; - case spv::Op::OpSelectionMerge: + case SpvOpSelectionMerge: merge_ = inst.words[1]; break; default: diff --git a/tools/cfg/cfg.cpp b/tools/cfg/cfg.cpp index 2d11e6fb..5380c21e 100644 --- a/tools/cfg/cfg.cpp +++ b/tools/cfg/cfg.cpp @@ -21,11 +21,11 @@ #include "spirv-tools/libspirv.h" #include "tools/cfg/bin_to_dot.h" #include "tools/io.h" -#include "tools/util/flags.h" -static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; -static const std::string kHelpText = - R"(%s - Show the control flow graph in GraphiViz "dot" form. EXPERIMENTAL +// Prints a program usage message to stdout. +static void print_usage(const char* argv0) { + printf( + R"(%s - Show the control flow graph in GraphiViz "dot" form. EXPERIMENTAL Usage: %s [options] [] @@ -40,42 +40,71 @@ Options: -o Set the output filename. Output goes to standard output if this option is not specified, or if the filename is "-". -)"; +)", + argv0, argv0); +} -// clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_string(o, /* default_value= */ "", /* required= */ false); -// clang-format on +static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; -int main(int, const char** argv) { - if (!flags::Parse(argv)) { - return 1; +int main(int argc, char** argv) { + const char* inFile = nullptr; + const char* outFile = nullptr; // Stays nullptr if printing to stdout. + + for (int argi = 1; argi < argc; ++argi) { + if ('-' == argv[argi][0]) { + switch (argv[argi][1]) { + case 'h': + print_usage(argv[0]); + return 0; + case 'o': { + if (!outFile && argi + 1 < argc) { + outFile = argv[++argi]; + } else { + print_usage(argv[0]); + return 1; + } + } break; + case '-': { + // Long options + if (0 == strcmp(argv[argi], "--help")) { + print_usage(argv[0]); + return 0; + } + if (0 == strcmp(argv[argi], "--version")) { + printf("%s EXPERIMENTAL\n", spvSoftwareVersionDetailsString()); + printf("Target: %s\n", + spvTargetEnvDescription(kDefaultEnvironment)); + return 0; + } + print_usage(argv[0]); + return 1; + } + case 0: { + // Setting a filename of "-" to indicate stdin. + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } + } break; + default: + print_usage(argv[0]); + return 1; + } + } else { + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } + } } - if (flags::h.value() || flags::help.value()) { - printf(kHelpText.c_str(), argv[0], argv[0]); - return 0; - } - - if (flags::version.value()) { - printf("%s EXPERIMENTAL\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(kDefaultEnvironment)); - return 0; - } - - if (flags::positional_arguments.size() != 1) { - fprintf(stderr, "error: exactly one input file must be specified.\n"); - return 1; - } - - std::string inFile = flags::positional_arguments[0]; - std::string outFile = flags::o.value(); - // Read the input binary. std::vector contents; - if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; + if (!ReadBinaryFile(inFile, &contents)) return 1; spv_context context = spvContextCreate(kDefaultEnvironment); spv_diagnostic diagnostic = nullptr; @@ -89,8 +118,7 @@ int main(int, const char** argv) { return error; } std::string str = ss.str(); - WriteFile(outFile.empty() ? nullptr : outFile.c_str(), "w", str.data(), - str.size()); + WriteFile(outFile, "w", str.data(), str.size()); spvDiagnosticDestroy(diagnostic); spvContextDestroy(context); diff --git a/tools/diff/diff.cpp b/tools/diff/diff.cpp index 2217896c..d3cad04b 100644 --- a/tools/diff/diff.cpp +++ b/tools/diff/diff.cpp @@ -17,25 +17,14 @@ #endif #include "source/diff/diff.h" + #include "source/opt/build_module.h" #include "source/opt/ir_context.h" #include "spirv-tools/libspirv.hpp" #include "tools/io.h" #include "tools/util/cli_consumer.h" -#include "tools/util/flags.h" -namespace { - -constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; - -constexpr bool kColorIsPossible = -#if SPIRV_COLOR_TERMINAL - true; -#else - false; -#endif - -void print_usage(const char* argv0) { +static void print_usage(char* argv0) { printf(R"(%s - Compare two SPIR-V files Usage: %s @@ -49,12 +38,11 @@ logical transformation from src to dst, in src's id-space. -h, --help Print this help. --version Display diff version information. - --color Force color output. The default when printing to a terminal. - If both --color and --no-color is present, --no-color prevails. - --no-color Don't print in color. The default when output goes to - something other than a terminal (e.g. a pipe, or a shell - redirection). - If both --color and --no-color is present, --no-color prevails. + --color Force color output. The default when printing to a terminal. + Overrides a previous --no-color option. + --no-color Don't print in color. Overrides a previous --color option. + The default when output goes to something other than a + terminal (e.g. a pipe, or a shell redirection). --no-indent Don't indent instructions. @@ -70,7 +58,9 @@ logical transformation from src to dst, in src's id-space. argv0, argv0); } -bool is_assembly(const char* path) { +static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; + +static bool is_assembly(const char* path) { const char* suffix = strrchr(path, '.'); if (suffix == nullptr) { return false; @@ -79,7 +69,7 @@ bool is_assembly(const char* path) { return strcmp(suffix, ".spvasm") == 0; } -std::unique_ptr load_module(const char* path) { +static std::unique_ptr load_module(const char* path) { if (is_assembly(path)) { std::vector contents; if (!ReadTextFile(path, &contents)) return {}; @@ -99,62 +89,101 @@ std::unique_ptr load_module(const char* path) { contents.data(), contents.size()); } -} // namespace - -// clang-format off -FLAG_SHORT_bool(h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( color, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( no_color, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( no_indent, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( no_header, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( with_id_map, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( ignore_set_binding, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( ignore_location, /* default_value= */ false, /* required= */ false); -// clang-format on - -int main(int, const char* argv[]) { - if (!flags::Parse(argv)) { - return 1; - } - - if (flags::h.value() || flags::help.value()) { - print_usage(argv[0]); - return 0; - } - - if (flags::version.value()) { - printf("%s\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(kDefaultEnvironment)); - return 0; - } - - if (flags::positional_arguments.size() != 2) { - fprintf(stderr, "error: two input files required.\n"); - return 1; - } - -#if defined(_POSIX_VERSION) - const bool output_is_tty = isatty(fileno(stdout)); +int main(int argc, char** argv) { + const char* src_file = nullptr; + const char* dst_file = nullptr; + bool color_is_possible = +#if SPIRV_COLOR_TERMINAL + true; #else - const bool output_is_tty = true; + false; #endif + bool force_color = false; + bool force_no_color = false; + bool allow_indent = true; + bool no_header = false; + bool dump_id_map = false; + bool ignore_set_binding = false; + bool ignore_location = false; - const std::string& src_file = flags::positional_arguments[0]; - const std::string& dst_file = flags::positional_arguments[1]; + for (int argi = 1; argi < argc; ++argi) { + if ('-' == argv[argi][0]) { + switch (argv[argi][1]) { + case 'h': + print_usage(argv[0]); + return 0; + case '-': { + // Long options + if (strcmp(argv[argi], "--no-color") == 0) { + force_no_color = true; + force_color = false; + } else if (strcmp(argv[argi], "--color") == 0) { + force_no_color = false; + force_color = true; + } else if (strcmp(argv[argi], "--no-indent") == 0) { + allow_indent = false; + } else if (strcmp(argv[argi], "--no-header") == 0) { + no_header = true; + } else if (strcmp(argv[argi], "--with-id-map") == 0) { + dump_id_map = true; + } else if (strcmp(argv[argi], "--ignore-set-binding") == 0) { + ignore_set_binding = true; + } else if (strcmp(argv[argi], "--ignore-location") == 0) { + ignore_location = true; + } else if (strcmp(argv[argi], "--help") == 0) { + print_usage(argv[0]); + return 0; + } else if (strcmp(argv[argi], "--version") == 0) { + printf("%s\n", spvSoftwareVersionDetailsString()); + printf("Target: %s\n", + spvTargetEnvDescription(kDefaultEnvironment)); + return 0; + } else { + print_usage(argv[0]); + return 1; + } + } break; + default: + print_usage(argv[0]); + return 1; + } + } else { + if (src_file == nullptr) { + src_file = argv[argi]; + } else if (dst_file == nullptr) { + dst_file = argv[argi]; + } else { + fprintf(stderr, "error: More than two input files specified\n"); + return 1; + } + } + } + + if (src_file == nullptr || dst_file == nullptr) { + print_usage(argv[0]); + return 1; + } spvtools::diff::Options options; - options.color_output = (output_is_tty || flags::color.value()) && - !flags::no_color.value() && kColorIsPossible; - options.indent = !flags::no_indent.value(); - options.no_header = flags::no_header.value(); - options.dump_id_map = flags::with_id_map.value(); - options.ignore_set_binding = flags::ignore_set_binding.value(); - options.ignore_location = flags::ignore_location.value(); - std::unique_ptr src = load_module(src_file.c_str()); - std::unique_ptr dst = load_module(dst_file.c_str()); + if (allow_indent) options.indent = true; + if (no_header) options.no_header = true; + if (dump_id_map) options.dump_id_map = true; + if (ignore_set_binding) options.ignore_set_binding = true; + if (ignore_location) options.ignore_location = true; + + if (color_is_possible && !force_no_color) { + bool output_is_tty = true; +#if defined(_POSIX_VERSION) + output_is_tty = isatty(fileno(stdout)); +#endif + if (output_is_tty || force_color) { + options.color_output = true; + } + } + + std::unique_ptr src = load_module(src_file); + std::unique_ptr dst = load_module(dst_file); if (!src) { fprintf(stderr, "error: Loading src file\n"); diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index aacd37f0..64380db0 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -24,9 +24,10 @@ #include "spirv-tools/libspirv.h" #include "tools/io.h" -#include "tools/util/flags.h" -static const std::string kHelpText = R"(%s - Disassemble a SPIR-V binary module +static void print_usage(char* argv0) { + printf( + R"(%s - Disassemble a SPIR-V binary module Usage: %s [options] [] @@ -57,49 +58,15 @@ Options: --offsets Show byte offsets for each instruction. --comment Add comments to make reading easier -)"; - -// clang-format off -FLAG_SHORT_bool (h, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_string(o, /* default_value= */ "-", /* required= */ false); -FLAG_LONG_bool (help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool (version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (color, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (no_color, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (no_indent, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (no_header, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (raw_id, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (offsets, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool (comment, /* default_value= */ false, /* required= */ false); -// clang-format on +)", + argv0, argv0); +} static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5; -int main(int, const char** argv) { - if (!flags::Parse(argv)) { - return 1; - } - - if (flags::h.value() || flags::help.value()) { - printf(kHelpText.c_str(), argv[0], argv[0]); - return 0; - } - - if (flags::version.value()) { - printf("%s\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(kDefaultEnvironment)); - return 0; - } - - if (flags::positional_arguments.size() > 1) { - fprintf(stderr, "error: more than one input file specified.\n"); - return 1; - } - - const std::string inFile = flags::positional_arguments.size() == 0 - ? "-" - : flags::positional_arguments[0]; - const std::string outFile = flags::o.value(); +int main(int argc, char** argv) { + const char* inFile = nullptr; + const char* outFile = nullptr; bool color_is_possible = #if SPIRV_COLOR_TERMINAL @@ -107,30 +74,105 @@ int main(int, const char** argv) { #else false; #endif + bool force_color = false; + bool force_no_color = false; + + bool allow_indent = true; + bool show_byte_offsets = false; + bool no_header = false; + bool friendly_names = true; + bool comments = false; + + for (int argi = 1; argi < argc; ++argi) { + if ('-' == argv[argi][0]) { + switch (argv[argi][1]) { + case 'h': + print_usage(argv[0]); + return 0; + case 'o': { + if (!outFile && argi + 1 < argc) { + outFile = argv[++argi]; + } else { + print_usage(argv[0]); + return 1; + } + } break; + case '-': { + // Long options + if (0 == strcmp(argv[argi], "--no-color")) { + force_no_color = true; + force_color = false; + } else if (0 == strcmp(argv[argi], "--color")) { + force_no_color = false; + force_color = true; + } else if (0 == strcmp(argv[argi], "--comment")) { + comments = true; + } else if (0 == strcmp(argv[argi], "--no-indent")) { + allow_indent = false; + } else if (0 == strcmp(argv[argi], "--offsets")) { + show_byte_offsets = true; + } else if (0 == strcmp(argv[argi], "--no-header")) { + no_header = true; + } else if (0 == strcmp(argv[argi], "--raw-id")) { + friendly_names = false; + } else if (0 == strcmp(argv[argi], "--help")) { + print_usage(argv[0]); + return 0; + } else if (0 == strcmp(argv[argi], "--version")) { + printf("%s\n", spvSoftwareVersionDetailsString()); + printf("Target: %s\n", + spvTargetEnvDescription(kDefaultEnvironment)); + return 0; + } else { + print_usage(argv[0]); + return 1; + } + } break; + case 0: { + // Setting a filename of "-" to indicate stdin. + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } + } break; + default: + print_usage(argv[0]); + return 1; + } + } else { + if (!inFile) { + inFile = argv[argi]; + } else { + fprintf(stderr, "error: More than one input file specified\n"); + return 1; + } + } + } uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NONE; - if (!flags::no_indent.value()) options |= SPV_BINARY_TO_TEXT_OPTION_INDENT; + if (allow_indent) options |= SPV_BINARY_TO_TEXT_OPTION_INDENT; - if (flags::offsets.value()) - options |= SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET; + if (show_byte_offsets) options |= SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET; - if (flags::no_header.value()) options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER; + if (no_header) options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER; - if (!flags::raw_id.value()) - options |= SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; + if (friendly_names) options |= SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; - if (flags::comment.value()) options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT; + if (comments) options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT; - if (flags::o.value() == "-") { + if (!outFile || (0 == strcmp("-", outFile))) { // Print to standard output. options |= SPV_BINARY_TO_TEXT_OPTION_PRINT; - if (color_is_possible && !flags::no_color.value()) { + + if (color_is_possible && !force_no_color) { bool output_is_tty = true; #if defined(_POSIX_VERSION) output_is_tty = isatty(fileno(stdout)); #endif - if (output_is_tty || flags::color.value()) { + if (output_is_tty || force_color) { options |= SPV_BINARY_TO_TEXT_OPTION_COLOR; } } @@ -138,7 +180,7 @@ int main(int, const char** argv) { // Read the input binary. std::vector contents; - if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1; + if (!ReadBinaryFile(inFile, &contents)) return 1; // If printing to standard output, then spvBinaryToText should // do the printing. In particular, colour printing on Windows is @@ -163,7 +205,7 @@ int main(int, const char** argv) { } if (!print_to_stdout) { - if (!WriteFile(outFile.c_str(), "w", text->str, text->length)) { + if (!WriteFile(outFile, "w", text->str, text->length)) { spvTextDestroy(text); return 1; } diff --git a/tools/fuzz/fuzz.cpp b/tools/fuzz/fuzz.cpp index 5f2a0080..ca6633a6 100644 --- a/tools/fuzz/fuzz.cpp +++ b/tools/fuzz/fuzz.cpp @@ -41,6 +41,12 @@ namespace { enum class FuzzingTarget { kSpirv, kWgsl }; +// Check that the std::system function can actually be used. +bool CheckExecuteCommand() { + int res = std::system(nullptr); + return res != 0; +} + // Execute a command using the shell. // Returns true if and only if the command's exit status was 0. bool ExecuteCommand(const std::string& command) { @@ -764,6 +770,11 @@ int main(int argc, const char** argv) { } break; case FuzzActions::SHRINK: { + if (!CheckExecuteCommand()) { + std::cerr << "could not find shell interpreter for executing a command" + << std::endl; + return 1; + } if (!Shrink(target_env, fuzzer_options, validator_options, binary_in, initial_facts, shrink_transformations_file, shrink_temp_file_prefix, interestingness_test, &binary_out, diff --git a/tools/io.h b/tools/io.h index a48e3c32..9dc834ed 100644 --- a/tools/io.h +++ b/tools/io.h @@ -127,7 +127,7 @@ class OutputFile { public: // Opens |filename| in the given mode. If |filename| is nullptr, the empty // string or "-", stdout will be set to the given mode. - OutputFile(const char* filename, const char* mode) : old_mode_(0) { + OutputFile(const char* filename, const char* mode) { const bool use_stdout = !filename || (filename[0] == '-' && filename[1] == '\0'); if (use_stdout) { @@ -144,7 +144,6 @@ class OutputFile { ~OutputFile() { if (fp_ == stdout) { - fflush(stdout); SET_STDOUT_MODE(old_mode_); } else if (fp_ != nullptr) { fclose(fp_); diff --git a/tools/link/linker.cpp b/tools/link/linker.cpp index f3898aab..bdddeb89 100644 --- a/tools/link/linker.cpp +++ b/tools/link/linker.cpp @@ -14,7 +14,6 @@ #include "spirv-tools/linker.hpp" -#include #include #include #include @@ -23,11 +22,10 @@ #include "source/table.h" #include "spirv-tools/libspirv.hpp" #include "tools/io.h" -#include "tools/util/flags.h" namespace { -constexpr auto kDefaultEnvironment = "spv1.6"; +const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; void print_usage(const char* program) { std::string target_env_list = spvTargetEnvList(16, 80); @@ -59,13 +57,6 @@ Options (in lexicographical order): NOTE: The SPIR-V version used by the linked binary module depends only on the version of the inputs, and is not affected by this option. - --use-highest-version - Upgrade the output SPIR-V version to the highest of the input - files, instead of requiring all of them to have the same - version. - NOTE: If one of the older input files uses an instruction that - is deprecated in the highest SPIR-V version, the output will - be invalid. --verify-ids Verify that IDs in the resulting modules are truly unique. --version @@ -76,59 +67,64 @@ Options (in lexicographical order): } // namespace -// clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( verify_ids, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( create_library, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( allow_partial_linkage, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_string(o, /* default_value= */ "", /* required= */ false); -FLAG_LONG_string( target_env, /* default_value= */ kDefaultEnvironment, /* required= */ false); -FLAG_LONG_bool( use_highest_version, /* default_value= */ false, /* required= */ false); -// clang-format on - -int main(int, const char* argv[]) { - if (!flags::Parse(argv)) { - return 1; - } - - if (flags::h.value() || flags::help.value()) { - print_usage(argv[0]); - return 0; - } - - if (flags::version.value()) { - spv_target_env target_env; - bool success = spvParseTargetEnv(kDefaultEnvironment, &target_env); - assert(success && "Default environment should always parse."); - if (!success) { - fprintf(stderr, - "error: invalid default target environment. Please report this " - "issue."); - return 1; - } - printf("%s\n", spvSoftwareVersionDetailsString()); - printf("Target: %s\n", spvTargetEnvDescription(target_env)); - return 0; - } - - spv_target_env target_env; - if (!spvParseTargetEnv(flags::target_env.value().c_str(), &target_env)) { - fprintf(stderr, "error: Unrecognized target env: %s\n", - flags::target_env.value().c_str()); - return 1; - } - - const std::string outFile = - flags::o.value().empty() ? "out.spv" : flags::o.value(); - const std::vector& inFiles = flags::positional_arguments; - +int main(int argc, char** argv) { + std::vector inFiles; + const char* outFile = nullptr; + spv_target_env target_env = kDefaultEnvironment; spvtools::LinkerOptions options; - options.SetAllowPartialLinkage(flags::allow_partial_linkage.value()); - options.SetCreateLibrary(flags::create_library.value()); - options.SetVerifyIds(flags::verify_ids.value()); - options.SetUseHighestVersion(flags::use_highest_version.value()); + + for (int argi = 1; argi < argc; ++argi) { + const char* cur_arg = argv[argi]; + if ('-' == cur_arg[0]) { + if (0 == strcmp(cur_arg, "-o")) { + if (argi + 1 < argc) { + if (!outFile) { + outFile = argv[++argi]; + } else { + fprintf(stderr, "error: More than one output file specified\n"); + return 1; + } + } else { + fprintf(stderr, "error: Missing argument to %s\n", cur_arg); + return 1; + } + } else if (0 == strcmp(cur_arg, "--allow-partial-linkage")) { + options.SetAllowPartialLinkage(true); + } else if (0 == strcmp(cur_arg, "--create-library")) { + options.SetCreateLibrary(true); + } else if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) { + print_usage(argv[0]); + return 0; + } else if (0 == strcmp(cur_arg, "--target-env")) { + if (argi + 1 < argc) { + const auto env_str = argv[++argi]; + if (!spvParseTargetEnv(env_str, &target_env)) { + fprintf(stderr, "error: Unrecognized target env: %s\n", env_str); + return 1; + } + } else { + fprintf(stderr, "error: Missing argument to --target-env\n"); + return 1; + } + } else if (0 == strcmp(cur_arg, "--verify-ids")) { + options.SetVerifyIds(true); + } else if (0 == strcmp(cur_arg, "--version")) { + printf("%s\n", spvSoftwareVersionDetailsString()); + printf("Target: %s\n", spvTargetEnvDescription(target_env)); + return 0; + } else { + fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]); + print_usage(argv[0]); + return 1; + } + } else { + inFiles.push_back(cur_arg); + } + } + + if (!outFile) { + outFile = "out.spv"; + } if (inFiles.empty()) { fprintf(stderr, "error: No input file specified\n"); @@ -137,7 +133,7 @@ int main(int, const char* argv[]) { std::vector> contents(inFiles.size()); for (size_t i = 0u; i < inFiles.size(); ++i) { - if (!ReadBinaryFile(inFiles[i].c_str(), &contents[i])) return 1; + if (!ReadBinaryFile(inFiles[i], &contents[i])) return 1; } const spvtools::MessageConsumer consumer = [](spv_message_level_t level, @@ -169,7 +165,7 @@ int main(int, const char* argv[]) { spv_result_t status = Link(context, contents, &linkingResult, options); if (status != SPV_SUCCESS && status != SPV_WARNING) return 1; - if (!WriteFile(outFile.c_str(), "wb", linkingResult.data(), + if (!WriteFile(outFile, "wb", linkingResult.data(), linkingResult.size())) return 1; diff --git a/tools/lint/lint.cpp b/tools/lint/lint.cpp index 00c6cd20..d37df830 100644 --- a/tools/lint/lint.cpp +++ b/tools/lint/lint.cpp @@ -18,57 +18,58 @@ #include "spirv-tools/linter.hpp" #include "tools/io.h" #include "tools/util/cli_consumer.h" -#include "tools/util/flags.h" + +const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; namespace { +// Status and actions to perform after parsing command-line arguments. +enum LintActions { LINT_CONTINUE, LINT_STOP }; -constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; -constexpr auto kHelpTextFmt = - R"(%s - Lint a SPIR-V binary module. +struct LintStatus { + LintActions action; + int code; +}; -Usage: %s [options] +// Parses command-line flags. |argc| contains the number of command-line flags. +// |argv| points to an array of strings holding the flags. +// +// On return, this function stores the name of the input program in |in_file|. +// The return value indicates whether optimization should continue and a status +// code indicating an error or success. +LintStatus ParseFlags(int argc, const char** argv, const char** in_file) { + // TODO (dongja): actually parse flags, etc. + if (argc != 2) { + spvtools::Error(spvtools::utils::CLIMessageConsumer, nullptr, {}, + "expected exactly one argument: in_file"); + return {LINT_STOP, 1}; + } -Options: - - -h, --help Print this help. - --version Display assembler version information. -)"; + *in_file = argv[1]; + return {LINT_CONTINUE, 0}; +} } // namespace -// clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -// clang-format on +int main(int argc, const char** argv) { + const char* in_file = nullptr; -int main(int, const char** argv) { - if (!flags::Parse(argv)) { - return 1; - } + spv_target_env target_env = kDefaultEnvironment; - if (flags::h.value() || flags::help.value()) { - printf(kHelpTextFmt, argv[0], argv[0]); - return 0; - } - - if (flags::version.value()) { - printf("%s\n", spvSoftwareVersionDetailsString()); - return 0; - } - - if (flags::positional_arguments.size() != 1) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, nullptr, {}, - "expected exactly one input file."); - return 1; - } - - spvtools::Linter linter(kDefaultEnvironment); + spvtools::Linter linter(target_env); linter.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); + + LintStatus status = ParseFlags(argc, argv, &in_file); + + if (status.action == LINT_STOP) { + return status.code; + } + std::vector binary; - if (!ReadBinaryFile(flags::positional_arguments[0].c_str(), &binary)) { + if (!ReadBinaryFile(in_file, &binary)) { return 1; } - return linter.Run(binary.data(), binary.size()) ? 0 : 1; + bool ok = linter.Run(binary.data(), binary.size()); + + return ok ? 0 : 1; } diff --git a/tools/objdump/extract_source.cpp b/tools/objdump/extract_source.cpp deleted file mode 100755 index 02959525..00000000 --- a/tools/objdump/extract_source.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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 "extract_source.h" - -#include -#include -#include -#include - -#include "source/opt/log.h" -#include "spirv-tools/libspirv.hpp" -#include "spirv/unified1/spirv.hpp" -#include "tools/util/cli_consumer.h" - -namespace { - -constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6; - -// Extract a string literal from a given range. -// Copies all the characters from `begin` to the first '\0' it encounters, while -// removing escape patterns. -// Not finding a '\0' before reaching `end` fails the extraction. -// -// Returns `true` if the extraction succeeded. -// `output` value is undefined if false is returned. -spv_result_t ExtractStringLiteral(const spv_position_t& loc, const char* begin, - const char* end, std::string* output) { - size_t sourceLength = std::distance(begin, end); - std::string escapedString; - escapedString.resize(sourceLength); - - size_t writeIndex = 0; - size_t readIndex = 0; - for (; readIndex < sourceLength; writeIndex++, readIndex++) { - const char read = begin[readIndex]; - if (read == '\0') { - escapedString.resize(writeIndex); - output->append(escapedString); - return SPV_SUCCESS; - } - - if (read == '\\') { - ++readIndex; - } - escapedString[writeIndex] = begin[readIndex]; - } - - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", loc, - "Missing NULL terminator for literal string."); - return SPV_ERROR_INVALID_BINARY; -} - -spv_result_t extractOpString(const spv_position_t& loc, - const spv_parsed_instruction_t& instruction, - std::string* output) { - assert(output != nullptr); - assert(instruction.opcode == spv::Op::OpString); - if (instruction.num_operands != 2) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", loc, - "Missing operands for OpString."); - return SPV_ERROR_INVALID_BINARY; - } - - const auto& operand = instruction.operands[1]; - const char* stringBegin = - reinterpret_cast(instruction.words + operand.offset); - const char* stringEnd = reinterpret_cast( - instruction.words + operand.offset + operand.num_words); - return ExtractStringLiteral(loc, stringBegin, stringEnd, output); -} - -spv_result_t extractOpSourceContinued( - const spv_position_t& loc, const spv_parsed_instruction_t& instruction, - std::string* output) { - assert(output != nullptr); - assert(instruction.opcode == spv::Op::OpSourceContinued); - if (instruction.num_operands != 1) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", loc, - "Missing operands for OpSourceContinued."); - return SPV_ERROR_INVALID_BINARY; - } - - const auto& operand = instruction.operands[0]; - const char* stringBegin = - reinterpret_cast(instruction.words + operand.offset); - const char* stringEnd = reinterpret_cast( - instruction.words + operand.offset + operand.num_words); - return ExtractStringLiteral(loc, stringBegin, stringEnd, output); -} - -spv_result_t extractOpSource(const spv_position_t& loc, - const spv_parsed_instruction_t& instruction, - spv::Id* filename, std::string* code) { - assert(filename != nullptr && code != nullptr); - assert(instruction.opcode == spv::Op::OpSource); - // OpCode [ Source Language | Version | File (optional) | Source (optional) ] - if (instruction.num_words < 3) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", loc, - "Missing operands for OpSource."); - return SPV_ERROR_INVALID_BINARY; - } - - *filename = 0; - *code = ""; - if (instruction.num_words < 4) { - return SPV_SUCCESS; - } - *filename = instruction.words[3]; - - if (instruction.num_words < 5) { - return SPV_SUCCESS; - } - - const char* stringBegin = - reinterpret_cast(instruction.words + 4); - const char* stringEnd = - reinterpret_cast(instruction.words + instruction.num_words); - return ExtractStringLiteral(loc, stringBegin, stringEnd, code); -} - -} // namespace - -bool ExtractSourceFromModule( - const std::vector& binary, - std::unordered_map* output) { - auto context = spvtools::SpirvTools(kDefaultEnvironment); - context.SetMessageConsumer(spvtools::utils::CLIMessageConsumer); - - // There is nothing valuable in the header. - spvtools::HeaderParser headerParser = [](const spv_endianness_t, - const spv_parsed_header_t&) { - return SPV_SUCCESS; - }; - - std::unordered_map stringMap; - std::vector> sources; - spv::Op lastOpcode = spv::Op::OpMax; - size_t instructionIndex = 0; - - spvtools::InstructionParser instructionParser = - [&stringMap, &sources, &lastOpcode, - &instructionIndex](const spv_parsed_instruction_t& instruction) { - const spv_position_t loc = {0, 0, instructionIndex + 1}; - spv_result_t result = SPV_SUCCESS; - - if (instruction.opcode == spv::Op::OpString) { - std::string content; - result = extractOpString(loc, instruction, &content); - if (result == SPV_SUCCESS) { - stringMap.emplace(instruction.result_id, std::move(content)); - } - } else if (instruction.opcode == spv::Op::OpSource) { - spv::Id filenameId; - std::string code; - result = extractOpSource(loc, instruction, &filenameId, &code); - if (result == SPV_SUCCESS) { - sources.emplace_back(std::make_pair(filenameId, std::move(code))); - } - } else if (instruction.opcode == spv::Op::OpSourceContinued) { - if (lastOpcode != spv::Op::OpSource) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", loc, - "OpSourceContinued MUST follow an OpSource."); - return SPV_ERROR_INVALID_BINARY; - } - - assert(sources.size() > 0); - result = extractOpSourceContinued(loc, instruction, - &sources.back().second); - } - - ++instructionIndex; - lastOpcode = static_cast(instruction.opcode); - return result; - }; - - if (!context.Parse(binary, headerParser, instructionParser)) { - return false; - } - - std::string defaultName = "unnamed-"; - size_t unnamedCount = 0; - for (auto & [ id, code ] : sources) { - std::string filename; - const auto it = stringMap.find(id); - if (it == stringMap.cend() || it->second.empty()) { - filename = "unnamed-" + std::to_string(unnamedCount) + ".hlsl"; - ++unnamedCount; - } else { - filename = it->second; - } - - if (output->count(filename) != 0) { - spvtools::Error(spvtools::utils::CLIMessageConsumer, "", {}, - "Source file name conflict."); - return false; - } - output->insert({filename, code}); - } - - return true; -} diff --git a/tools/objdump/extract_source.h b/tools/objdump/extract_source.h deleted file mode 100755 index 3e5ecfa9..00000000 --- a/tools/objdump/extract_source.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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. - -#ifndef INCLUDE_SPIRV_TOOLS_EXTRACT_SOURCE_HPP_ -#define INCLUDE_SPIRV_TOOLS_EXTRACT_SOURCE_HPP_ - -#include -#include -#include -#include - -// Parse a SPIR-V module, and extracts all HLSL source code from it. -// This function doesn't lift the SPIR-V code, but only relies on debug symbols. -// This means if the compiler didn't include some files, they won't show up. -// -// Returns a map of extracted from it. -// - `binary`: a vector containing the whole SPIR-V binary to extract source -// from. -// - `output`: mapping, mapping each filename -// (if defined) to its code. -// -// Returns `true` if the extraction succeeded, `false` otherwise. -// `output` value is undefined if `false` is returned. -bool ExtractSourceFromModule( - const std::vector& binary, - std::unordered_map* output); - -#endif // INCLUDE_SPIRV_TOOLS_EXTRACT_SOURCE_HPP_ diff --git a/tools/objdump/objdump.cpp b/tools/objdump/objdump.cpp deleted file mode 100755 index 79181b0a..00000000 --- a/tools/objdump/objdump.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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 "extract_source.h" -#include "source/opt/log.h" -#include "tools/io.h" -#include "tools/util/cli_consumer.h" -#include "tools/util/flags.h" - -namespace { - -constexpr auto kHelpTextFmt = - R"(%s - Dumps information from a SPIR-V binary. - -Usage: %s [options] - -one of the following switches must be given: - --source Extract source files obtained from debug symbols, output to stdout. - --entrypoint Extracts the entrypoint name of the module, output to stdout. - --compiler-cmd Extracts the command line used to compile this module, output to stdout. - - -General options: - -h, --help Print this help. - --version Display assembler version information. - -f,--force Allow output file overwrite. - -Source dump options: - --list Do not extract source code, only print filenames to stdout. - --outdir Where shall the exrtacted HLSL/HLSL files be written to? - File written to stdout if '-' is given. Default is `-`. -)"; - -// Removes trailing '/' from `input`. -// A behavior difference has been observed between libc++ implementations. -// Fixing path to prevent this edge case to be reached. -// (https://github.com/llvm/llvm-project/issues/60634) -std::string fixPathForLLVM(std::string input) { - while (!input.empty() && input.back() == '/') input.resize(input.size() - 1); - return input; -} - -// Write each HLSL file described in `sources` in a file in `outdirPath`. -// Doesn't ovewrite existing files, unless `overwrite` is set to true. The -// created HLSL file's filename is the path's filename obtained from `sources`. -// Returns true if all files could be written. False otherwise. -bool OutputSourceFiles( - const std::unordered_map& sources, - const std::string& outdirPath, bool overwrite) { - std::filesystem::path outdir(fixPathForLLVM(outdirPath)); - if (!std::filesystem::is_directory(outdir)) { - if (!std::filesystem::create_directories(outdir)) { - std::cerr << "error: could not create output directory " << outdir - << std::endl; - return false; - } - } - - for (const auto & [ filepath, code ] : sources) { - if (code.empty()) { - std::cout << "Ignoring source for " << filepath - << ": no code source in debug infos." << std::endl; - continue; - } - - std::filesystem::path old_path(filepath); - std::filesystem::path new_path = outdir / old_path.filename(); - - if (!overwrite && std::filesystem::exists(new_path)) { - std::cerr << "file " << filepath - << " already exists, aborting (use --overwrite to allow it)." - << std::endl; - return false; - } - - std::cout << "Exporting " << new_path << std::endl; - if (!WriteFile(new_path.string().c_str(), "w", code.c_str(), - code.size())) { - return false; - } - } - return true; -} - -} // namespace - -// clang-format off -FLAG_SHORT_bool( h, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( help, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( version, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( source, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( entrypoint, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( compiler_cmd, /* default_value= */ false, /* required= */ false); -FLAG_SHORT_bool( f, /* default_value= */ false, /* required= */ false); -FLAG_LONG_bool( force, /* default_value= */ false, /* required= */ false); -FLAG_LONG_string( outdir, /* default_value= */ "-", /* required= */ false); -FLAG_LONG_bool( list, /* default_value= */ false, /* required= */ false); -// clang-format on - -int main(int, const char** argv) { - if (!flags::Parse(argv)) { - return 1; - } - if (flags::h.value() || flags::help.value()) { - printf(kHelpTextFmt, argv[0], argv[0]); - return 0; - } - if (flags::version.value()) { - printf("%s\n", spvSoftwareVersionDetailsString()); - return 0; - } - - if (flags::positional_arguments.size() != 1) { - std::cerr << "Expected exactly one input file." << std::endl; - return 1; - } - if (flags::entrypoint.value() || flags::compiler_cmd.value()) { - std::cerr << "Unimplemented flags." << std::endl; - return 1; - } - - std::vector binary; - if (!ReadBinaryFile(flags::positional_arguments[0].c_str(), &binary)) { - return 1; - } - - if (flags::source.value()) { - std::unordered_map sourceCode; - if (!ExtractSourceFromModule(binary, &sourceCode)) { - return 1; - } - - if (flags::list.value()) { - for (const auto & [ filename, source ] : sourceCode) { - printf("%s\n", filename.c_str()); - } - return 0; - } - - const bool outputToConsole = flags::outdir.value() == "-"; - - if (outputToConsole) { - for (const auto & [ filename, source ] : sourceCode) { - std::cout << filename << ":" << std::endl - << source << std::endl - << std::endl; - } - return 0; - } - - const std::filesystem::path outdirPath(flags::outdir.value()); - if (!OutputSourceFiles(sourceCode, outdirPath.string(), - flags::force.value())) { - return 1; - } - } - - // FIXME: implement logic. - return 0; -} diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 3dfa021f..ce2103ca 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -496,10 +496,6 @@ Options (in lexicographical order):)", covers reflection information defined by SPV_GOOGLE_hlsl_functionality1 and SPV_KHR_non_semantic_info)"); printf(R"( - --switch-descriptorset=: - Switch any DescriptoSet decorations using the value to - the new value .)"); - printf(R"( --target-env= Set the target environment. Without this flag the target environment defaults to spv1.5. must be one of diff --git a/tools/reduce/reduce.cpp b/tools/reduce/reduce.cpp index 959f5a2f..37600543 100644 --- a/tools/reduce/reduce.cpp +++ b/tools/reduce/reduce.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -30,6 +29,12 @@ namespace { +// Check that the std::system function can actually be used. +bool CheckExecuteCommand() { + int res = std::system(nullptr); + return res != 0; +} + // Execute a command using the shell. // Returns true if and only if the command's exit status was 0. bool ExecuteCommand(const std::string& command) { @@ -277,6 +282,12 @@ int main(int argc, const char** argv) { return status.code; } + if (!CheckExecuteCommand()) { + std::cerr << "could not find shell interpreter for executing a command" + << std::endl; + return 2; + } + spvtools::reduce::Reducer reducer(target_env); std::stringstream joined; diff --git a/tools/sva/.eslintrc.json b/tools/sva/.eslintrc.json old mode 100755 new mode 100644 diff --git a/tools/sva/.gitignore b/tools/sva/.gitignore old mode 100755 new mode 100644 diff --git a/tools/sva/package.json b/tools/sva/package.json index 15feacae..3072d4cc 100644 --- a/tools/sva/package.json +++ b/tools/sva/package.json @@ -15,11 +15,11 @@ "bundle": "rollup -c" }, "devDependencies": { - "chai": "^4.3.7", - "eslint": "^8.41.0", + "chai": "^4.2.0", + "eslint": "^6.3.0", "esm": "^3.2.25", - "mocha": "^10.2.0", - "rollup": "^3.23.0", - "serve": "^14.2.0" + "mocha": "^6.2.0", + "rollup": "^1.21.4", + "serve": "^11.1.0" } } diff --git a/tools/sva/yarn.lock b/tools/sva/yarn.lock index eed94ced..e7b735e0 100644 --- a/tools/sva/yarn.lock +++ b/tools/sva/yarn.lock @@ -2,206 +2,158 @@ # yarn lockfile v1 -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== +"@babel/code-frame@^7.0.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== dependencies: - eslint-visitor-keys "^3.3.0" + "@babel/highlight" "^7.0.0" -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" -"@eslint/js@8.41.0": - version "8.41.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.41.0.tgz#080321c3b68253522f7646b55b577dd99d2950b3" - integrity sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA== +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" +"@types/node@^12.7.5": + version "12.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f" + integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w== -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@zeit/schemas@2.29.0": - version "2.29.0" - resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.29.0.tgz#a59ae6ebfdf4ddc66a876872dd736baa58b6696c" - integrity sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA== +"@zeit/schemas@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3" + integrity sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg== accepts@~1.3.5: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" + mime-types "~2.1.24" + negotiator "0.6.2" -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-jsx@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== -acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== -ajv@8.11.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== +ajv@6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9" + integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg== dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-align@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== +ajv@^6.10.0, ajv@^6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: - string-width "^4.1.0" + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= dependencies: - color-convert "^2.0.1" + string-width "^2.0.0" -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" + color-convert "^1.9.0" -arch@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== +arch@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" + integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== -arg@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== +arg@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arg/-/arg-2.0.0.tgz#c06e7ff69ab05b3a4a03ebe0407fac4cba657545" + integrity sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w== -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -boxen@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32" - integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg== +boxen@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== dependencies: - ansi-align "^3.0.1" - camelcase "^7.0.0" - chalk "^5.0.1" - cli-boxes "^3.0.0" - string-width "^5.1.2" - type-fest "^2.13.0" - widest-line "^4.0.1" - wrap-ansi "^8.0.1" + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -211,20 +163,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -233,154 +171,163 @@ browser-stdout@1.3.1: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048" - integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw== +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -chai@^4.3.7: - version "4.3.7" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" - integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== dependencies: assertion-error "^1.1.0" check-error "^1.0.2" - deep-eql "^4.1.2" + deep-eql "^3.0.1" get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" + pathval "^1.1.0" type-detect "^4.0.5" -chalk-template@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b" - integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg== +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: - chalk "^4.1.2" + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" -chalk@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" - integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w== - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" -chalk@^5.0.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" + restore-cursor "^2.0.0" -cli-boxes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" - integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= -clipboardy@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" - integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== +clipboardy@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef" + integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA== dependencies: - arch "^2.2.0" - execa "^5.1.1" - is-wsl "^2.2.0" + arch "^2.1.0" + execa "^0.8.0" -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: - color-name "~1.1.4" + color-name "1.1.3" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== +compressible@~2.0.14: + version "2.0.17" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" + integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw== dependencies: - mime-db ">= 1.43.0 < 2" + mime-db ">= 1.40.0 < 2" -compression@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== +compression@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" + integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== dependencies: accepts "~1.3.5" bytes "3.0.0" - compressible "~2.0.16" + compressible "~2.0.14" debug "2.6.9" - on-headers "~1.0.2" + on-headers "~1.0.1" safe-buffer "5.1.2" vary "~1.1.2" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" debug@2.6.9: version "2.6.9" @@ -389,22 +336,29 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.1.1, debug@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: - ms "2.1.2" + ms "^2.1.1" -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +debug@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" -deep-eql@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== dependencies: type-detect "^4.0.0" @@ -413,15 +367,22 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== doctrine@^3.0.0: version "3.0.0" @@ -430,254 +391,319 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" + once "^1.4.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@^8.41.0: - version "8.41.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.41.0.tgz#3062ca73363b4714b16dbc1e60f035e6134b6f1c" - integrity sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q== +es-abstract@^1.5.1: + version "1.14.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" + integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg== dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.41.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.0" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.0.0" + string.prototype.trimright "^2.0.0" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" + integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== + dependencies: + eslint-visitor-keys "^1.0.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.3.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a" + integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA== + dependencies: + "@babel/code-frame" "^7.0.0" ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" - esquery "^1.4.2" + eslint-scope "^5.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" + esquery "^1.0.1" esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^11.7.0" + ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" + inquirer "^6.4.1" is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" + js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" + optionator "^0.8.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" text-table "^0.2.0" + v8-compile-cache "^2.0.3" esm@^3.2.25: version "3.2.25" resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== dependencies: - estraverse "^5.1.0" + estraverse "^4.0.0" -esrecurse@^4.3.0: +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= -fast-levenshtein@^2.0.6: +fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-url-parser@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== + integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0= dependencies: punycode "^1.3.2" -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: - reusify "^1.0.4" + escape-string-regexp "^1.0.5" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^3.0.4" + flat-cache "^2.0.1" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: - to-regex-range "^5.0.1" + locate-path "^3.0.0" -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" + is-buffer "~2.0.3" -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-caller-file@^2.0.5: +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" - integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: - is-glob "^4.0.3" + pump "^3.0.0" -glob-parent@~5.1.2: +glob-parent@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -687,53 +713,65 @@ glob@7.2.0: path-is-absolute "^1.0.0" glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.1.1" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== +globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: - type-fest "^0.20.2" - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + function-bind "^1.1.1" he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== +import-fresh@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -741,12 +779,12 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -757,147 +795,193 @@ inherits@2: integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== +inquirer@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: - binary-extensions "^2.0.0" + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +is-buffer@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: +is-promise@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-port-reachable@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-4.0.0.tgz#dac044091ef15319c8ab2f34604d8794181f8c2d" - integrity sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: - is-docker "^2.0.0" + has "^1.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.1, js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== dependencies: - argparse "^2.0.1" + argparse "^1.0.7" + esprima "^4.0.0" json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== - dependencies: - get-func-name "^2.0.0" - -merge-stream@^2.0.0: +lcid@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +"mime-db@>= 1.40.0 < 2": + version "1.41.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0" + integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw== mime-db@~1.33.0: version "1.33.0" @@ -911,150 +995,237 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== +mime-types@~2.1.24: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== dependencies: - mime-db "1.52.0" + mime-db "1.40.0" -mimic-fn@^2.1.0: +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@^1.2.0: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -mocha@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== +mkdirp@0.5.1, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: - ansi-colors "4.1.1" + minimist "0.0.8" + +mocha@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56" + integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ== + dependencies: + ansi-colors "3.2.3" browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" + js-yaml "3.13.1" + log-symbols "2.2.0" + minimatch "3.0.4" + mkdirp "0.5.1" + ms "2.1.1" + node-environment-flags "1.0.5" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.2.2" + yargs-parser "13.0.0" + yargs-unparser "1.5.0" ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.2: +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== +node-environment-flags@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" + integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== dependencies: - path-key "^3.0.0" + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" -on-headers@~1.0.2: +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +on-headers@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: - mimic-fn "^2.1.0" + mimic-fn "^1.0.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" -p-limit@^3.0.2: +os-locale@^3.0.0, os-locale@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - yocto-queue "^0.1.0" + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: - p-limit "^3.0.2" + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== parent-module@^1.0.0: version "1.0.1" @@ -1063,72 +1234,73 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-to-regexp@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== -pathval@^1.1.1: +pathval@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" punycode@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== range-parser@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= rc@^1.0.1, rc@^1.1.6: version "1.2.8" @@ -1140,12 +1312,10 @@ rc@^1.0.1, rc@^1.1.6: minimist "^1.2.0" strip-json-comments "~2.0.1" -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== registry-auth-token@3.3.2: version "3.3.2" @@ -1158,317 +1328,451 @@ registry-auth-token@3.3.2: registry-url@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA== + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= dependencies: rc "^1.0.1" require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" -rollup@^3.23.0: - version "3.23.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.23.0.tgz#b8d6146dac4bf058ee817f92820988e9b358b564" - integrity sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ== - optionalDependencies: - fsevents "~2.3.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== +rollup@^1.21.4: + version "1.21.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.21.4.tgz#00a41a30f90095db890301b226cbe2918e4cf54d" + integrity sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw== dependencies: - queue-microtask "^1.2.2" + "@types/estree" "0.0.39" + "@types/node" "^12.7.5" + acorn "^7.0.0" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +rxjs@^6.4.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== + dependencies: + tslib "^1.9.0" safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@^5.0.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -serve-handler@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.5.tgz#a4a0964f5c55c7e37a02a633232b6f0d6f068375" - integrity sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg== +semver@^5.5.0, semver@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +serve-handler@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.0.tgz#f1606dc6ff8f9029a1ee042c11dfe7903a5cb92e" + integrity sha512-63N075Tn3PsFYcu0NVV7tb367UbiW3gnC+/50ohL4oqOhAG6bmbaWqiRcXQgbzqc0ALBjSAzg7VTfa0Qw4E3hA== dependencies: bytes "3.0.0" content-disposition "0.5.2" fast-url-parser "1.1.3" mime-types "2.1.18" - minimatch "3.1.2" + minimatch "3.0.4" path-is-inside "1.0.2" path-to-regexp "2.2.1" range-parser "1.2.0" -serve@^14.2.0: - version "14.2.0" - resolved "https://registry.yarnpkg.com/serve/-/serve-14.2.0.tgz#3d768e88fa13ad8644f2393599189707176e66b8" - integrity sha512-+HOw/XK1bW8tw5iBilBz/mJLWRzM8XM6MPxL4J/dKzdxq1vfdEWSwhaR7/yS8EJp5wzvP92p1qirysJvnEtjXg== +serve@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/serve/-/serve-11.1.0.tgz#1bfe2f4a08d0130cbf44711cdb7996cb742172e0" + integrity sha512-+4wpDtOSS+4ZLyDWMxThutA3iOTawX2+yDovOI8cjOUOmemyvNlHyFAsezBlSgbZKTYChI3tzA1Mh0z6XZ62qA== dependencies: - "@zeit/schemas" "2.29.0" - ajv "8.11.0" - arg "5.0.2" - boxen "7.0.0" - chalk "5.0.1" - chalk-template "0.4.0" - clipboardy "3.0.0" - compression "1.7.4" - is-port-reachable "4.0.0" - serve-handler "6.1.5" - update-check "1.5.4" + "@zeit/schemas" "2.6.0" + ajv "6.5.3" + arg "2.0.0" + boxen "1.3.0" + chalk "2.4.1" + clipboardy "1.2.3" + compression "1.7.3" + serve-handler "6.1.0" + update-check "1.5.2" -shebang-command@^2.0.0: +set-blocking@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: - shebang-regex "^3.0.0" + shebang-regex "^1.0.0" -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: - ansi-regex "^5.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== dependencies: - ansi-regex "^6.0.1" + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +string.prototype.trimleft@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +string.prototype.trimright@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" -strip-json-comments@~2.0.1: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== dependencies: - has-flag "^4.0.0" + has-flag "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: - prelude-ls "^1.2.1" + os-tmpdir "~1.0.2" + +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^2.13.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - -update-check@1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.4.tgz#5b508e259558f1ad7dbc8b4b0457d4c9d28c8743" - integrity sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ== +update-check@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.2.tgz#2fe09f725c543440b3d7dabe8971f2d5caaedc28" + integrity sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ== dependencies: registry-auth-token "3.3.2" registry-url "3.1.0" uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1.3.1, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -widest-line@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" - integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: - string-width "^5.0.1" + string-width "^1.0.2 || 2" -word-wrap@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + string-width "^2.1.1" -wrap-ansi@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" + string-width "^1.0.1" + strip-ansi "^3.0.1" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" + mkdirp "^0.5.1" -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yargs-parser@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" + integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^13.0.0: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" + integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== + dependencies: + flat "^4.1.0" + lodash "^4.17.11" + yargs "^12.0.5" + +yargs@13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" + integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== + dependencies: + cliui "^4.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.0.0" -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" diff --git a/tools/util/flags.cpp b/tools/util/flags.cpp deleted file mode 100755 index 11b89671..00000000 --- a/tools/util/flags.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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 "flags.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace flags { - -std::vector positional_arguments; - -namespace { - -using token_t = const char*; -using token_iterator_t = token_t*; - -// Extracts the flag name from a potential token. -// This function only looks for a '=', to split the flag name from the value for -// long-form flags. Returns the name of the flag, prefixed with the hyphen(s). -inline std::string get_flag_name(const std::string& flag, bool is_short_flag) { - if (is_short_flag) { - return flag; - } - - size_t equal_index = flag.find('='); - if (equal_index == std::string::npos) { - return flag; - } - return flag.substr(0, equal_index); -} - -// Parse a boolean flag. Returns `true` if the parsing succeeded, `false` -// otherwise. -bool parse_bool_flag(Flag& flag, bool is_short_flag, - const std::string& token) { - if (is_short_flag) { - flag.value() = true; - return true; - } - - const std::string raw_flag(token); - size_t equal_index = raw_flag.find('='); - if (equal_index == std::string::npos) { - flag.value() = true; - return true; - } - - const std::string value = raw_flag.substr(equal_index + 1); - if (value == "true") { - flag.value() = true; - return true; - } - - if (value == "false") { - flag.value() = false; - return true; - } - - return false; -} - -// Parse a uint32_t flag value. -bool parse_flag_value(Flag& flag, const std::string& value) { - std::regex unsigned_pattern("^ *[0-9]+ *$"); - if (!std::regex_match(value, unsigned_pattern)) { - std::cerr << "'" << value << "' is not a unsigned number." << std::endl; - return false; - } - - errno = 0; - char* end_ptr = nullptr; - const uint64_t number = strtoull(value.c_str(), &end_ptr, 10); - if (end_ptr == nullptr || end_ptr != value.c_str() + value.size() || - errno == EINVAL) { - std::cerr << "'" << value << "' is not a unsigned number." << std::endl; - return false; - } - - if (errno == ERANGE || number > static_cast(UINT32_MAX)) { - std::cerr << "'" << value << "' cannot be represented as a 32bit unsigned." - << std::endl; - return false; - } - - flag.value() = static_cast(number); - return true; -} - -// "Parse" a string flag value (assigns it, cannot fail). -bool parse_flag_value(Flag& flag, const std::string& value) { - flag.value() = value; - return true; -} - -// Parse a potential multi-token flag. Moves the iterator to the last flag's -// token if it's a multi-token flag. Returns `true` if the parsing succeeded. -// The iterator is moved to the last parsed token. -template -bool parse_flag(Flag& flag, bool is_short_flag, const char*** iterator) { - const std::string raw_flag(**iterator); - std::string raw_value; - const size_t equal_index = raw_flag.find('='); - - if (is_short_flag || equal_index == std::string::npos) { - if ((*iterator)[1] == nullptr) { - return false; - } - - // This is a bi-token flag. Moving iterator to the last parsed token. - raw_value = (*iterator)[1]; - *iterator += 1; - } else { - // This is a mono-token flag, no need to move the iterator. - raw_value = raw_flag.substr(equal_index + 1); - } - - return parse_flag_value(flag, raw_value); -} - -} // namespace - -// This is the function to expand if you want to support a new type. -bool FlagList::parse_flag_info(FlagInfo& info, token_iterator_t* iterator) { - bool success = false; - - std::visit( - [&](auto&& item) { - using T = std::decay_t; - if constexpr (std::is_same_v>) { - success = parse_bool_flag(item.get(), info.is_short, **iterator); - } else if constexpr (std::is_same_v>) { - success = parse_flag(item.get(), info.is_short, iterator); - } else if constexpr (std::is_same_v>) { - success = parse_flag(item.get(), info.is_short, iterator); - } else { - static_assert(always_false_v, "Unsupported flag type."); - } - }, - info.flag); - - return success; -} - -bool FlagList::parse(token_t* argv) { - flags::positional_arguments.clear(); - std::unordered_set parsed_flags; - - bool ignore_flags = false; - for (const char** it = argv + 1; *it != nullptr; it++) { - if (ignore_flags) { - flags::positional_arguments.emplace_back(*it); - continue; - } - - // '--' alone is used to mark the end of the flags. - if (std::strcmp(*it, "--") == 0) { - ignore_flags = true; - continue; - } - - // '-' alone is not a flag, but often used to say 'stdin'. - if (std::strcmp(*it, "-") == 0) { - flags::positional_arguments.emplace_back(*it); - continue; - } - - const std::string raw_flag(*it); - if (raw_flag.size() == 0) { - continue; - } - - if (raw_flag[0] != '-') { - flags::positional_arguments.emplace_back(*it); - continue; - } - - // Only case left: flags (long and shorts). - if (raw_flag.size() < 2) { - std::cerr << "Unknown flag " << raw_flag << std::endl; - return false; - } - const bool is_short_flag = std::strncmp(*it, "--", 2) != 0; - const std::string flag_name = get_flag_name(raw_flag, is_short_flag); - - auto needle = std::find_if( - get_flags().begin(), get_flags().end(), - [&flag_name](const auto& item) { return item.name == flag_name; }); - if (needle == get_flags().end()) { - std::cerr << "Unknown flag " << flag_name << std::endl; - return false; - } - - if (parsed_flags.count(&*needle) != 0) { - std::cerr << "The flag " << flag_name << " was specified multiple times." - << std::endl; - return false; - } - parsed_flags.insert(&*needle); - - if (!parse_flag_info(*needle, &it)) { - std::cerr << "Invalid usage for flag " << flag_name << std::endl; - return false; - } - } - - // Check that we parsed all required flags. - for (const auto& flag : get_flags()) { - if (!flag.required) { - continue; - } - - if (parsed_flags.count(&flag) == 0) { - std::cerr << "Missing required flag " << flag.name << std::endl; - return false; - } - } - - return true; -} - -// Just the public wrapper around the parse function. -bool Parse(const char** argv) { return FlagList::parse(argv); } - -} // namespace flags diff --git a/tools/util/flags.h b/tools/util/flags.h deleted file mode 100755 index 20bb3693..00000000 --- a/tools/util/flags.h +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) 2023 Google LLC. -// -// 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. - -#ifndef INCLUDE_SPIRV_TOOLS_UTIL_FLAGS_HPP_ -#define INCLUDE_SPIRV_TOOLS_UTIL_FLAGS_HPP_ - -#include - -#include -#include -#include -#include - -// This file provides some utils to define a command-line interface with -// required and optional flags. -// - Flag order is not checked. -// - Currently supported flag types: BOOLEAN, STRING -// - As with most nix tools, using '--' in the command-line means all following -// tokens will be considered positional -// arguments. -// Example: binary -g -- -g --some-other-flag -// - the first `-g` is a flag. -// - the second `-g` is not a flag. -// - `--some-other-flag` is not a flag. -// - Both long-form and short-form flags are supported, but boolean flags don't -// support split boolean literals (short and long form). -// Example: -// -g : allowed, sets g to true. -// --my-flag : allowed, sets --my-flag to true. -// --my-flag=true : allowed, sets --my-flag to true. -// --my-flag true : NOT allowed. -// -g true : NOT allowed. -// --my-flag=TRUE : NOT allowed. -// -// - This implementation also supports string flags: -// -o myfile.spv : allowed, sets -o to `myfile.spv`. -// --output=myfile.spv : allowed, sets --output to `myfile.spv`. -// --output myfile.spv : allowd, sets --output to `myfile.spv`. -// -// Note: then second token is NOT checked for hyphens. -// --output -file.spv -// flag name: `output` -// flag value: `-file.spv` -// -// - This implementation generates flag at compile time. Meaning flag names -// must be valid C++ identifiers. -// However, flags are usually using hyphens for word separation. Hence -// renaming is done behind the scenes. Example: -// // Declaring a long-form flag. -// FLAG_LONG_bool(my_flag, [...]) -// -// -> in the code: flags::my_flag.value() -// -> command-line: --my-flag -// -// - The only additional lexing done is around '='. Otherwise token list is -// processed as received in the Parse() -// function. -// Lexing the '=' sign: -// - This is only done when parsing a long-form flag name. -// - the first '=' found is considered a marker for long-form, splitting -// the token into 2. -// Example: --option=value=abc -> [--option, value=abc] -// -// In most cases, you want to define some flags, parse them, and query them. -// Here is a small code sample: -// -// ```c -// // Defines a '-h' boolean flag for help printing, optional. -// FLAG_SHORT_bool(h, /*default=*/ false, "Print the help.", false); -// // Defines a '--my-flag' string flag, required. -// FLAG_LONG_string(my_flag, /*default=*/ "", "A magic flag!", true); -// -// int main(int argc, const char** argv) { -// if (!flags::Parse(argv)) { -// return -1; -// } -// -// if (flags::h.value()) { -// printf("usage: my-bin --my-flag=\n"); -// return 0; -// } -// -// printf("flag value: %s\n", flags::my_flag.value().c_str()); -// for (const std::string& arg : flags::positional_arguments) { -// printf("arg: %s\n", arg.c_str()); -// } -// return 0; -// } -// ```c - -// Those macros can be used to define flags. -// - They should be used in the global scope. -// - Underscores in the flag variable name are replaced with hyphens ('-'). -// -// Example: -// FLAG_SHORT_bool(my_flag, false, "some help", false); -// - in the code: flags::my_flag -// - command line: --my-flag=true -// -#define FLAG_LONG_string(Name, Default, Required) \ - UTIL_FLAGS_FLAG_LONG(std::string, Name, Default, Required) -#define FLAG_LONG_bool(Name, Default, Required) \ - UTIL_FLAGS_FLAG_LONG(bool, Name, Default, Required) -#define FLAG_LONG_uint(Name, Default, Required) \ - UTIL_FLAGS_FLAG_LONG(uint32_t, Name, Default, Required) - -#define FLAG_SHORT_string(Name, Default, Required) \ - UTIL_FLAGS_FLAG_SHORT(std::string, Name, Default, Required) -#define FLAG_SHORT_bool(Name, Default, Required) \ - UTIL_FLAGS_FLAG_SHORT(bool, Name, Default, Required) -#define FLAG_SHORT_uint(Name, Default, Required) \ - UTIL_FLAGS_FLAG_SHORT(uint32_t, Name, Default, Required) - -namespace flags { - -// Parse the command-line arguments, checking flags, and separating positional -// arguments from flags. -// -// * argv: the argv array received in the main function. This utility expects -// the last pointer to -// be NULL, as it should if coming from the main() function. -// -// Returns `true` if the parsing succeeds, `false` otherwise. -bool Parse(const char** argv); - -} // namespace flags - -// ===================== BEGIN NON-PUBLIC SECTION ============================= -// All the code below belongs to the implementation, and there is no guaranteed -// around the API stability. Please do not use it directly. - -// Defines the static variable holding the flag, allowing access like -// flags::my_flag. -// By creating the FlagRegistration object, the flag can be added to -// the global list. -// The final `extern` definition is ONLY useful for clang-format: -// - if the macro doesn't ends with a semicolon, clang-format goes wild. -// - cannot disable clang-format for those macros on clang < 16. -// (https://github.com/llvm/llvm-project/issues/54522) -// - cannot allow trailing semi (-Wextra-semi). -#define UTIL_FLAGS_FLAG(Type, Prefix, Name, Default, Required, IsShort) \ - namespace flags { \ - Flag Name(Default); \ - namespace { \ - static FlagRegistration Name##_registration(Name, Prefix #Name, Required, \ - IsShort); \ - } \ - } \ - extern flags::Flag flags::Name - -#define UTIL_FLAGS_FLAG_LONG(Type, Name, Default, Required) \ - UTIL_FLAGS_FLAG(Type, "--", Name, Default, Required, false) -#define UTIL_FLAGS_FLAG_SHORT(Type, Name, Default, Required) \ - UTIL_FLAGS_FLAG(Type, "-", Name, Default, Required, true) - -namespace flags { - -// Just a wrapper around the flag value. -template -struct Flag { - public: - Flag(T&& default_value) : value_(default_value) {} - Flag(Flag&& other) = delete; - Flag(const Flag& other) = delete; - - const T& value() const { return value_; } - T& value() { return value_; } - - private: - T value_; -}; - -// To add support for new flag-types, this needs to be extended, and the visitor -// below. -using FlagType = std::variant>, - std::reference_wrapper>, - std::reference_wrapper>>; - -template -inline constexpr bool always_false_v = false; - -extern std::vector positional_arguments; - -// Static class keeping track of the flags/arguments values. -class FlagList { - struct FlagInfo { - FlagInfo(FlagType&& flag_, std::string&& name_, bool required_, - bool is_short_) - : flag(std::move(flag_)), - name(std::move(name_)), - required(required_), - is_short(is_short_) {} - - FlagType flag; - std::string name; - bool required; - bool is_short; - }; - - public: - template - static void register_flag(Flag& flag, std::string&& name, bool required, - bool is_short) { - get_flags().emplace_back(flag, std::move(name), required, is_short); - } - - static bool parse(const char** argv); - -#ifdef TESTING - // Flags are supposed to be constant for the whole app execution, hence the - // static storage. Gtest doesn't fork before running a test, meaning we have - // to manually clear the context at teardown. - static void reset() { - get_flags().clear(); - positional_arguments.clear(); - } -#endif - - private: - static std::vector& get_flags() { - static std::vector flags; - return flags; - } - - static bool parse_flag_info(FlagInfo& info, const char*** iterator); - static void print_usage(const char* binary_name, - const std::string& usage_format); -}; - -template -struct FlagRegistration { - FlagRegistration(Flag& flag, std::string&& name, bool required, - bool is_short) { - std::string fixed_name = name; - for (auto& c : fixed_name) { - if (c == '_') { - c = '-'; - } - } - - FlagList::register_flag(flag, std::move(fixed_name), required, is_short); - } -}; - -// Explicit deduction guide to avoid `-Wctad-maybe-unsupported`. -template -FlagRegistration(Flag&, std::string&&, bool, bool) -> FlagRegistration; - -} // namespace flags - -#endif // INCLUDE_SPIRV_TOOLS_UTIL_FLAGS_HPP_ diff --git a/utils/check_code_format.sh b/utils/check_code_format.sh index da5e0198..79947402 100755 --- a/utils/check_code_format.sh +++ b/utils/check_code_format.sh @@ -18,7 +18,7 @@ # # This script assumes to be invoked at the project root directory. -BASE_BRANCH=${1:-main} +BASE_BRANCH=${1:-master} FILES_TO_CHECK=$(git diff --name-only ${BASE_BRANCH} | grep -E ".*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$") diff --git a/utils/check_copyright.py b/utils/check_copyright.py index e3e74bc9..aa647af5 100755 --- a/utils/check_copyright.py +++ b/utils/check_copyright.py @@ -41,9 +41,8 @@ AUTHORS = ['The Khronos Group Inc.', 'Alastair F. Donaldson', 'Mostafa Ashraf', 'Shiyu Liu', - 'ZHOU He', - 'Nintendo'] -CURRENT_YEAR = 2023 + 'ZHOU He'] +CURRENT_YEAR = 2022 FIRST_YEAR = 2014 FINAL_YEAR = CURRENT_YEAR + 5 diff --git a/utils/check_symbol_exports.py b/utils/check_symbol_exports.py index e1ca0b78..7795d72b 100755 --- a/utils/check_symbol_exports.py +++ b/utils/check_symbol_exports.py @@ -67,7 +67,7 @@ def check_library(library): # by the protobuf compiler: # - AddDescriptors_spvtoolsfuzz_2eproto() # - InitDefaults_spvtoolsfuzz_2eproto() - symbol_allowlist_pattern = re.compile(r'_Z[0-9]+.*spvtoolsfuzz_2eproto.*') + symbol_allowlist_pattern = re.compile(r'_Z[0-9]+(InitDefaults|AddDescriptors)_spvtoolsfuzz_2eprotov') symbol_is_new_or_delete = re.compile(r'^(_Zna|_Znw|_Zdl|_Zda)') # Compilaion for Arm has various thunks for constructors, destructors, vtables. diff --git a/utils/generate_changelog.py b/utils/generate_changelog.py deleted file mode 100755 index 54db7282..00000000 --- a/utils/generate_changelog.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2023 Google Inc. -# -# 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. - -# Args: -# Updates an output file with changelog from the given CHANGES file and tag. -# - search for first line matching in file -# - search for the next line with a tag -# - writes all the lines in between those 2 tags into - -import errno -import os -import os.path -import re -import subprocess -import logging -import sys - -# Regex to match the SPIR-V version tag. -# Example of matching tags: -# - v2020.1 -# - v2020.1-dev -# - v2020.1.rc1 -VERSION_REGEX = re.compile(r'^(v\d+\.\d+) +[0-9]+-[0-9]+-[0-9]+$') - -def mkdir_p(directory): - """Make the directory, and all its ancestors as required. Any of the - directories are allowed to already exist.""" - - if directory == "": - # We're being asked to make the current directory. - return - - try: - os.makedirs(directory) - except OSError as e: - if e.errno == errno.EEXIST and os.path.isdir(directory): - pass - else: - raise - -def main(): - FORMAT = '%(asctime)s %(message)s' - logging.basicConfig(format="[%(asctime)s][%(levelname)-8s] %(message)s", datefmt="%H:%M:%S") - if len(sys.argv) != 4: - logging.error("usage: {} ".format(sys.argv[0])) - sys.exit(1) - - changes_path = sys.argv[1] - start_tag = sys.argv[2] - output_file_path = sys.argv[3] - - changelog = [] - has_found_start = False - with open(changes_path, "r") as file: - for line in file.readlines(): - m = VERSION_REGEX.match(line) - if m: - print(m.groups()[0]) - print(start_tag) - if has_found_start: - break; - if start_tag == m.groups()[0]: - has_found_start = True - continue - - if has_found_start: - changelog.append(line) - - if not has_found_start: - logging.error("No tag matching {} found.".format(start_tag)) - sys.exit(1) - - content = "".join(changelog) - if os.path.isfile(output_file_path): - with open(output_file_path, 'r') as f: - if content == f.read(): - sys.exit(0) - - mkdir_p(os.path.dirname(output_file_path)) - with open(output_file_path, 'w') as f: - f.write(content) - sys.exit(0) - -if __name__ == '__main__': - main() diff --git a/utils/generate_grammar_tables.py b/utils/generate_grammar_tables.py index e6a14558..74aa2829 100755 --- a/utils/generate_grammar_tables.py +++ b/utils/generate_grammar_tables.py @@ -33,7 +33,6 @@ SPV_AMD_shader_trinary_minmax SPV_KHR_non_semantic_info """ -OUTPUT_LANGUAGE = 'c' def make_path_to_file(f): """Makes all ancestor directories to the given file, if they don't yet @@ -77,14 +76,9 @@ def compose_capability_list(caps): - caps: a sequence of capability names Returns: - a string containing the braced list of SpvCapability* or spv::Capability:: enums named by caps. + a string containing the braced list of SpvCapability* enums named by caps. """ - base_string = 'SpvCapability' - global OUTPUT_LANGUAGE - if OUTPUT_LANGUAGE == 'c++': - base_string = 'spv::Capability::' - - return '{' + ', '.join([(base_string + '{}').format(c) for c in caps]) + '}' + return '{' + ', '.join(['SpvCapability{}'.format(c) for c in caps]) + '}' def get_capability_array_name(caps): @@ -105,12 +99,8 @@ def generate_capability_arrays(caps): - caps: a sequence of sequence of capability names """ caps = sorted(set([tuple(c) for c in caps if c])) - cap_str = 'SpvCapability' - global OUTPUT_LANGUAGE - if OUTPUT_LANGUAGE == 'c++': - cap_str = 'spv::Capability' arrays = [ - 'static const ' + cap_str + ' {}[] = {};'.format( + 'static const SpvCapability {}[] = {};'.format( get_capability_array_name(c), compose_capability_list(c)) for c in caps] return '\n'.join(arrays) @@ -265,12 +255,7 @@ class InstInitializer(object): self.operands.pop() def __str__(self): - global OUTPUT_LANGUAGE - base_str = 'SpvOp' - if OUTPUT_LANGUAGE == 'c++': - base_str = 'spv::Op::Op' - - template = ['{{"{opname}"', base_str + '{opname}', + template = ['{{"{opname}"', 'SpvOp{opname}', '{num_caps}', '{caps_mask}', '{num_operands}', '{{{operands}}}', '{def_result_id}', '{ref_type_id}', @@ -540,7 +525,7 @@ def generate_operand_kind_table(enums): # We have a few operand kinds that require their optional counterpart to # exist in the operand info table. - optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat', 'CooperativeMatrixOperands'] + optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat'] optional_enums = [e for e in enums if e[0] in optional_enums] enums.extend(optional_enums) @@ -649,16 +634,9 @@ def generate_capability_to_string_mapping(operand_kinds): We take care to avoid emitting duplicate values. """ - cap_str = 'SpvCapability' - cap_join = '' - global OUTPUT_LANGUAGE - if OUTPUT_LANGUAGE == 'c++': - cap_str = 'spv::Capability' - cap_join = '::' - - function = 'const char* CapabilityToString(' + cap_str + ' capability) {\n' + function = 'const char* CapabilityToString(SpvCapability capability) {\n' function += ' switch (capability) {\n' - template = ' case ' + cap_str + cap_join + '{capability}:\n' \ + template = ' case SpvCapability{capability}:\n' \ ' return "{capability}";\n' emitted = set() # The values of capabilities we already have emitted for capability in get_capabilities(operand_kinds): @@ -666,8 +644,8 @@ def generate_capability_to_string_mapping(operand_kinds): if value not in emitted: emitted.add(value) function += template.format(capability=capability.get('enumerant')) - function += ' case ' + cap_str + cap_join + 'Max:\n' \ - ' assert(0 && "Attempting to convert ' + cap_str + cap_join + 'Max to string");\n' \ + function += ' case SpvCapabilityMax:\n' \ + ' assert(0 && "Attempting to convert SpvCapabilityMax to string");\n' \ ' return "";\n' function += ' }\n\n return "";\n}' return function @@ -756,10 +734,6 @@ def main(): type=str, required=False, default=None, help='input JSON grammar file for OpenCL extended ' 'instruction set') - parser.add_argument('--output-language', - type=str, required=False, default='c', - choices=['c','c++'], - help='specify output language type') parser.add_argument('--core-insts-output', metavar='', type=str, required=False, default=None, @@ -791,9 +765,6 @@ def main(): help='prefix for operand kinds (to disambiguate operand type enums)') args = parser.parse_args() - global OUTPUT_LANGUAGE - OUTPUT_LANGUAGE = args.output_language - # The GN build system needs this because it doesn't handle quoting # empty string arguments well. if args.vendor_operand_kind_prefix == "...nil...": diff --git a/utils/generate_language_headers.py b/utils/generate_language_headers.py index 18a8d5ea..83fa99e1 100755 --- a/utils/generate_language_headers.py +++ b/utils/generate_language_headers.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright (c) 2017 Google Inc. # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/generate_registry_tables.py b/utils/generate_registry_tables.py index 14d4909f..28152ef3 100755 --- a/utils/generate_registry_tables.py +++ b/utils/generate_registry_tables.py @@ -15,9 +15,8 @@ """Generates the vendor tool table from the SPIR-V XML registry.""" import errno -import io import os.path -from xml.etree.ElementTree import XML, XMLParser, TreeBuilder +import xml.etree.ElementTree def mkdir_p(directory): @@ -79,9 +78,8 @@ def main(): help='output file for SPIR-V generators table') args = parser.parse_args() - with io.open(args.xml, encoding='utf-8') as xml_in: - parser = XMLParser(target=TreeBuilder(), encoding='utf-8') - registry = XML(xml_in.read(), parser=parser) + with open(args.xml) as xml_in: + registry = xml.etree.ElementTree.fromstring(xml_in.read()) mkdir_p(os.path.dirname(args.generator_output)) with open(args.generator_output, 'w') as f: diff --git a/utils/git-sync-deps b/utils/git-sync-deps index 6549afb1..7a7e606f 100755 --- a/utils/git-sync-deps +++ b/utils/git-sync-deps @@ -28,9 +28,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Parse a DEPS file and git checkout all of the dependencies. -""" -EXTRA_HELP = """ +Args: + An optional list of deps_os values. + Environment Variables: GIT_EXECUTABLE: path to "git" binary; if unset, will look for one of ['git', 'git.exe', 'git.bat'] in your default path. @@ -51,7 +52,6 @@ Git Config: """ -import argparse import os import re import subprocess @@ -59,14 +59,12 @@ import sys import threading from builtins import bytes + def git_executable(): """Find the git executable. Returns: - A triple: - A string suitable for passing to subprocess functions, or None. - The major version number - The minor version number + A string suitable for passing to subprocess functions, or None. """ envgit = os.environ.get('GIT_EXECUTABLE') searchlist = ['git', 'git.exe', 'git.bat'] @@ -74,36 +72,30 @@ def git_executable(): searchlist.insert(0, envgit) with open(os.devnull, 'w') as devnull: for git in searchlist: - major=None - minor=None try: - version_info = subprocess.check_output([git, '--version']).decode('utf-8') - match = re.search("^git version (\d+)\.(\d+)",version_info) - print("Using {}".format(version_info)) - if match: - major = int(match.group(1)) - minor = int(match.group(2)) - else: - continue + subprocess.call([git, '--version'], stdout=devnull) except (OSError,): continue - return (git,major,minor) - return (None,0,0) + return git + return None DEFAULT_DEPS_PATH = os.path.normpath( os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS')) -def get_deps_os_str(deps_file): - parsed_deps = parse_file_to_dict(deps_file) - parts = [] - if 'deps_os' in parsed_deps: - for deps_os in parsed_deps['deps_os']: - parts.append(' [{}]]'.format(deps_os)) - return "\n".join(parts) -def looks_like_raw_commit(commit): - return re.match('^[a-f0-9]{40}$', commit) is not None +def usage(deps_file_path = None): + sys.stderr.write( + 'Usage: run to grab dependencies, with optional platform support:\n') + sys.stderr.write(' %s %s' % (sys.executable, __file__)) + if deps_file_path: + parsed_deps = parse_file_to_dict(deps_file_path) + if 'deps_os' in parsed_deps: + for deps_os in parsed_deps['deps_os']: + sys.stderr.write(' [%s]' % deps_os) + sys.stderr.write('\n\n') + sys.stderr.write(__doc__) + def git_repository_sync_is_disabled(git, directory): try: @@ -133,14 +125,14 @@ def is_git_toplevel(git, directory): def status(directory, checkoutable): def truncate(s, length): - return s if len(s) <= length else '...' + s[-(length - 3):] + return s if len(s) <= length else s[:(length - 3)] + '...' dlen = 36 directory = truncate(directory, dlen) checkoutable = truncate(checkoutable, 40) sys.stdout.write('%-*s @ %s\n' % (dlen, directory, checkoutable)) -def git_checkout_to_directory(git, repo, checkoutable, directory, verbose, treeless): +def git_checkout_to_directory(git, repo, checkoutable, directory, verbose): """Checkout (and clone if needed) a Git repository. Args: @@ -155,22 +147,13 @@ def git_checkout_to_directory(git, repo, checkoutable, directory, verbose, treel directory (string) the path into which the repository should be checked out. - verbose (boolean): emit status info to stdout - - treeless (boolean): when true, clone without any trees. + verbose (boolean) Raises an exception if any calls to git fail. """ if not os.path.isdir(directory): - # Use blobless or treeless checkouts for faster downloads. - # This defers some work to checkout time. - # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ - filter = ['--filter=tree:0'] if treeless else ['--filter=blob:none'] - # If the thing to check out looks like a tag (and not like a commit), - # then limit the checkout to that branch. - branch = [] if looks_like_raw_commit(checkoutable) else ['--branch={}'.format(checkoutable)] subprocess.check_call( - [git, 'clone', '--quiet', '--single-branch'] + filter + branch + [repo, directory]) + [git, 'clone', '--quiet', repo, directory]) if not is_git_toplevel(git, directory): # if the directory exists, but isn't a git repo, you will modify @@ -217,7 +200,7 @@ def parse_file_to_dict(path): return dictionary -def git_sync_deps(deps_file_path, command_line_os_requests, verbose, treeless): +def git_sync_deps(deps_file_path, command_line_os_requests, verbose): """Grab dependencies, with optional platform support. Args: @@ -227,20 +210,11 @@ def git_sync_deps(deps_file_path, command_line_os_requests, verbose, treeless): List of strings that should each be a key in the deps_os dictionary in the DEPS file. - verbose (boolean): emit status info to stdout - - treeless (boolean): when true, clone as treeless instead of blobless - Raises git Exceptions. """ - (git,git_major,git_minor) = git_executable() + git = git_executable() assert git - # --filter=tree:0 is available in git 2.20 and later - if (git_major,git_minor) < (2,20): - print("disabling --treeless: git is older than v2.20") - treeless = False - deps_file_directory = os.path.dirname(deps_file_path) deps_file = parse_file_to_dict(deps_file_path) dependencies = deps_file['deps'].copy() @@ -267,7 +241,7 @@ def git_sync_deps(deps_file_path, command_line_os_requests, verbose, treeless): relative_directory = os.path.join(deps_file_directory, directory) list_of_arg_lists.append( - (git, repo, checkoutable, relative_directory, verbose, treeless)) + (git, repo, checkoutable, relative_directory, verbose)) multithread(git_checkout_to_directory, list_of_arg_lists) @@ -290,47 +264,17 @@ def multithread(function, list_of_arg_lists): def main(argv): - argparser = argparse.ArgumentParser( - prog = "git-sync-deps", - description = "Checkout git-based dependencies as specified by the DEPS file", - add_help=False # Because we want to print deps_os with -h option - ) - argparser.add_argument("--help", "-h", - action='store_true', - help="show this help message and exit") - argparser.add_argument("--deps", - default = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH), - help="location of the the DEPS file") - argparser.add_argument("--verbose", - default=not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False)), - action='store_true', - help="be verbose: print status messages") - argparser.add_argument("--treeless", - default=False, - action='store_true', - help=""" - Clone repos without trees (--filter=tree:0). - This is the fastest option for a build machine, - when you only need a single commit. - Defers getting objects until checking out a commit. + deps_file_path = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH) + verbose = not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False)) - The default is to clone with trees but without blobs. + if '--help' in argv or '-h' in argv: + usage(deps_file_path) + return 1 - Only takes effect if using git 2.20 or later. - - See https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ - """) - argparser.add_argument("os_requests",nargs="*", - help="OS requests, as keys in the deps_os dictionariy in the DEPS file") - - args = argparser.parse_args() - if args.help: - print(argparser.format_help()) - print(EXTRA_HELP) - print(get_deps_os_str(args.deps)) - return 0 - - git_sync_deps(args.deps, args.os_requests, args.verbose, args.treeless) + git_sync_deps(deps_file_path, argv, verbose) + # subprocess.check_call( + # [sys.executable, + # os.path.join(os.path.dirname(deps_file_path), 'bin', 'fetch-gn')]) return 0 diff --git a/utils/roll_deps.sh b/utils/roll_deps.sh index d19ee000..20c061fd 100755 --- a/utils/roll_deps.sh +++ b/utils/roll_deps.sh @@ -20,22 +20,14 @@ set -eo pipefail -function ExitIfIsInterestingError() { - local return_code=$1 - if [[ ${return_code} -ne 0 && ${return_code} -ne 2 ]]; then - exit ${return_code} - fi - return 0 -} - - -dependencies=("external/effcee/" - "external/googletest/" - "external/re2/" - "external/spirv-headers/") - - -branch="origin/main" +effcee_dir="external/effcee/" +effcee_trunk="origin/main" +googletest_dir="external/googletest/" +googletest_trunk="origin/main" +re2_dir="external/re2/" +re2_trunk="origin/main" +spirv_headers_dir="external/spirv-headers/" +spirv_headers_trunk="origin/master" # This script assumes it's parent directory is the repo root. repo_path=$(dirname "$0")/.. @@ -52,9 +44,10 @@ echo "*** Ignore messages about running 'git cl upload' ***" old_head=$(git rev-parse HEAD) set +e +roll-dep --ignore-dirty-tree --roll-to="${effcee_trunk}" "${effcee_dir}" +roll-dep --ignore-dirty-tree --roll-to="${googletest_trunk}" "${googletest_dir}" +roll-dep --ignore-dirty-tree --roll-to="${re2_trunk}" "${re2_dir}" +roll-dep --ignore-dirty-tree --roll-to="${spirv_headers_trunk}" "${spirv_headers_dir}" + +git rebase --interactive "${old_head}" -for dep in ${dependencies[@]}; do - echo "Rolling $dep" - roll-dep --ignore-dirty-tree --roll-to="${branch}" "${dep}" - ExitIfIsInterestingError $? -done diff --git a/utils/update_build_version.py b/utils/update_build_version.py index f3d05b5d..2a1ca600 100755 --- a/utils/update_build_version.py +++ b/utils/update_build_version.py @@ -35,13 +35,9 @@ import os import os.path import re import subprocess -import logging import sys import time -# Format of the output generated by this script. Example: -# "v2023.1", "SPIRV-Tools v2023.1 0fc5526f2b01a0cc89192c10cf8bef77f1007a62, 2023-01-18T14:51:49" -OUTPUT_FORMAT = '"{version_tag}", "SPIRV-Tools {version_tag} {description}"\n' def mkdir_p(directory): """Make the directory, and all its ancestors as required. Any of the @@ -59,36 +55,31 @@ def mkdir_p(directory): else: raise + def command_output(cmd, directory): """Runs a command in a directory and returns its standard output stream. - Returns (False, None) if the command fails to launch or otherwise fails. + Captures the standard error stream. + + Raises a RuntimeError if the command fails to launch or otherwise fails. """ - try: - # Set shell=True on Windows so that Chromium's git.bat can be found when - # 'git' is invoked. - p = subprocess.Popen(cmd, - cwd=directory, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=os.name == 'nt') - (stdout, _) = p.communicate() - if p.returncode != 0: - return False, None - except Exception as e: - return False, None - return p.returncode == 0, stdout + p = subprocess.Popen(cmd, + cwd=directory, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (stdout, _) = p.communicate() + if p.returncode != 0: + raise RuntimeError('Failed to run %s in %s' % (cmd, directory)) + return stdout + def deduce_software_version(changes_file): - """Returns a tuple (success, software version number) parsed from the - given CHANGES file. + """Returns a software version number parsed from the given CHANGES file. - Success is set to True if the software version could be deduced. - Software version is undefined if success if False. - Function expects the CHANGES file to describes most recent versions first. + The CHANGES file describes most recent versions first. """ - # Match the first well-formed version-and-date line + # Match the first well-formed version-and-date line. # Allow trailing whitespace in the checked-out source code has # unexpected carriage returns on a linefeed-only system such as # Linux. @@ -97,73 +88,60 @@ def deduce_software_version(changes_file): for line in f.readlines(): match = pattern.match(line) if match: - return True, match.group(1) - return False, None + return match.group(1) + raise Exception('No version number found in {}'.format(changes_file)) -def describe(repo_path): +def describe(directory): """Returns a string describing the current Git HEAD version as descriptively as possible. Runs 'git describe', or alternately 'git rev-parse HEAD', in directory. If successful, returns the output; otherwise returns 'unknown hash, '.""" + try: + # decode() is needed here for Python3 compatibility. In Python2, + # str and bytes are the same type, but not in Python3. + # Popen.communicate() returns a bytes instance, which needs to be + # decoded into text data first in Python3. And this decode() won't + # hurt Python2. + return command_output(['git', 'describe'], directory).rstrip().decode() + except: + try: + return command_output( + ['git', 'rev-parse', 'HEAD'], directory).rstrip().decode() + except: + # This is the fallback case where git gives us no information, + # e.g. because the source tree might not be in a git tree. + # In this case, usually use a timestamp. However, to ensure + # reproducible builds, allow the builder to override the wall + # clock time with environment variable SOURCE_DATE_EPOCH + # containing a (presumably) fixed timestamp. + timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) + formatted = datetime.datetime.utcfromtimestamp(timestamp).isoformat() + return 'unknown hash, {}'.format(formatted) - # if we're in a git repository, attempt to extract version info - success, output = command_output(["git", "rev-parse", "--show-toplevel"], repo_path) - if success: - success, output = command_output(["git", "describe", "--tags", "--match=v*", "--long"], repo_path) - if not success: - success, output = command_output(["git", "rev-parse", "HEAD"], repo_path) - - if success: - # decode() is needed here for Python3 compatibility. In Python2, - # str and bytes are the same type, but not in Python3. - # Popen.communicate() returns a bytes instance, which needs to be - # decoded into text data first in Python3. And this decode() won't - # hurt Python2. - return output.rstrip().decode() - - # This is the fallback case where git gives us no information, - # e.g. because the source tree might not be in a git tree or - # git is not available on the system. - # In this case, usually use a timestamp. However, to ensure - # reproducible builds, allow the builder to override the wall - # clock time with environment variable SOURCE_DATE_EPOCH - # containing a (presumably) fixed timestamp. - timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) - iso_date = datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc).isoformat() - return "unknown hash, {}".format(iso_date) def main(): - FORMAT = '%(asctime)s %(message)s' - logging.basicConfig(format="[%(asctime)s][%(levelname)-8s] %(message)s", datefmt="%H:%M:%S") if len(sys.argv) != 3: - logging.error("usage: {} ".format(sys.argv[0])) + print('usage: {} '.format(sys.argv[0])) sys.exit(1) - changes_file_path = os.path.realpath(sys.argv[1]) - output_file_path = sys.argv[2] + output_file = sys.argv[2] + mkdir_p(os.path.dirname(output_file)) - success, version = deduce_software_version(changes_file_path) - if not success: - logging.error("Could not deduce latest release version from {}.".format(changes_file_path)) - sys.exit(1) + software_version = deduce_software_version(sys.argv[1]) + directory = os.path.dirname(sys.argv[1]) + new_content = '"{}", "SPIRV-Tools {} {}"\n'.format( + software_version, software_version, + describe(directory).replace('"', '\\"')) - repo_path = os.path.dirname(changes_file_path) - description = describe(repo_path) - content = OUTPUT_FORMAT.format(version_tag=version, description=description) + if os.path.isfile(output_file): + with open(output_file, 'r') as f: + if new_content == f.read(): + return - # Escape file content. - content.replace('"', '\\"') - - if os.path.isfile(output_file_path): - with open(output_file_path, 'r') as f: - if content == f.read(): - return - - mkdir_p(os.path.dirname(output_file_path)) - with open(output_file_path, 'w') as f: - f.write(content) + with open(output_file, 'w') as f: + f.write(new_content) if __name__ == '__main__': main() diff --git a/utils/vscode/.gitignore b/utils/vscode/.gitignore old mode 100755 new mode 100644