Skip to content

Commit 692f758

Browse files
committed
[Driver][SYCL] Improvements to -fsycl-device-only behaviors
Make some improvements to -fsycl-device-only to better match the device compilations for regular -fsycl device compiles. - Do not force the device triple at the initial target setting, allowing for improved capabilities with user provided -target <triple> - Allow for proper C++ assumptions (source and standard)
1 parent 049ae99 commit 692f758

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,17 +1263,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
12631263
T.setObjectFormat(llvm::Triple::COFF);
12641264
TargetTriple = T.str();
12651265
}
1266-
if (Args.hasArg(options::OPT_fsycl_device_only)) {
1267-
// -fsycl-device-only implies spir arch and SYCL Device
1268-
llvm::Triple T(TargetTriple);
1269-
// FIXME: defaults to spir64, should probably have a way to set spir
1270-
// possibly new -sycl-target option
1271-
T.setArch(llvm::Triple::spir64);
1272-
T.setVendor(llvm::Triple::UnknownVendor);
1273-
T.setOS(llvm::Triple(llvm::sys::getProcessTriple()).getOS());
1274-
T.setEnvironment(llvm::Triple::SYCLDevice);
1275-
TargetTriple = T.str();
1276-
}
12771266
if (const Arg *A = Args.getLastArg(options::OPT_target))
12781267
TargetTriple = A->getValue();
12791268
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
@@ -2384,7 +2373,9 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
23842373
// actually use it, so we warn about unused -x arguments.
23852374
types::ID InputType = types::TY_Nothing;
23862375
Arg *InputTypeArg = nullptr;
2387-
bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false);
2376+
bool IsSYCL =
2377+
Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) ||
2378+
Args.hasArg(options::OPT_fsycl_device_only);
23882379

23892380
// The last /TC or /TP option sets the input type to C or C++ globally.
23902381
if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3978,14 +3978,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
39783978
const ArgList &Args, const char *LinkingOutput) const {
39793979
const auto &TC = getToolChain();
39803980
const llvm::Triple &RawTriple = TC.getTriple();
3981-
const llvm::Triple &Triple = TC.getEffectiveTriple();
3982-
const std::string &TripleStr = Triple.getTriple();
3981+
llvm::Triple Triple = TC.getEffectiveTriple();
39833982

39843983
bool KernelOrKext =
39853984
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
39863985
const Driver &D = TC.getDriver();
39873986
ArgStringList CmdArgs;
39883987

3988+
// -fsycl-device-only implies a SPIRV arch triple. Do not set if current
3989+
// effective triple is SYCLDevice
3990+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
3991+
Triple.getEnvironment() != llvm::Triple::SYCLDevice) {
3992+
const char *SYCLTargetArch = "spir64";
3993+
if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
3994+
SYCLTargetArch = "spir";
3995+
Triple = C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch);
3996+
}
3997+
const std::string &TripleStr = Triple.getTriple();
3998+
39893999
// Check number of inputs for sanity. We need at least one input.
39904000
assert(Inputs.size() >= 1 && "Must have at least one input.");
39914001
// CUDA/HIP compilation may have multiple inputs (source file + results of
@@ -4000,7 +4010,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40004010
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
40014011
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
40024012
bool IsSYCLOffloadDevice = JA.isDeviceOffloading(Action::OFK_SYCL);
4003-
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL);
4013+
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL) ||
4014+
Args.hasArg(options::OPT_fsycl_device_only);
40044015
bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
40054016
assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) || IsSYCL ||
40064017
IsHeaderModulePrecompile || Inputs.size() == 1) &&
@@ -4048,14 +4059,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40484059
(IsSYCL || IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
40494060
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
40504061
bool IsIAMCU = RawTriple.isOSIAMCU();
4051-
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice);
4062+
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice ||
4063+
Triple.getEnvironment() == llvm::Triple::SYCLDevice);
40524064
// Using just the sycldevice environment is not enough to determine usage
40534065
// of the device triple when considering fat static archives. The
40544066
// compilation path requires the host object to be fed into the partial link
40554067
// step, and being part of the SYCL tool chain causes the incorrect target.
40564068
// FIXME - Is it possible to retain host environment when on a target
40574069
// device toolchain.
4058-
bool UseSYCLTriple = IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice);
4070+
bool UseSYCLTriple =
4071+
IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice ||
4072+
Args.hasArg(options::OPT_fsycl_device_only));
40594073

