1// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -ffake-address-space-map -triple i686-pc-darwin | FileCheck -check-prefixes=COM,X86 %s
2// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -finclude-default-header -triple amdgcn-amdhsa-amd-amdgizcl | FileCheck -check-prefixes=COM,AMD %s
3
4typedef struct {
5  int cells[9];
6} Mat3X3;
7
8typedef struct {
9  int cells[16];
10} Mat4X4;
11
12struct StructOneMember {
13  int2 x;
14};
15
16struct StructTwoMember {
17  int2 x;
18  int2 y;
19};
20
21// COM-LABEL: define void @foo
22Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) {
23  Mat4X4 out;
24  return out;
25}
26
27// COM-LABEL: define {{.*}} void @ker
28// Expect two mem copies: one for the argument "in", and one for
29// the return value.
30// X86: call void @llvm.memcpy.p0i8.p1i8.i32(i8*
31// X86: call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)*
32// AMD: call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)*
33// AMD: call void @llvm.memcpy.p1i8.p5i8.i64(i8 addrspace(1)*
34kernel void ker(global Mat3X3 *in, global Mat4X4 *out) {
35  out[0] = foo(in[1]);
36}
37
38// AMD-LABEL: define void @FuncOneMember(%struct.StructOneMember addrspace(5)* byval align 8 %u)
39void FuncOneMember(struct StructOneMember u) {
40  u.x = (int2)(0, 0);
41}
42
43// AMD-LABEL: define amdgpu_kernel void @KernelOneMember
44// AMD-SAME:  (<2 x i32> %[[u_coerce:.*]])
45// AMD:  %[[u:.*]] = alloca %struct.StructOneMember, align 8, addrspace(5)
46// AMD:  %[[coerce_dive:.*]] = getelementptr inbounds %struct.StructOneMember, %struct.StructOneMember addrspace(5)* %[[u]], i32 0, i32 0
47// AMD:  store <2 x i32> %[[u_coerce]], <2 x i32> addrspace(5)* %[[coerce_dive]]
48// AMD:  call void @FuncOneMember(%struct.StructOneMember addrspace(5)* byval align 8 %[[u]])
49kernel void KernelOneMember(struct StructOneMember u) {
50  FuncOneMember(u);
51}
52
53// AMD-LABEL: define void @FuncTwoMember(%struct.StructTwoMember addrspace(5)* byval align 8 %u)
54void FuncTwoMember(struct StructTwoMember u) {
55  u.x = (int2)(0, 0);
56}
57
58// AMD-LABEL: define amdgpu_kernel void @KernelTwoMember
59// AMD-SAME:  (%struct.StructTwoMember %[[u_coerce:.*]])
60// AMD:  %[[u:.*]] = alloca %struct.StructTwoMember, align 8, addrspace(5)
61// AMD:  store %struct.StructTwoMember %[[u_coerce]], %struct.StructTwoMember addrspace(5)* %[[u]]
62// AMD:  call void @FuncTwoMember(%struct.StructTwoMember addrspace(5)* byval align 8 %[[u]])
63kernel void KernelTwoMember(struct StructTwoMember u) {
64  FuncTwoMember(u);
65}
66