aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatalie Chouinard <sudonatalie@google.com>2023-12-04 12:24:51 -0500
committerGitHub <noreply@github.com>2023-12-04 12:24:51 -0500
commitf368e6424fbfb7fdea4b9d9a2e44f2f7e188c133 (patch)
tree3bed7a3511702e2a6ad3c5958c726681eb012b14
parentdff2f59be39765c8d6814c9a06155f76a5393673 (diff)
downloadllvm-f368e6424fbfb7fdea4b9d9a2e44f2f7e188c133.zip
llvm-f368e6424fbfb7fdea4b9d9a2e44f2f7e188c133.tar.gz
llvm-f368e6424fbfb7fdea4b9d9a2e44f2f7e188c133.tar.bz2
[SPIR-V] Add SPIRV-Tools for testing (#73044)
Add spirv-dis (disassembler) and spirv-val (validator) from SPIRV-Tools as external dependencies for testing the SPIR-V backend. These tools are test dependencies only. SPIR-V backend tests now have a dependency on the spirv-dis and spirv-val targets when the `LLVM_INCLUDE_SPIRV_TOOLS_TESTS` cmake variable is set, which allows additional test files with the `REQUIRES: spirv-tools` constraint to run, along with additional `RUN: %if spirv-tools ...` lines in existing tests. All other SPIR-V backend tests will run normally when `LLVM_INCLUDE_SPIRV_TOOLS_TESTS` is not set. Several tests are included to show these tools' use, however more tests will be migrated and added later. * OpVariable_order.ll shows how spirv-val can catch bugs in the backend. * basic_int_types_spirvdis.ll shows how tests can be much shorter and more readable by FileChecking the spirv-dis output. * basic_int_types.ll shows how an additional RUN line can add validation to existing tests. RFC: https://discourse.llvm.org/t/rfc-add-a-test-dependency-on-spirv-tools/75135
-rw-r--r--llvm/test/CMakeLists.txt6
-rw-r--r--llvm/test/CodeGen/SPIRV/OpVariable_order.ll17
-rw-r--r--llvm/test/CodeGen/SPIRV/basic_int_types.ll1
-rw-r--r--llvm/test/CodeGen/SPIRV/basic_int_types_spirvdis.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/lit.local.cfg5
-rw-r--r--llvm/test/lit.site.cfg.py.in1
-rw-r--r--llvm/tools/spirv-tools/CMakeLists.txt65
7 files changed, 140 insertions, 0 deletions
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 8aa6522..6127b76 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -24,6 +24,7 @@ llvm_canonicalize_cmake_booleans(
LLVM_ENABLE_REVERSE_ITERATION
LLVM_INCLUDE_DXIL_TESTS
LLVM_TOOL_LLVM_DRIVER_BUILD
+ LLVM_INCLUDE_SPIRV_TOOLS_TESTS
)
configure_lit_site_cfg(
@@ -222,6 +223,11 @@ if(LLVM_ENABLE_HTTPLIB)
list(APPEND LLVM_TEST_DEPENDS llvm-debuginfod)
endif()
+if (LLVM_INCLUDE_SPIRV_TOOLS_TESTS)
+ list(APPEND LLVM_TEST_DEPENDS spirv-dis)
+ list(APPEND LLVM_TEST_DEPENDS spirv-val)
+endif()
+
add_custom_target(llvm-test-depends DEPENDS ${LLVM_TEST_DEPENDS})
set_target_properties(llvm-test-depends PROPERTIES FOLDER "Tests")
diff --git a/llvm/test/CodeGen/SPIRV/OpVariable_order.ll b/llvm/test/CodeGen/SPIRV/OpVariable_order.ll
new file mode 100644
index 0000000..a4ca3aa
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/OpVariable_order.ll
@@ -0,0 +1,17 @@
+; REQUIRES: spirv-tools
+; RUN: llc -O0 -mtriple=spirv-unknown-linux %s -o - -filetype=obj | not spirv-val 2>&1 | FileCheck %s
+
+; TODO(#66261): The SPIR-V backend should reorder OpVariable instructions so this doesn't fail,
+; but in the meantime it's a good example of the spirv-val tool working as intended.
+
+; CHECK: All OpVariable instructions in a function must be the first instructions in the first block.
+
+define void @main() #1 {
+entry:
+ %0 = alloca <2 x i32>, align 4
+ %1 = getelementptr <2 x i32>, ptr %0, i32 0, i32 0
+ %2 = alloca float, align 4
+ ret void
+}
+
+attributes #1 = { "hlsl.numthreads"="4,8,16" "hlsl.shader"="compute" }
diff --git a/llvm/test/CodeGen/SPIRV/basic_int_types.ll b/llvm/test/CodeGen/SPIRV/basic_int_types.ll
index b479cee..6bfc990 100644
--- a/llvm/test/CodeGen/SPIRV/basic_int_types.ll
+++ b/llvm/test/CodeGen/SPIRV/basic_int_types.ll
@@ -1,6 +1,7 @@
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
define void @main() {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/basic_int_types_spirvdis.ll b/llvm/test/CodeGen/SPIRV/basic_int_types_spirvdis.ll
new file mode 100644
index 0000000..3778d89
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/basic_int_types_spirvdis.ll
@@ -0,0 +1,45 @@
+; REQUIRES: spirv-tools
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - --filetype=obj | spirv-dis | FileCheck %s
+
+define void @main() {
+entry:
+; CHECK: %int16_t_Val = OpVariable %_ptr_Function_ushort Function
+ %int16_t_Val = alloca i16, align 2
+
+; CHECK: %int_Val = OpVariable %_ptr_Function_uint Function
+ %int_Val = alloca i32, align 4
+
+; CHECK: %int64_t_Val = OpVariable %_ptr_Function_ulong Function
+ %int64_t_Val = alloca i64, align 8
+
+; CHECK: %int16_t2_Val = OpVariable %_ptr_Function_v2ushort Function
+ %int16_t2_Val = alloca <2 x i16>, align 4
+
+; CHECK: %int16_t3_Val = OpVariable %_ptr_Function_v3ushort Function
+ %int16_t3_Val = alloca <3 x i16>, align 8
+
+; CHECK: %int16_t4_Val = OpVariable %_ptr_Function_v4ushort Function
+ %int16_t4_Val = alloca <4 x i16>, align 8
+
+; CHECK: %int2_Val = OpVariable %_ptr_Function_v2uint Function
+ %int2_Val = alloca <2 x i32>, align 8
+
+; CHECK: %int3_Val = OpVariable %_ptr_Function_v3uint Function
+ %int3_Val = alloca <3 x i32>, align 16
+
+; CHECK: %int4_Val = OpVariable %_ptr_Function_v4uint Function
+ %int4_Val = alloca <4 x i32>, align 16
+
+; CHECK: %int64_t2_Val = OpVariable %_ptr_Function_v2ulong Function
+ %int64_t2_Val = alloca <2 x i64>, align 16
+
+; CHECK: %int64_t3_Val = OpVariable %_ptr_Function_v3ulong Function
+ %int64_t3_Val = alloca <3 x i64>, align 32
+
+; CHECK: %int64_t4_Val = OpVariable %_ptr_Function_v4ulong Function
+ %int64_t4_Val = alloca <4 x i64>, align 32
+
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/lit.local.cfg b/llvm/test/CodeGen/SPIRV/lit.local.cfg
index 78dd74c..00f50fb 100644
--- a/llvm/test/CodeGen/SPIRV/lit.local.cfg
+++ b/llvm/test/CodeGen/SPIRV/lit.local.cfg
@@ -1,2 +1,7 @@
if not "SPIRV" in config.root.targets:
config.unsupported = True
+
+if config.spirv_tools_tests:
+ config.available_features.add("spirv-tools")
+ config.substitutions.append(("spirv-dis", os.path.join(config.llvm_tools_dir, "spirv-dis")))
+ config.substitutions.append(("spirv-val", os.path.join(config.llvm_tools_dir, "spirv-val")))
diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 6f3ab65..1138b2c 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -60,6 +60,7 @@ config.expensive_checks = @LLVM_ENABLE_EXPENSIVE_CHECKS@
config.reverse_iteration = @LLVM_ENABLE_REVERSE_ITERATION@
config.dxil_tests = @LLVM_INCLUDE_DXIL_TESTS@
config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
+config.spirv_tools_tests = @LLVM_INCLUDE_SPIRV_TOOLS_TESTS@
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/llvm/tools/spirv-tools/CMakeLists.txt b/llvm/tools/spirv-tools/CMakeLists.txt
new file mode 100644
index 0000000..f73dcad
--- /dev/null
+++ b/llvm/tools/spirv-tools/CMakeLists.txt
@@ -0,0 +1,65 @@
+option(LLVM_INCLUDE_SPIRV_TOOLS_TESTS "Include tests that use SPIRV-Tools" Off)
+mark_as_advanced(LLVM_INCLUDE_SPIRV_TOOLS_TESTS)
+
+if (NOT LLVM_INCLUDE_SPIRV_TOOLS_TESTS)
+ return()
+endif ()
+
+if (NOT "SPIRV" IN_LIST LLVM_TARGETS_TO_BUILD)
+ message(FATAL_ERROR "Building SPIRV-Tools tests is unsupported without the SPIR-V target")
+endif ()
+
+# SPIRV_DIS and SPIRV_VAL variables can be used to provide paths to existing
+# spirv-dis and spirv-val binaries, respectively. Otherwise, build them from
+# SPIRV-Tools source.
+if (NOT SPIRV_DIS OR NOT SPIRV_VAL)
+ include(ExternalProject)
+
+ set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/SPIRVTools-bin)
+
+ ExternalProject_Add(SPIRVTools
+ GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Tools.git
+ GIT_TAG main
+ BINARY_DIR ${BINARY_DIR}
+ BUILD_COMMAND ${CMAKE_COMMAND} --build ${BINARY_DIR} --target spirv-dis spirv-val
+ BUILD_BYPRODUCTS ${BINARY_DIR}/tools/spirv-dis ${BINARY_DIR}/tools/spirv-val
+ DOWNLOAD_COMMAND git clone https://github.com/KhronosGroup/SPIRV-Tools.git SPIRVTools &&
+ cd SPIRVTools &&
+ ${Python3_EXECUTABLE} utils/git-sync-deps
+ UPDATE_COMMAND git pull origin main &&
+ ${Python3_EXECUTABLE} utils/git-sync-deps
+ # Don't auto-update on every build.
+ UPDATE_DISCONNECTED 1
+ # Allow manual updating with an explicit SPIRVTools-update target.
+ STEP_TARGETS update
+ # Install handled below.
+ INSTALL_COMMAND ""
+ )
+endif ()
+
+if (CMAKE_HOST_UNIX)
+ set(LLVM_LINK_OR_COPY create_symlink)
+else ()
+ set(LLVM_LINK_OR_COPY copy)
+endif ()
+
+# Link the provided or just built spirv-dis and spirv-val binaries.
+if (SPIRV_DIS)
+ add_custom_target(spirv-dis
+ COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${SPIRV_DIS}" "${LLVM_RUNTIME_OUTPUT_INTDIR}/spirv-dis")
+else ()
+ add_custom_target(spirv-dis
+ COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${BINARY_DIR}/tools/spirv-dis" "${LLVM_RUNTIME_OUTPUT_INTDIR}/spirv-dis"
+ DEPENDS SPIRVTools
+ )
+endif ()
+
+if (SPIRV_VAL)
+ add_custom_target(spirv-val
+ COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${SPIRV_VAL}" "${LLVM_RUNTIME_OUTPUT_INTDIR}/spirv-val")
+else ()
+ add_custom_target(spirv-val
+ COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${BINARY_DIR}/tools/spirv-val" "${LLVM_RUNTIME_OUTPUT_INTDIR}/spirv-val"
+ DEPENDS SPIRVTools
+ )
+endif ()