Skip to content

Commit 74aa9a0

Browse files
[SYCL] Remove "unreachable" instruction from LLVM IR for SYCL devices (intel#1789)
C/C++ standard functions with `__attribute__ ((__noreturn__))` in SYCL device code emit "unreachable" instruction in LLVM IR.
1 parent 13fe9fb commit 74aa9a0

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4988,10 +4988,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
49884988

49894989
// 4. Finish the call.
49904990

4991-
// If the call doesn't return, finish the basic block and clear the
4992-
// insertion point; this allows the rest of IRGen to discard
4991+
// If the call doesn't return for non-sycl devices, finish the basic block and
4992+
// clear the insertion point; this allows the rest of IRGen to discard
49934993
// unreachable code.
4994-
if (CI->doesNotReturn()) {
4994+
if (CI->doesNotReturn() && !getLangOpts().SYCLIsDevice) {
49954995
if (UnusedReturnSizePtr)
49964996
PopCleanupBlock();
49974997

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s
2+
3+
SYCL_EXTERNAL void doesNotReturn() throw() __attribute__((__noreturn__));
4+
5+
template <typename name, typename Func>
6+
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
7+
kernelFunc();
8+
}
9+
10+
int main() {
11+
kernel<class test>([]() {
12+
doesNotReturn();
13+
// CHECK-NOT: unreachable
14+
});
15+
return 0;
16+
}

sycl/test/devicelib/assert.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,19 @@
6565
// in SYCL Runtime, so it doesn't look into a device extensions list and always
6666
// link the fallback library.
6767
//
68-
// NOTE that Intel OpenCL CPU Vectorizer crashes when an `unreachable'
69-
// instruction is found in IR. Workaround it for now using
70-
// CL_CONFIG_USE_VECTORIZER=False environment variable.
7168
//
7269
// We also skip the native test entirely (see SKIP_IF_NO_EXT), since the assert
7370
// extension is a new feature and may not be supported by the runtime used with
7471
// SYCL.
7572
//
7673
// Overall this sounds stable enough. What could possibly go wrong?
7774
//
78-
// RUN: env SYCL_PI_TRACE=2 SHOULD_CRASH=1 CL_CONFIG_USE_VECTORIZER=False SYCL_DEVICE_TYPE=CPU EXPECTED_SIGNAL=SIGABRT SKIP_IF_NO_EXT=1 %t.out 2>%t.stderr.native >%t.stdout.native
75+
// RUN: env SYCL_PI_TRACE=2 SHOULD_CRASH=1 SYCL_DEVICE_TYPE=CPU EXPECTED_SIGNAL=SIGABRT SKIP_IF_NO_EXT=1 %t.out 2>%t.stderr.native >%t.stdout.native
7976
// RUN: FileCheck %s --input-file %t.stdout.native --check-prefixes=CHECK-NATIVE || FileCheck %s --input-file %t.stderr.native --check-prefix CHECK-NOTSUPPORTED
8077
// RUN: FileCheck %s --input-file %t.stderr.native --check-prefixes=CHECK-MESSAGE || FileCheck %s --input-file %t.stderr.native --check-prefix CHECK-NOTSUPPORTED
8178
//
82-
// RUN: env SYCL_PI_TRACE=2 SYCL_DEVICELIB_INHIBIT_NATIVE=cl_intel_devicelib_assert CL_CONFIG_USE_VECTORIZER=False SYCL_DEVICE_TYPE=CPU EXPECTED_SIGNAL=SIGSEGV %t.out >%t.stdout.pi.fallback
83-
// RUN: env SHOULD_CRASH=1 SYCL_DEVICELIB_INHIBIT_NATIVE=cl_intel_devicelib_assert CL_CONFIG_USE_VECTORIZER=False SYCL_DEVICE_TYPE=CPU EXPECTED_SIGNAL=SIGSEGV %t.out >%t.stdout.msg.fallback
79+
// RUN: env SYCL_PI_TRACE=2 SYCL_DEVICELIB_INHIBIT_NATIVE=cl_intel_devicelib_assert SYCL_DEVICE_TYPE=CPU %t.out >%t.stdout.pi.fallback
80+
// RUN: env SYCL_DEVICELIB_INHIBIT_NATIVE=cl_intel_devicelib_assert SYCL_DEVICE_TYPE=CPU %t.out >%t.stdout.msg.fallback
8481
// RUN: FileCheck %s --input-file %t.stdout.pi.fallback --check-prefixes=CHECK-FALLBACK
8582
// RUN: FileCheck %s --input-file %t.stdout.msg.fallback --check-prefixes=CHECK-MESSAGE
8683
//
@@ -141,7 +138,6 @@ void simple_vadd(const std::array<T, N> &VA, const std::array<T, N> &VB,
141138
exit(EXIT_SKIP_TEST);
142139
}
143140

144-
int shouldCrash = getenv("SHOULD_CRASH") ? 1 : 0;
145141

146142
cl::sycl::range<1> numOfItems{N};
147143
cl::sycl::buffer<T, 1> bufferA(VA.data(), numOfItems);
@@ -155,9 +151,7 @@ void simple_vadd(const std::array<T, N> &VA, const std::array<T, N> &VB,
155151

156152
cgh.parallel_for<class SimpleVaddT>(numOfItems, [=](cl::sycl::id<1> wiID) {
157153
accessorC[wiID] = accessorA[wiID] + accessorB[wiID];
158-
if (shouldCrash) {
159154
assert(accessorC[wiID] == 0 && "Invalid value");
160-
}
161155
});
162156
});
163157
deviceQueue.wait_and_throw();

0 commit comments

Comments
 (0)