Skip to content

Commit 76bcf3c

Browse files
committed
[SYCL] Enable support for generating LLVM-BC with spir target
Given the spir/sycldevice target, pull in the host environment to satisfy the needed C++ headers. Also, use of --sycl as an alias for -target spir64-unknown-linux-sycldevice -emit-spirv. Signed-off-by: Vladimir Lazarev <[email protected]>
1 parent a11308a commit 76bcf3c

File tree

11 files changed

+74
-61
lines changed

11 files changed

+74
-61
lines changed

clang/include/clang/Driver/Types.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,6 @@ TYPE("image", Image, INVALID, "out", "")
101101
TYPE("dSYM", dSYM, INVALID, "dSYM", "A")
102102
TYPE("dependencies", Dependencies, INVALID, "d", "")
103103
TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin","A")
104+
TYPE("spirv", SPIRV, INVALID, "spv", "")
104105
TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", "A")
105106
TYPE("none", Nothing, INVALID, nullptr, "u")

clang/lib/Driver/Driver.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,17 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
10221022
T.setObjectFormat(llvm::Triple::COFF);
10231023
TargetTriple = T.str();
10241024
}
1025+
if (Args.hasArg(options::OPT_sycl)) {
1026+
// --sycl implies spir arch and SYCL Device
1027+
llvm::Triple T(TargetTriple);
1028+
// FIXME: defaults to spir64, should probably have a way to set spir
1029+
// possibly new -sycl-target option
1030+
T.setArch(llvm::Triple::spir64);
1031+
T.setVendor(llvm::Triple::UnknownVendor);
1032+
T.setOS(llvm::Triple(llvm::sys::getProcessTriple()).getOS());
1033+
T.setEnvironment(llvm::Triple::SYCLDevice);
1034+
TargetTriple = T.str();
1035+
}
10251036
if (const Arg *A = Args.getLastArg(options::OPT_target))
10261037
TargetTriple = A->getValue();
10271038
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
@@ -3423,6 +3434,9 @@ Action *Driver::ConstructPhaseAction(
34233434
Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
34243435
return C.MakeAction<BackendJobAction>(Input, Output);
34253436
}
3437+
if (Args.hasArg(options::OPT_sycl)) {
3438+
return C.MakeAction<BackendJobAction>(Input, types::TY_SPIRV);
3439+
}
34263440
return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
34273441
}
34283442
case phases::Assemble:

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,7 +3417,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
34173417
bool IsWindowsCygnus = RawTriple.isWindowsCygwinEnvironment();
34183418
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
34193419
bool IsIAMCU = RawTriple.isOSIAMCU();
3420-
bool IsSYCL = Args.hasArg(options::OPT_sycl);
3420+
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice);
34213421

34223422
// Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
34233423
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
@@ -3466,10 +3466,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
34663466
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
34673467
}
34683468

3469-
if (IsSYCL) {
3469+
if (IsSYCLDevice) {
34703470
// We want to compile sycl kernels.
34713471
CmdArgs.push_back("-std=c++11");
34723472
CmdArgs.push_back("-fsycl-is-device");
3473+
// Pass the triple of host when doing SYCL
3474+
std::string NormalizedTriple =
3475+
llvm::Triple(llvm::sys::getProcessTriple()).normalize();
3476+
CmdArgs.push_back("-aux-triple");
3477+
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
34733478
}
34743479

34753480
if (IsOpenMPDevice) {
@@ -3555,6 +3560,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
35553560
} else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
35563561
CmdArgs.push_back("-rewrite-objc");
35573562
rewriteKind = RK_Fragile;
3563+
} else if (JA.getType() == types::TY_SPIRV) {
3564+
CmdArgs.push_back("-emit-spirv");
35583565
} else {
35593566
assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
35603567
}

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,12 @@ static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
215215

216216
Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
217217
: Generic_ELF(D, Triple, Args) {
218-
GCCInstallation.init(Triple, Args);
218+
// for SYCL device targets, we rely on the host GCC for proper compilation
219+
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
220+
GCCInstallation.init(llvm::Triple(llvm::sys::getProcessTriple()), Args);
221+
} else {
222+
GCCInstallation.init(Triple, Args);
223+
}
219224
Multilibs = GCCInstallation.getMultilibs();
220225
SelectedMultilib = GCCInstallation.getMultilib();
221226
llvm::Triple::ArchType Arch = Triple.getArch();
@@ -840,6 +845,13 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
840845
if (getTriple().isAndroid())
841846
MultiarchIncludeDirs = AndroidMultiarchIncludeDirs;
842847

