Skip to content

Commit 6da9cc9

Browse files
committed
Added coge generation tests for exception handling.
1 parent 1035a57 commit 6da9cc9

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

clang/include/clang/Basic/AttrDocs.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ functions, an ODR-use is not required; the offload kernel entry point will be
721721
emitted if the function is defined. In any case, a call to the function is
722722
required for the synthesized call to ``sycl_kernel_launch()`` to occur.
723723

724+
A function declared with the ``sycl_kernel_entry_point`` attribute may include
725+
an exception specification. If a non-throwing exception specification is
726+
present, an exception propagating from the implicit call to the
727+
``sycl_kernel_launch`` template will result in a call to ``std::terminate()``.
728+
Otherwise, such an exception will propagate normally.
729+
724730
Functions declared with the ``sycl_kernel_entry_point`` attribute are not
725731
limited to the simple example shown above. They may have additional template
726732
parameters, declare additional function parameters, and have complex control
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fcxx-exceptions -fexceptions -fsycl-is-host -emit-llvm -o - %s | FileCheck %s
2+
3+
// Validate generation of exception handling code for functions declared
4+
// with the sycl_kernel_entry_point attribute that implicitly call a
5+
// sycl_kernel_launch function that may throw an exception. Exception
6+
// handling is not relevant for the generated offload kernel entry point
7+
// function, so device compilation is intentionally not exercised.
8+
9+
// A unique kernel name type is required for each declared kernel entry point.
10+
template<int> struct KN;
11+
12+
// A generic kernel object type.
13+
template<int, int = 0>
14+
struct KT {
15+
void operator()() const;
16+
};
17+
18+
19+
// Validate that exception handling instructions are omitted when a
20+
// potentially throwing sycl_kernel_entry_point attributed function
21+
// calls a potentially throwing sycl_kernel_launch function (a thrown
22+
// exception will propagate with no explicit handling required).
23+
namespace ns1 {
24+
template<typename KN, typename... Ts>
25+
void sycl_kernel_launch(const char *, Ts...);
26+
[[clang::sycl_kernel_entry_point(KN<1>)]]
27+
void skep(KT<1> k) {
28+
k();
29+
}
30+
}
31+
// CHECK: ; Function Attrs: mustprogress noinline optnone
32+
// CHECK: define dso_local void @_ZN3ns14skepE2KTILi1ELi0EE() #{{[0-9]+}} {
33+
// CHECK: call void @_ZN3ns118sycl_kernel_launchI2KNILi1EEJ2KTILi1ELi0EEEEEvPKcDpT0_(ptr noundef @.str)
34+
// CHECK: ret void
35+
// CHECK: }
36+
37+
38+
// Validate that exception handling instructions are emitted when a
39+
// non-throwing sycl_kernel_entry_point attributed function calls
40+
// a potentially throwing sycl_kernel_launch function.
41+
namespace ns2 {
42+
template<typename KN, typename... Ts>
43+
void sycl_kernel_launch(const char *, Ts...);
44+
[[clang::sycl_kernel_entry_point(KN<2>)]]
45+
void skep(KT<2> k) noexcept {
46+
k();
47+
}
48+
}
49+
// CHECK: ; Function Attrs: mustprogress noinline nounwind optnone
50+
// CHECK: define dso_local void @_ZN3ns24skepE2KTILi2ELi0EE() #{{[0-9]+}} personality ptr @__gxx_personality_v0 {
51+
// CHECK: invoke void @_ZN3ns218sycl_kernel_launchI2KNILi2EEJ2KTILi2ELi0EEEEEvPKcDpT0_(ptr noundef @.str.1)
52+
// CHECK: to label %invoke.cont unwind label %terminate.lpad
53+
// CHECK: invoke.cont:
54+
// CHECK: ret void
55+
// CHECK: terminate.lpad:
56+
// CHECK: call void @__clang_call_terminate(ptr %1) #{{[0-9]+}}
57+
// CHECK: unreachable
58+
// CHECK: }
59+
60+
61+
// Validate that exception handling instructions are omitted when a
62+
// potentially throwing sycl_kernel_entry_point attributed function
63+
// calls a non-throwing sycl_kernel_launch function (a thrown
64+
// exception will terminate within sycl_kernel_launch).
65+
namespace ns3 {
66+
template<typename KN, typename... Ts>
67+
void sycl_kernel_launch(const char *, Ts...) noexcept;
68+
[[clang::sycl_kernel_entry_point(KN<3>)]]
69+
void skep(KT<3> k) {
70+
k();
71+
}
72+
}
73+
// CHECK: ; Function Attrs: mustprogress noinline nounwind optnone
74+
// CHECK: define dso_local void @_ZN3ns34skepE2KTILi3ELi0EE() #{{[0-9]+}} {
75+
// CHECK: call void @_ZN3ns318sycl_kernel_launchI2KNILi3EEJ2KTILi3ELi0EEEEEvPKcDpT0_(ptr noundef @.str.2)
76+
// CHECK: ret void
77+
// CHECK: }
78+
79+
80+
// Validate that exception handling instructions are omitted when a
81+
// non-throwing sycl_kernel_entry_point attributed function calls a
82+
// non-throwing sycl_kernel_launch function.
83+
namespace ns4 {
84+
template<typename KN, typename... Ts>
85+
void sycl_kernel_launch(const char *, Ts...) noexcept;
86+
[[clang::sycl_kernel_entry_point(KN<4>)]]
87+
void skep(KT<4> k) noexcept {
88+
k();
89+
}
90+
}
91+
// CHECK: ; Function Attrs: mustprogress noinline nounwind optnone
92+
// CHECK: define dso_local void @_ZN3ns44skepE2KTILi4ELi0EE() #{{[0-9]+}} {
93+
// CHECK: call void @_ZN3ns418sycl_kernel_launchI2KNILi4EEJ2KTILi4ELi0EEEEEvPKcDpT0_(ptr noundef @.str.3)
94+
// CHECK: ret void
95+
// CHECK: }

0 commit comments

Comments
 (0)