diff --git a/buildbot/configure.py b/buildbot/configure.py index 4874c0a44557a..6798bfa7356ad 100644 --- a/buildbot/configure.py +++ b/buildbot/configure.py @@ -200,6 +200,16 @@ def do_configure(args, passthrough_args): "-DBUG_REPORT_URL=https://github.com/intel/llvm/issues", ] + llvm_spirv64_runtimes = "libc" + runtime_targets += ";spirv64-unknown-unknown" + cmake_cmd.extend( + [ + "-DRUNTIMES_spirv64-unknown-unknown_LLVM_ENABLE_RUNTIMES={}".format( + llvm_spirv64_runtimes + ), + ] + ) + if llvm_enable_runtimes: cmake_cmd.extend( [ @@ -225,19 +235,18 @@ def do_configure(args, passthrough_args): if libclc_enabled: for target in runtime_targets.split(";"): - if target == "default": + if target == "default" or target == "spirv64-unknown-unknown": continue cmake_cmd.extend( [ f"-DRUNTIMES_{target}_LLVM_ENABLE_RUNTIMES=libclc", ] ) - cmake_cmd.extend( - [ - "-DLLVM_RUNTIME_TARGETS={}".format(runtime_targets), - ] - ) - + cmake_cmd.extend( + [ + "-DLLVM_RUNTIME_TARGETS={}".format(runtime_targets), + ] + ) if args.l0_headers and args.l0_loader: cmake_cmd.extend( [ diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6d5487613873e..418eca8fdf001 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -261,6 +261,7 @@ LANGOPT(GPUDeferDiag, 1, 0, NotCompatible, "defer host/device related diagnostic LANGOPT(GPUExcludeWrongSideOverloads, 1, 0, NotCompatible, "always exclude wrong side overloads in overloading resolution for CUDA/HIP") LANGOPT(OffloadingNewDriver, 1, 0, NotCompatible, "use the new driver for generating offloading code.") LANGOPT(OffloadViaLLVM, 1, 0, NotCompatible, "target LLVM/Offload as portable offloading runtime.") +LANGOPT(DefaultAddrSpaceIsGeneric, 1, 0, NotCompatible, "use generic address space as default address space for SPIR-V targets") LANGOPT(SYCLIsDevice , 1, 0, NotCompatible, "Generate code for SYCL device") LANGOPT(SYCLIsHost , 1, 0, NotCompatible, "SYCL host compilation") diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 37288df8dfc7d..324150e4b5d41 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -9202,6 +9202,10 @@ def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, NormalizedValuesScope<"LangOptions">, NormalizedValues<["DCC_CDecl", "DCC_FastCall", "DCC_StdCall", "DCC_VectorCall", "DCC_RegCall", "DCC_RtdCall"]>, MarshallingInfoEnum, "DCC_None">; +def fdefault_addr_space_is_generic : Flag<["-"], "fdefault-addr-space-is-generic">, + HelpText<"Use generic address space as the default address space for SPIR-V targets">, + Visibility<[CC1Option]>, + MarshallingInfoFlag>; // These options cannot be marshalled, because they are used to set up the LangOptions defaults. def finclude_default_header : Flag<["-"], "finclude-default-header">, diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 54bc370f8d6b0..91ba086fa64e0 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -237,6 +237,7 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { // SYCL and HIP/CUDA. setAddressSpaceMap( /*DefaultIsGeneric=*/Opts.SYCLIsDevice || + Opts.DefaultAddrSpaceIsGeneric || // The address mapping from HIP/CUDA language for device code is only // defined for SPIR-V, and all Intel SPIR-V code should have the default // AS as generic. diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 5890b0644b168..d4dda10abf965 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5863,6 +5863,15 @@ class OffloadingActionBuilder final { SmallVector, 4> LibLocCandidates; SYCLInstallation.getSYCLDeviceLibPath(LibLocCandidates); + if (TC->getTriple().isSPIROrSPIRV()) { + SmallVector, 4> OriginalLibLocs(LibLocCandidates); + for (auto LibLoc : OriginalLibLocs) { + SmallString<128> SPIRVLibLoc(LibLoc); + llvm::sys::path::append(SPIRVLibLoc, "spirv64-unknown-unknown"); + if (llvm::sys::fs::exists(SPIRVLibLoc)) + LibLocCandidates.emplace_back(SPIRVLibLoc); + } + } const toolchains::SYCLToolChain &SYCLTC = static_cast(*TC); SmallVector DeviceLibraries; diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index 51bc17f3eb700..270a2449d9210 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -666,7 +666,7 @@ SYCLToolChain::getDeviceLibNames(const Driver &D, #if defined(_WIN32) "libsycl-msvc-math", #endif - "libsycl-imf"}; + "libsycl-imf", "libc"}; auto addLibraries = [&](const SYCLDeviceLibsList &LibsList) { for (const StringRef &Lib : LibsList) addLibToList(Args.MakeArgString(Lib + ".bc")); @@ -883,6 +883,9 @@ const char *SYCL::Linker::constructLLVMLinkCommand( InputFilename.contains("libspirv") || InputFilename.contains("libdevice"))) return true; + if ((InputFilename.compare("libc.bc") == 0) && + (FileName.find("spirv64-unknown-unknown") != std::string::npos)) + return true; StringRef LibSyclPrefix("libsycl-"); if (!InputFilename.starts_with(LibSyclPrefix) || !InputFilename.ends_with(LibPostfix)) @@ -1978,6 +1981,15 @@ SYCLToolChain::getDeviceLibs( SmallVector, 4> LibraryPaths; SYCLInstallation.getSYCLDeviceLibPath(LibraryPaths); + if (getTriple().isSPIROrSPIRV()) { + SmallVector, 4> OriginalLibraryPaths(LibraryPaths); + for (auto LP : OriginalLibraryPaths) { + SmallString<128> SPIRVLibraryPath(LP); + llvm::sys::path::append(SPIRVLibraryPath, "spirv64-unknown-unknown"); + if (llvm::sys::fs::exists(SPIRVLibraryPath)) + LibraryPaths.emplace_back(SPIRVLibraryPath); + } + } // Formulate all of the device libraries needed for this compilation. SmallVector DeviceLibs = getDeviceLibNames(getDriver(), DriverArgs, getTriple()); diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index c65fc4db605c9..7c18fb65b4de7 100644 --- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -345,6 +345,8 @@ function(_get_common_compile_options output_var flags) endif() elseif(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU) list(APPEND compile_options "SHELL:-Xclang -mcode-object-version=none") + elseif(LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + list(APPEND compile_options "SHELL:-Xclang -fdefault-addr-space-is-generic") endif() endif() set(${output_var} ${compile_options} PARENT_SCOPE) diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake index 2df8f49100b99..2dc346fc15330 100644 --- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake +++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake @@ -83,7 +83,7 @@ endfunction() # A rule to build a library from a collection of entrypoint objects and bundle # it in a single LLVM-IR bitcode file. # Usage: -# add_bitcode_entrypoint_library( +# add_gpu_entrypoint_library( # DEPENDS # ) function(add_bitcode_entrypoint_library target_name base_target_name) @@ -119,6 +119,51 @@ function(add_bitcode_entrypoint_library target_name base_target_name) add_dependencies(${base_target_name} ${target_name}) endfunction(add_bitcode_entrypoint_library) +# A rule to build a library from a collection of entrypoint objects and bundle +# it in a single LLVM-IR bitcode file with llvm-link +# Usage: +# link_bitcode_library( +# DEPENDS +# ) +function(link_bitcode_library target_name base_target_name output_name) + cmake_parse_arguments( + "ENTRYPOINT_LIBRARY" + "" # No optional arguments + "" # No single value arguments + "DEPENDS" # Multi-value arguments + ${ARGN} + ) + if(NOT ENTRYPOINT_LIBRARY_DEPENDS) + message(FATAL_ERROR "'link_bitcode_library' target requires a DEPENDS list " + "of 'add_entrypoint_object' targets.") + endif() + + get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS}) + get_all_object_file_deps(all_deps "${fq_deps_list}") + + set(objects "") + foreach(dep IN LISTS all_deps) + set(object $<$,${dep}>:$>) + list(APPEND objects ${object}) + endforeach() + + find_program(LLVM_LINK_EXE + NAMES llvm-link + PATHS ${LLVM_TOOLS_BINARY_DIR} + NO_DEFAULT_PATH) + string(REPLACE ";" "\n" rsp_contents "${objects}") + file(GENERATE + OUTPUT ${CMAKE_BINARY_DIR}/${target_name}.rsp + CONTENT "${rsp_contents}") + if(LLVM_LINK_EXE) + set(bc_file ${CMAKE_BINARY_DIR}/libc/lib/${output_name}) + add_custom_target(${target_name} + COMMAND ${LLVM_LINK_EXE} -o ${bc_file} @${CMAKE_BINARY_DIR}/${target_name}.rsp + DEPENDS ${objects}) + add_dependencies(${base_target_name} ${target_name}) + endif() +endfunction(link_bitcode_library) + # A rule to build a library from a collection of entrypoint objects. # Usage: # add_entrypoint_library( diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt index 08026e937be94..e924efc792150 100644 --- a/libc/lib/CMakeLists.txt +++ b/libc/lib/CMakeLists.txt @@ -41,17 +41,37 @@ foreach(archive IN ZIP_LISTS # Add the offloading version of the library for offloading languages. These # are installed in the standard search path separate from the other libraries. if(LIBC_TARGET_OS_IS_GPU) - add_bitcode_entrypoint_library( - ${archive_1}bitcode - ${archive_1} - DEPENDS - ${${archive_2}} - ) - set_target_properties( - ${archive_1}bitcode - PROPERTIES - OUTPUT_NAME ${archive_1}.bc - ) + if (NOT WIN32) + add_bitcode_entrypoint_library( + ${archive_1}bitcode + ${archive_1} + DEPENDS + ${${archive_2}} + ) + set_target_properties( + ${archive_1}bitcode + PROPERTIES + OUTPUT_NAME ${archive_1}.bc + ) + else() + link_bitcode_library( + ${archive_1}bitcode + ${archive_1} + ${archive_1}.bc + DEPENDS + ${${archive_2}} + ) + set_target_properties( + ${archive_1}bitcode + PROPERTIES + LINK_OUTPUT_NAME ${CMAKE_BINARY_DIR}/libc/lib/${archive_1}.bc + ) + set_target_properties( + ${archive_1}bitcode + PROPERTIES + OUTPUT_NAME ${archive_1}.bc + ) + endif() list(APPEND added_bitcode_targets ${archive_1}bitcode) endif() endforeach() @@ -62,13 +82,23 @@ install( COMPONENT libc ) -foreach(file ${added_bitcode_targets}) - install(FILES $ - DESTINATION ${LIBC_INSTALL_LIBRARY_DIR} - RENAME $ - COMPONENT libc - ) -endforeach() +if(WIN32) + foreach(file ${added_bitcode_targets}) + install(FILES $ + DESTINATION ${LIBC_INSTALL_LIBRARY_DIR} + RENAME $ + COMPONENT libc + ) + endforeach() +else() + foreach(file ${added_bitcode_targets}) + install(FILES $ + DESTINATION ${LIBC_INSTALL_LIBRARY_DIR} + RENAME $ + COMPONENT libc + ) + endforeach() +endif() set(startup_target "") if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_BAREMETAL) @@ -83,19 +113,17 @@ if(LLVM_LIBC_FULL_BUILD) set(header_install_target install-libc-headers) endif() +set(install-libc-depends ${added_archive_targets} ${added_bitcode_targets} ${header_install_target}) +if (NOT LIBC_TARGET_ARCHITECTURE_IS_SPIRV) + list(APPEND install-libc-depends ${startup_target}) +endif() add_custom_target(install-libc - DEPENDS ${added_archive_targets} - ${added_bitcode_targets} - ${startup_target} - ${header_install_target} + DEPENDS ${install-libc-depends} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=libc -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") add_custom_target(install-libc-stripped - DEPENDS ${added_archive_targets} - ${added_bitcode_targets} - ${startup_target} - ${header_install_target} + DEPENDS ${install-libc-depends} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=libc -DCMAKE_INSTALL_DO_STRIP=1 diff --git a/libdevice/crt_wrapper.cpp b/libdevice/crt_wrapper.cpp index 8c9cb715f7036..f2952facb4266 100644 --- a/libdevice/crt_wrapper.cpp +++ b/libdevice/crt_wrapper.cpp @@ -17,6 +17,7 @@ __attribute__((weak)) DeviceGlobal RandNext; #ifdef __LIBDEVICE_TARGET_SUPPORT +#if defined(__NVPTX__) || defined(__AMDGCN__) DEVICE_EXTERN_C_INLINE void *memcpy(void *dest, const void *src, size_t n) { return __devicelib_memcpy(dest, src, n); @@ -84,6 +85,7 @@ int strncmp(const char *s1, const char *s2, size_t n) { return s1[idx] - s2[idx]; } +#endif // This simple rand is for ease of use only, the implementation aligns with // LLVM libc rand which is based on xorshift64star pseudo random number diff --git a/sycl-jit/jit-compiler/CMakeLists.txt b/sycl-jit/jit-compiler/CMakeLists.txt index e0ac377ac4195..e6b021d7a5b1b 100644 --- a/sycl-jit/jit-compiler/CMakeLists.txt +++ b/sycl-jit/jit-compiler/CMakeLists.txt @@ -18,7 +18,8 @@ set(SYCL_JIT_RESOURCE_INSTALL_COMPONENTS sycl-headers OpenCL-Headers clang-resource-headers - libsycldevice) + libsycldevice + runtimes-spirv64-unknown-unknown) set(libclc_enabled FALSE) foreach(target IN LISTS LLVM_RUNTIME_TARGETS) @@ -53,6 +54,9 @@ foreach(component IN LISTS SYCL_JIT_RESOURCE_INSTALL_COMPONENTS) sycl_jit_add_install_command("${component}" "${CMAKE_BINARY_DIR}/runtimes/runtimes-${tgt}-bins/libclc") endif() endforeach() + elseif("${component}" STREQUAL "runtimes-spirv64-unknown-unknown") + list(APPEND SYCL_JIT_RESOURCE_DEPS runtimes-spirv64-unknown-unknown) + sycl_jit_add_install_command("libc" "${CMAKE_BINARY_DIR}/runtimes/runtimes-spirv64-unknown-unknown-bins/libc") else() list(APPEND SYCL_JIT_RESOURCE_DEPS ${component}) sycl_jit_add_install_command("${component}" "${CMAKE_BINARY_DIR}") diff --git a/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp b/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp index 15ede8cc2bc10..1a4396fb40d41 100644 --- a/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp +++ b/sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp @@ -796,7 +796,7 @@ static void getDeviceLibraries(const ArgList &Args, #if defined(_WIN32) "libsycl-msvc-math", #endif - "libsycl-imf"}; + "libsycl-imf", "libc"}; StringRef LibSuffix = ".bc"; auto AddLibraries = [&](const SYCLDeviceLibsList &LibsList) { @@ -850,10 +850,14 @@ Error jit_compiler::linkDeviceLibraries(llvm::Module &Module, ? "nvptx64-nvidia-cuda" : "amdgcn-amd-amdhsa"; - std::string LibPath = - (LibName.find("libspirv") != std::string::npos) - ? (TC.getLibclcDir() + TripleName + "/" + LibName).str() - : (TC.getPrefix() + getLibPathSuffix() + LibName).str(); + std::string LibPath; + if (LibName.find("libspirv") != std::string::npos) + LibPath = (TC.getLibclcDir() + TripleName + "/" + LibName).str(); + else if (LibName == "libc.bc") + LibPath = + (TC.getPrefix() + "/lib/spirv64-unknown-unknown/" + LibName).str(); + else + LibPath = (TC.getPrefix() + getLibPathSuffix() + LibName).str(); ModuleUPtr LibModule; if (auto Error = diff --git a/sycl/CMakeLists.txt b/sycl/CMakeLists.txt index adbde3f63235e..605613a3697ea 100644 --- a/sycl/CMakeLists.txt +++ b/sycl/CMakeLists.txt @@ -546,6 +546,11 @@ if("lld" IN_LIST LLVM_ENABLE_PROJECTS) list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS lld) endif() +if ("libc" IN_LIST RUNTIMES_spirv64-unknown-unknown_LLVM_ENABLE_RUNTIMES) + add_dependencies(sycl-toolchain runtimes-spirv64-unknown-unknown) + list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS runtimes-spirv64-unknown-unknown) +endif() + set(libclc_enabled FALSE) foreach(target IN LISTS LLVM_RUNTIME_TARGETS) if("libclc" IN_LIST RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES)