@@ -1754,14 +1754,11 @@ static void checkSLMInit(Module &M) {
1754
1754
SmallPtrSet<const Function *, 8u > Callers;
1755
1755
for (auto &F : M) {
1756
1756
if (isSlmInit (F)) {
1757
- auto filterInvokeSimdUse = [](const Instruction *, const Function *) {
1758
- return false ;
1759
- };
1760
1757
for (User *U : F.users ()) {
1761
1758
auto *FCall = dyn_cast<CallInst>(U);
1762
1759
if (FCall && FCall->getCalledFunction () == &F) {
1763
1760
Function *GenF = FCall->getFunction ();
1764
-
1761
+ SmallPtrSet<Function *, 32 > Visited;
1765
1762
sycl::utils::traverseCallgraphUp (
1766
1763
GenF,
1767
1764
[&](Function *GraphNode) {
@@ -1778,7 +1775,21 @@ static void checkSLMInit(Module &M) {
1778
1775
}
1779
1776
}
1780
1777
},
1781
- false , filterInvokeSimdUse);
1778
+ Visited, false );
1779
+ bool VisitedKernel = false ;
1780
+ for (const Function *Caller : Visited) {
1781
+ if (llvm::esimd::isESIMDKernel (*Caller)) {
1782
+ VisitedKernel = true ;
1783
+ break ;
1784
+ }
1785
+ }
1786
+ if (!VisitedKernel) {
1787
+ F.getContext ().emitError (
1788
+ " slm_init must be called directly from ESIMD kernel." );
1789
+ }
1790
+ } else {
1791
+ F.getContext ().emitError (
1792
+ " slm_init can only be used as a direct call." );
1782
1793
}
1783
1794
}
1784
1795
}
@@ -1886,7 +1897,7 @@ bool SYCLLowerESIMDPass::prepareForAlwaysInliner(Module &M) {
1886
1897
if (FCall && FCall->getCalledFunction () == &F) {
1887
1898
Function *GenF = FCall->getFunction ();
1888
1899
// The original kernel (UserK) if often automatically separated into
1889
- // a spir_func (GenF) that is then cal led from spir_kernel (GenK).
1900
+ // a spir_func (GenF) that is then called from spir_kernel (GenK).
1890
1901
// When that happens, the calls of slm_init<N>() originally placed
1891
1902
// in 'UserK' get moved to spir_func 'GenF', which creates wrong IR
1892
1903
// because slm_init() must be called only from a kernel.
@@ -1943,8 +1954,10 @@ static void fixFunctionReadWriteAttributes(Module &M) {
1943
1954
1944
1955
PreservedAnalyses SYCLLowerESIMDPass::run (Module &M,
1945
1956
ModuleAnalysisManager &MAM) {
1957
+
1946
1958
// Check validity of slm_init calls.
1947
1959
checkSLMInit (M);
1960
+
1948
1961
// AlwaysInlinerPass is required for correctness.
1949
1962
bool ForceInline = prepareForAlwaysInliner (M);
1950
1963
if (ForceInline) {
0 commit comments