diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -130,3 +130,12 @@ // RUN: -o a.out 2>&1 | FileCheck %s --check-prefix=MISSING-LIBRARY // MISSING-LIBRARY: error: unable to find library -ldummy + +// RUN: clang-offload-packager -o %t.out \ +// RUN: --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \ +// RUN: --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out +// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --clang-backend \ +// RUN: --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CLANG-BACKEND + +// CLANG-BACKEND: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx908 -O2 -Wl,--no-undefined {{.*}}.bc diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -427,6 +427,17 @@ for (StringRef Arg : Args.getAllArgValues(OPT_linker_arg_EQ)) CmdArgs.push_back(Args.MakeArgString("-Wl," + Arg)); + for (StringRef Arg : Args.getAllArgValues(OPT_builtin_bitcode_EQ)) { + if (llvm::Triple(Arg.split('=').first) == Triple) + CmdArgs.append({"-Xclang", "-mlink-builtin-bitcode", "-Xclang", + Args.MakeArgString(Arg.split('=').second)}); + } + + // The OpenMPOpt pass can introduce new calls and is expensive, we do not want + // this when running CodeGen through clang. + if (Args.hasArg(OPT_clang_backend) || Args.hasArg(OPT_builtin_bitcode_EQ)) + CmdArgs.append({"-mllvm", "-openmp-opt-disable"}); + if (Error Err = executeCommands(*ClangPath, CmdArgs)) return std::move(Err); @@ -629,7 +640,7 @@ llvm::erase_if(InputFiles, [](OffloadFile &F) { return !F.getBinary(); }); // LTO Module hook to output bitcode without running the backend. - SmallVector BitcodeOutput; + SmallVector BitcodeOutput; auto OutputBitcode = [&](size_t, const Module &M) { auto TempFileOrErr = createOutputFile(sys::path::filename(ExecutableName) + "-jit-" + Triple.getTriple(), @@ -648,7 +659,9 @@ // We assume visibility of the whole program if every input file was bitcode. auto Features = getTargetFeatures(BitcodeInputFiles); - auto LTOBackend = Args.hasArg(OPT_embed_bitcode) + auto LTOBackend = Args.hasArg(OPT_embed_bitcode) || + Args.hasArg(OPT_builtin_bitcode_EQ) || + Args.hasArg(OPT_clang_backend) ? createLTO(Args, Features, OutputBitcode) : createLTO(Args, Features); @@ -757,8 +770,12 @@ return Error::success(); } - // Append the new inputs to the device linker input. - for (StringRef File : Files) + // Append the new inputs to the device linker input. If the user requested an + // internalizing link we need to pass the bitcode to clang. + for (StringRef File : + Args.hasArg(OPT_clang_backend) || Args.hasArg(OPT_builtin_bitcode_EQ) + ? BitcodeOutput + : Files) OutputFiles.push_back(File); return Error::success(); diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td --- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td +++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td @@ -25,9 +25,16 @@ def bitcode_library_EQ : Joined<["--"], "bitcode-library=">, Flags<[WrapperOnlyOption]>, MetaVarName<"--=">, HelpText<"Extra bitcode library to link">; +def builtin_bitcode_EQ : Joined<["--"], "builtin-bitcode=">, + Flags<[WrapperOnlyOption]>, MetaVarName<"=">, + HelpText<"Perform a special internalizing link on the bitcode file. " + "This is necessary for some vendor libraries to be linked correctly">; def device_linker_args_EQ : Joined<["--"], "device-linker=">, Flags<[WrapperOnlyOption]>, MetaVarName<" or =">, HelpText<"Arguments to pass to the device linker invocation">; +def clang_backend : Flag<["--"], "clang-backend">, + Flags<[WrapperOnlyOption]>, + HelpText<"Run the backend using clang rather than the LTO backend">; def dry_run : Flag<["--"], "dry-run">, Flags<[WrapperOnlyOption]>, HelpText<"Print program arguments without running">;