1 // REQUIRES: amdgpu-registered-target
2 
3 // RUN: %clang_cc1 -no-opaque-pointers -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-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel1Pi(i32* {{.*}} %x)
10 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]*
11 __attribute__((amdgpu_kernel)) void kernel1(int *x) {
12   x[0]++;
13 }
14 
15 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel2Ri(i32* {{.*}} nonnull align 4 dereferenceable(4) %x)
16 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]*
17 __attribute__((amdgpu_kernel)) void kernel2(int &x) {
18   x++;
19 }
20 
21 // CHECK-LABEL: define{{.*}} amdgpu_kernel void  @_Z7kernel3PU3AS2iPU3AS1i(i32 addrspace(2)*{{.*}} %x, i32 addrspace(1)*{{.*}} %y)
22 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]*
23 __attribute__((amdgpu_kernel)) void kernel3(__attribute__((address_space(2))) int *x,
24                                             __attribute__((address_space(1))) int *y) {
25   y[0] = x[0];
26 }
27 
28 // COMMON-LABEL: define{{.*}} void @_Z4funcPi(i32*{{.*}} %x)
29 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]*
30 __attribute__((amdgpu_kernel)) void func(int *x) {
31   x[0]++;
32 }
33 
34 struct S {
35   int *x;
36   float *y;
37 };
38 // `by-val` struct is passed by-indirect-alias (a mix of by-ref and indirect
39 // by-val). However, the enhanced address inferring pass should be able to
40 // assume they are global pointers.
41 //
42 
43 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel41S(%struct.S addrspace(4)*{{.*}} byref(%struct.S) align 8 %0)
44 __attribute__((amdgpu_kernel)) void kernel4(struct S s) {
45   s.x[0]++;
46   s.y[0] += 1.f;
47 }
48 
49 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel5P1S(%struct.S* {{.*}} %s)
50 __attribute__((amdgpu_kernel)) void kernel5(struct S *s) {
51   s->x[0]++;
52   s->y[0] += 1.f;
53 }
54 
55 struct T {
56   float *x[2];
57 };
58 // `by-val` array is passed by-indirect-alias (a mix of by-ref and indirect
59 // by-val). However, the enhanced address inferring pass should be able to
60 // assume they are global pointers.
61 //
62 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel61T(%struct.T addrspace(4)*{{.*}} byref(%struct.T) align 8 %0)
63 __attribute__((amdgpu_kernel)) void kernel6(struct T t) {
64   t.x[0][0] += 1.f;
65   t.x[1][0] += 2.f;
66 }
67 
68 // Check that coerced pointers retain the noalias attribute when qualified with __restrict.
69 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel7Pi(i32* noalias{{.*}} %x)
70 __attribute__((amdgpu_kernel)) void kernel7(int *__restrict x) {
71   x[0]++;
72 }
73 
74 // Single element struct.
75 struct SS {
76   float *x;
77 };
78 // COMMON-LABEL: define{{.*}} amdgpu_kernel void @_Z7kernel82SS(float* %a.coerce)
79 // CHECK-NOT: ={{.*}} addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]*
80 __attribute__((amdgpu_kernel)) void kernel8(struct SS a) {
81   *a.x += 3.f;
82 }
83 
84