Skip to content

Commit fcd33bd

Browse files
authored
[SYCL][ESIMD] Don't error on functions with local names (#7996)
In the ESIMD Verifier, we have a known good list of functions and want to check that any ESIMD code only calls those functions. We do that by demangling the names of all ESIMD functions and comparing them against the known good functions. In the case where there's a function that is from a local name such as a lambda, functor, or local class, the demangled name may include the return type of the parent function if it's a template function. If this happens, we end up using the return type in the function name check which makes us check the wrong thing. We don't care about local names, so just skip them. Signed-off-by: Sarnie, Nick <[email protected]>
1 parent 3ffb169 commit fcd33bd

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

llvm/lib/SYCLLowerIR/ESIMD/ESIMDVerifier.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ class ESIMDVerifierImpl {
118118
if (!NameNode) // Can it be null?
119119
continue;
120120

121+
// Skip local names, which are functions whose type
122+
// is not exposed outside of the current function,
123+
// such as lambdas or local classes. Note we will
124+
// still analyze functions called by these constructs,
125+
// assuming they are marked as ESIMD functions.
126+
if (NameNode->getKind() == id::Node::KLocalName)
127+
continue;
128+
121129
id::OutputBuffer NameBuf;
122130
NameNode->print(NameBuf);
123131
StringRef Name(NameBuf.getBuffer(), NameBuf.getCurrentPosition());
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %clangxx -fsycl -fsycl-device-only -S %s -o /dev/null
2+
// Test that the ESIMD Verifier doesn't error on locally defined types
3+
#include <sycl.hpp>
4+
#include <sycl/ext/intel/esimd.hpp>
5+
6+
using namespace sycl::ext::intel::esimd;
7+
8+
constexpr size_t n = 64;
9+
10+
constexpr size_t size = 4;
11+
12+
class functor {
13+
public:
14+
template <typename T> sycl::event operator()(sycl::queue &q, T *x) {
15+
return q.submit([&](sycl::handler &cgh) {
16+
cgh.parallel_for(n / size, [=](auto item) SYCL_ESIMD_KERNEL {
17+
size_t offset = item.get_id(0);
18+
simd<T, size> vec(offset);
19+
block_store(x + offset * size, vec);
20+
});
21+
});
22+
}
23+
};
24+
25+
template <typename T> sycl::event func(sycl::queue &q, T *x) {
26+
return q.submit([&](sycl::handler &cgh) {
27+
cgh.parallel_for(n / size, [=](auto item) SYCL_ESIMD_KERNEL {
28+
size_t offset = item.get_id(0);
29+
simd<T, size> vec(offset);
30+
block_store(x + offset * size, vec);
31+
});
32+
});
33+
}
34+
35+
int main() {
36+
sycl::queue q;
37+
float *x = sycl::malloc_shared<float>(n, q);
38+
auto event = func(q, x);
39+
event.wait();
40+
functor f;
41+
auto event2 = f(q, x);
42+
event2.wait();
43+
sycl::free(x, q);
44+
return 0;
45+
}

0 commit comments

Comments
 (0)