diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index f1355c1ec21f9..2a33c8e42293b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4971,10 +4971,21 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // 4. Finish the call. + // SYCL does not support C++ exceptions or termination in device code, so all + // functions have to return. + bool SyclSkipNoReturn = false; + if (getLangOpts().SYCLIsDevice && CI->doesNotReturn()) { + if (auto *F = CI->getCalledFunction()) + F->removeFnAttr(llvm::Attribute::NoReturn); + CI->removeAttribute(llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoReturn); + SyclSkipNoReturn = true; + } + // If the call doesn't return for non-sycl devices, finish the basic block and // clear the insertion point; this allows the rest of IRGen to discard // unreachable code. - if (CI->doesNotReturn() && !getLangOpts().SYCLIsDevice) { + if (!SyclSkipNoReturn && CI->doesNotReturn()) { if (UnusedReturnSizePtr) PopCleanupBlock(); diff --git a/clang/test/CodeGenSYCL/remove-ur-inst.cpp b/clang/test/CodeGenSYCL/remove-ur-inst.cpp index 67fe27cf0c22b..7866aff7f07a3 100644 --- a/clang/test/CodeGenSYCL/remove-ur-inst.cpp +++ b/clang/test/CodeGenSYCL/remove-ur-inst.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-enable-optimizations -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s SYCL_EXTERNAL void doesNotReturn() throw() __attribute__((__noreturn__)); @@ -11,6 +12,7 @@ int main() { kernel([]() { doesNotReturn(); // CHECK-NOT: unreachable + // CHECK-NOT: noreturn }); return 0; -} \ No newline at end of file +}