Skip to content

Commit 059f62a

Browse files
committed
Merge branch 'sycl' into run-mode
2 parents 63b5db6 + 0c7e1cb commit 059f62a

File tree

58 files changed

+1053
-1261
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1053
-1261
lines changed

.github/workflows/sycl-containers.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ jobs:
5151
file: ubuntu2204_intel_drivers
5252
tag: unstable
5353
build_args: "use_latest=true"
54+
- name: Build + Intel Drivers Ubuntu 22.04 Docker image
55+
file: ubuntu2204_intel_drivers
56+
tag: alldeps
57+
build_args: |
58+
base_image=ghcr.io/intel/llvm/ubuntu2204_build
59+
base_tag=latest
60+
use_latest=false
5461
steps:
5562
- name: Checkout
5663
uses: actions/checkout@v4

.github/workflows/sycl-linux-run-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ jobs:
185185
with:
186186
path: khronos_sycl_cts
187187
repository: 'KhronosGroup/SYCL-CTS'
188-
ref: 'SYCL-2020'
189-
default_branch: 'SYCL-2020'
188+
ref: 'main'
189+
default_branch: 'main'
190190
cache_path: "/__w/repo_cache/"
191191
- name: SYCL CTS GIT submodules init
192192
if: inputs.tests_selector == 'cts'

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5194,7 +5194,10 @@ void Clang::ConstructHostCompilerJob(Compilation &C, const JobAction &JA,
51945194
if (HostCompilerDefArg) {
51955195
ExecPath = HostCompilerDefArg->getValue();
51965196
if (!ExecPath.empty() && ExecPath == llvm::sys::path::stem(ExecPath))
5197-
ExecPath = TC.GetProgramPath(ExecPath.c_str());
5197+
// Use PATH to find executable passed in from -fsycl-host-compiler.
5198+
if (llvm::ErrorOr<std::string> Prog =
5199+
llvm::sys::findProgramByName(ExecPath))
5200+
ExecPath = *Prog;
51985201
}
51995202

52005203
// Add any user-specified arguments.

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,18 +1504,13 @@ static void parseTargetOpts(StringRef ArgString, const llvm::opt::ArgList &Args,
15041504
void SYCLToolChain::TranslateGPUTargetOpt(const llvm::opt::ArgList &Args,
15051505
llvm::opt::ArgStringList &CmdArgs,
15061506
OptSpecifier Opt_EQ) const {
1507-
for (auto *A : Args) {
1508-
if (A->getOption().matches(Opt_EQ)) {
1509-
if (auto GpuDevice =
1510-
tools::SYCL::gen::isGPUTarget<tools::SYCL::gen::AmdGPU>(
1511-
A->getValue())) {
1512-
StringRef ArgString;
1513-
SmallString<64> OffloadArch("--offload-arch=");
1514-
OffloadArch += GpuDevice->data();
1515-
ArgString = OffloadArch;
1516-
parseTargetOpts(ArgString, Args, CmdArgs);
1517-
A->claim();
1518-
}
1507+
if (const Arg *TargetArg = Args.getLastArg(Opt_EQ)) {
1508+
StringRef Val = TargetArg->getValue();
1509+
if (auto GpuDevice =
1510+
tools::SYCL::gen::isGPUTarget<tools::SYCL::gen::AmdGPU>(Val)) {
1511+
SmallString<64> OffloadArch("--offload-arch=");
1512+
OffloadArch += GpuDevice->data();
1513+
parseTargetOpts(OffloadArch, Args, CmdArgs);
15191514
}
15201515
}
15211516
}

clang/test/Driver/sycl-host-compiler-old-model.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,13 @@
9090
// CHECK_SAVE_TEMPS-NEXT: g++{{.*}} "[[APPEND_CPP]]" "-c"
9191
// CHECK_SAVE_TEMPS-SAME: "-o" "[[HOST_OBJ:.+\.o]]"
9292
// CHECK_SAVE_TEMPS-NEXT: clang-offload-bundler{{.*}} "-input=[[DEVICE_BC]]" "-input=[[HOST_OBJ]]"
93+
94+
/// Test to verify binary from PATH is used
95+
// RUN: rm -rf %t && mkdir -p %t/test_path
96+
// RUN: touch %t/test_path/clang++ && chmod +x %t/test_path/clang++
97+
// RUN: env "PATH=%t/test_path%{pathsep}%PATH%" \
98+
// RUN: %clangxx -### -fsycl -fsycl-host-compiler=clang++ \
99+
// RUN: -fsycl-host-compiler-options=-DDUMMY_OPT --no-offload-new-driver \
100+
// RUN: %s 2>&1 \
101+
// RUN: | FileCheck -check-prefix=PATH_CHECK %s
102+
// PATH_CHECK: {{(/|\\\\)}}test_path{{(/|\\\\)}}clang++{{.*}} "-DDUMMY_OPT"

clang/test/Driver/sycl-offload.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,9 @@
104104
// CHECK_FSYCL_FP64_CONV_EMU_WIN-NOT: clang{{.*}} "-cc1" "-triple x86_64-unknown-linux-gnu" {{.*}} "-fsycl-fp64-conv-emu"
105105
// CHECK_FSYCL_FP64_CONV_EMU_WIN-DAG: clang{{.*}} "-cc1" "-triple" "spir64_gen{{.*}}" "-fsycl-fp64-conv-emu"
106106
// CHECK_FSYCL_FP64_CONV_EMU_WIN-DAG: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spir64_gen-unknown-unknown,arch=,kind=sycl,compile-opts={{.*}}-options -ze-fp64-gen-conv-emu{{.*}}"
107+
108+
/// Compilation checks to make sure an early empty -fsycl-targets does not
109+
/// crash.
110+
// RUN: %clangxx -### -fsycl -fsycl-targets= -fsycl-targets=spir64 %s 2>&1 \
111+
// RUN: | FileCheck %s -check-prefix=CHECK_SPIR64
112+
// CHECK_SPIR64: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown"{{.*}} "-fsycl-is-device"

llvm/lib/SYCLLowerIR/LowerWGScope.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,8 @@ Instruction *spirv::genWGBarrier(Instruction &Before, const Triple &TT) {
10011001
FunctionCallee FC =
10021002
M.getOrInsertFunction(Name, Attr, RetTy, ScopeTy, ScopeTy, SemanticsTy);
10031003
assert(FC.getCallee() && "spirv intrinsic creation failed");
1004+
if (TT.isSPIROrSPIRV())
1005+
cast<Function>(FC.getCallee())->setCallingConv(CallingConv::SPIR_FUNC);
10041006

10051007
IRBuilder<> Bld(Ctx);
10061008
Bld.SetInsertPoint(&Before);
@@ -1011,5 +1013,7 @@ Instruction *spirv::genWGBarrier(Instruction &Before, const Triple &TT) {
10111013
asUInt(spirv::MemorySemantics::WorkgroupMemory));
10121014
auto BarrierCall = Bld.CreateCall(FC, {ArgExec, ArgMem, ArgSema});
10131015
BarrierCall->addFnAttr(llvm::Attribute::Convergent);
1016+
if (TT.isSPIROrSPIRV())
1017+
BarrierCall->setCallingConv(CallingConv::SPIR_FUNC);
10141018
return BarrierCall;
10151019
}

llvm/lib/SYCLLowerIR/SYCLJointMatrixTransform.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,43 @@ namespace {
2222
static constexpr char ACCESS_CHAIN[] = "_Z19__spirv_AccessChain";
2323
static constexpr char MATRIX_TYPE[] = "spirv.CooperativeMatrixKHR";
2424

25-
// This routine extracts spirv.CooperativeMatrixKHR target extension type
26-
// from sycl::joint_matrix class object if it's used in __spirv_AccessChain
27-
// function call. It's necessary because otherwise OpAccessChain indices would
28-
// be wrong.
25+
// This function finds all calls to __spirv_AccessChain function and transforms
26+
// its users and operands to make LLVM IR more SPIR-V friendly.
2927
bool transformAccessChain(Function *F) {
3028
bool ModuleChanged = false;
3129
for (auto I : F->users()) {
3230
auto *CI = dyn_cast<CallInst>(I);
3331
if (!CI)
3432
continue;
33+
34+
// This is a W/A for bfloat16 and tf32 types - they are represented in SYCL
35+
// as structures with int16/float storages. It means, that in LLVM IR
36+
// user of CallInst to __spirv_AccessChain function would be not load/store
37+
// instruction, but a zero GEP. This zero GEP is no-op, but can confuse a
38+
// SPIR-V consumer, so lets remove it here.
39+
auto *Unique = CI->getUniqueUndroppableUser();
40+
if (auto *GEP = dyn_cast_or_null<GetElementPtrInst>(Unique)) {
41+
if (GEP->hasAllZeroIndices()) {
42+
GEP->replaceAllUsesWith(CI);
43+
GEP->dropAllReferences();
44+
GEP->eraseFromParent();
45+
}
46+
}
47+
48+
// It can happen that the optimizer can remove duplicated or dead uses
49+
// of CallInst to __spirv_AccessChain function. But it can't remove
50+
// __spirv_AccessChain call itself as it's a call to external function.
51+
// Lets clean such calls.
52+
if (CI->getNumUses() == 0) {
53+
CI->dropAllReferences();
54+
CI->eraseFromParent();
55+
continue;
56+
}
57+
58+
// This routine extracts spirv.CooperativeMatrixKHR target extension type
59+
// from sycl::joint_matrix class object if it's used in __spirv_AccessChain
60+
// function call. It's necessary because otherwise OpAccessChain indices
61+
// would be wrong.
3562
Instruction *Ptr =
3663
dyn_cast<Instruction>(CI->getArgOperand(0)->stripPointerCasts());
3764
if (!Ptr || !isa<AllocaInst>(Ptr))

llvm/lib/SYCLLowerIR/SYCLVirtualFunctionsAnalysis.cpp

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,37 +71,23 @@ void checkKernel(const Function *F, const CallGraphTy &CG) {
7171
void computeFunctionToKernelsMappingImpl(Function *Kernel, const Function *F,
7272
const CallGraphTy &CG,
7373
FuncToFuncMapTy &Mapping) {
74+
Mapping[F].insert(Kernel);
7475
CallGraphTy::const_iterator It = CG.find(F);
7576
// It could be that the function itself is a leaf and doesn't call anything
7677
if (It == CG.end())
7778
return;
7879

79-
Mapping[F].insert(Kernel);
80-
8180
const SmallPtrSet<Value *, 8> &Callees = It->getSecond();
8281
for (const Value *V : Callees)
8382
if (auto *Callee = dyn_cast<Function>(V))
8483
computeFunctionToKernelsMappingImpl(Kernel, Callee, CG, Mapping);
8584
}
8685

86+
// Compute a map from functions used by a kernel to that kernel.
87+
// For simplicity we also consider a kernel to be using itself.
8788
void computeFunctionToKernelsMapping(Function *Kernel, const CallGraphTy &CG,
8889
FuncToFuncMapTy &Mapping) {
89-
// For simplicity we also consider a kernel to be using itself
90-
Mapping[Kernel].insert(Kernel);
91-
92-
CallGraphTy::const_iterator It = CG.find(Kernel);
93-
// It could be that the kernel doesn't call anything
94-
if (It == CG.end())
95-
return;
96-
97-
const SmallPtrSet<Value *, 8> &Callees = It->getSecond();
98-
for (const Value *V : Callees) {
99-
auto *Callee = dyn_cast<Function>(V);
100-
if (!Callee)
101-
continue;
102-
Mapping[Callee].insert(Kernel);
103-
computeFunctionToKernelsMappingImpl(Kernel, Callee, CG, Mapping);
104-
}
90+
computeFunctionToKernelsMappingImpl(Kernel, Kernel, CG, Mapping);
10591
}
10692

10793
void collectVTablesThatUseFunction(

llvm/lib/SYCLLowerIR/SpecConstants.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ Instruction *emitCall(Type *RetTy, StringRef BaseFunctionName,
475475
auto *FT = FunctionType::get(RetTy, ArgTys, false /*isVarArg*/);
476476
std::string FunctionName = mangleFuncItanium(BaseFunctionName, FT);
477477
Module *M = InsertBefore->getFunction()->getParent();
478+
bool IsSPIROrSPIRV = llvm::Triple(M->getTargetTriple()).isSPIROrSPIRV();
478479

479480
if (RetTy->isIntegerTy(1)) {
480481
assert(ArgTys.size() == 2 && "Expected a scalar spec constant");
@@ -500,6 +501,11 @@ Instruction *emitCall(Type *RetTy, StringRef BaseFunctionName,
500501

501502
auto *Call =
502503
CallInst::Create(NewFT, NewFC.getCallee(), Args, "", InsertBefore);
504+
if (IsSPIROrSPIRV) {
505+
cast<Function>(NewFC.getCallee())
506+
->setCallingConv(CallingConv::SPIR_FUNC);
507+
Call->setCallingConv(CallingConv::SPIR_FUNC);
508+
}
503509
return CastInst::CreateTruncOrBitCast(Call, RetTy, "tobool",
504510
InsertBefore);
505511
}
@@ -520,7 +526,12 @@ Instruction *emitCall(Type *RetTy, StringRef BaseFunctionName,
520526
// types? Is it necessary?
521527

522528
FunctionCallee FC = M->getOrInsertFunction(FunctionName, FT);
523-
return CallInst::Create(FT, FC.getCallee(), Args, "", InsertBefore);
529+
auto *Call = CallInst::Create(FT, FC.getCallee(), Args, "", InsertBefore);
530+
if (IsSPIROrSPIRV) {
531+
cast<Function>(FC.getCallee())->setCallingConv(CallingConv::SPIR_FUNC);
532+
Call->setCallingConv(CallingConv::SPIR_FUNC);
533+
}
534+
return Call;
524535
}
525536

526537
Instruction *emitSpecConstant(unsigned NumericID, Type *Ty,

0 commit comments

Comments
 (0)