From a76062888fd97ab82919751f19cf5b1ba2211084 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Fri, 23 Jul 2021 17:01:44 -0700 Subject: [PATCH 1/5] [Driver][SYCL] Enable adding of default device triple Add the default device triple (spir64) when we encounter any incoming objects or libraries that have been previously built with the spir64 target. The use of -fno-sycl-link-spirv has been added to disable this behavior. Also add a supplemental option of -fsycl-add-spirv which will add the default device triple (spir64) if it is not already being used via -fsycl-targets. --- clang/include/clang/Driver/Driver.h | 19 +++++ clang/include/clang/Driver/Options.td | 6 ++ clang/lib/Driver/Driver.cpp | 85 +++++++++++++++++-- clang/lib/Driver/ToolChains/Clang.cpp | 8 +- clang/lib/Driver/ToolChains/SYCL.cpp | 41 ++++++--- clang/lib/Driver/ToolChains/SYCL.h | 10 ++- clang/test/Driver/sycl-intelfpga-aoco-win.cpp | 2 +- clang/test/Driver/sycl-intelfpga-aoco.cpp | 4 +- clang/test/Driver/sycl-offload-intelfpga.cpp | 1 - clang/test/Driver/sycl-offload.cpp | 57 +++++++++++++ 10 files changed, 207 insertions(+), 26 deletions(-) diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index cc43503558be0..1a0e019ad099d 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -655,6 +655,21 @@ class Driver { FPGAEmulationMode = IsEmulation; } + /// The inclusion of the default SYCL device triple is dependent on either + /// the discovery of an existing object/archive that contains the device code + /// or if a user explicitly turns this on with -fsycl-add-spirv. + /// We need to keep track of this so any use of any generic target option + /// setting is only applied to the user specified triples. + bool SYCLDefaultTripleSet = false; + void setSYCLDefaultTriple(bool IsDefaultSet) { + SYCLDefaultTripleSet = IsDefaultSet; + } + + /// Returns true if an offload binary is found that contains the default + /// triple for SYCL (spir64) + bool checkForSYCLDefaultDevice(Compilation &C, + llvm::opt::DerivedArgList &Args) const; + /// Returns true if an offload static library is found. bool checkForOffloadStaticLib(Compilation &C, llvm::opt::DerivedArgList &Args) const; @@ -714,6 +729,10 @@ class Driver { /// FPGA Emulation. This is only used for SYCL offloading to FPGA device. bool isFPGAEmulationMode() const { return FPGAEmulationMode; }; + /// isSYCLDefaultTripleSet - The default SYCL triple (spir64) has been added + /// or should be added given proper criteria. + bool isSYCLDefaultTripleSet() const { return SYCLDefaultTripleSet; }; + /// addIntegrationFiles - Add the integration files that will be populated /// by the device compilation and used by the host compile. void addIntegrationFiles(StringRef IntHeaderName, StringRef IntFooterName, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 05d6203453c20..709eeb3f19a15 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2635,6 +2635,12 @@ def fsycl_host_compiler_options_EQ : Joined<["-"], "fsycl-host-compiler-options= def fno_sycl_use_footer : Flag<["-"], "fno-sycl-use-footer">, Flags<[CoreOption]>, HelpText<"Disable usage of the integration footer during SYCL enabled " "compilations.">; +def fno_sycl_link_spirv : Flag<["-"], "fno-sycl-link-spirv">, + Flags<[CoreOption]>, HelpText<"Disable adding of the default (spir64) triple " + "when discovered in user specified objects and archives.">; +def fsycl_add_spirv : Flag<["-"], "fsycl-add-spirv">, Flags<[CoreOption]>, + HelpText<"Add the default spir64 device target to the compilation if not " + "specified with -fsycl-targets.">; def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[NoXarchOption,CoreOption,CC1Option,FC1Option]>, Group; def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index fb2ec73acaf4a..72ddebc040261 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -718,6 +718,23 @@ static bool isValidSYCLTriple(llvm::Triple T) { return true; } +static void addSYCLDefaultTriple(Compilation &C, + SmallVectorImpl &SYCLTriples) { + if (!C.getDriver().isSYCLDefaultTripleSet()) + return; + for (const auto &SYCLTriple : SYCLTriples) { + if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch && + SYCLTriple.isSPIR()) + return; + // If we encounter a known non-spir* target, do not add the default triple. + if (SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN()) + return; + } + // Add the default triple as it was not found. + llvm::Triple DefaultTriple = C.getDriver().MakeSYCLDeviceTriple("spir64"); + SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple); +} + void Driver::CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs) { @@ -929,6 +946,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, FoundNormalizedTriples[NormalizedName] = Val; UniqueSYCLTriplesVec.push_back(TT); } + addSYCLDefaultTriple(C, UniqueSYCLTriplesVec); } else Diag(clang::diag::warn_drv_empty_joined_argument) << SYCLTargetsValues->getAsString(C.getInputArgs()); @@ -987,8 +1005,10 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, else if (HasValidSYCLRuntime) // Triple for -fintelfpga is spir64_fpga-unknown-unknown-sycldevice. SYCLTargetArch = SYCLfpga ? "spir64_fpga" : "spir64"; - if (!SYCLTargetArch.empty()) + if (!SYCLTargetArch.empty()) { UniqueSYCLTriplesVec.push_back(MakeSYCLDeviceTriple(SYCLTargetArch)); + addSYCLDefaultTriple(C, UniqueSYCLTriplesVec); + } } // We'll need to use the SYCL and host triples as the key into // getOffloadingDeviceToolChain, because the device toolchains we're @@ -1418,6 +1438,12 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { if (checkForOffloadStaticLib(*C, *TranslatedArgs)) setOffloadStaticLibSeen(); + // Check for any objects/archives that need to be compiled with the default + // triple. + if (checkForSYCLDefaultDevice(*C, *TranslatedArgs) || + TranslatedArgs->hasArg(options::OPT_fsycl_add_spirv)) + setSYCLDefaultTriple(true); + // Populate the tool chains for the offloading devices, if any. CreateOffloadingDeviceToolChains(*C, Inputs); @@ -1428,7 +1454,8 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { const ToolChain *TC = SYCLTCRange.first->second; const toolchains::SYCLToolChain *SYCLTC = static_cast(TC); - SYCLTC->TranslateBackendTargetArgs(*TranslatedArgs, TargetArgs); + SYCLTC->TranslateBackendTargetArgs(SYCLTC->getTriple(), *TranslatedArgs, + TargetArgs); for (StringRef ArgString : TargetArgs) { if (ArgString.equals("-hardware") || ArgString.equals("-simulation")) { setFPGAEmulationMode(false); @@ -2762,6 +2789,29 @@ bool hasFPGABinary(Compilation &C, std::string Object, types::ID Type) { return runBundler(BundlerArgs, C); } +static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File) { + // Do not do the check if the file doesn't exist + if (!llvm::sys::fs::exists(File)) + return false; + + bool IsArchive = isStaticArchiveFile(File); + if (!(IsArchive || isObjectFile(File.str()))) + return false; + + llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple("spir64")); + // Checking uses -check-section option with the input file, no output + // file and the target triple being looked for. + const char *Targets = C.getArgs().MakeArgString( + Twine("-targets=sycl-") + TT.str()); + const char *Inputs = C.getArgs().MakeArgString( + Twine("-inputs=") + File.str()); + // Always use -type=ao for bundle checking. The 'bundles' are + // actually archives. + SmallVector BundlerArgs = {"clang-offload-bundler", + IsArchive ? "-type=ao" : "-type=o", Targets, Inputs, "-check-section"}; + return runBundler(BundlerArgs, C); +} + static bool hasOffloadSections(Compilation &C, const StringRef &Archive, DerivedArgList &Args) { // Do not do the check if the file doesn't exist @@ -2793,13 +2843,15 @@ static bool optionMatches(const std::string &Option, // handling options and explicitly named static archives as these need to be // partially linked. static SmallVector getLinkerArgs(Compilation &C, - DerivedArgList &Args) { + DerivedArgList &Args, + bool IncludeObj = false) { SmallVector LibArgs; for (const auto *A : Args) { std::string FileName = A->getAsString(Args); if (A->getOption().getKind() == Option::InputClass) { StringRef Value(A->getValue()); - if (isStaticArchiveFile(Value)) { + if (isStaticArchiveFile(Value) || + (IncludeObj && isObjectFile(Value.str()))) { LibArgs.push_back(Args.MakeArgString(FileName)); continue; } @@ -2818,7 +2870,8 @@ static SmallVector getLinkerArgs(Compilation &C, // Only add named static libs objects and --whole-archive options. if (optionMatches("-whole-archive", V.str()) || optionMatches("-no-whole-archive", V.str()) || - isStaticArchiveFile(V)) { + isStaticArchiveFile(V) || + (IncludeObj && isObjectFile(V.str()))) { LibArgs.push_back(Args.MakeArgString(V)); return; } @@ -2884,6 +2937,26 @@ static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv) { return Ret; } +// Goes through all of the arguments, including inputs expected for the +// linker directly, to determine if we need to potentially add the SYCL +// default triple. +bool Driver::checkForSYCLDefaultDevice(Compilation &C, + DerivedArgList &Args) const { + // Check only if enabled with -fsycl + if (!Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) + return false; + + if (Args.hasArg(options::OPT_fno_sycl_link_spirv)) + return false; + + SmallVector AllArgs(getLinkerArgs(C, Args, true)); + for (StringRef Arg : AllArgs) { + if (hasSYCLDefaultSection(C, Arg)) + return true; + } + return false; +} + // Goes through all of the arguments, including inputs expected for the // linker directly, to determine if we need to perform additional work for // static offload libraries. @@ -4666,6 +4739,7 @@ class OffloadingActionBuilder final { if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga) SYCLfpgaTriple = true; } + addSYCLDefaultTriple(C, SYCLTripleList); } if (SYCLAddTargets) { for (StringRef Val : SYCLAddTargets->getValues()) { @@ -4688,6 +4762,7 @@ class OffloadingActionBuilder final { const char *SYCLTargetArch = SYCLfpga ? "spir64_fpga" : "spir64"; SYCLTripleList.push_back( C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch)); + addSYCLDefaultTriple(C, SYCLTripleList); if (SYCLfpga) SYCLfpgaTriple = true; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df01fe9c93c5e..f9384c2d07e6e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8274,6 +8274,8 @@ void OffloadBundler::ConstructJobMultipleOutputs( if (getToolChain().getTriple().getSubArch() == llvm::Triple::SPIRSubArch_fpga && Dep.DependentOffloadKind == Action::OFK_SYCL) { + if (J++) + Triples += ','; llvm::Triple TT; TT.setArchName(types::getTypeName(InputType)); TT.setVendorName("intel"); @@ -8284,6 +8286,8 @@ void OffloadBundler::ConstructJobMultipleOutputs( } else if (getToolChain().getTriple().getSubArch() != llvm::Triple::SPIRSubArch_fpga && Dep.DependentOffloadKind == Action::OFK_Host) { + if (J++) + Triples += ','; Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind); Triples += '-'; Triples += Dep.DependentToolChain->getTriple().normalize(); @@ -8442,10 +8446,10 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA, // Only store compile/link opts in the image descriptor for the SPIR-V // target; AOT compilation has already been performed otherwise. TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs); - TC.TranslateBackendTargetArgs(TCArgs, BuildArgs); + TC.TranslateBackendTargetArgs(TT, TCArgs, BuildArgs); createArgString("-compile-opts="); BuildArgs.clear(); - TC.TranslateLinkerTargetArgs(TCArgs, BuildArgs); + TC.TranslateLinkerTargetArgs(TT, TCArgs, BuildArgs); createArgString("-link-opts="); } diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index 4bbf9b8f7b649..66d69956c4ac3 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -387,8 +387,8 @@ void SYCL::fpga::BackendCompiler::constructOpenCLAOTCommand( llvm::Triple CPUTriple("spir64_x86_64"); TC.AddImpliedTargetArgs(CPUTriple, Args, CmdArgs); // Add the target args passed in - TC.TranslateBackendTargetArgs(Args, CmdArgs); - TC.TranslateLinkerTargetArgs(Args, CmdArgs); + TC.TranslateBackendTargetArgs(CPUTriple, Args, CmdArgs); + TC.TranslateLinkerTargetArgs(CPUTriple, Args, CmdArgs); SmallString<128> ExecPath( getToolChain().GetProgramPath(makeExeName(C, "opencl-aot"))); @@ -414,7 +414,7 @@ void SYCL::fpga::BackendCompiler::ConstructJob( const toolchains::SYCLToolChain &TC = static_cast(getToolChain()); ArgStringList TargetArgs; - TC.TranslateBackendTargetArgs(Args, TargetArgs); + TC.TranslateBackendTargetArgs(TC.getTriple(), Args, TargetArgs); // When performing emulation compilations for FPGA AOT, we want to use // opencl-aot instead of aoc. @@ -534,8 +534,8 @@ void SYCL::fpga::BackendCompiler::ConstructJob( TC.AddImpliedTargetArgs(getToolChain().getTriple(), Args, CmdArgs); // Add -Xsycl-target* options. - TC.TranslateBackendTargetArgs(Args, CmdArgs); - TC.TranslateLinkerTargetArgs(Args, CmdArgs); + TC.TranslateBackendTargetArgs(getToolChain().getTriple(), Args, CmdArgs); + TC.TranslateLinkerTargetArgs(getToolChain().getTriple(), Args, CmdArgs); // Look for -reuse-exe=XX option if (Arg *A = Args.getLastArg(options::OPT_reuse_exe_EQ)) { @@ -581,8 +581,8 @@ void SYCL::gen::BackendCompiler::ConstructJob(Compilation &C, const toolchains::SYCLToolChain &TC = static_cast(getToolChain()); TC.AddImpliedTargetArgs(getToolChain().getTriple(), Args, CmdArgs); - TC.TranslateBackendTargetArgs(Args, CmdArgs); - TC.TranslateLinkerTargetArgs(Args, CmdArgs); + TC.TranslateBackendTargetArgs(getToolChain().getTriple(), Args, CmdArgs); + TC.TranslateLinkerTargetArgs(getToolChain().getTriple(), Args, CmdArgs); SmallString<128> ExecPath( getToolChain().GetProgramPath(makeExeName(C, "ocloc"))); const char *Exec = C.getArgs().MakeArgString(ExecPath); @@ -614,8 +614,8 @@ void SYCL::x86_64::BackendCompiler::ConstructJob( static_cast(getToolChain()); TC.AddImpliedTargetArgs(getToolChain().getTriple(), Args, CmdArgs); - TC.TranslateBackendTargetArgs(Args, CmdArgs); - TC.TranslateLinkerTargetArgs(Args, CmdArgs); + TC.TranslateBackendTargetArgs(getToolChain().getTriple(), Args, CmdArgs); + TC.TranslateLinkerTargetArgs(getToolChain().getTriple(), Args, CmdArgs); SmallString<128> ExecPath( getToolChain().GetProgramPath(makeExeName(C, "opencl-aot"))); const char *Exec = C.getArgs().MakeArgString(ExecPath); @@ -765,7 +765,8 @@ void SYCLToolChain::AddImpliedTargetArgs( } void SYCLToolChain::TranslateBackendTargetArgs( - const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { + const llvm::Triple &Triple, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { // Handle -Xs flags. for (auto *A : Args) { // When parsing the target args, the -Xs type option applies to all @@ -775,6 +776,15 @@ void SYCLToolChain::TranslateBackendTargetArgs( // -Xs "-DFOO -DBAR" // -XsDFOO -XsDBAR // All of the above examples will pass -DFOO -DBAR to the backend compiler. + + // Do not add the -Xs to the default SYCL triple (spir64) when we know we + // have implied the setting. + if ((A->getOption().matches(options::OPT_Xs) || + A->getOption().matches(options::OPT_Xs_separate)) && + Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && + getDriver().isSYCLDefaultTripleSet()) + continue; + if (A->getOption().matches(options::OPT_Xs)) { // Take the arg and create an option out of it. CmdArgs.push_back(Args.MakeArgString(Twine("-") + A->getValue())); @@ -788,13 +798,22 @@ void SYCLToolChain::TranslateBackendTargetArgs( continue; } } + // Do not process -Xsycl-target-backend for implied spir64 + if (Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && + getDriver().isSYCLDefaultTripleSet()) + return; // Handle -Xsycl-target-backend. TranslateTargetOpt(Args, CmdArgs, options::OPT_Xsycl_backend, options::OPT_Xsycl_backend_EQ); } void SYCLToolChain::TranslateLinkerTargetArgs( - const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { + const llvm::Triple &Triple, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Do not process -Xsycl-target-linker for implied spir64 + if (Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && + getDriver().isSYCLDefaultTripleSet()) + return; // Handle -Xsycl-target-linker. TranslateTargetOpt(Args, CmdArgs, options::OPT_Xsycl_linker, options::OPT_Xsycl_linker_EQ); diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h index e6c1ab2ed3966..e767ede212b9b 100644 --- a/clang/lib/Driver/ToolChains/SYCL.h +++ b/clang/lib/Driver/ToolChains/SYCL.h @@ -151,10 +151,12 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain { void AddImpliedTargetArgs(const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - void TranslateBackendTargetArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; - void TranslateLinkerTargetArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + void TranslateBackendTargetArgs(const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + void TranslateLinkerTargetArgs(const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; bool useIntegratedAs() const override { return true; } bool isPICDefault() const override { return false; } diff --git a/clang/test/Driver/sycl-intelfpga-aoco-win.cpp b/clang/test/Driver/sycl-intelfpga-aoco-win.cpp index c96b8f2ff9028..3cc1587ebf54c 100755 --- a/clang/test/Driver/sycl-intelfpga-aoco-win.cpp +++ b/clang/test/Driver/sycl-intelfpga-aoco-win.cpp @@ -3,7 +3,7 @@ // RUN: echo "void foo() {}" > %t.c // RUN: echo "void foo2() {}" > %t2.c // RUN: %clang -target x86_64-pc-windows-msvc -c -o %t.o %t.c -// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -c -o %t2.o %t2.c +// RUN: %clang_cl --target=x86_64-pc-windows-msvc -fsycl -fintelfpga -c -o %t2.o %t2.c // RUN: clang-offload-wrapper -o %t-aoco.bc -host=x86_64-pc-windows-msvc -kind=sycl -target=fpga_aoco-intel-unknown-sycldevice %t.aoco // RUN: llc -filetype=obj -o %t-aoco.o %t-aoco.bc // RUN: llvm-ar crv %t_aoco.a %t.o %t2.o %t-aoco.o diff --git a/clang/test/Driver/sycl-intelfpga-aoco.cpp b/clang/test/Driver/sycl-intelfpga-aoco.cpp index 2ba6edfbe2700..cf9160bd57968 100755 --- a/clang/test/Driver/sycl-intelfpga-aoco.cpp +++ b/clang/test/Driver/sycl-intelfpga-aoco.cpp @@ -5,8 +5,8 @@ // RUN: echo "void foo() {}" > %t.c // RUN: echo "void foo2() {}" > %t2.c // RUN: %clang -c -o %t.o %t.c -// RUN: %clang -fsycl -c -o %t2.o %t2.c -// RUN: %clang_cl -fsycl -c -o %t2_cl.o %t2.c +// RUN: %clang -fsycl -fintelfpga -c -o %t2.o %t2.c +// RUN: %clang_cl -fsycl -fintelfpga -c -o %t2_cl.o %t2.c // RUN: clang-offload-wrapper -o %t-aoco.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aoco-intel-unknown-sycldevice %t.aoco // RUN: llc -filetype=obj -o %t-aoco.o %t-aoco.bc // RUN: clang-offload-wrapper -o %t-aoco_cl.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aoco-intel-unknown-sycldevice %t.aoco diff --git a/clang/test/Driver/sycl-offload-intelfpga.cpp b/clang/test/Driver/sycl-offload-intelfpga.cpp index 1a035f866b5e7..1f8f42c93675f 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -46,7 +46,6 @@ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK,CHK-FPGA-IMAGE %s // RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fno-sycl-device-lib=all -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice -fsycl-link=image -Xshardware %t.o -o libfoo.a 2>&1 \ // RUN: | FileCheck -check-prefixes=CHK-FPGA-LINK,CHK-FPGA-IMAGE %s -// CHK-FPGA-LINK-NOT: clang-offload-bundler{{.*}} "-check-section" // CHK-FPGA-LINK: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64_fpga-unknown-unknown-sycldevice" "-inputs=[[INPUT:.+\.o]]" "-outputs=[[OUTPUT1:.+\.o]]" "-unbundle" // CHK-FPGA-LINK-NOT: clang-offload-bundler{{.*}} // CHK-FPGA-LINK: llvm-link{{.*}} "[[OUTPUT1]]" "-o" "[[OUTPUT2_1:.+\.bc]]" diff --git a/clang/test/Driver/sycl-offload.cpp b/clang/test/Driver/sycl-offload.cpp index b0ec06346bb6c..770aea9447f76 100644 --- a/clang/test/Driver/sycl-offload.cpp +++ b/clang/test/Driver/sycl-offload.cpp @@ -47,3 +47,60 @@ // CHECK_S_LLVM: clang{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm"{{.*}} "-o" "[[DEVICE:.+\.ll]]" // CHECK_S_LLVM: clang{{.*}} "-fsycl-is-host"{{.*}} "-emit-llvm"{{.*}} "-o" "[[HOST:.+\.ll]]" // CHECK_S_LLVM: clang-offload-bundler{{.*}} "-type=ll"{{.*}} "-inputs=[[DEVICE]],[[HOST]]" + +/// Check for default device triple compilations based on object, archive or +/// forced from command line. +// RUN: echo "void foo();" > %t_dummy.cpp +// RUN: %clang -fsycl -c %t_dummy.cpp -o %t_dummy.o +// RUN: llvm-ar cr %t_dummy.a %t_dummy.o +// RUN: touch %t_empty.o +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_x86_64 %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_fpga %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_gen %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fintelfpga %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_x86_64 %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_fpga %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_gen %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fintelfpga %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s +// IMPLIED_DEVICE_OBJ: clang-offload-bundler{{.*}} "-type=o"{{.*}} "-targets=sycl-spir64-unknown-unknown-sycldevice,sycl-spir64_{{.*}}-unknown-unknown-sycldevice"{{.*}} "-unbundle" + +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_x86_64 %t_dummy.a %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_LIB %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_fpga %t_dummy.a %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_LIB %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_gen %t_dummy.a %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_LIB %s +// RUN: %clangxx -### -fsycl -fintelfpga %t_dummy.a %s 2>&1 \ +// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_LIB %s +// IMPLIED_DEVICE_LIB: clang-offload-bundler{{.*}} "-type=a"{{.*}} "-targets=sycl-spir64-unknown-unknown-sycldevice,sycl-spir64_{{.*}}-unknown-unknown-sycldevice"{{.*}} "-unbundle" + +/// Check that the default device triple is not used with -fno-sycl-link-spirv +// RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_x86_64 %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_fpga %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_gen %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fintelfpga %t_dummy.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// NO_IMPLIED_DEVICE_OPT-NOT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice"{{.*}} "-check-section" +// NO_IMPLIED_DEVICE_OPT-NOT: clang-offload-bundler{{.*}} "-targets={{.*}}spir64-unknown-unknown-sycldevice{{.*}}" "-unbundle" + +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_x86_64 %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_fpga %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE %s +// RUN: %clangxx -### -fsycl -fsycl-targets=spir64_gen %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE %s +// RUN: %clangxx -### -fsycl -fintelfpga %t_empty.o %s 2>&1 \ +// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE %s +// NO_IMPLIED_DEVICE: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice"{{.*}} "-check-section" +// NO_IMPLIED_DEVICE-NOT: clang-offload-bundler{{.*}} "-targets={{.*}}spir64-unknown-unknown-sycldevice{{.*}}" "-unbundle" From 657a8d5e15a625c3efaa3c760d14c20c9f9983af Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Fri, 23 Jul 2021 17:06:26 -0700 Subject: [PATCH 2/5] clang format --- clang/lib/Driver/Driver.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 72ddebc040261..db934f55ac49a 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2801,14 +2801,15 @@ static bool hasSYCLDefaultSection(Compilation &C, const StringRef &File) { llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple("spir64")); // Checking uses -check-section option with the input file, no output // file and the target triple being looked for. - const char *Targets = C.getArgs().MakeArgString( - Twine("-targets=sycl-") + TT.str()); - const char *Inputs = C.getArgs().MakeArgString( - Twine("-inputs=") + File.str()); + const char *Targets = + C.getArgs().MakeArgString(Twine("-targets=sycl-") + TT.str()); + const char *Inputs = + C.getArgs().MakeArgString(Twine("-inputs=") + File.str()); // Always use -type=ao for bundle checking. The 'bundles' are // actually archives. SmallVector BundlerArgs = {"clang-offload-bundler", - IsArchive ? "-type=ao" : "-type=o", Targets, Inputs, "-check-section"}; + IsArchive ? "-type=ao" : "-type=o", + Targets, Inputs, "-check-section"}; return runBundler(BundlerArgs, C); } @@ -2842,9 +2843,8 @@ static bool optionMatches(const std::string &Option, // Process linker inputs for use with offload static libraries. We are only // handling options and explicitly named static archives as these need to be // partially linked. -static SmallVector getLinkerArgs(Compilation &C, - DerivedArgList &Args, - bool IncludeObj = false) { +static SmallVector +getLinkerArgs(Compilation &C, DerivedArgList &Args, bool IncludeObj = false) { SmallVector LibArgs; for (const auto *A : Args) { std::string FileName = A->getAsString(Args); @@ -2870,8 +2870,7 @@ static SmallVector getLinkerArgs(Compilation &C, // Only add named static libs objects and --whole-archive options. if (optionMatches("-whole-archive", V.str()) || optionMatches("-no-whole-archive", V.str()) || - isStaticArchiveFile(V) || - (IncludeObj && isObjectFile(V.str()))) { + isStaticArchiveFile(V) || (IncludeObj && isObjectFile(V.str()))) { LibArgs.push_back(Args.MakeArgString(V)); return; } From 9285bf96cb8d61b47b3a3d15542b6d69e365b58a Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Thu, 29 Jul 2021 12:17:55 -0700 Subject: [PATCH 3/5] Remove -fsycl-add-spirv, equivalent to just adding to -fsycl-targets --- clang/include/clang/Driver/Options.td | 3 --- clang/lib/Driver/Driver.cpp | 3 +-- clang/test/Driver/sycl-offload.cpp | 8 -------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2463baff42fcc..4d91d9c0061d0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2647,9 +2647,6 @@ def fsycl_footer_path_EQ : Joined<["-"], "fsycl-footer-path=">, def fno_sycl_link_spirv : Flag<["-"], "fno-sycl-link-spirv">, Flags<[CoreOption]>, HelpText<"Disable adding of the default (spir64) triple " "when discovered in user specified objects and archives.">; -def fsycl_add_spirv : Flag<["-"], "fsycl-add-spirv">, Flags<[CoreOption]>, - HelpText<"Add the default spir64 device target to the compilation if not " - "specified with -fsycl-targets.">; def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[NoXarchOption,CoreOption,CC1Option,FC1Option]>, Group; def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a098b2caf4b43..7a2a5016cc7e7 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1440,8 +1440,7 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // Check for any objects/archives that need to be compiled with the default // triple. - if (checkForSYCLDefaultDevice(*C, *TranslatedArgs) || - TranslatedArgs->hasArg(options::OPT_fsycl_add_spirv)) + if (checkForSYCLDefaultDevice(*C, *TranslatedArgs)) setSYCLDefaultTriple(true); // Populate the tool chains for the offloading devices, if any. diff --git a/clang/test/Driver/sycl-offload.cpp b/clang/test/Driver/sycl-offload.cpp index 770aea9447f76..e9641646357f4 100644 --- a/clang/test/Driver/sycl-offload.cpp +++ b/clang/test/Driver/sycl-offload.cpp @@ -62,14 +62,6 @@ // RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s // RUN: %clangxx -### -fsycl -fintelfpga %t_dummy.o %s 2>&1 \ // RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s -// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_x86_64 %t_empty.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s -// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_fpga %t_empty.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s -// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fsycl-targets=spir64_gen %t_empty.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s -// RUN: %clangxx -### -fsycl -fsycl-add-spirv -fintelfpga %t_empty.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix IMPLIED_DEVICE_OBJ %s // IMPLIED_DEVICE_OBJ: clang-offload-bundler{{.*}} "-type=o"{{.*}} "-targets=sycl-spir64-unknown-unknown-sycldevice,sycl-spir64_{{.*}}-unknown-unknown-sycldevice"{{.*}} "-unbundle" // RUN: %clangxx -### -fsycl -fsycl-targets=spir64_x86_64 %t_dummy.a %s 2>&1 \ From 032ff020237152c8d26018fd65e629fd78f89e0b Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Thu, 29 Jul 2021 12:26:45 -0700 Subject: [PATCH 4/5] [NFC] update func/variable names to better represent implied settings --- clang/include/clang/Driver/Driver.h | 12 ++++++------ clang/lib/Driver/Driver.cpp | 2 +- clang/lib/Driver/ToolChains/SYCL.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 1a0e019ad099d..8a099a51df628 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -660,9 +660,9 @@ class Driver { /// or if a user explicitly turns this on with -fsycl-add-spirv. /// We need to keep track of this so any use of any generic target option /// setting is only applied to the user specified triples. - bool SYCLDefaultTripleSet = false; - void setSYCLDefaultTriple(bool IsDefaultSet) { - SYCLDefaultTripleSet = IsDefaultSet; + bool SYCLDefaultTripleImplied = false; + void setSYCLDefaultTriple(bool IsDefaultImplied) { + SYCLDefaultTripleImplied = IsDefaultImplied; } /// Returns true if an offload binary is found that contains the default @@ -729,9 +729,9 @@ class Driver { /// FPGA Emulation. This is only used for SYCL offloading to FPGA device. bool isFPGAEmulationMode() const { return FPGAEmulationMode; }; - /// isSYCLDefaultTripleSet - The default SYCL triple (spir64) has been added - /// or should be added given proper criteria. - bool isSYCLDefaultTripleSet() const { return SYCLDefaultTripleSet; }; + /// isSYCLDefaultTripleImplied - The default SYCL triple (spir64) has been + /// added or should be added given proper criteria. + bool isSYCLDefaultTripleImplied() const { return SYCLDefaultTripleImplied; }; /// addIntegrationFiles - Add the integration files that will be populated /// by the device compilation and used by the host compile. diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 7a2a5016cc7e7..e0f4474d3c3dd 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -720,7 +720,7 @@ static bool isValidSYCLTriple(llvm::Triple T) { static void addSYCLDefaultTriple(Compilation &C, SmallVectorImpl &SYCLTriples) { - if (!C.getDriver().isSYCLDefaultTripleSet()) + if (!C.getDriver().isSYCLDefaultTripleImplied()) return; for (const auto &SYCLTriple : SYCLTriples) { if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch && diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index 66d69956c4ac3..1efbd80023448 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -782,7 +782,7 @@ void SYCLToolChain::TranslateBackendTargetArgs( if ((A->getOption().matches(options::OPT_Xs) || A->getOption().matches(options::OPT_Xs_separate)) && Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && - getDriver().isSYCLDefaultTripleSet()) + getDriver().isSYCLDefaultTripleImplied()) continue; if (A->getOption().matches(options::OPT_Xs)) { @@ -800,7 +800,7 @@ void SYCLToolChain::TranslateBackendTargetArgs( } // Do not process -Xsycl-target-backend for implied spir64 if (Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && - getDriver().isSYCLDefaultTripleSet()) + getDriver().isSYCLDefaultTripleImplied()) return; // Handle -Xsycl-target-backend. TranslateTargetOpt(Args, CmdArgs, options::OPT_Xsycl_backend, @@ -812,7 +812,7 @@ void SYCLToolChain::TranslateLinkerTargetArgs( llvm::opt::ArgStringList &CmdArgs) const { // Do not process -Xsycl-target-linker for implied spir64 if (Triple.getSubArch() == llvm::Triple::NoSubArch && Triple.isSPIR() && - getDriver().isSYCLDefaultTripleSet()) + getDriver().isSYCLDefaultTripleImplied()) return; // Handle -Xsycl-target-linker. TranslateTargetOpt(Args, CmdArgs, options::OPT_Xsycl_linker, From 346a16f9d633c8f27d76584ec4527ebbd6909e9e Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Thu, 29 Jul 2021 12:37:06 -0700 Subject: [PATCH 5/5] Update test to make sure expected device is compiled for --- clang/test/Driver/sycl-offload.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/test/Driver/sycl-offload.cpp b/clang/test/Driver/sycl-offload.cpp index e9641646357f4..1208f4214104c 100644 --- a/clang/test/Driver/sycl-offload.cpp +++ b/clang/test/Driver/sycl-offload.cpp @@ -76,13 +76,16 @@ /// Check that the default device triple is not used with -fno-sycl-link-spirv // RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_x86_64 %t_dummy.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: | FileCheck -check-prefixes=NO_IMPLIED_DEVICE_OPT,NO_IMPLIED_DEVICE_CPU %s // RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_fpga %t_dummy.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: | FileCheck -check-prefixes=NO_IMPLIED_DEVICE_OPT,NO_IMPLIED_DEVICE_FPGA %s // RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fsycl-targets=spir64_gen %t_dummy.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: | FileCheck -check-prefixes=NO_IMPLIED_DEVICE_OPT,NO_IMPLIED_DEVICE_GEN %s // RUN: %clangxx -### -fsycl -fno-sycl-link-spirv -fintelfpga %t_dummy.o %s 2>&1 \ -// RUN: | FileCheck -check-prefix NO_IMPLIED_DEVICE_OPT %s +// RUN: | FileCheck -check-prefixes=NO_IMPLIED_DEVICE_OPT,NO_IMPLIED_DEVICE_FPGA %s +// NO_IMPLIED_DEVICE_CPU: clang{{.*}} "-triple" "spir64_x86_64-unknown-unknown-sycldevice" +// NO_IMPLIED_DEVICE_FPGA: clang{{.*}} "-triple" "spir64_fpga-unknown-unknown-sycldevice" +// NO_IMPLIED_DEVICE_GEN: clang{{.*}} "-triple" "spir64_gen-unknown-unknown-sycldevice" // NO_IMPLIED_DEVICE_OPT-NOT: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown-sycldevice"{{.*}} "-check-section" // NO_IMPLIED_DEVICE_OPT-NOT: clang-offload-bundler{{.*}} "-targets={{.*}}spir64-unknown-unknown-sycldevice{{.*}}" "-unbundle"