xref: /llvm-project/clang/test/CodeGenCXX/amdgpu-kernel-arg-pointer-type.cpp (revision e169cc162adbe89d498e774bccf4e228af989849)
1 // REQUIRES: amdgpu-registered-target
2 
3 // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm %s -o - | FileCheck --check-prefixes=COMMON,CHECK %s
4 
5 // Derived from CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu by deleting references to HOST
6 // The original test passes the result through opt O2, but that seems to introduce invalid
7 // addrspace casts which are not being fixed as part of the present change.
8 
9 // COMMON: define{{.*}} amdgpu_kernel void @_Z6kernelv() #[[ATTR:[0-9]+]]
10 __attribute__((amdgpu_kernel, amdgpu_flat_work_group_size(1, 256))) void
11     kernel() {}
12 
13 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel1Pi(ptr {{.*}} %x)
14 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to ptr
15 __attribute__((amdgpu_kernel)) void kernel1(int *x) {
16   x[0]++;
17 }
18 
19 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel2Ri(ptr {{.*}} nonnull align 4 dereferenceable(4) %x)
20 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to ptr
21 __attribute__((amdgpu_kernel)) void kernel2(int &x) {
22   x++;
23 }
24 
25 // CHECK-LABEL: define{{.*}} amdgpu_kernel void  @_Z7kernel3PU3AS2iPU3AS1i(ptr addrspace(2){{.*}} %x, ptr addrspace(1){{.*}} %y)
26 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to ptr
27 __attribute__((amdgpu_kernel)) void kernel3(__attribute__((address_space(2))) int *x,
28                                             __attribute__((address_space(1))) int *y) {
29   y[0] = x[0];
30 }
31 
32 // COMMON-LABEL: define{{.*}} void @_Z4funcPi(ptr{{.*}} %x)
33 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to ptr
34 __attribute__((amdgpu_kernel)) void func(int *x) {
35   x[0]++;
36 }
37 
38 struct S {
39   int *x;
40   float *y;
41 };
42 // `by-val` struct is passed by-indirect-alias (a mix of by-ref and indirect
43 // by-val). However, the enhanced address inferring pass should be able to
44 // assume they are global pointers.
45 //
46 
47 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel41S(ptr addrspace(4){{.*}} byref(%struct.S) align 8 %0)
48 __attribute__((amdgpu_kernel)) void kernel4(struct S s) {
49   s.x[0]++;
50   s.y[0] += 1.f;
51 }
52 
53 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel5P1S(ptr {{.*}} %s)
54 __attribute__((amdgpu_kernel)) void kernel5(struct S *s) {
55   s->x[0]++;
56   s->y[0] += 1.f;
57 }
58 
59 struct T {
60   float *x[2];
61 };
62 // `by-val` array is passed by-indirect-alias (a mix of by-ref and indirect
63 // by-val). However, the enhanced address inferring pass should be able to
64 // assume they are global pointers.
65 //
66 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel61T(ptr addrspace(4){{.*}} byref(%struct.T) align 8 %0)
67 __attribute__((amdgpu_kernel)) void kernel6(struct T t) {
68   t.x[0][0] += 1.f;
69   t.x[1][0] += 2.f;
70 }
71 
72 // Check that coerced pointers retain the noalias attribute when qualified with __restrict.
73 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel7Pi(ptr noalias{{.*}} %x)
74 __attribute__((amdgpu_kernel)) void kernel7(int *__restrict x) {
75   x[0]++;
76 }
77 
78 // Single element struct.
79 struct SS {
80   float *x;
81 };
82 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel82SS(ptr %a.coerce)
83 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to ptr
84 __attribute__((amdgpu_kernel)) void kernel8(struct SS a) {
85   *a.x += 3.f;
86 }
87 
88 // COMMON: attributes #[[ATTR]] = { {{.*}}"amdgpu-flat-work-group-size"="1,256"{{.*}} }
89