diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index cc43503558be0..8a099a51df628 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 SYCLDefaultTripleImplied = false; + void setSYCLDefaultTriple(bool IsDefaultImplied) { + SYCLDefaultTripleImplied = IsDefaultImplied; + } + + /// 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; }; + /// 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. void addIntegrationFiles(StringRef IntHeaderName, StringRef IntFooterName, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0146787363c32..4d91d9c0061d0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2644,6 +2644,9 @@ def fno_sycl_use_footer : Flag<["-"], "fno-sycl-use-footer">, Flags<[CoreOption] def fsycl_footer_path_EQ : Joined<["-"], "fsycl-footer-path=">, Flags<[CoreOption]>, HelpText<"Specify the location of the temporary " "source file with the included integration footer.">; +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 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 1e19957ad921f..e0f4474d3c3dd 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().isSYCLDefaultTripleImplied()) + 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,11 @@ 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)) + setSYCLDefaultTriple(true); + // Populate the tool chains for the offloading devices, if any. CreateOffloadingDeviceToolChains(*C, Inputs); @@ -1428,7 +1453,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 +2788,30 @@ 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 @@ -2792,14 +2842,15 @@ 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) { +static SmallVector +getLinkerArgs(Compilation &C, 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 +2869,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)) { + isStaticArchiveFile(V) || (IncludeObj && isObjectFile(V.str()))) { LibArgs.push_back(Args.MakeArgString(V)); return; } @@ -2884,6 +2935,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. @@ -4665,6 +4736,7 @@ class OffloadingActionBuilder final { if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga) SYCLfpgaTriple = true; } + addSYCLDefaultTriple(C, SYCLTripleList); } if (SYCLAddTargets) { for (StringRef Val : SYCLAddTargets->getValues()) { @@ -4687,6 +4759,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 dc3c39af9f16c..2e5e3cf375b09 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(); @@ -8443,10 +8447,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..1efbd80023448 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().isSYCLDefaultTripleImplied()) + 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().isSYCLDefaultTripleImplied()) + 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().isSYCLDefaultTripleImplied()) + 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 0b3f3caf418b4..a9779d59934d3 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..1208f4214104c 100644 --- a/clang/test/Driver/sycl-offload.cpp +++ b/clang/test/Driver/sycl-offload.cpp @@ -47,3 +47,55 @@ // 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 +// 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-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-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-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-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" + +// 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"