Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -73,6 +73,7 @@ InGroup; def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">; def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">; +def err_drv_invalid_hip_platform : Error<"Unsupported HIP Platform Selected.">; def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; def err_drv_invalid_linker_name : Error< Index: clang/include/clang/Driver/Action.h =================================================================== --- clang/include/clang/Driver/Action.h +++ clang/include/clang/Driver/Action.h @@ -73,9 +73,10 @@ OffloadBundlingJobClass, OffloadUnbundlingJobClass, OffloadWrapperJobClass, + StaticLibJobClass, JobClassFirst = PreprocessJobClass, - JobClassLast = OffloadWrapperJobClass + JobClassLast = StaticLibJobClass }; // The offloading kind determines if this action is binded to a particular @@ -637,6 +638,17 @@ } }; +class StaticLibJobAction : public JobAction { + void anchor() override; + +public: + StaticLibJobAction(ActionList &Inputs, types::ID Type); + + static bool classof(const Action *A) { + return A->getKind() == StaticLibJobClass; + } +}; + } // namespace driver } // namespace clang Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -580,6 +580,8 @@ def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[DriverOption]>, HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; +def hip_emit_static_lib : Flag<["--"], "hip-emit-static-lib">, + HelpText<"Link clang-offload-bundler bundles and generate static library for HIP.">; def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, Alias; def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, Index: clang/include/clang/Driver/ToolChain.h =================================================================== --- clang/include/clang/Driver/ToolChain.h +++ clang/include/clang/Driver/ToolChain.h @@ -139,6 +139,7 @@ mutable std::unique_ptr Flang; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; + mutable std::unique_ptr StaticLibTool; mutable std::unique_ptr IfsMerge; mutable std::unique_ptr OffloadBundler; mutable std::unique_ptr OffloadWrapper; @@ -147,6 +148,7 @@ Tool *getFlang() const; Tool *getAssemble() const; Tool *getLink() const; + Tool *getStaticLibTool() const; Tool *getIfsMerge() const; Tool *getClangAs() const; Tool *getOffloadBundler() const; @@ -174,6 +176,7 @@ virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; + virtual Tool *buildStaticLibTool() const; virtual Tool *getTool(Action::ActionClass AC) const; /// \name Utilities for implementing subclasses. @@ -326,6 +329,8 @@ /// the linker suffix or name. std::string GetLinkerPath() const; + std::string GetStaticLibToolPath() const; + /// Dispatch to the specific toolchain for verbose printing. /// /// This is used when handling the verbose option to print detailed, Index: clang/lib/Driver/Action.cpp =================================================================== --- clang/lib/Driver/Action.cpp +++ clang/lib/Driver/Action.cpp @@ -43,6 +43,8 @@ return "clang-offload-unbundler"; case OffloadWrapperJobClass: return "clang-offload-wrapper"; + case StaticLibJobClass: + return "static-lib-linker"; } llvm_unreachable("invalid class"); @@ -415,3 +417,8 @@ OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs, types::ID Type) : JobAction(OffloadWrapperJobClass, Inputs, Type) {} + +void StaticLibJobAction::anchor() {} + +StaticLibJobAction::StaticLibJobAction(ActionList &Inputs, types::ID Type) + : JobAction(StaticLibJobClass, Inputs, Type) {} Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -3498,7 +3498,13 @@ if (!LinkerInputs.empty()) { if (Action *Wrapper = OffloadBuilder.makeHostLinkAction()) LinkerInputs.push_back(Wrapper); - Action *LA = C.MakeAction(LinkerInputs, types::TY_Image); + Action *LA; + // Choose StaticLibJob if option is passed, otherwise use default LinkerJob + if (Args.hasArg(options::OPT_hip_emit_static_lib)) { + LA = C.MakeAction(LinkerInputs, types::TY_Image); + } else { + LA = C.MakeAction(LinkerInputs, types::TY_Image); + } LA = OffloadBuilder.processHostLinkAction(LA); Actions.push_back(LA); } Index: clang/lib/Driver/ToolChain.cpp =================================================================== --- clang/lib/Driver/ToolChain.cpp +++ clang/lib/Driver/ToolChain.cpp @@ -272,6 +272,10 @@ llvm_unreachable("Linking is not supported by this toolchain"); } +Tool *ToolChain::buildStaticLibTool() const { + llvm_unreachable("Creating static lib is not supported by this toolchain"); +} + Tool *ToolChain::getAssemble() const { if (!Assemble) Assemble.reset(buildAssembler()); @@ -290,6 +294,12 @@ return Link.get(); } +Tool *ToolChain::getStaticLibTool() const { + if (!StaticLibTool) + StaticLibTool.reset(buildStaticLibTool()); + return StaticLibTool.get(); +} + Tool *ToolChain::getIfsMerge() const { if (!IfsMerge) IfsMerge.reset(new tools::ifstool::Merger(*this)); @@ -319,6 +329,9 @@ case Action::LinkJobClass: return getLink(); + case Action::StaticLibJobClass: + return getStaticLibTool(); + case Action::InputClass: case Action::BindArchClass: case Action::OffloadClass: @@ -562,6 +575,11 @@ return GetProgramPath(getDefaultLinker()); } +std::string ToolChain::GetStaticLibToolPath() const { + // TODO: Add support for static lib archiving on Windows + return GetProgramPath("llvm-ar"); +} + types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { types::ID id = types::lookupTypeForExtension(Ext); Index: clang/lib/Driver/ToolChains/CommonArgs.h =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.h +++ clang/lib/Driver/ToolChains/CommonArgs.h @@ -45,11 +45,12 @@ llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args); -void AddHIPLinkerScript(const ToolChain &TC, Compilation &C, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs, const JobAction &JA, - const Tool &T); +void AddGenerateObjFileFromHIPFatBinary(const ToolChain &TC, Compilation &C, + const InputInfo &Output, + const InputInfoList &Inputs, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + const JobAction &JA, const Tool &T); const char *SplitDebugName(const llvm::opt::ArgList &Args, const InputInfo &Input, const InputInfo &Output); Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1286,17 +1286,15 @@ } } -/// Add HIP linker script arguments at the end of the argument list so that -/// the fat binary is built by embedding the device images into the host. The -/// linker script also defines a symbol required by the code generation so that +/// Add Generated HIP Object File which has device images embedded into the +/// host to the argument list for linking. Using MC directives, embed the +/// device code and also define symbols required by the code generation so that /// the image can be retrieved at runtime. This should be used only in tool -/// chains that support linker scripts. -void tools::AddHIPLinkerScript(const ToolChain &TC, Compilation &C, - const InputInfo &Output, - const InputInfoList &Inputs, const ArgList &Args, - ArgStringList &CmdArgs, const JobAction &JA, - const Tool &T) { - +/// chains that support llvm-mc. +void tools::AddGenerateObjFileFromHIPFatBinary( + const ToolChain &TC, Compilation &C, const InputInfo &Output, + const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, + const JobAction &JA, const Tool &T) { // If this is not a HIP host toolchain, we don't need to do anything. if (!JA.isHostOffloading(Action::OFK_HIP)) return; @@ -1313,86 +1311,82 @@ if (DeviceInputs.empty()) return; - // Create temporary linker script. Keep it if save-temps is enabled. - const char *LKS; std::string Name = std::string(llvm::sys::path::filename(Output.getFilename())); - if (C.getDriver().isSaveTempsEnabled()) { - LKS = C.getArgs().MakeArgString(Name + ".lk"); - } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "lk"); - LKS = C.addTempFile(C.getArgs().MakeArgString(TmpName)); - } - - // Add linker script option to the command. - CmdArgs.push_back("-T"); - CmdArgs.push_back(LKS); - // Create a buffer to write the contents of the linker script. - std::string LksBuffer; - llvm::raw_string_ostream LksStream(LksBuffer); - - // Get the HIP offload tool chain. - auto *HIPTC = static_cast( - C.getSingleOffloadToolChain()); - assert(HIPTC->getTriple().getArch() == llvm::Triple::amdgcn && - "Wrong platform"); - (void)HIPTC; + // Only supporting HIP on amdgcn platform + if(C.getSingleOffloadToolChain()->getTriple().getArch() != + llvm::Triple::amdgcn) { + C.getDriver().Diag(clang::diag::err_drv_invalid_hip_platform); + return; + } + // Create Temp Object File Generator, + // Offload Bundled file and Bundled Object file. + // Keep them if save-temps is enabled. + const char *McinFile; const char *BundleFile; + const char *BundledObjFile; if (C.getDriver().isSaveTempsEnabled()) { + McinFile = C.getArgs().MakeArgString(Name + ".mcin"); BundleFile = C.getArgs().MakeArgString(Name + ".hipfb"); + BundledObjFile = C.getArgs().MakeArgString(Name + ".hipfbo"); } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "hipfb"); - BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpName)); + auto TmpNameMcin = C.getDriver().GetTemporaryPath(Name, "mcin"); + McinFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameMcin)); + auto TmpNameFb = C.getDriver().GetTemporaryPath(Name, "hipfb"); + BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameFb)); + auto TmpNameFbo = C.getDriver().GetTemporaryPath(Name, "hipfbo"); + BundledObjFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameFbo)); } AMDGCN::constructHIPFatbinCommand(C, JA, BundleFile, DeviceInputs, Args, T); - // Add commands to embed target binaries. We ensure that each section and - // image is 16-byte aligned. This is not mandatory, but increases the - // likelihood of data to be aligned with a cache block in several main host - // machines. - LksStream << "/*\n"; - LksStream << " HIP Offload Linker Script\n"; - LksStream << " *** Automatically generated by Clang ***\n"; - LksStream << "*/\n"; - LksStream << "TARGET(binary)\n"; - LksStream << "INPUT(" << BundleFile << ")\n"; - LksStream << "SECTIONS\n"; - LksStream << "{\n"; - LksStream << " .hip_fatbin :\n"; - LksStream << " ALIGN(0x10)\n"; - LksStream << " {\n"; - LksStream << " PROVIDE_HIDDEN(__hip_fatbin = .);\n"; - LksStream << " " << BundleFile << "\n"; - LksStream << " }\n"; - LksStream << " /DISCARD/ :\n"; - LksStream << " {\n"; - LksStream << " * ( __CLANG_OFFLOAD_BUNDLE__* )\n"; - LksStream << " }\n"; - LksStream << "}\n"; - LksStream << "INSERT BEFORE .data\n"; - LksStream.flush(); - - // Dump the contents of the linker script if the user requested that. We - // support this option to enable testing of behavior with -###. + // Create a buffer to write the contents of the temp obj generator. + std::string ObjBuffer; + llvm::raw_string_ostream ObjStream(ObjBuffer); + + // Add MC directives to embed target binaries. We ensure that each + // section and image is 16-byte aligned. This is not mandatory, but + // increases the likelihood of data to be aligned with a cache block + // in several main host machines. + ObjStream << "# HIP Object Generator\n"; + ObjStream << "# *** Automatically generated by Clang ***\n"; + ObjStream << " .type __hip_fatbin,@object\n"; + ObjStream << " .section .hip_fatbin,\"aMS\",@progbits,1\n"; + ObjStream << " .data\n"; + ObjStream << " .globl __hip_fatbin\n"; + ObjStream << " .p2align 3\n"; + ObjStream << "__hip_fatbin:\n"; + ObjStream << " .incbin \"" << BundleFile << "\"\n"; + ObjStream.flush(); + + // Dump the contents of the temp object file gen if the user requested that. + // We support this option to enable testing of behavior with -###. if (C.getArgs().hasArg(options::OPT_fhip_dump_offload_linker_script)) - llvm::errs() << LksBuffer; + llvm::errs() << ObjBuffer; + + ArgStringList McArgs{"-triple", Args.MakeArgString(TC.getTripleString()), + "-o", BundledObjFile, + McinFile, "--filetype=obj"}; + const char *Mc = Args.MakeArgString(TC.GetProgramPath("llvm-mc")); + C.addCommand(std::make_unique(JA, T, Mc, McArgs, Inputs)); + + CmdArgs.push_back(BundledObjFile); - // If this is a dry run, do not create the linker script file. + // If this is a dry run, do not create the temp object file generator. if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) return; // Open script file and write the contents. std::error_code EC; - llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream Objf(McinFile, EC, llvm::sys::fs::OF_None); if (EC) { C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); return; } - Lksf << LksBuffer; + Objf << ObjBuffer; } SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args, Index: clang/lib/Driver/ToolChains/Gnu.h =================================================================== --- clang/lib/Driver/ToolChains/Gnu.h +++ clang/lib/Driver/ToolChains/Gnu.h @@ -71,6 +71,20 @@ const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; }; + +class LLVM_LIBRARY_VISIBILITY StaticLibTool : public GnuTool { +public: + StaticLibTool(const ToolChain &TC) + : GnuTool("GNU::StaticLibTool", "static-lib-linker", TC) {} + + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; } // end namespace gnutools /// gcc - Generic GCC tool implementations. Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -341,6 +341,47 @@ !Args.hasArg(options::OPT_static_pie); } +void tools::gnutools::StaticLibTool::ConstructJob( + Compilation &C, const JobAction &JA, const InputInfo &Output, + const InputInfoList &Inputs, const ArgList &Args, + const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + + // Silence warning for "clang -g foo.o -o foo" + Args.ClaimAllArgs(options::OPT_g_Group); + // and "clang -emit-llvm foo.o -o foo" + Args.ClaimAllArgs(options::OPT_emit_llvm); + // and for "clang -w foo.o -o foo". Other warning options are already + // handled somewhere else. + Args.ClaimAllArgs(options::OPT_w); + // Silence warnings when linking C code with a C++ '-stdlib' argument. + Args.ClaimAllArgs(options::OPT_stdlib_EQ); + + // GNU ar tool command "ar ". + ArgStringList CmdArgs; + // Create and insert file members with a deterministic index. + CmdArgs.push_back("rcsD"); + CmdArgs.push_back(Output.getFilename()); + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + // Delete old output archive file if it already exists before generating a new + // archive file. + auto OutputFileName = Output.getFilename(); + if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) { + if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) { + D.Diag(diag::err_drv_unable_to_remove_file) << EC.message(); + return; + } + } + + // Add Generated HIP Bundled Object File. + AddGenerateObjFileFromHIPFatBinary(getToolChain(), C, Output, Inputs, Args, + CmdArgs, JA, *this); + + const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); + C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); +} + void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -626,9 +667,9 @@ } } - // Add HIP offloading linker script args if required. - AddHIPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA, - *this); + // Add Generated HIP Bundled Object File. + AddGenerateObjFileFromHIPFatBinary(getToolChain(), C, Output, Inputs, Args, + CmdArgs, JA, *this); Args.AddAllArgs(CmdArgs, options::OPT_T); Index: clang/lib/Driver/ToolChains/Linux.h =================================================================== --- clang/lib/Driver/ToolChains/Linux.h +++ clang/lib/Driver/ToolChains/Linux.h @@ -55,6 +55,7 @@ protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; + Tool *buildStaticLibTool() const override; std::string getMultiarchTriple(const Driver &D, const llvm::Triple &TargetTriple, Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -363,6 +363,10 @@ Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } +Tool *Linux::buildStaticLibTool() const { + return new tools::gnutools::StaticLibTool(*this); +} + Tool *Linux::buildAssembler() const { return new tools::gnutools::Assembler(*this); } Index: clang/test/Driver/bindings.c =================================================================== --- clang/test/Driver/bindings.c +++ clang/test/Driver/bindings.c @@ -23,3 +23,7 @@ // CHECK14: "clang", inputs: ["{{.*}}bindings.c"], output: "{{.*}}.s" // CHECK14: "darwin::Assembler", inputs: ["{{.*}}.s"], output: "{{.*}}.o" // CHECK14: "darwin::Linker", inputs: ["{{.*}}.o"], output: "a.out" + +// GNU StaticLibTool binding +// RUN: %clang -target x86_64-linux-gnu -ccc-print-bindings --hip-emit-static-lib %s 2>&1 | FileCheck %s --check-prefix=CHECK15 +// CHECK15: "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["{{.*}}.o"], output: "a.out" Index: clang/test/Driver/hip-link-static-library.hip =================================================================== --- /dev/null +++ clang/test/Driver/hip-link-static-library.hip @@ -0,0 +1,24 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: touch %t.o +// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \ +// RUN: --hip-emit-static-lib \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 -fgpu-rdc %t.o\ +// RUN: 2>&1 | FileCheck %s + +// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"] +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ2]]"], output: "[[IMG2:.*out]]" +// CHECK-NOT: offload bundler +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]" +// CHECK-NOT: offload bundler +// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["[[OBJ1]]", "[[IMG2]]", "[[IMG3]]"], output: "a.out" + +// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \ +// RUN: --hip-emit-static-lib \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o\ +// RUN: 2>&1 | FileCheck -check-prefix=NORDC %s + +// NORDC-NOT: offload bundler +// NORDC: # "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["{{.*o}}"], output: "a.out" Index: clang/test/Driver/hip-toolchain-rdc-static-lib.hip =================================================================== --- /dev/null +++ clang/test/Driver/hip-toolchain-rdc-static-lib.hip @@ -0,0 +1,94 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 \ +// RUN: --hip-emit-static-lib -nogpulib \ +// RUN: -fuse-ld=lld -fgpu-rdc \ +// RUN: %S/Inputs/hip_multiple_inputs/a.cu \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s + +// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]] + +// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC]] [[B_BC]] +// CHECK-SAME: "-o" [[LINKED_BC_DEV1:".*-gfx803-linked-.*bc"]] + +// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV1]] "-mtriple=amdgcn-amd-amdhsa" +// CHECK-SAME: "-mcpu=gfx803" +// CHECK-SAME: "-o" [[OPT_BC_DEV1:".*-gfx803-optimized.*bc"]] + +// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV1]] "-mtriple=amdgcn-amd-amdhsa" +// CHECK-SAME: "-mcpu=gfx803" +// CHECK-SAME: "-filetype=obj" +// CHECK-SAME: "-o" [[OBJ_DEV1:".*-gfx803-.*o"]] + +// CHECK: [[LLD: ".*lld"]] {{.*}} "-o" "[[IMG_DEV1:.*out]]" [[OBJ_DEV1]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx900" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx900" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC]] + +// CHECK: [[LLVM_LINK]] [[A_BC]] [[B_BC]] +// CHECK-SAME: "-o" [[LINKED_BC_DEV2:".*-gfx900-linked-.*bc"]] + +// CHECK: [[OPT]] [[LINKED_BC_DEV2]] "-mtriple=amdgcn-amd-amdhsa" +// CHECK-SAME: "-mcpu=gfx900" +// CHECK-SAME: "-o" [[OPT_BC_DEV2:".*-gfx900-optimized.*bc"]] + +// CHECK: [[LLC]] [[OPT_BC_DEV2]] "-mtriple=amdgcn-amd-amdhsa" +// CHECk-SAME: "-mcpu=gfx900" +// CHECK-SAME: "-filetype=obj" +// CHECK-SAME: "-o" [[OBJ_DEV2:".*-gfx900-.*o"]] + +// CHECK: [[LLD]] {{.*}} "-o" "[[IMG_DEV2:.*out]]" [[OBJ_DEV2]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" +// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" +// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC]] + +// CHECK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" +// CHECK-SAME: "-targets={{.*}},hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" +// CHECK-SAME: "-inputs={{.*}},[[IMG_DEV1]],[[IMG_DEV2]]" "-outputs=[[BUNDLE:.*hipfb]]" + +// CHECK: [[MC:".*llvm-mc"]] "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-o" [[OBJBUNDLE:".*hipfbo"]] "{{.*}}.mcin" "--filetype=obj" + +// CHECK: [[AR:".*llvm-ar.*"]] "rcsD" "{{.*}}.out" [[A_OBJ_HOST]] [[B_OBJ_HOST]] [[OBJBUNDLE]] Index: clang/test/Driver/hip-toolchain-rdc.hip =================================================================== --- clang/test/Driver/hip-toolchain-rdc.hip +++ clang/test/Driver/hip-toolchain-rdc.hip @@ -98,5 +98,7 @@ // CHECK-SAME: "-targets={{.*}},hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" // CHECK-SAME: "-inputs={{.*}},[[IMG_DEV1]],[[IMG_DEV2]]" "-outputs=[[BUNDLE:.*hipfb]]" -// CHECK: [[LD:".*ld.*"]] {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]] -// CHECK-SAME: {{.*}} "-T" "{{.*}}.lk" +// CHECK: [[MC:".*llvm-mc"]] "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-o" [[OBJBUNDLE:".*hipfbo"]] "{{.*}}.mcin" "--filetype=obj" + +// CHECK: [[LD:".*ld.*"]] {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]] {{.*}} [[OBJBUNDLE]]