Recommit r310809 with a fix for the spill problem
[llvm-core.git] / test / CodeGen / AMDGPU / byval-frame-setup.ll
blob398c7d32aee63046759a269084b6710b7951d171
1 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,VI %s
2 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CI %s
4 %struct.ByValStruct = type { [4 x i32] }
6 ; GCN-LABEL: {{^}}void_func_byval_struct:
7 ; GCN: s_mov_b32 s5, s32
8 ; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}}
9 ; GCN-NOT: s32
10 ; GCN: buffer_store_dword [[LOAD0]], off, s[0:3], s5 offset:4{{$}}
11 ; GCN-NOT: s32
13 ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}}
14 ; GCN-NOT: s32
15 ; GCN: buffer_store_dword [[LOAD1]], off, s[0:3], s5 offset:20{{$}}
16 ; GCN-NOT: s32
17 define void @void_func_byval_struct(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 {
18 entry:
19   %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
20   %tmp = load volatile i32, i32* %arrayidx, align 4
21   %add = add nsw i32 %tmp, 1
22   store volatile i32 %add, i32* %arrayidx, align 4
23   %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
24   %tmp1 = load volatile i32, i32* %arrayidx2, align 4
25   %add3 = add nsw i32 %tmp1, 2
26   store volatile i32 %add3, i32* %arrayidx2, align 4
27   store volatile i32 9, i32 addrspace(1)* null, align 4
28   ret void
31 ; GCN-LABEL: {{^}}void_func_byval_struct_non_leaf:
32 ; GCN: s_mov_b32 s5, s32
33 ; GCN-DAG: buffer_store_dword v32
34 ; GCN-DAG: buffer_store_dword v33
35 ; GCN-NOT: v_writelane_b32 v{{[0-9]+}}, s32
36 ; GCN: v_writelane_b32
38 ; GCN-DAG: s_add_u32 s32, s32, 0xb00{{$}}
40 ; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}}
41 ; GCN: v_add_i32_e32 [[ADD0:v[0-9]+]], vcc, 1, [[LOAD0]]
42 ; GCN: buffer_store_dword [[ADD0]], off, s[0:3], s5 offset:4{{$}}
44 ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}}
45 ; GCN: v_add_i32_e32 [[ADD1:v[0-9]+]], vcc, 2, [[LOAD1]]
47 ; GCN: s_swappc_b64
49 ; GCN: buffer_store_dword [[ADD1]], off, s[0:3], s5 offset:20{{$}}
51 ; GCN: v_readlane_b32
52 ; GCN-NOT: v_readlane_b32 s32
53 ; GCN: buffer_load_dword v32,
54 ; GCN: buffer_load_dword v33,
55 ; GCN: s_sub_u32 s32, s32, 0xb00{{$}}
56 ; GCN: s_setpc_b64
57 define void  @void_func_byval_struct_non_leaf(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 {
58 entry:
59   %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
60   %tmp = load volatile i32, i32* %arrayidx, align 4
61   %add = add nsw i32 %tmp, 1
62   store volatile i32 %add, i32* %arrayidx, align 4
63   %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
64   %tmp1 = load volatile i32, i32* %arrayidx2, align 4
65   %add3 = add nsw i32 %tmp1, 2
66   call void @external_void_func_void()
67   store volatile i32 %add3, i32* %arrayidx2, align 4
68   store volatile i32 9, i32 addrspace(1)* null, align 4
69   ret void
72 ; GCN-LABEL: {{^}}call_void_func_byval_struct_func:
73 ; GCN: s_mov_b32 s5, s32
74 ; GCN-DAG: s_add_u32 s32, s32, 0xc00{{$}}
75 ; GCN-DAG: v_writelane_b32
77 ; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9
78 ; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13
80 ; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s5 offset:8
81 ; GCN-DAG: buffer_store_dword [[THIRTEEN]], off, s[0:3], s5 offset:24
83 ; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:8
84 ; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:12
85 ; GCN: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s5 offset:16
86 ; GCN: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s5 offset:20
88 ; GCN-NOT: s_add_u32 s32, s32, 0x800
90 ; GCN-DAG: buffer_store_dword [[LOAD0]], off, s[0:3], s32 offset:4{{$}}
91 ; GCN-DAG: buffer_store_dword [[LOAD1]], off, s[0:3], s32 offset:8
92 ; GCN-DAG: buffer_store_dword [[LOAD2]], off, s[0:3], s32 offset:12
93 ; GCN-DAG: buffer_store_dword [[LOAD3]], off, s[0:3], s32 offset:16
95 ; GCN: buffer_load_dword [[LOAD4:v[0-9]+]], off, s[0:3], s5 offset:24
96 ; GCN: buffer_load_dword [[LOAD5:v[0-9]+]], off, s[0:3], s5 offset:28
97 ; GCN: buffer_load_dword [[LOAD6:v[0-9]+]], off, s[0:3], s5 offset:32
98 ; GCN: buffer_load_dword [[LOAD7:v[0-9]+]], off, s[0:3], s5 offset:36
100 ; GCN-DAG: buffer_store_dword [[LOAD4]], off, s[0:3], s32 offset:20
101 ; GCN-DAG: buffer_store_dword [[LOAD5]], off, s[0:3], s32 offset:24
102 ; GCN-DAG: buffer_store_dword [[LOAD6]], off, s[0:3], s32 offset:28
103 ; GCN-DAG: buffer_store_dword [[LOAD7]], off, s[0:3], s32 offset:32
105 ; GCN: s_swappc_b64
106 ; GCN-NOT: v_readlane_b32 s32
107 ; GCN: v_readlane_b32
108 ; GCN-NOT: v_readlane_b32 s32
110 ; GCN-NOT: s_sub_u32 s32, s32, 0x800
112 ; GCN: s_sub_u32 s32, s32, 0xc00{{$}}
113 ; GCN-NEXT: s_waitcnt
114 ; GCN-NEXT: s_setpc_b64
115 define void @call_void_func_byval_struct_func() #0 {
116 entry:
117   %arg0 = alloca %struct.ByValStruct, align 4
118   %arg1 = alloca %struct.ByValStruct, align 4
119   %tmp = bitcast %struct.ByValStruct* %arg0 to i8*
120   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp)
121   %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8*
122   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1)
123   %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
124   store volatile i32 9, i32* %arrayidx, align 4
125   %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
126   store volatile i32 13, i32* %arrayidx2, align 4
127   call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1)
128   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1)
129   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp)
130   ret void
133 ; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel:
134 ; GCN: s_mov_b32 s33, s7
135 ; GCN: s_add_u32 s32, s33, 0xa00{{$}}
137 ; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9
138 ; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13
139 ; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s33 offset:8
140 ; GCN: buffer_store_dword [[THIRTEEN]], off, s[0:3], s33 offset:24
142 ; GCN-NOT: s_add_u32 s32, s32, 0x800
144 ; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s33 offset:8
145 ; GCN-DAG: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s33 offset:12
146 ; GCN-DAG: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s33 offset:16
147 ; GCN-DAG: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s33 offset:20
149 ; GCN-DAG: buffer_store_dword [[LOAD0]], off, s[0:3], s32 offset:4{{$}}
150 ; GCN-DAG: buffer_store_dword [[LOAD1]], off, s[0:3], s32 offset:8
151 ; GCN-DAG: buffer_store_dword [[LOAD2]], off, s[0:3], s32 offset:12
152 ; GCN-DAG: buffer_store_dword [[LOAD3]], off, s[0:3], s32 offset:16
154 ; GCN-DAG: buffer_load_dword [[LOAD4:v[0-9]+]], off, s[0:3], s33 offset:24
155 ; GCN-DAG: buffer_load_dword [[LOAD5:v[0-9]+]], off, s[0:3], s33 offset:28
156 ; GCN-DAG: buffer_load_dword [[LOAD6:v[0-9]+]], off, s[0:3], s33 offset:32
157 ; GCN-DAG: buffer_load_dword [[LOAD7:v[0-9]+]], off, s[0:3], s33 offset:36
159 ; GCN-DAG: buffer_store_dword [[LOAD4]], off, s[0:3], s32 offset:20
160 ; GCN-DAG: buffer_store_dword [[LOAD5]], off, s[0:3], s32 offset:24
161 ; GCN-DAG: buffer_store_dword [[LOAD6]], off, s[0:3], s32 offset:28
162 ; GCN-DAG: buffer_store_dword [[LOAD7]], off, s[0:3], s32 offset:32
165 ; GCN: s_swappc_b64
166 ; GCN-NOT: s_sub_u32 s32
167 ; GCN: s_endpgm
168 define amdgpu_kernel void @call_void_func_byval_struct_kernel() #0 {
169 entry:
170   %arg0 = alloca %struct.ByValStruct, align 4
171   %arg1 = alloca %struct.ByValStruct, align 4
172   %tmp = bitcast %struct.ByValStruct* %arg0 to i8*
173   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp)
174   %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8*
175   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1)
176   %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
177   store volatile i32 9, i32* %arrayidx, align 4
178   %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
179   store volatile i32 13, i32* %arrayidx2, align 4
180   call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1)
181   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1)
182   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp)
183   ret void
186 ; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel_no_frame_pointer_elim:
187 define amdgpu_kernel void @call_void_func_byval_struct_kernel_no_frame_pointer_elim() #2 {
188 entry:
189   %arg0 = alloca %struct.ByValStruct, align 4
190   %arg1 = alloca %struct.ByValStruct, align 4
191   %tmp = bitcast %struct.ByValStruct* %arg0 to i8*
192   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp)
193   %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8*
194   call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1)
195   %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
196   store volatile i32 9, i32* %arrayidx, align 4
197   %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
198   store volatile i32 13, i32* %arrayidx2, align 4
199   call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1)
200   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1)
201   call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp)
202   ret void
205 declare void @external_void_func_void() #0
207 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #3
208 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #3
210 attributes #0 = { nounwind }
211 attributes #1 = { noinline norecurse nounwind }
212 attributes #2 = { nounwind norecurse "no-frame-pointer-elim"="true" }