40604074
// Adjust IsWindowsXYZ for CUDA/HIP/SYCL compilations. Even when compiling in
40614075
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
@@ -4144,7 +4158,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41444158
options::OPT_fno_sycl_early_optimizations,
41454159
Triple.getSubArch() != llvm::Triple::SPIRSubArch_fpga))
41464160
CmdArgs.push_back("-fno-sycl-early-optimizations");
4147-
else if (RawTriple.isSPIR()) {
4161+
else if (IsSYCLDevice) {
41484162
// Set `sycl-opt` option to configure LLVM passes for SPIR target
41494163
CmdArgs.push_back("-mllvm");
41504164
CmdArgs.push_back("-sycl-opt");
@@ -4157,7 +4171,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41574171

41584172
// Pass the triple of host when doing SYCL
41594173
llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
4160-
if (Args.hasFlag(options::OPT_fsycl_device_only, OptSpecifier(), false))
4174+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
4175+
RawTriple.getEnvironment() == llvm::Triple::SYCLDevice)
41614176
AuxT = llvm::Triple(llvm::sys::getProcessTriple());
41624177
std::string NormalizedTriple = AuxT.normalize();
41634178
CmdArgs.push_back("-aux-triple");
@@ -6812,6 +6827,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
68126827
unsigned RTOptionID = options::OPT__SLASH_MT;
68136828
bool isNVPTX = getToolChain().getTriple().isNVPTX();
68146829
bool isSYCLDevice =
6830+
Args.hasArg(options::OPT_fsycl_device_only) ||
68156831
getToolChain().getTriple().getEnvironment() == llvm::Triple::SYCLDevice;
68166832
bool isSYCL = Args.hasArg(options::OPT_fsycl) || isSYCLDevice;
68176833
// For SYCL Windows, /MD is the default.
@@ -7823,7 +7839,8 @@ void SPIRVTranslator::ConstructJob(Compilation &C, const JobAction &JA,
78237839

78247840
TranslatorArgs.push_back("-o");
78257841
TranslatorArgs.push_back(Output.getFilename());
7826-
if (getToolChain().getTriple().isSYCLDeviceEnvironment()) {
7842+
if (getToolChain().getTriple().isSYCLDeviceEnvironment() ||
7843+
TCArgs.hasArg(options::OPT_fsycl_device_only)) {
78277844
TranslatorArgs.push_back("-spirv-max-version=1.1");
78287845
TranslatorArgs.push_back("-spirv-debug-info-version=legacy");
78297846
// Prevent crash in the translator if input IR contains DIExpression

clang/test/Driver/sycl.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
// DEFAULT: "-triple" "spir64-unknown-{{.*}}-sycldevice{{.*}}" "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
4141
// DEFAULT: "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
4242
// DEFAULT: "-internal-isystem" "{{.*lib.*clang.*include}}"
43+
// DEFAULT: "-std=c++17"
4344
// DEFAULT-NOT: "{{.*}}llvm-spirv"{{.*}} "-spirv-max-version=1.1"{{.*}} "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes"
4445
// DEFAULT-NOT: "-std=c++11"
4546
// DEFAULT-NOT: "-std=c++14"
@@ -49,15 +50,28 @@
4950
// COMBINED: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
5051
// TEXTUAL: "-triple" "spir64-unknown-{{.*}}-sycldevice{{.*}}" "-fsycl-is-device"{{.*}} "-emit-llvm"
5152

53+
/// -fsycl-device-only triple checks
54+
// RUN: %clang -fsycl-device-only -target x86_64-unknown-linux-gnu -### %s 2>&1 \
55+
// RUN: | FileCheck --check-prefix=DEVICE-64 %s
56+
// RUN: %clang_cl -fsycl-device-only --target=x86_64-unknown-linux-gnu -### %s 2>&1 \
57+
// RUN: | FileCheck --check-prefix=DEVICE-64 %s
58+
// DEVICE-64: clang{{.*}} "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-aux-triple" "x86_64-unknown-linux-gnu"
59+
60+
// RUN: %clang -fsycl-device-only -target i386-unknown-linux-gnu -### %s 2>&1 \
61+
// RUN: | FileCheck --check-prefix=DEVICE-32 %s
62+
// RUN: %clang_cl -fsycl-device-only --target=i386-unknown-linux-gnu -### %s 2>&1 \
63+
// RUN: | FileCheck --check-prefix=DEVICE-32 %s
64+
// DEVICE-32: clang{{.*}} "-triple" "spir-unknown-unknown-sycldevice" {{.*}} "-aux-triple" "i386-unknown-linux-gnu"
65+
5266
/// Verify that the sycl header directory is before /usr/include
5367
// RUN: %clangxx -### -fsycl-device-only %s 2>&1 | FileCheck %s --check-prefix=HEADER_ORDER
5468
// RUN: %clangxx -### -fsycl %s 2>&1 | FileCheck %s --check-prefix=HEADER_ORDER
5569
// HEADER_ORDER-NOT: clang{{.*}} "/usr/include"{{.*}} "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}
5670

5771
/// Verify -fsycl-device-only phases
5872
// RUN: %clang -### -ccc-print-phases -fsycl-device-only %s 2>&1 | FileCheck %s --check-prefix=DEFAULT-PHASES
59-
// DEFAULT-PHASES: 0: input, "{{.*}}", c
60-
// DEFAULT-PHASES: 1: preprocessor, {0}, cpp-output
73+
// DEFAULT-PHASES: 0: input, "{{.*}}", c++
74+
// DEFAULT-PHASES: 1: preprocessor, {0}, c++-cpp-output
6175
// DEFAULT-PHASES: 2: compiler, {1}, ir
6276
// DEFAULT-PHASES: 3: backend, {2}, ir
6377
// DEFAULT-PHASES-NOT: linker

0 commit comments

Comments
 (0)