848+
// SYCL Device uses Host includes
849+
if (getTriple().getEnvironment() == llvm::Triple::SYCLDevice) {
850+
llvm::Triple HostTriple = llvm::Triple(llvm::sys::getProcessTriple());
851+
if (HostTriple.getArch() == llvm::Triple::x86_64)
852+
MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
853+
}
854+
843855
for (StringRef Dir : MultiarchIncludeDirs) {
844856
if (D.getVFS().exists(SysRoot + Dir)) {
845857
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
911911
if (!hasTarget())
912912
return false;
913913

914-
// Create TargetInfo for the other side of CUDA and OpenMP compilation.
915-
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) &&
914+
// Create TargetInfo for the other side of CUDA, SYCL and OpenMP compilation.
915+
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice ||
916+
getLangOpts().SYCL) &&
916917
!getFrontendOpts().AuxTriple.empty()) {
917918
auto TO = std::make_shared<TargetOptions>();
918919
TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);

clang/lib/Frontend/InitPreprocessor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,8 @@ void clang::InitializePreprocessor(
11081108
if (InitOpts.UsePredefines) {
11091109
// FIXME: This will create multiple definitions for most of the predefined
11101110
// macros. This is not the right way to handle this.
1111-
if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo())
1111+
if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice || LangOpts.SYCL) &&
1112+
PP.getAuxTargetInfo())
11121113
InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
11131114
Builder);
11141115

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
1-
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
1+
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s
22

33
// CHECK: define {{.*}}spir_kernel void @kernel_function() {{[^{]+}} !kernel_arg_addr_space ![[MD:[0-9]+]] !kernel_arg_access_qual ![[MD]] !kernel_arg_type ![[MD]] !kernel_arg_base_type ![[MD]] !kernel_arg_type_qual ![[MD]] {
44
// CHECK: ![[MD]] = !{}
55

6-
// XFAIL:*
7-
8-
#include <CL/sycl.hpp>
9-
10-
11-
using namespace cl::sycl;
6+
template <typename name, typename Func>
7+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
8+
kernelFunc();
9+
}
1210

1311
int main() {
14-
15-
queue myQueue;
16-
17-
myQueue.submit([&](handler &cgh) {
18-
19-
cgh.single_task<class kernel_function>([=]() {
20-
});
21-
});
22-
23-
myQueue.wait();
12+
kernel_single_task<class kernel_function>([]() {});
13+
return 0;
2414
}

clang/test/CodeGenSYCL/kernel-with-id.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
2-
1+
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s
32
// XFAIL:*
43

54
#include <CL/sycl.hpp>
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
1-
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
1+
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s
22

3-
// XFAIL:*
4-
5-
#include <CL/sycl.hpp>
6-
7-
8-
using namespace cl::sycl;
3+
template <typename name, typename Func>
4+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
5+
kernelFunc();
6+
}
97

108
int main() {
119

12-
queue myQueue;
13-
14-
myQueue.submit([&](handler &cgh) {
15-
16-
// CHECK: define spir_kernel void @kernel_function()
17-
18-
// CHECK: call spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %0)
10+
// CHECK: define spir_kernel void @kernel_function()
1911

20-
// CHECK: define internal spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %this)
12+
// CHECK: call spir_func void @"_ZZ4mainENK3$_0clEv"(%class.anon* %0)
2113

22-
cgh.single_task<class kernel_function>([=]() {
23-
});
24-
});
14+
// CHECK: define internal spir_func void @"_ZZ4mainENK3$_0clEv"(%class.anon* %this)
2515

26-
myQueue.wait();
16+
kernel_single_task<class kernel_function>([]() {});
17+
return 0;
2718
}

clang/test/CodeGenSYCL/spir-opencl-version.cpp

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
// RUN: %clang -cc1 -DCL_TARGET_OPENCL_VERSION=220 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s
1+
// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -emit-llvm -x c++ %s -o - | FileCheck %s
22

3-
// XFAIL:*
4-
5-
#include <CL/sycl.hpp>
6-
7-
using namespace cl::sycl;
3+
template <typename name, typename Func>
4+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
5+
kernelFunc();
6+
}
87

98
int main() {
10-
11-
queue myQueue;
12-
13-
myQueue.submit([&](handler &cgh) {
14-
15-
cgh.single_task<class kernel_function>([=]() {
16-
});
17-
});
18-
19-
myQueue.wait();
9+
kernel_single_task<class kernel_function>([]() {});
10+
return 0;
2011
}
2112

22-
2313
// CHECK: !opencl.spir.version = !{[[SPIR:![0-9]+]]}
2414
// CHECK: !spirv.Source = !{[[LANG:![0-9]+]]}
2515
// CHECK: [[SPIR]] = !{i32 1, i32 2}

clang/test/Driver/sycl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang -### --sycl -c %s 2>&1 | FileCheck %s --check-prefix=DEFAULT
2+
// RUN: %clang -### -target spir64-unknown-linux-sycldevice -c -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=TARGET
3+
// RUN: %clang -### --sycl -c -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=COMBINED
4+
5+
// DEFAULT: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-spirv"
6+
// TARGET: "-triple" "spir64-unknown-linux-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
7+
// COMBINED: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"

0 commit comments

Comments
 (0)