xref: /llvm-project/clang/test/CodeGenCUDA/lambda.cu (revision 0419465fa4358af1ec808e376e3881377bfac76b)
1*0419465fSNikita Popov // RUN: %clang_cc1 -x hip -emit-llvm -std=c++11 %s -o - \
21eaad010SYaxun (Sam) Liu // RUN:   -triple x86_64-linux-gnu \
31eaad010SYaxun (Sam) Liu // RUN:   | FileCheck -check-prefix=HOST %s
4*0419465fSNikita Popov // RUN: %clang_cc1 -x hip -emit-llvm -std=c++11 %s -o - \
51eaad010SYaxun (Sam) Liu // RUN:   -triple amdgcn-amd-amdhsa -fcuda-is-device \
61eaad010SYaxun (Sam) Liu // RUN:   | FileCheck -check-prefix=DEV %s
71eaad010SYaxun (Sam) Liu 
81eaad010SYaxun (Sam) Liu #include "Inputs/cuda.h"
91eaad010SYaxun (Sam) Liu 
101eaad010SYaxun (Sam) Liu // Device side kernel name.
111eaad010SYaxun (Sam) Liu // HOST: @[[KERN_CAPTURE:[0-9]+]] = {{.*}} c"_Z1gIZ12test_capturevEUlvE_EvT_\00"
121eaad010SYaxun (Sam) Liu // HOST: @[[KERN_RESOLVE:[0-9]+]] = {{.*}} c"_Z1gIZ12test_resolvevEUlvE_EvT_\00"
131eaad010SYaxun (Sam) Liu 
141eaad010SYaxun (Sam) Liu // Check functions emitted for test_capture in host compilation.
151eaad010SYaxun (Sam) Liu // Check lambda is not emitted in host compilation.
16fd739804SFangrui Song // HOST-LABEL: define{{.*}} void @_Z12test_capturev
171eaad010SYaxun (Sam) Liu // HOST:  call void @_Z19test_capture_helperIZ12test_capturevEUlvE_EvT_
181eaad010SYaxun (Sam) Liu // HOST-LABEL: define internal void @_Z19test_capture_helperIZ12test_capturevEUlvE_EvT_
191eaad010SYaxun (Sam) Liu // HOST:  call void @_Z16__device_stub__gIZ12test_capturevEUlvE_EvT_
201eaad010SYaxun (Sam) Liu // HOST-NOT: define{{.*}}@_ZZ4mainENKUlvE_clEv
211eaad010SYaxun (Sam) Liu 
221eaad010SYaxun (Sam) Liu // Check functions emitted for test_resolve in host compilation.
231eaad010SYaxun (Sam) Liu // Check host version of template function 'overloaded' is emitted and called
241eaad010SYaxun (Sam) Liu // by the lambda function.
25fd739804SFangrui Song // HOST-LABEL: define{{.*}} void @_Z12test_resolvev
261eaad010SYaxun (Sam) Liu // HOST:  call void @_Z19test_resolve_helperIZ12test_resolvevEUlvE_EvT_()
271eaad010SYaxun (Sam) Liu // HOST-LABEL: define internal void @_Z19test_resolve_helperIZ12test_resolvevEUlvE_EvT_
281eaad010SYaxun (Sam) Liu // HOST:  call void @_Z16__device_stub__gIZ12test_resolvevEUlvE_EvT_
291eaad010SYaxun (Sam) Liu // HOST:  call void @_ZZ12test_resolvevENKUlvE_clEv
301eaad010SYaxun (Sam) Liu // HOST-LABEL: define internal void @_ZZ12test_resolvevENKUlvE_clEv
311b1c8d83Shyeongyu kim // HOST:  call noundef i32 @_Z10overloadedIiET_v
321b1c8d83Shyeongyu kim // HOST-LABEL: define linkonce_odr noundef i32 @_Z10overloadedIiET_v
331eaad010SYaxun (Sam) Liu // HOST:  ret i32 2
341eaad010SYaxun (Sam) Liu 
351eaad010SYaxun (Sam) Liu // Check kernel is registered with correct device side kernel name.
361eaad010SYaxun (Sam) Liu // HOST: @__hipRegisterFunction({{.*}}@[[KERN_CAPTURE]]
371eaad010SYaxun (Sam) Liu // HOST: @__hipRegisterFunction({{.*}}@[[KERN_RESOLVE]]
381eaad010SYaxun (Sam) Liu 
39fd739804SFangrui Song // DEV: @a ={{.*}} addrspace(1) externally_initialized global i32 0
401eaad010SYaxun (Sam) Liu 
411eaad010SYaxun (Sam) Liu // Check functions emitted for test_capture in device compilation.
421eaad010SYaxun (Sam) Liu // Check lambda is emitted in device compilation and accessing device variable.
43fd739804SFangrui Song // DEV-LABEL: define{{.*}} amdgpu_kernel void @_Z1gIZ12test_capturevEUlvE_EvT_
441eaad010SYaxun (Sam) Liu // DEV:  call void @_ZZ12test_capturevENKUlvE_clEv
451eaad010SYaxun (Sam) Liu // DEV-LABEL: define internal void @_ZZ12test_capturevENKUlvE_clEv
46*0419465fSNikita Popov // DEV:  store i32 1, ptr addrspacecast (ptr addrspace(1) @a to ptr)
471eaad010SYaxun (Sam) Liu 
481eaad010SYaxun (Sam) Liu // Check functions emitted for test_resolve in device compilation.
491eaad010SYaxun (Sam) Liu // Check device version of template function 'overloaded' is emitted and called
501eaad010SYaxun (Sam) Liu // by the lambda function.
51fd739804SFangrui Song // DEV-LABEL: define{{.*}} amdgpu_kernel void @_Z1gIZ12test_resolvevEUlvE_EvT_
521eaad010SYaxun (Sam) Liu // DEV:  call void @_ZZ12test_resolvevENKUlvE_clEv
531eaad010SYaxun (Sam) Liu // DEV-LABEL: define internal void @_ZZ12test_resolvevENKUlvE_clEv
541b1c8d83Shyeongyu kim // DEV:  call noundef i32 @_Z10overloadedIiET_v
551b1c8d83Shyeongyu kim // DEV-LABEL: define linkonce_odr noundef i32 @_Z10overloadedIiET_v
561eaad010SYaxun (Sam) Liu // DEV:  ret i32 1
571eaad010SYaxun (Sam) Liu 
581eaad010SYaxun (Sam) Liu __device__ int a;
591eaad010SYaxun (Sam) Liu 
601eaad010SYaxun (Sam) Liu template<class T>
overloaded()611eaad010SYaxun (Sam) Liu __device__ T overloaded() { return 1; }
621eaad010SYaxun (Sam) Liu 
631eaad010SYaxun (Sam) Liu template<class T>
overloaded()641eaad010SYaxun (Sam) Liu __host__ T overloaded() { return 2; }
651eaad010SYaxun (Sam) Liu 
661eaad010SYaxun (Sam) Liu template<class F>
g(F f)671eaad010SYaxun (Sam) Liu __global__ void g(F f) { f(); }
681eaad010SYaxun (Sam) Liu 
691eaad010SYaxun (Sam) Liu template<class F>
test_capture_helper(F f)701eaad010SYaxun (Sam) Liu void test_capture_helper(F f) { g<<<1,1>>>(f); }
711eaad010SYaxun (Sam) Liu 
721eaad010SYaxun (Sam) Liu template<class F>
test_resolve_helper(F f)731eaad010SYaxun (Sam) Liu void test_resolve_helper(F f) { g<<<1,1>>>(f); f(); }
741eaad010SYaxun (Sam) Liu 
751eaad010SYaxun (Sam) Liu // Test capture of device variable in lambda function.
test_capture(void)761eaad010SYaxun (Sam) Liu void test_capture(void) {
771eaad010SYaxun (Sam) Liu   test_capture_helper([](){ a = 1;});
781eaad010SYaxun (Sam) Liu }
791eaad010SYaxun (Sam) Liu 
801eaad010SYaxun (Sam) Liu // Test resolving host/device function in lambda function.
811eaad010SYaxun (Sam) Liu // Callee should resolve to correct host/device function based on where
821eaad010SYaxun (Sam) Liu // the lambda function is called, not where it is defined.
test_resolve(void)831eaad010SYaxun (Sam) Liu void test_resolve(void) {
841eaad010SYaxun (Sam) Liu   test_resolve_helper([](){ overloaded<int>();});
851eaad010SYaxun (Sam) Liu }
86