https://github.com/frasercrmck updated https://github.com/llvm/llvm-project/pull/146503
>From 40f82d88c4a190fd63a2aff8abc53ea22dce10f5 Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Mon, 30 Jun 2025 10:59:02 +0100 Subject: [PATCH 1/4] [libclc] Place libclc files in clang's resource dir --- libclc/CMakeLists.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index e2871d1b01a16..8bc3a75739fcd 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -63,6 +63,9 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DI set( ${tool}_target ) endforeach() endif() + + # Setup the paths where libclc runtimes should be stored. + set( LIBCLC_OUTPUT_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) else() # In-tree configuration set( LIBCLC_STANDALONE_BUILD FALSE ) @@ -82,10 +85,14 @@ else() get_host_tool_path( llvm-link LLVM_LINK llvm-link_exe llvm-link_target ) get_host_tool_path( opt OPT opt_exe opt_target ) endif() -endif() -# Setup the paths where libclc runtimes should be stored. -set( LIBCLC_OUTPUT_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) + # Setup the paths where libclc runtimes should be stored. By default, in an + # in-tree build we place the libraries in clang's resource driectory. + get_clang_resource_dir( LIBCLC_OUTPUT_DIR PREFIX ${LLVM_LIBRARY_OUTPUT_INTDIR}/.. ) + + # Note we do not adhere to LLVM_ENABLE_PER_TARGET_RUNTIME_DIR. + set( LIBCLC_OUTPUT_LIBRARY_DIR ${LIBCLC_OUTPUT_DIR}/lib/libclc ) +endif() if( EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) message( WARNING "Using custom LLVM tools to build libclc: " >From 4e134b75a220b9ba8329ae978a4cbefe04b32dab Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Tue, 1 Jul 2025 10:56:54 +0100 Subject: [PATCH 2/4] [clang] Add the ability to link libclc OpenCL libraries This commit adds driver support for linking libclc OpenCL libraries. It takes the form of a new optional flag: --libclc-lib=namespec. Nothing is linked unless this flag is specified. Not all libclc targets have corresponding clang targets. For this reason it is desirable for users to be able to specify a libclc library name. We support this by taking both a library name (without the .bc suffix) or a filename. Both of these are searched for in the clang resource directory or in the LIBRARY_PATH environment variable. Filenames are also checked themselves so that absolute paths can be provided. The syntax for specifying filenames (as opposed to library names) uses a leading colon (:), inspired by the -l option. To accommodate this option, libclc libraries are now placed into clang's resource directory in an in-tree configuration. The aliases are not currently placed there to avoid polluting the directory, but that can be changed. The libraries are all placed in <resource-dir>/lib/libclc and are not grouped under host-specific directories as some other runtime libraries are; it is not expected that OpenCL libraries will differ depending on the host toolchain. Currently only the AMDGPU toolchain supports this option as a proof of concept. Other targets such as NVPTX or SPIR/SPIR-V could support it too. We could optionally let target toolchains search for libclc libraries themselves, possibly when passed an empty --libclc-lib. --- .../clang/Basic/DiagnosticDriverKinds.td | 3 + clang/include/clang/Driver/CommonArgs.h | 3 + clang/include/clang/Driver/Options.td | 2 + clang/lib/Driver/ToolChains/AMDGPU.cpp | 2 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 59 +++++++++++++++++++ clang/test/Driver/Inputs/libclc/libclc.bc | 0 .../Driver/Inputs/libclc/subdir/libclc.bc | 0 clang/test/Driver/opencl-libclc.cl | 10 ++++ 8 files changed, 79 insertions(+) create mode 100644 clang/test/Driver/Inputs/libclc/libclc.bc create mode 100644 clang/test/Driver/Inputs/libclc/subdir/libclc.bc create mode 100644 clang/test/Driver/opencl-libclc.cl diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 34b6c0d7a8acd..019161c22a24f 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -392,6 +392,9 @@ def warn_drv_fraw_string_literals_in_cxx11 : Warning< "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C and C++ standards before C++11">, InGroup<UnusedCommandLineArgument>; +def err_drv_libclc_not_found : Error< + "no libclc library '%0' found in the clang resource directory or in LIBRARY_PATH">; + def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index 26aa3ccf84786..7e8ab82eb7863 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -215,6 +215,9 @@ void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs, StringRef BitcodeSuffix, const llvm::Triple &Triple, const ToolChain &HostTC); +void addOpenCLBuiltinsLib(const Driver &D, const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args); + void addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 483516cf1b13d..d628010ceb330 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1421,6 +1421,8 @@ def openacc_macro_override_EQ // End Clang specific/exclusive options for OpenACC. +def libclc_lib_EQ : Joined<["--"], "libclc-lib=">, Group<opencl_Group>, + HelpText<"Namespec of libclc OpenCL bitcode library to link">; def libomptarget_amdgpu_bc_path_EQ : Joined<["--"], "libomptarget-amdgpu-bc-path=">, Group<i_Group>, HelpText<"Path to libomptarget-amdgcn bitcode library">; def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path=">, Group<i_Group>, diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index b7564a0495da8..e6d1baa2a1caa 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -795,6 +795,8 @@ void AMDGPUToolChain::addClangTargetOptions( CC1Args.push_back("-fvisibility=hidden"); CC1Args.push_back("-fapply-global-visibility-to-externs"); } + + addOpenCLBuiltinsLib(getDriver(), DriverArgs, CC1Args); } void AMDGPUToolChain::addClangWarningOptions(ArgStringList &CC1Args) const { diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 070901f037823..2a9abdf2004e8 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2942,6 +2942,65 @@ void tools::addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C, } } +void tools::addOpenCLBuiltinsLib(const Driver &D, + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) { + // Check whether user specifies a libclc bytecode library + if (const Arg *A = DriverArgs.getLastArg(options::OPT_libclc_lib_EQ)) { + SmallVector<StringRef, 8> LibraryPaths; + + // Add user defined library paths from LIBRARY_PATH. + std::optional<std::string> LibPath = + llvm::sys::Process::GetEnv("LIBRARY_PATH"); + if (LibPath) { + SmallVector<StringRef, 8> Frags; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; + llvm::SplitString(*LibPath, Frags, EnvPathSeparatorStr); + for (StringRef Path : Frags) + LibraryPaths.emplace_back(Path.trim()); + } + + // Find device libraries in <LLVM_DIR>/lib/clang/<ver>/lib/libclc/ + SmallString<128> LibclcPath(D.ResourceDir); + llvm::sys::path::append(LibclcPath, "lib", "libclc"); + LibraryPaths.emplace_back(LibclcPath); + + bool FoundBCLibrary = false; + StringRef LibclcNamespec(A->getValue()); + + // If the namespec is of the form :filename, search for that file. + bool FilenameSearch = LibclcNamespec.starts_with(":"); + SmallString<128> LibclcTargetFile( + LibclcNamespec.drop_front(FilenameSearch ? 1 : 0)); + + if (FilenameSearch && llvm::sys::fs::exists(LibclcTargetFile)) { + FoundBCLibrary = true; + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(LibclcTargetFile)); + } else { + // Search the library paths for the file + if (!FilenameSearch) + LibclcTargetFile += ".bc"; + + for (StringRef LibraryPath : LibraryPaths) { + SmallString<128> LibclcPath(LibraryPath); + llvm::sys::path::append(LibclcPath, LibclcTargetFile); + if (llvm::sys::fs::exists(LibclcPath)) { + FoundBCLibrary = true; + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(LibclcPath)); + break; + } + } + } + + // Since the user requested a library, if we haven't one then report an + // error. + if (!FoundBCLibrary) + D.Diag(diag::err_drv_libclc_not_found) << LibclcTargetFile; + } +} + void tools::addOutlineAtomicsArgs(const Driver &D, const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, diff --git a/clang/test/Driver/Inputs/libclc/libclc.bc b/clang/test/Driver/Inputs/libclc/libclc.bc new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/libclc/subdir/libclc.bc b/clang/test/Driver/Inputs/libclc/subdir/libclc.bc new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/opencl-libclc.cl b/clang/test/Driver/opencl-libclc.cl new file mode 100644 index 0000000000000..34b863b128682 --- /dev/null +++ b/clang/test/Driver/opencl-libclc.cl @@ -0,0 +1,10 @@ +// RUN: %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:%S/Inputs/libclc/libclc.bc %s 2>&1 | FileCheck %s +// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s +// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s + +// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR +// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR +// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:subdir/libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR + +// CHECK: -mlink-builtin-bitcode{{.*}}Inputs/libclc/libclc.bc +// CHECK-SUBDIR: -mlink-builtin-bitcode{{.*}}Inputs/libclc/subdir/libclc.bc >From 5b9e273c7a1f6947edd0b05b1eed07779fc5ec9d Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Tue, 1 Jul 2025 12:26:22 +0100 Subject: [PATCH 3/4] adjust LIBRARY_PATH usage in tests --- clang/test/Driver/opencl-libclc.cl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/test/Driver/opencl-libclc.cl b/clang/test/Driver/opencl-libclc.cl index 34b863b128682..8608a4f741b23 100644 --- a/clang/test/Driver/opencl-libclc.cl +++ b/clang/test/Driver/opencl-libclc.cl @@ -1,10 +1,10 @@ // RUN: %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:%S/Inputs/libclc/libclc.bc %s 2>&1 | FileCheck %s -// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s -// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s +// RUN: env LIBRARY_PATH=%S/Inputs/libclc %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s +// RUN: env LIBRARY_PATH=%S/Inputs/libclc %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s -// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR -// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR -// RUN: env LIBRARY_PATH=%S/Inputs/libclc:$LIBRARY_PATH %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:subdir/libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR +// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=libclc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR +// RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR +// RUN: env LIBRARY_PATH=%S/Inputs/libclc %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:subdir/libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR // CHECK: -mlink-builtin-bitcode{{.*}}Inputs/libclc/libclc.bc // CHECK-SUBDIR: -mlink-builtin-bitcode{{.*}}Inputs/libclc/subdir/libclc.bc >From 5f72f82793359da80a09d85155426170abad88fb Mon Sep 17 00:00:00 2001 From: Fraser Cormack <fra...@codeplay.com> Date: Tue, 1 Jul 2025 12:50:15 +0100 Subject: [PATCH 4/4] fix path checks --- clang/test/Driver/opencl-libclc.cl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/opencl-libclc.cl b/clang/test/Driver/opencl-libclc.cl index 8608a4f741b23..b7780d1af8d40 100644 --- a/clang/test/Driver/opencl-libclc.cl +++ b/clang/test/Driver/opencl-libclc.cl @@ -6,5 +6,5 @@ // RUN: env LIBRARY_PATH=%S/Inputs/libclc/subdir %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR // RUN: env LIBRARY_PATH=%S/Inputs/libclc %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:subdir/libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR -// CHECK: -mlink-builtin-bitcode{{.*}}Inputs/libclc/libclc.bc -// CHECK-SUBDIR: -mlink-builtin-bitcode{{.*}}Inputs/libclc/subdir/libclc.bc +// CHECK: -mlink-builtin-bitcode{{.*}}Inputs{{/|\\\\}}libclc{{/|\\\\}}libclc.bc +// CHECK-SUBDIR: -mlink-builtin-bitcode{{.*}}Inputs{{/|\\\\}}libclc{{/|\\\\}}subdir{{/|\\\\}}libclc.bc _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits