diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 759ba0419bd45..0f17f4aa761ea 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -394,6 +394,8 @@ 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; +def err_drv_libclc_not_found : Error<"no libclc library '%0' found in the clang resource directory">; + 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 49c7149380fba..9802962d107c9 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 3c04aeb5af59c..6aab43c9ed57f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1422,6 +1422,21 @@ def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">, HelpText<"Do not override toolchain to compile HIP source to relocatable">; } +// Clang specific/exclusive options for OpenACC. +def openacc_macro_override + : Separate<["-"], "fexperimental-openacc-macro-override">, + Visibility<[ClangOption, CC1Option]>, + Group, + HelpText<"Overrides the _OPENACC macro value for experimental testing " + "during OpenACC support development">; +def openacc_macro_override_EQ + : Joined<["-"], "fexperimental-openacc-macro-override=">, + Alias; + +// End Clang specific/exclusive options for OpenACC. + +def libclc_lib_EQ : Joined<["--"], "libclc-lib=">, Group, + HelpText<"Namespec of libclc OpenCL bitcode library to link">; def libomptarget_amdgpu_bc_path_EQ : Joined<["--"], "libomptarget-amdgpu-bc-path=">, Group, HelpText<"Path to libomptarget-amdgcn bitcode library">; def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path=">, Group, diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 07816830f8e3d..5e463b9c98687 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -857,6 +857,9 @@ void AMDGPUToolChain::addClangTargetOptions( CC1Args.push_back("-fvisibility=hidden"); CC1Args.push_back("-fapply-global-visibility-to-externs"); } + + if (DeviceOffloadingKind == Action::OFK_None) + 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 334fcbb5b1eb2..53fd525e941e3 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2985,6 +2985,43 @@ 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 + const Arg *A = DriverArgs.getLastArg(options::OPT_libclc_lib_EQ); + if (!A) + return; + + // Find device libraries in /lib/clang//lib/libclc/ + SmallString<128> LibclcPath(D.ResourceDir); + llvm::sys::path::append(LibclcPath, "lib", "libclc"); + + // If the namespec is of the form :filename, search for that file. + StringRef LibclcNamespec(A->getValue()); + bool FilenameSearch = LibclcNamespec.consume_front(":"); + SmallString<128> LibclcTargetFile(LibclcNamespec); + + if (FilenameSearch && llvm::sys::fs::exists(LibclcTargetFile)) { + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(LibclcTargetFile)); + } else { + // Search the library paths for the file + if (!FilenameSearch) + LibclcTargetFile += ".bc"; + + llvm::sys::path::append(LibclcPath, LibclcTargetFile); + if (llvm::sys::fs::exists(LibclcPath)) { + CC1Args.push_back("-mlink-builtin-bitcode"); + CC1Args.push_back(DriverArgs.MakeArgString(LibclcPath)); + } else { + // Since the user requested a library, if we haven't one then report an + // error. + 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..185690768c75b --- /dev/null +++ b/clang/test/Driver/opencl-libclc.cl @@ -0,0 +1,9 @@ +// RUN: %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:%S/Inputs/libclc/libclc.bc %s 2>&1 | FileCheck %s +// RUN: %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:%S/Inputs/libclc/subdir/libclc.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-SUBDIR + +// RUN: not %clang -### -target amdgcn-amd-amdhsa --no-offloadlib --libclc-lib=:%S/Inputs/libclc/subdir/not-here.bc %s 2>&1 | FileCheck %s --check-prefix CHECK-ERROR + +// CHECK: -mlink-builtin-bitcode{{.*}}Inputs{{/|\\\\}}libclc{{/|\\\\}}libclc.bc +// CHECK-SUBDIR: -mlink-builtin-bitcode{{.*}}Inputs{{/|\\\\}}libclc{{/|\\\\}}subdir{{/|\\\\}}libclc.bc + +// CHECK-ERROR: no libclc library{{.*}}not-here.bc' found in the clang resource directory diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 5b95edc75bcdf..adfabf48297af 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -73,6 +73,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 ) @@ -92,10 +95,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: "