1*eba69b59SErich Keane // RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
2*eba69b59SErich Keane // CHECK: @[[LAMBDA_KERNEL3:[^\w]+]] = private unnamed_addr constant [[LAMBDA_K3_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ4mainEUlPZ4mainEUlvE10000_E10000_\00"
3*eba69b59SErich Keane // CHECK: @[[INT1:[^\w]+]] = private unnamed_addr constant [[INT_SIZE:\[[0-9]+ x i8\]]] c"_ZTSi\00"
4*eba69b59SErich Keane // CHECK: @[[STRING:[^\w]+]] = private unnamed_addr constant [[STRING_SIZE:\[[0-9]+ x i8\]]] c"_ZTSAppL_ZZ4mainE1jE_i\00",
5*eba69b59SErich Keane // CHECK: @[[INT2:[^\w]+]] = private unnamed_addr constant [[INT_SIZE]] c"_ZTSi\00"
6*eba69b59SErich Keane // CHECK: @[[LAMBDA_X:[^\w]+]] = private unnamed_addr constant [[LAMBDA_X_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE_\00"
7*eba69b59SErich Keane // CHECK: @[[MACRO_X:[^\w]+]] = private unnamed_addr constant [[MACRO_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE0_\00"
8*eba69b59SErich Keane // CHECK: @[[MACRO_Y:[^\w]+]] =  private unnamed_addr constant [[MACRO_SIZE]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE1_\00"
9*eba69b59SErich Keane // CHECK: @{{.*}} = private unnamed_addr constant [36 x i8] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE2_\00", align 1
10*eba69b59SErich Keane // CHECK: @{{.*}} = private unnamed_addr constant [36 x i8] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE3_\00", align 1
11*eba69b59SErich Keane // CHECK: @[[MACRO_MACRO_X:[^\w]+]] = private unnamed_addr constant [[MACRO_MACRO_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE4_\00"
12*eba69b59SErich Keane // CHECK: @[[MACRO_MACRO_Y:[^\w]+]] = private unnamed_addr constant [[MACRO_MACRO_SIZE]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE5_\00"
13*eba69b59SErich Keane // CHECK: @[[INT3:[^\w]+]] = private unnamed_addr constant [[INT_SIZE]] c"_ZTSi\00"
14*eba69b59SErich Keane // CHECK: @[[LAMBDA:[^\w]+]] = private unnamed_addr constant [[LAMBDA_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE10001_clEvEUlvE_\00"
15*eba69b59SErich Keane // CHECK: @[[LAMBDA_IN_DEP_INT:[^\w]+]] = private unnamed_addr constant [[DEP_INT_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ28lambda_in_dependent_functionIiEvvEUlvE_\00",
16*eba69b59SErich Keane // CHECK: @[[LAMBDA_IN_DEP_X:[^\w]+]] = private unnamed_addr constant [[DEP_LAMBDA_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ28lambda_in_dependent_functionIZZ4mainENKUlvE10001_clEvEUlvE_EvvEUlvE_\00",
17*eba69b59SErich Keane // CHECK: @[[LAMBDA_NO_DEP:[^\w]+]] = private unnamed_addr constant [[NO_DEP_LAMBDA_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ13lambda_no_depIidEvT_T0_EUlidE_\00",
18*eba69b59SErich Keane // CHECK: @[[LAMBDA_TWO_DEP:[^\w]+]] = private unnamed_addr constant [[DEP_LAMBDA1_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ14lambda_two_depIZZ4mainENKUlvE10001_clEvEUliE_ZZ4mainENKS0_clEvEUldE_EvvEUlvE_\00",
19*eba69b59SErich Keane // CHECK: @[[LAMBDA_TWO_DEP2:[^\w]+]] = private unnamed_addr constant [[DEP_LAMBDA2_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ14lambda_two_depIZZ4mainENKUlvE10001_clEvEUldE_ZZ4mainENKS0_clEvEUliE_EvvEUlvE_\00",
20*eba69b59SErich Keane 
21*eba69b59SErich Keane extern "C" void puts(const char *) {}
22*eba69b59SErich Keane 
23*eba69b59SErich Keane template <typename T>
24*eba69b59SErich Keane void template_param() {
25*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(T));
26*eba69b59SErich Keane }
27*eba69b59SErich Keane 
28*eba69b59SErich Keane template <typename T>
29*eba69b59SErich Keane void lambda_in_dependent_function() {
30*eba69b59SErich Keane   auto y = [] {};
31*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(y)));
32*eba69b59SErich Keane }
33*eba69b59SErich Keane 
34*eba69b59SErich Keane template <typename Tw, typename Tz>
35*eba69b59SErich Keane void lambda_two_dep() {
36*eba69b59SErich Keane   auto z = [] {};
37*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(z)));
38*eba69b59SErich Keane }
39*eba69b59SErich Keane 
40*eba69b59SErich Keane template <typename Tw, typename Tz>
41*eba69b59SErich Keane void lambda_no_dep(Tw a, Tz b) {
42*eba69b59SErich Keane   auto p = [](Tw a, Tz b) { return ((Tz)a + b); };
43*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(p)));
44*eba69b59SErich Keane }
45*eba69b59SErich Keane 
46*eba69b59SErich Keane #define DEF_IN_MACRO()                                        \
47*eba69b59SErich Keane   auto MACRO_X = []() {};                                     \
48*eba69b59SErich Keane   auto MACRO_Y = []() {};                                     \
49*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(MACRO_X))); \
50*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(MACRO_Y)));
51*eba69b59SErich Keane 
52*eba69b59SErich Keane #define MACRO_CALLS_MACRO() \
53*eba69b59SErich Keane   { DEF_IN_MACRO(); }       \
54*eba69b59SErich Keane   { DEF_IN_MACRO(); }
55*eba69b59SErich Keane 
56*eba69b59SErich Keane template <typename Ty>
57*eba69b59SErich Keane auto func() -> decltype(__builtin_sycl_unique_stable_name(decltype(Ty::str)));
58*eba69b59SErich Keane 
59*eba69b59SErich Keane struct Derp {
60*eba69b59SErich Keane   static constexpr const char str[] = "derp derp derp";
61*eba69b59SErich Keane };
62*eba69b59SErich Keane 
63*eba69b59SErich Keane template <typename KernelName, typename KernelType>
64*eba69b59SErich Keane [[clang::sycl_kernel]] void kernel_single_task(KernelType kernelFunc) {
65*eba69b59SErich Keane   kernelFunc();
66*eba69b59SErich Keane }
67*eba69b59SErich Keane 
68*eba69b59SErich Keane int main() {
69*eba69b59SErich Keane   kernel_single_task<class kernel2>(func<Derp>);
70*eba69b59SErich Keane   // CHECK: call spir_func void @_Z18kernel_single_taskIZ4mainE7kernel2PFPKcvEEvT0_(i8 addrspace(4)* ()* @_Z4funcI4DerpEDTu33__builtin_sycl_unique_stable_nameDtsrT_3strEEEv)
71*eba69b59SErich Keane 
72*eba69b59SErich Keane   auto l1 = []() { return 1; };
73*eba69b59SErich Keane   auto l2 = [](decltype(l1) *l = nullptr) { return 2; };
74*eba69b59SErich Keane   kernel_single_task<class kernel3>(l2);
75*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(l2)));
76*eba69b59SErich Keane   // CHECK: call spir_func void @_Z18kernel_single_taskIZ4mainE7kernel3Z4mainEUlPZ4mainEUlvE_E_EvT0_
77*eba69b59SErich Keane   // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[LAMBDA_K3_SIZE]], [[LAMBDA_K3_SIZE]]* @[[LAMBDA_KERNEL3]], i32 0, i32 0) to i8 addrspace(4)*))
78*eba69b59SErich Keane 
79*eba69b59SErich Keane   constexpr const char str[] = "lalala";
80*eba69b59SErich Keane   static_assert(__builtin_strcmp(__builtin_sycl_unique_stable_name(decltype(str)), "_ZTSA7_Kc\0") == 0, "unexpected mangling");
81*eba69b59SErich Keane 
82*eba69b59SErich Keane   int i = 0;
83*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(decltype(i++)));
84*eba69b59SErich Keane   // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[INT_SIZE]], [[INT_SIZE]]* @[[INT1]], i32 0, i32 0) to i8 addrspace(4)*))
85*eba69b59SErich Keane 
86*eba69b59SErich Keane   // FIXME: Ensure that j is incremented because VLAs are terrible.
87*eba69b59SErich Keane   int j = 55;
88*eba69b59SErich Keane   puts(__builtin_sycl_unique_stable_name(int[++j]));
89*eba69b59SErich Keane   // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[STRING_SIZE]], [[STRING_SIZE]]* @[[STRING]], i32 0, i32 0) to i8 addrspace(4)*))
90*eba69b59SErich Keane 
91*eba69b59SErich Keane   // CHECK: define internal spir_func void @_Z18kernel_single_taskIZ4mainE7kernel2PFPKcvEEvT0_
92*eba69b59SErich Keane   // CHECK: declare spir_func i8 addrspace(4)* @_Z4funcI4DerpEDTu33__builtin_sycl_unique_stable_nameDtsrT_3strEEEv
93*eba69b59SErich Keane   // CHECK: define internal spir_func void @_Z18kernel_single_taskIZ4mainE7kernel3Z4mainEUlPZ4mainEUlvE_E_EvT0_
94*eba69b59SErich Keane   // CHECK: define internal spir_func void @_Z18kernel_single_taskIZ4mainE6kernelZ4mainEUlvE0_EvT0_
95*eba69b59SErich Keane 
96*eba69b59SErich Keane   kernel_single_task<class kernel>(
97*eba69b59SErich Keane       []() {
98*eba69b59SErich Keane         puts(__builtin_sycl_unique_stable_name(int));
99*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[INT_SIZE]], [[INT_SIZE]]* @[[INT2]], i32 0, i32 0) to i8 addrspace(4)*))
100*eba69b59SErich Keane 
101*eba69b59SErich Keane         auto x = []() {};
102*eba69b59SErich Keane         puts(__builtin_sycl_unique_stable_name(decltype(x)));
103*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[LAMBDA_X_SIZE]], [[LAMBDA_X_SIZE]]* @[[LAMBDA_X]], i32 0, i32 0) to i8 addrspace(4)*))
104*eba69b59SErich Keane 
105*eba69b59SErich Keane         DEF_IN_MACRO();
106*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[MACRO_SIZE]], [[MACRO_SIZE]]* @[[MACRO_X]], i32 0, i32 0) to i8 addrspace(4)*))
107*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[MACRO_SIZE]], [[MACRO_SIZE]]* @[[MACRO_Y]], i32 0, i32 0) to i8 addrspace(4)*))
108*eba69b59SErich Keane 
109*eba69b59SErich Keane         MACRO_CALLS_MACRO();
110*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[MACRO_MACRO_SIZE]], [[MACRO_MACRO_SIZE]]* @[[MACRO_MACRO_X]], i32 0, i32 0) to i8 addrspace(4)*))
111*eba69b59SErich Keane         // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[MACRO_MACRO_SIZE]], [[MACRO_MACRO_SIZE]]* @[[MACRO_MACRO_Y]], i32 0, i32 0) to i8 addrspace(4)*))
112*eba69b59SErich Keane 
113*eba69b59SErich Keane         template_param<int>();
114*eba69b59SErich Keane         // CHECK: call spir_func void @_Z14template_paramIiEvv
115*eba69b59SErich Keane 
116*eba69b59SErich Keane         template_param<decltype(x)>();
117*eba69b59SErich Keane         // CHECK: call spir_func void @_Z14template_paramIZZ4mainENKUlvE0_clEvEUlvE_Evv
118*eba69b59SErich Keane 
119*eba69b59SErich Keane         lambda_in_dependent_function<int>();
120*eba69b59SErich Keane         // CHECK: call spir_func void @_Z28lambda_in_dependent_functionIiEvv
121*eba69b59SErich Keane 
122*eba69b59SErich Keane         lambda_in_dependent_function<decltype(x)>();
123*eba69b59SErich Keane         // CHECK: call spir_func void @_Z28lambda_in_dependent_functionIZZ4mainENKUlvE0_clEvEUlvE_Evv
124*eba69b59SErich Keane 
125*eba69b59SErich Keane         lambda_no_dep<int, double>(3, 5.5);
126*eba69b59SErich Keane         // CHECK: call spir_func void @_Z13lambda_no_depIidEvT_T0_(i32 3, double 5.500000e+00)
127*eba69b59SErich Keane 
128*eba69b59SErich Keane         int a = 5;
129*eba69b59SErich Keane         double b = 10.7;
130*eba69b59SErich Keane         auto y = [](int a) { return a; };
131*eba69b59SErich Keane         auto z = [](double b) { return b; };
132*eba69b59SErich Keane         lambda_two_dep<decltype(y), decltype(z)>();
133*eba69b59SErich Keane         // CHECK: call spir_func void @_Z14lambda_two_depIZZ4mainENKUlvE0_clEvEUliE_ZZ4mainENKS0_clEvEUldE_Evv
134*eba69b59SErich Keane 
135*eba69b59SErich Keane         lambda_two_dep<decltype(z), decltype(y)>();
136*eba69b59SErich Keane         // CHECK: call spir_func void @_Z14lambda_two_depIZZ4mainENKUlvE0_clEvEUldE_ZZ4mainENKS0_clEvEUliE_Evv
137*eba69b59SErich Keane       });
138*eba69b59SErich Keane }
139*eba69b59SErich Keane 
140*eba69b59SErich Keane // CHECK: define linkonce_odr spir_func void @_Z14template_paramIiEvv
141*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[INT_SIZE]], [[INT_SIZE]]* @[[INT3]], i32 0, i32 0) to i8 addrspace(4)*))
142*eba69b59SErich Keane 
143*eba69b59SErich Keane // CHECK: define internal spir_func void @_Z14template_paramIZZ4mainENKUlvE0_clEvEUlvE_Evv
144*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[LAMBDA_SIZE]], [[LAMBDA_SIZE]]* @[[LAMBDA]], i32 0, i32 0) to i8 addrspace(4)*))
145*eba69b59SErich Keane 
146*eba69b59SErich Keane // CHECK: define linkonce_odr spir_func void @_Z28lambda_in_dependent_functionIiEvv
147*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[DEP_INT_SIZE]], [[DEP_INT_SIZE]]* @[[LAMBDA_IN_DEP_INT]], i32 0, i32 0) to i8 addrspace(4)*))
148*eba69b59SErich Keane 
149*eba69b59SErich Keane // CHECK: define internal spir_func void @_Z28lambda_in_dependent_functionIZZ4mainENKUlvE0_clEvEUlvE_Evv
150*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[DEP_LAMBDA_SIZE]], [[DEP_LAMBDA_SIZE]]* @[[LAMBDA_IN_DEP_X]], i32 0, i32 0) to i8 addrspace(4)*))
151*eba69b59SErich Keane 
152*eba69b59SErich Keane // CHECK: define linkonce_odr spir_func void @_Z13lambda_no_depIidEvT_T0_(i32 %a, double %b)
153*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[NO_DEP_LAMBDA_SIZE]], [[NO_DEP_LAMBDA_SIZE]]* @[[LAMBDA_NO_DEP]], i32 0, i32 0) to i8 addrspace(4)*))
154*eba69b59SErich Keane 
155*eba69b59SErich Keane // CHECK: define internal spir_func void @_Z14lambda_two_depIZZ4mainENKUlvE0_clEvEUliE_ZZ4mainENKS0_clEvEUldE_Evv
156*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[DEP_LAMBDA1_SIZE]], [[DEP_LAMBDA1_SIZE]]* @[[LAMBDA_TWO_DEP]], i32 0, i32 0) to i8 addrspace(4)*))
157*eba69b59SErich Keane 
158*eba69b59SErich Keane // CHECK: define internal spir_func void @_Z14lambda_two_depIZZ4mainENKUlvE0_clEvEUldE_ZZ4mainENKS0_clEvEUliE_Evv
159*eba69b59SErich Keane // CHECK: call spir_func void @puts(i8 addrspace(4)* addrspacecast (i8* getelementptr inbounds ([[DEP_LAMBDA2_SIZE]], [[DEP_LAMBDA2_SIZE]]* @[[LAMBDA_TWO_DEP2]], i32 0, i32 0) to i8 addrspace(4)*))
160