Skip to content

Commit 3d54d7e

Browse files
authored
[SYCL][ESIMD] Fix a compilation of mix of unnamed ESIMD and non ESIMD kernels (#6557)
* Fix an issue that causes a program containing ESIMD and non-ESIMD kernels to crash
1 parent e286166 commit 3d54d7e

File tree

8 files changed

+68
-4
lines changed

8 files changed

+68
-4
lines changed

llvm/include/llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace llvm {
1616
namespace esimd {
1717

1818
constexpr char ATTR_DOUBLE_GRF[] = "esimd-double-grf";
19+
constexpr char ESIMD_MARKER_MD[] = "sycl_explicit_simd";
1920

2021
using CallGraphNodeAction = std::function<void(Function *)>;
2122
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction NodeF,
@@ -34,6 +35,8 @@ void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
3435

3536
// Tells whether given function is a ESIMD kernel.
3637
bool isESIMDKernel(const Function &F);
38+
// Tells whether given function is a ESIMD function.
39+
bool isESIMD(const Function &F);
3740

3841
/// Reports and error with the message \p Msg concatenated with the optional
3942
/// \p OptMsg if \p Condition is false.

llvm/include/llvm/SYCLLowerIR/ESIMD/LowerESIMD.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ class SYCLLowerESIMDKernelPropsPass
7676
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
7777
};
7878

79+
// Fixes ESIMD Kernel attributes for wrapper functions for ESIMD kernels
80+
class SYCLFixupESIMDKernelWrapperMDPass
81+
: public PassInfoMixin<SYCLFixupESIMDKernelWrapperMDPass> {
82+
public:
83+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
84+
};
7985
} // namespace llvm
8086

8187
#endif // LLVM_SYCLLOWERIR_LOWERESIMD_H

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ MODULE_PASS("SYCLMutatePrintfAddrspace", SYCLMutatePrintfAddrspacePass())
135135
MODULE_PASS("SPIRITTAnnotations", SPIRITTAnnotationsPass())
136136
MODULE_PASS("deadargelim-sycl", DeadArgumentEliminationSYCLPass())
137137
MODULE_PASS("sycllowerwglocalmemory", SYCLLowerWGLocalMemoryPass())
138+
MODULE_PASS("lower-esimd-kernel-attrs", SYCLFixupESIMDKernelWrapperMDPass())
138139
#undef MODULE_PASS
139140

140141
#ifndef MODULE_PASS_WITH_PARAMS

llvm/lib/SYCLLowerIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ add_llvm_component_library(LLVMSYCLLowerIR
5353
ESIMD/LowerESIMDVecArg.cpp
5454
ESIMD/ESIMDUtils.cpp
5555
ESIMD/ESIMDVerifier.cpp
56+
ESIMD/LowerESIMDKernelAttrs.cpp
5657
LowerInvokeSimd.cpp
5758
LowerWGScope.cpp
5859
LowerWGLocalMemory.cpp

llvm/lib/SYCLLowerIR/ESIMD/ESIMDUtils.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction ActionF,
5454
} else {
5555
auto *CI = cast<CallInst>(FCall);
5656

57-
if ((CI->getCalledFunction() != CurF) && ErrorOnNonCallUse) {
57+
if ((CI->getCalledFunction() != CurF)) {
5858
// CurF is used in a call, but not as the callee.
59-
llvm::report_fatal_error(ErrMsg);
59+
if (ErrorOnNonCallUse)
60+
llvm::report_fatal_error(ErrMsg);
6061
} else {
6162
auto FCaller = CI->getFunction();
6263

@@ -69,9 +70,12 @@ void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction ActionF,
6970
}
7071
}
7172

73+
bool isESIMD(const Function &F) {
74+
return F.getMetadata(ESIMD_MARKER_MD) != nullptr;
75+
}
76+
7277
bool isESIMDKernel(const Function &F) {
73-
return (F.getCallingConv() == CallingConv::SPIR_KERNEL) &&
74-
(F.getMetadata("sycl_explicit_simd") != nullptr);
78+
return (F.getCallingConv() == CallingConv::SPIR_KERNEL) && isESIMD(F);
7579
}
7680

7781
} // namespace esimd

llvm/lib/SYCLLowerIR/ESIMD/LowerESIMD.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,7 @@ translateSpirvGlobalUses(LoadInst *LI, StringRef SpirvGlobalName,
12151215
// TODO: Implement support for the following intrinsics:
12161216
// uint32_t __spirv_BuiltIn NumSubgroups;
12171217
// uint32_t __spirv_BuiltIn SubgroupId;
1218+
// uint32_t __spirv_BuiltIn GlobalLinearId
12181219

12191220
// Translate those loads from _scalar_ SPIRV globals that can be replaced with
12201221
// a const value here.
@@ -1227,6 +1228,8 @@ translateSpirvGlobalUses(LoadInst *LI, StringRef SpirvGlobalName,
12271228
SpirvGlobalName == "SubgroupMaxSize") {
12281229
NewInst = llvm::Constant::getIntegerValue(LI->getType(),
12291230
llvm::APInt(32, 1, true));
1231+
} else if (SpirvGlobalName == "GlobalLinearId") {
1232+
NewInst = llvm::Constant::getNullValue(LI->getType());
12301233
}
12311234
if (NewInst) {
12321235
LI->replaceAllUsesWith(NewInst);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===---- LowerESIMDKernelAttrs - lower __esimd_set_kernel_attributes ---===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// Finds and adds sycl_explicit_simd attributes to wrapper functions that wrap
9+
// ESIMD kernel functions
10+
11+
#include "llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h"
12+
#include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h"
13+
14+
#include "llvm/IR/Module.h"
15+
#include "llvm/Pass.h"
16+
17+
#define DEBUG_TYPE "LowerESIMDKernelAttrs"
18+
19+
using namespace llvm;
20+
21+
namespace llvm {
22+
PreservedAnalyses
23+
SYCLFixupESIMDKernelWrapperMDPass::run(Module &M, ModuleAnalysisManager &MAM) {
24+
bool Modified = false;
25+
for (Function &F : M) {
26+
if (llvm::esimd::isESIMD(F)) {
27+
llvm::esimd::traverseCallgraphUp(
28+
&F,
29+
[&](Function *GraphNode) {
30+
if (!llvm::esimd::isESIMD(*GraphNode)) {
31+
GraphNode->setMetadata(
32+
llvm::esimd::ESIMD_MARKER_MD,
33+
llvm::MDNode::get(GraphNode->getContext(), {}));
34+
Modified = true;
35+
}
36+
},
37+
false);
38+
}
39+
}
40+
return Modified ? PreservedAnalyses::none() : PreservedAnalyses::all();
41+
}
42+
} // namespace llvm

llvm/tools/sycl-post-link/sycl-post-link.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,10 @@ processInputModule(std::unique_ptr<Module> M) {
665665
// if none were made.
666666
bool Modified = false;
667667

668+
// Propagate ESIMD attribute to wrapper functions to prevent
669+
// spurious splits and kernel link errors.
670+
Modified |= runModulePass<SYCLFixupESIMDKernelWrapperMDPass>(*M);
671+
668672
// After linking device bitcode "llvm.used" holds references to the kernels
669673
// that are defined in the device image. But after splitting device image into
670674
// separate kernels we may end up with having references to kernel declaration

0 commit comments

Comments
 (0)