// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fcxx-exceptions -fexceptions -fsycl-is-host -emit-llvm -o - %s | FileCheck %s // Validate generation of exception handling code for functions declared // with the sycl_kernel_entry_point attribute that implicitly call a // sycl_kernel_launch function that may throw an exception. Exception // handling is not relevant for the generated offload kernel entry point // function, so device compilation is intentionally not exercised. // A unique kernel name type is required for each declared kernel entry point. template struct KN; // A generic kernel object type. template struct KT { void operator()() const; }; // Validate that exception handling instructions are omitted when a // potentially throwing sycl_kernel_entry_point attributed function // calls a potentially throwing sycl_kernel_launch function (a thrown // exception will propagate with no explicit handling required). namespace ns1 { template void sycl_kernel_launch(const char *, Ts...); [[clang::sycl_kernel_entry_point(KN<1>)]] void skep(KT<1> k) { k(); } } // CHECK: ; Function Attrs: mustprogress noinline optnone // CHECK: define dso_local void @_ZN3ns14skepE2KTILi1ELi0EE() #{{[0-9]+}} { // CHECK: call void @_ZN3ns118sycl_kernel_launchI2KNILi1EEJ2KTILi1ELi0EEEEEvPKcDpT0_(ptr noundef @.str) // CHECK: ret void // CHECK: } // Validate that exception handling instructions are emitted when a // non-throwing sycl_kernel_entry_point attributed function calls // a potentially throwing sycl_kernel_launch function. namespace ns2 { template void sycl_kernel_launch(const char *, Ts...); [[clang::sycl_kernel_entry_point(KN<2>)]] void skep(KT<2> k) noexcept { k(); } } // CHECK: ; Function Attrs: mustprogress noinline nounwind optnone // CHECK: define dso_local void @_ZN3ns24skepE2KTILi2ELi0EE() #{{[0-9]+}} personality ptr @__gxx_personality_v0 { // CHECK: invoke void @_ZN3ns218sycl_kernel_launchI2KNILi2EEJ2KTILi2ELi0EEEEEvPKcDpT0_(ptr noundef @.str.1) // CHECK: to label %invoke.cont unwind label %terminate.lpad // CHECK: invoke.cont: // CHECK: ret void // CHECK: terminate.lpad: // CHECK: call void @__clang_call_terminate(ptr %1) #{{[0-9]+}} // CHECK: unreachable // CHECK: } // Validate that exception handling instructions are omitted when a // potentially throwing sycl_kernel_entry_point attributed function // calls a non-throwing sycl_kernel_launch function (a thrown // exception will terminate within sycl_kernel_launch). namespace ns3 { template void sycl_kernel_launch(const char *, Ts...) noexcept; [[clang::sycl_kernel_entry_point(KN<3>)]] void skep(KT<3> k) { k(); } } // CHECK: ; Function Attrs: mustprogress noinline nounwind optnone // CHECK: define dso_local void @_ZN3ns34skepE2KTILi3ELi0EE() #{{[0-9]+}} { // CHECK: call void @_ZN3ns318sycl_kernel_launchI2KNILi3EEJ2KTILi3ELi0EEEEEvPKcDpT0_(ptr noundef @.str.2) // CHECK: ret void // CHECK: } // Validate that exception handling instructions are omitted when a // non-throwing sycl_kernel_entry_point attributed function calls a // non-throwing sycl_kernel_launch function. namespace ns4 { template void sycl_kernel_launch(const char *, Ts...) noexcept; [[clang::sycl_kernel_entry_point(KN<4>)]] void skep(KT<4> k) noexcept { k(); } } // CHECK: ; Function Attrs: mustprogress noinline nounwind optnone // CHECK: define dso_local void @_ZN3ns44skepE2KTILi4ELi0EE() #{{[0-9]+}} { // CHECK: call void @_ZN3ns418sycl_kernel_launchI2KNILi4EEJ2KTILi4ELi0EEEEEvPKcDpT0_(ptr noundef @.str.3) // CHECK: ret void // CHECK: }