Skip to content

Commit b036051

Browse files
authored
[Driver][SYCL] Improvements to -fsycl-device-only behaviors (#2597)
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 909459b commit b036051

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
@@ -3989,14 +3989,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
39893989
const ArgList &Args, const char *LinkingOutput) const {
39903990
const auto &TC = getToolChain();
39913991
const llvm::Triple &RawTriple = TC.getTriple();
3992-
const llvm::Triple &Triple = TC.getEffectiveTriple();
3993-
const std::string &TripleStr = Triple.getTriple();
3992+
llvm::Triple Triple = TC.getEffectiveTriple();
39943993

39953994
bool KernelOrKext =
39963995
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
39973996
const Driver &D = TC.getDriver();
39983997
ArgStringList CmdArgs;
39993998

3999+
// -fsycl-device-only implies a SPIRV arch triple. Do not set if current
4000+
// effective triple is SYCLDevice
4001+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
4002+
Triple.getEnvironment() != llvm::Triple::SYCLDevice) {
4003+
const char *SYCLTargetArch = "spir64";
4004+
if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
4005+
SYCLTargetArch = "spir";
4006+
Triple = C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch);
4007+
}
4008+
const std::string &TripleStr = Triple.getTriple();
4009+
40004010
// Check number of inputs for sanity. We need at least one input.
40014011
assert(Inputs.size() >= 1 && "Must have at least one input.");
40024012
// CUDA/HIP compilation may have multiple inputs (source file + results of
@@ -4011,7 +4021,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40114021
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
40124022
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
40134023
bool IsSYCLOffloadDevice = JA.isDeviceOffloading(Action::OFK_SYCL);
4014-
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL);
4024+
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL) ||
4025+
Args.hasArg(options::OPT_fsycl_device_only);
40154026
bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
40164027
assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) || IsSYCL ||
40174028
IsHeaderModulePrecompile || Inputs.size() == 1) &&
@@ -4059,14 +4070,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40594070
(IsSYCL || IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
40604071
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
40614072
bool IsIAMCU = RawTriple.isOSIAMCU();
4062-
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice);
4073+
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice ||
4074+
Triple.getEnvironment() == llvm::Triple::SYCLDevice);
40634075
// Using just the sycldevice environment is not enough to determine usage
40644076
// of the device triple when considering fat static archives. The
40654077
// compilation path requires the host object to be fed into the partial link
40664078
// step, and being part of the SYCL tool chain causes the incorrect target.
40674079
// FIXME - Is it possible to retain host environment when on a target
40684080
// device toolchain.
4069-
bool UseSYCLTriple = IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice);
4081+
bool UseSYCLTriple =
4082+
IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice ||
4083+
Args.hasArg(options::OPT_fsycl_device_only));
40704084

40714085
// Adjust IsWindowsXYZ for CUDA/HIP/SYCL compilations. Even when compiling in
40724086
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
@@ -4155,7 +4169,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41554169
options::OPT_fno_sycl_early_optimizations,
41564170
Triple.getSubArch() != llvm::Triple::SPIRSubArch_fpga))
41574171
CmdArgs.push_back("-fno-sycl-early-optimizations");
4158-
else if (RawTriple.isSPIR()) {
4172+
else if (IsSYCLDevice) {
41594173
// Set `sycl-opt` option to configure LLVM passes for SPIR target
41604174
CmdArgs.push_back("-mllvm");
41614175
CmdArgs.push_back("-sycl-opt");
@@ -4168,7 +4182,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41684182

41694183
// Pass the triple of host when doing SYCL
41704184
llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
4171-
if (Args.hasFlag(options::OPT_fsycl_device_only, OptSpecifier(), false))
4185+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
4186+
RawTriple.getEnvironment() == llvm::Triple::SYCLDevice)
41724187
AuxT = llvm::Triple(llvm::sys::getProcessTriple());
41734188
std::string NormalizedTriple = AuxT.normalize();
41744189
CmdArgs.push_back("-aux-triple");
@@ -6828,6 +6843,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
68286843
unsigned RTOptionID = options::OPT__SLASH_MT;
68296844
bool isNVPTX = getToolChain().getTriple().isNVPTX();
68306845
bool isSYCLDevice =
6846+
Args.hasArg(options::OPT_fsycl_device_only) ||
68316847
getToolChain().getTriple().getEnvironment() == llvm::Triple::SYCLDevice;
68326848
bool isSYCL = Args.hasArg(options::OPT_fsycl) || isSYCLDevice;
68336849
// For SYCL Windows, /MD is the default.
@@ -7839,7 +7855,8 @@ void SPIRVTranslator::ConstructJob(Compilation &C, const JobAction &JA,
78397855

78407856
TranslatorArgs.push_back("-o");
78417857
TranslatorArgs.push_back(Output.getFilename());
7842-
if (getToolChain().getTriple().isSYCLDeviceEnvironment()) {
7858+
if (getToolChain().getTriple().isSYCLDeviceEnvironment() ||
7859+
TCArgs.hasArg(options::OPT_fsycl_device_only)) {
78437860
TranslatorArgs.push_back("-spirv-max-version=1.1");
78447861
TranslatorArgs.push_back("-spirv-debug-info-version=legacy");
78457862
// 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)