llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libc Author: fineg74 <details> <summary>Changes</summary> This is to add support to build and run libc tests for SPIRV backend This is still work in progress since many tests are failing. The test failures were attributed to backend issues, driver issues or the fact that currently libc is currenly built with pretty small subset of the API which results in unresolved symbols test failures. All of these issues will be addressed in separate PRs. In addition clock functionality is currently stubbed out to return 0 because native spirv does not contain timer/clock capabilities. It will be addressed in separate PR. --- Full diff: https://github.com/llvm/llvm-project/pull/208129.diff 13 Files Affected: - (modified) clang/lib/Headers/llvm_libc_wrappers/stdlib.h (+3-2) - (modified) libc/CMakeLists.txt (+1-1) - (modified) libc/cmake/modules/LLVMLibCLibraryRules.cmake (+1-1) - (modified) libc/cmake/modules/LLVMLibCTestRules.cmake (+69-35) - (modified) libc/cmake/modules/prepare_libc_gpu_build.cmake (+6) - (modified) libc/config/gpu/spirv/entrypoints.txt (+47) - (modified) libc/config/gpu/spirv/headers.txt (+2) - (modified) libc/src/__support/GPU/utils.h (+6-1) - (modified) libc/startup/gpu/CMakeLists.txt (+10-3) - (modified) libc/test/UnitTest/CMakeLists.txt (+19-7) - (modified) llvm/runtimes/CMakeLists.txt (+1-1) - (modified) llvm/tools/llvm-gpu-loader/CMakeLists.txt (+1) - (modified) llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp (+14-1) ``````````diff diff --git a/clang/lib/Headers/llvm_libc_wrappers/stdlib.h b/clang/lib/Headers/llvm_libc_wrappers/stdlib.h index 7af5e2ebe031a..6d4987936b295 100644 --- a/clang/lib/Headers/llvm_libc_wrappers/stdlib.h +++ b/clang/lib/Headers/llvm_libc_wrappers/stdlib.h @@ -9,13 +9,14 @@ #ifndef __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__ #define __CLANG_LLVM_LIBC_WRAPPERS_STDLIB_H__ -#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__) +#if !defined(_OPENMP) && !defined(__HIP__) && !defined(__CUDA__) && \ + !defined(__SPIRV__) #error "This file is for GPU offloading compilation only" #endif #include_next <stdlib.h> -#if defined(__HIP__) || defined(__CUDA__) +#if defined(__HIP__) || defined(__CUDA__) || defined(__SPIRV__) #define __LIBC_ATTRS __attribute__((device)) #else #define __LIBC_ATTRS diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 6ddd75a0a3335..efa506d1a461c 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -422,7 +422,7 @@ add_subdirectory(hdr) add_subdirectory(src) add_subdirectory(utils) -if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_ARCHITECTURE_IS_SPIRV) +if(LLVM_LIBC_FULL_BUILD) # The startup system can potentially depend on the library components so add # it after the library implementation directories. add_subdirectory(startup) diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake index 2df8f49100b99..9db9358a8131c 100644 --- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake +++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake @@ -111,7 +111,7 @@ function(add_bitcode_entrypoint_library target_name base_target_name) add_executable(${target_name} ${objects}) if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}" - "-nostdlib" "-emit-llvm") + "-nostdlib" "-flto" "-emit-llvm") else() target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}" "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm") diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index d86fb4369a381..b9f3dfbb434e7 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -110,6 +110,9 @@ function(_get_hermetic_test_compile_options output_var) list(APPEND compile_options -Wno-multi-gpu --cuda-path=${LIBC_CUDA_ROOT} -nogpulib -march=${LIBC_GPU_TARGET_ARCHITECTURE} -fno-use-cxa-atexit) + elseif(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + list(APPEND compile_options + -nogpulib -flto) endif() set(${output_var} ${compile_options} PARENT_SCOPE) @@ -586,16 +589,18 @@ function(add_integration_test test_name) list(REMOVE_DUPLICATES link_object_files) # Make a library of all deps - add_library( - ${fq_target_name}.__libc__ - STATIC - EXCLUDE_FROM_ALL - ${link_object_files} - ) - set_target_properties(${fq_target_name}.__libc__ - PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_target_properties(${fq_target_name}.__libc__ - PROPERTIES ARCHIVE_OUTPUT_NAME ${fq_target_name}.libc) + if(NOT LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + add_library( + ${fq_target_name}.__libc__ + STATIC + EXCLUDE_FROM_ALL + ${link_object_files} + ) + set_target_properties(${fq_target_name}.__libc__ + PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties(${fq_target_name}.__libc__ + PROPERTIES ARCHIVE_OUTPUT_NAME ${fq_target_name}.libc) + endif() set(fq_build_target_name ${fq_target_name}.__build__) add_executable( @@ -627,6 +632,10 @@ function(add_integration_test test_name) "-Wl,-mllvm,-nvptx-emit-init-fini-kernel" -march=${LIBC_GPU_TARGET_ARCHITECTURE} -nostdlib -static "--cuda-path=${LIBC_CUDA_ROOT}") + elseif(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + target_link_options(${fq_build_target_name} PRIVATE + ${LIBC_COMPILE_OPTIONS_DEFAULT} ${INTEGRATION_TEST_COMPILE_OPTIONS} + -nostdlib -flto -Wno-multi-gpu) elseif(LIBC_CC_SUPPORTS_NOSTDLIBPP) set(link_options -nolibc @@ -650,13 +659,21 @@ function(add_integration_test test_name) target_link_options(${fq_build_target_name} PRIVATE ${link_options}) list(APPEND compiler_runtime ${LIBGCC_S_LOCATION}) endif() - target_link_libraries( - ${fq_build_target_name} - libc.startup.${LIBC_TARGET_OS}.crt1 - libc.test.IntegrationTest.test - ${fq_target_name}.__libc__ - ${compiler_runtime} - ) + if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + target_link_libraries( + ${fq_build_target_name} + ${link_object_files} + ${compiler_runtime} + ) + else() + target_link_libraries( + ${fq_build_target_name} + libc.startup.${LIBC_TARGET_OS}.crt1 + libc.test.IntegrationTest.test + ${fq_target_name}.__libc__ + ${compiler_runtime} + ) + endif() add_dependencies(${fq_build_target_name} libc.test.IntegrationTest.test ${INTEGRATION_TEST_DEPENDS}) @@ -804,16 +821,18 @@ function(add_libc_hermetic test_name) list(REMOVE_DUPLICATES link_object_files) # Make a library of all deps - add_library( - ${fq_target_name}.__libc__ - STATIC - EXCLUDE_FROM_ALL - ${link_object_files} - ) - set_target_properties(${fq_target_name}.__libc__ - PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - set_target_properties(${fq_target_name}.__libc__ - PROPERTIES ARCHIVE_OUTPUT_NAME ${fq_target_name}.libc) + if(NOT LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + add_library( + ${fq_target_name}.__libc__ + STATIC + EXCLUDE_FROM_ALL + ${link_object_files} + ) + set_target_properties(${fq_target_name}.__libc__ + PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties(${fq_target_name}.__libc__ + PROPERTIES ARCHIVE_OUTPUT_NAME ${fq_target_name}.libc) + endif() if(HERMETIC_TEST_NO_RUN_POSTBUILD) set(fq_build_target_name ${fq_target_name}) @@ -866,6 +885,10 @@ function(add_libc_hermetic test_name) "-Wl,-mllvm,-nvptx-emit-init-fini-kernel" -march=${LIBC_GPU_TARGET_ARCHITECTURE} -nostdlib -static "--cuda-path=${LIBC_CUDA_ROOT}") + elseif(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + target_link_options(${fq_build_target_name} PRIVATE + ${LIBC_COMPILE_OPTIONS_DEFAULT} + -nostdlib -flto -Wno-multi-gpu) elseif(LIBC_CC_SUPPORTS_NOSTDLIBPP) set(link_options -nolibc @@ -889,15 +912,26 @@ function(add_libc_hermetic test_name) target_link_options(${fq_build_target_name} PRIVATE ${link_options}) list(APPEND compiler_runtime ${LIBGCC_S_LOCATION}) endif() - target_link_libraries( - ${fq_build_target_name} - PRIVATE - libc.startup.${LIBC_TARGET_OS}.crt1 - ${link_libraries} - LibcHermeticTestSupport.hermetic - ${fq_target_name}.__libc__ - ${compiler_runtime} + if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + target_link_libraries( + ${fq_build_target_name} + PRIVATE + ${link_libraries} + LibcHermeticTestSupport.hermetic + ${link_object_files} + ${compiler_runtime} ) + else() + target_link_libraries( + ${fq_build_target_name} + PRIVATE + libc.startup.${LIBC_TARGET_OS}.crt1 + ${link_libraries} + LibcHermeticTestSupport.hermetic + ${fq_target_name}.__libc__ + ${compiler_runtime} + ) + endif() add_dependencies(${fq_build_target_name} LibcTest.hermetic libc.test.UnitTest.ErrnoSetterMatcher diff --git a/libc/cmake/modules/prepare_libc_gpu_build.cmake b/libc/cmake/modules/prepare_libc_gpu_build.cmake index 36ab321e4994c..15426dada3462 100644 --- a/libc/cmake/modules/prepare_libc_gpu_build.cmake +++ b/libc/cmake/modules/prepare_libc_gpu_build.cmake @@ -39,6 +39,8 @@ if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU) check_cxx_compiler_flag(-mcpu=native PLATFORM_HAS_GPU) elseif(LIBC_TARGET_ARCHITECTURE_IS_NVPTX) check_cxx_compiler_flag(-march=native PLATFORM_HAS_GPU) +elseif(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + set(PLATFORM_HAS_GPU TRUE) endif() set(gpu_test_architecture "") @@ -50,6 +52,10 @@ elseif(DEFINED LLVM_TARGETS_TO_BUILD AND LIBC_TARGET_ARCHITECTURE_IS_NVPTX AND NOT "NVPTX" IN_LIST LLVM_TARGETS_TO_BUILD) set(LIBC_GPU_TESTS_DISABLED TRUE) message(STATUS "NVPTX backend is not available, tests will not be built") +elseif(DEFINED LLVM_TARGETS_TO_BUILD AND LIBC_TARGET_ARCHITECTURE_IS_SPIRV + AND NOT "SPIRV" IN_LIST LLVM_TARGETS_TO_BUILD) + set(LIBC_GPU_TESTS_DISABLED TRUE) + message(STATUS "SPIRV backend is not available, tests will not be built") elseif(LIBC_GPU_TEST_ARCHITECTURE) set(LIBC_GPU_TESTS_DISABLED FALSE) set(gpu_test_architecture ${LIBC_GPU_TEST_ARCHITECTURE}) diff --git a/libc/config/gpu/spirv/entrypoints.txt b/libc/config/gpu/spirv/entrypoints.txt index 36c98339582cd..b2fe92ac15adc 100644 --- a/libc/config/gpu/spirv/entrypoints.txt +++ b/libc/config/gpu/spirv/entrypoints.txt @@ -85,6 +85,53 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.strings.strcasecmp libc.src.strings.strncasecmp + # stdlib.h entrypoints + libc.src.stdlib._Exit + libc.src.stdlib.abort + libc.src.stdlib.abs + libc.src.stdlib.atexit + libc.src.stdlib.atof + libc.src.stdlib.atoi + libc.src.stdlib.atol + libc.src.stdlib.atoll + libc.src.stdlib.bsearch + libc.src.stdlib.div + libc.src.stdlib.exit + libc.src.stdlib.labs + libc.src.stdlib.ldiv + libc.src.stdlib.llabs + libc.src.stdlib.lldiv + libc.src.stdlib.memalignment + libc.src.stdlib.qsort + libc.src.stdlib.qsort_r + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.stdlib.strtod + libc.src.stdlib.strtod_l + libc.src.stdlib.strtof + libc.src.stdlib.strtof_l + libc.src.stdlib.strtol + libc.src.stdlib.strtol_l + libc.src.stdlib.strtold + libc.src.stdlib.strtold_l + libc.src.stdlib.strtoll + libc.src.stdlib.strtoll_l + libc.src.stdlib.strtoul + libc.src.stdlib.strtoul_l + libc.src.stdlib.strtoull + libc.src.stdlib.strtoull_l + libc.src.stdlib.at_quick_exit + libc.src.stdlib.quick_exit + libc.src.stdlib.getenv + libc.src.stdlib.system + + # TODO: Implement these correctly + libc.src.stdlib.aligned_alloc + libc.src.stdlib.calloc + libc.src.stdlib.free + libc.src.stdlib.malloc + libc.src.stdlib.realloc + ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/config/gpu/spirv/headers.txt b/libc/config/gpu/spirv/headers.txt index ae5e0de66c7a2..e81157d349b73 100644 --- a/libc/config/gpu/spirv/headers.txt +++ b/libc/config/gpu/spirv/headers.txt @@ -2,4 +2,6 @@ set(TARGET_PUBLIC_HEADERS libc.include.ctype libc.include.string libc.include.strings + libc.include.errno + libc.include.stdlib ) diff --git a/libc/src/__support/GPU/utils.h b/libc/src/__support/GPU/utils.h index e12684bf25c6a..15d2088c52adb 100644 --- a/libc/src/__support/GPU/utils.h +++ b/libc/src/__support/GPU/utils.h @@ -126,12 +126,17 @@ LIBC_INLINE uint32_t scan(uint64_t lane_mask, uint32_t x) { return __gpu_prefix_scan_add_u32(lane_mask, x); } +#if defined(LIBC_TARGET_ARCH_IS_SPIRV) +LIBC_INLINE uint64_t fixed_frequency_clock() { return 0; } + +LIBC_INLINE uint64_t processor_clock() { return 0; } +#else LIBC_INLINE uint64_t fixed_frequency_clock() { return __builtin_readsteadycounter(); } LIBC_INLINE uint64_t processor_clock() { return __builtin_readcyclecounter(); } - +#endif } // namespace gpu } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/startup/gpu/CMakeLists.txt b/libc/startup/gpu/CMakeLists.txt index 12cb891a687d8..191da218cbed0 100644 --- a/libc/startup/gpu/CMakeLists.txt +++ b/libc/startup/gpu/CMakeLists.txt @@ -33,9 +33,16 @@ function(add_startup_object name) set_target_properties(${fq_target_name}.exe PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR} RUNTIME_OUTPUT_NAME ${name}.o) - target_link_options(${fq_target_name}.exe PRIVATE - ${LIBC_COMPILE_OPTIONS_DEFAULT} - "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm") + if (LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + target_link_options(${fq_target_name}.exe PRIVATE + ${LIBC_COMPILE_OPTIONS_DEFAULT} + "-nostdlib" "-flto" + ) + else() + target_link_options(${fq_target_name}.exe PRIVATE + ${LIBC_COMPILE_OPTIONS_DEFAULT} + "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm") + endif() endif() endfunction() diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt index 02489107efc06..f3311294a0863 100644 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -12,13 +12,25 @@ function(add_unittest_framework_library name) endif() foreach(lib IN ITEMS ${name}.unit ${name}.hermetic) - add_library( - ${lib} - STATIC - EXCLUDE_FROM_ALL - ${TEST_LIB_SRCS} - ${TEST_LIB_HDRS} - ) + if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + add_library( + ${lib} + OBJECT + EXCLUDE_FROM_ALL + ${TEST_LIB_SRCS} + ${TEST_LIB_HDRS} + ) + target_link_options(${lib} PRIVATE + "-nostdlib" "-flto") + else() + add_library( + ${lib} + STATIC + EXCLUDE_FROM_ALL + ${TEST_LIB_SRCS} + ${TEST_LIB_HDRS} + ) + endif() target_include_directories(${lib} PRIVATE ${LIBC_SOURCE_DIR}) if(TARGET libc.src.time.clock) target_compile_definitions(${lib} PRIVATE TARGET_SUPPORTS_CLOCK) diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index 501ea55a327c7..5025343e33e02 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -632,7 +632,7 @@ if(build_runtimes) if(LLVM_LIBC_GPU_BUILD) set(_gpu_loader "${LLVM_TOOLS_BINARY_DIR}/llvm-gpu-loader${CMAKE_EXECUTABLE_SUFFIX}") foreach(name ${LLVM_RUNTIME_TARGETS}) - if(name MATCHES "^(amdgcn|nvptx)") + if(name MATCHES "^(amdgcn|nvptx|spirv)") set(RUNTIMES_${name}_CMAKE_CROSSCOMPILING_EMULATOR "${_gpu_loader}" CACHE STRING "") endif() endforeach() diff --git a/llvm/tools/llvm-gpu-loader/CMakeLists.txt b/llvm/tools/llvm-gpu-loader/CMakeLists.txt index 37377ddc0506b..96d7b60a83402 100644 --- a/llvm/tools/llvm-gpu-loader/CMakeLists.txt +++ b/llvm/tools/llvm-gpu-loader/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS BinaryFormat TargetParser Support + FrontendOffloading ) add_llvm_tool(llvm-gpu-loader diff --git a/llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp b/llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp index b17403406c43f..e77710232a81c 100644 --- a/llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp +++ b/llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp @@ -15,6 +15,7 @@ #include "llvm-gpu-loader.h" #include "llvm/BinaryFormat/Magic.h" +#include "llvm/Frontend/Offloading/Utility.h" #include "llvm/Object/ELF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/CommandLine.h" @@ -207,7 +208,7 @@ int main(int argc, const char **argv, const char **envp) { handleError(errorCodeToError(EC)); MemoryBufferRef Image = **ImageOrErr; - ol_platform_backend_t Backend; + ol_platform_backend_t Backend = OL_PLATFORM_BACKEND_UNKNOWN; ol_init_args_t InitArgs = OL_INIT_ARGS_INIT; file_magic Magic = identify_magic(Image.getBuffer()); @@ -224,12 +225,22 @@ int main(int argc, const char **argv, const char **envp) { case ELF::EM_CUDA: Backend = OL_PLATFORM_BACKEND_CUDA; break; + case ELF::EM_INTELGT: + Backend = OL_PLATFORM_BACKEND_LEVEL_ZERO; + break; default: handleError(createStringError( "unhandled ELF architecture: %s", ELF::convertEMachineToArchName(ElfOrErr->getHeader().e_machine) .data())); } + } else if (Magic == file_magic::spirv_object) { + // SPIR-V objects are assumed to be for Level Zero for now as that is the + // only platform that currently supports them. + Backend = OL_PLATFORM_BACKEND_LEVEL_ZERO; + } + + if (Backend != OL_PLATFORM_BACKEND_UNKNOWN) { InitArgs.NumPlatforms = 1; InitArgs.Platforms = &Backend; } @@ -239,6 +250,8 @@ int main(int argc, const char **argv, const char **envp) { [](const std::string &Arg) { return Arg.c_str(); }); OFFLOAD_ERR(olInit(&InitArgs)); + if (InitArgs.NumPlatforms == 0) + handleError(createStringError("No compatible platforms were found")); ol_device_handle_t Device = findDevice(Image); if (!Device) handleError(createStringError("No compatible device was found")); `````````` </details> https://github.com/llvm/llvm-project/pull/208129 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
