blob: bd3546827840c62fddc8146beff8c0d98bdfbe58 [file] [log] [blame]
Matt Arsenaulta2025382017-08-03 23:24:05 +00001; 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
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +00003
4%struct.ByValStruct = type { [4 x i32] }
5
6; GCN-LABEL: {{^}}void_func_byval_struct:
7; GCN: s_mov_b32 s5, s32
Matt Arsenaultd1867c02017-08-02 00:59:51 +00008; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +00009; GCN-NOT: s32
Matt Arsenaultd1867c02017-08-02 00:59:51 +000010; GCN: buffer_store_dword [[LOAD0]], off, s[0:3], s5 offset:4{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000011; GCN-NOT: s32
12
Matt Arsenaultd1867c02017-08-02 00:59:51 +000013; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000014; GCN-NOT: s32
Matt Arsenaultd1867c02017-08-02 00:59:51 +000015; GCN: buffer_store_dword [[LOAD1]], off, s[0:3], s5 offset:20{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000016; GCN-NOT: s32
17define void @void_func_byval_struct(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 {
18entry:
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
29}
30
31; GCN-LABEL: {{^}}void_func_byval_struct_non_leaf:
32; GCN: s_mov_b32 s5, s32
Matt Arsenault8e8f8f42017-08-02 01:52:45 +000033; GCN-DAG: buffer_store_dword v32
34; GCN-DAG: buffer_store_dword v33
Matt Arsenaultecb43ef2017-09-13 23:47:01 +000035; GCN-NOT: v_writelane_b32 v{{[0-9]+}}, s32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000036; GCN: v_writelane_b32
37
Matt Arsenault8e8f8f42017-08-02 01:52:45 +000038; GCN-DAG: s_add_u32 s32, s32, 0xb00{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000039
Matt Arsenaultd1867c02017-08-02 00:59:51 +000040; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:4{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000041; GCN: v_add_i32_e32 [[ADD0:v[0-9]+]], vcc, 1, [[LOAD0]]
Matt Arsenaultd1867c02017-08-02 00:59:51 +000042; GCN: buffer_store_dword [[ADD0]], off, s[0:3], s5 offset:4{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000043
Matt Arsenaultd1867c02017-08-02 00:59:51 +000044; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:20{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000045; GCN: v_add_i32_e32 [[ADD1:v[0-9]+]], vcc, 2, [[LOAD1]]
46
47; GCN: s_swappc_b64
48
Matt Arsenaultd1867c02017-08-02 00:59:51 +000049; GCN: buffer_store_dword [[ADD1]], off, s[0:3], s5 offset:20{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000050
51; GCN: v_readlane_b32
Matt Arsenaultecb43ef2017-09-13 23:47:01 +000052; GCN-NOT: v_readlane_b32 s32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000053; GCN: buffer_load_dword v32,
Matt Arsenault8e8f8f42017-08-02 01:52:45 +000054; GCN: buffer_load_dword v33,
55; GCN: s_sub_u32 s32, s32, 0xb00{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000056; GCN: s_setpc_b64
57define void @void_func_byval_struct_non_leaf(%struct.ByValStruct* byval noalias nocapture align 4 %arg0, %struct.ByValStruct* byval noalias nocapture align 4 %arg1) #1 {
58entry:
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
70}
71
72; GCN-LABEL: {{^}}call_void_func_byval_struct_func:
73; GCN: s_mov_b32 s5, s32
Matt Arsenaultecb43ef2017-09-13 23:47:01 +000074; GCN-DAG: s_add_u32 s32, s32, 0xc00{{$}}
75; GCN-DAG: v_writelane_b32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000076
77; GCN-DAG: s_add_u32 s32, s32, 0x800{{$}}
78; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9
79; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13
80
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000081; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s5 offset:8
82; GCN-DAG: buffer_store_dword [[THIRTEEN]], off, s[0:3], s5 offset:24
83
Matt Arsenaultacc5e822017-08-02 00:43:42 +000084; GCN: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s5 offset:8
85; GCN: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s5 offset:12
86; GCN: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s5 offset:16
87; GCN: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s5 offset:20
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000088
89
Matt Arsenaultd1867c02017-08-02 00:59:51 +000090; 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
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000094
Matt Arsenaultacc5e822017-08-02 00:43:42 +000095; 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
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +000099
Matt Arsenaultd1867c02017-08-02 00:59:51 +0000100; 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
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000104
105; GCN: s_swappc_b64
Matt Arsenaultecb43ef2017-09-13 23:47:01 +0000106; GCN-NOT: v_readlane_b32 s32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000107; GCN: v_readlane_b32
Matt Arsenaultecb43ef2017-09-13 23:47:01 +0000108; GCN-NOT: v_readlane_b32 s32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000109
Matt Arsenaultecb43ef2017-09-13 23:47:01 +0000110; GCN: s_sub_u32 s32, s32, 0x800{{$}}
111; GCN-NEXT: s_sub_u32 s32, s32, 0xc00{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000112; GCN-NEXT: s_waitcnt
113; GCN-NEXT: s_setpc_b64
114define void @call_void_func_byval_struct_func() #0 {
115entry:
116 %arg0 = alloca %struct.ByValStruct, align 4
117 %arg1 = alloca %struct.ByValStruct, align 4
118 %tmp = bitcast %struct.ByValStruct* %arg0 to i8*
119 call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp)
120 %tmp1 = bitcast %struct.ByValStruct* %arg1 to i8*
121 call void @llvm.lifetime.start.p0i8(i64 32, i8* %tmp1)
122 %arrayidx = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg0, i32 0, i32 0, i32 0
123 store volatile i32 9, i32* %arrayidx, align 4
124 %arrayidx2 = getelementptr inbounds %struct.ByValStruct, %struct.ByValStruct* %arg1, i32 0, i32 0, i32 0
125 store volatile i32 13, i32* %arrayidx2, align 4
126 call void @void_func_byval_struct(%struct.ByValStruct* byval nonnull align 4 %arg0, %struct.ByValStruct* byval nonnull align 4 %arg1)
127 call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp1)
128 call void @llvm.lifetime.end.p0i8(i64 32, i8* %tmp)
129 ret void
130}
131
132; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel:
Geoff Berry4e38e022017-08-17 04:04:11 +0000133; GCN: s_mov_b32 s33, s7
134; GCN: s_add_u32 s32, s33, 0xa00{{$}}
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000135
136; GCN-DAG: v_mov_b32_e32 [[NINE:v[0-9]+]], 9
137; GCN-DAG: v_mov_b32_e32 [[THIRTEEN:v[0-9]+]], 13
Geoff Berry4e38e022017-08-17 04:04:11 +0000138; GCN-DAG: buffer_store_dword [[NINE]], off, s[0:3], s33 offset:8
139; GCN: buffer_store_dword [[THIRTEEN]], off, s[0:3], s33 offset:24
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000140
141; GCN-DAG: s_add_u32 s32, s32, 0x800{{$}}
142
Geoff Berry4e38e022017-08-17 04:04:11 +0000143; GCN-DAG: buffer_load_dword [[LOAD0:v[0-9]+]], off, s[0:3], s33 offset:8
144; GCN-DAG: buffer_load_dword [[LOAD1:v[0-9]+]], off, s[0:3], s33 offset:12
145; GCN-DAG: buffer_load_dword [[LOAD2:v[0-9]+]], off, s[0:3], s33 offset:16
146; GCN-DAG: buffer_load_dword [[LOAD3:v[0-9]+]], off, s[0:3], s33 offset:20
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000147
Matt Arsenaultd1867c02017-08-02 00:59:51 +0000148; GCN-DAG: buffer_store_dword [[LOAD0]], off, s[0:3], s32 offset:4{{$}}
149; GCN-DAG: buffer_store_dword [[LOAD1]], off, s[0:3], s32 offset:8
150; GCN-DAG: buffer_store_dword [[LOAD2]], off, s[0:3], s32 offset:12
151; GCN-DAG: buffer_store_dword [[LOAD3]], off, s[0:3], s32 offset:16
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000152
Matt Arsenaultacc5e822017-08-02 00:43:42 +0000153; GCN-DAG: buffer_load_dword [[LOAD4:v[0-9]+]], off, s[0:3], s33 offset:24
154; GCN-DAG: buffer_load_dword [[LOAD5:v[0-9]+]], off, s[0:3], s33 offset:28
155; GCN-DAG: buffer_load_dword [[LOAD6:v[0-9]+]], off, s[0:3], s33 offset:32
156; GCN-DAG: buffer_load_dword [[LOAD7:v[0-9]+]], off, s[0:3], s33 offset:36
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000157
Matt Arsenaultd1867c02017-08-02 00:59:51 +0000158; GCN-DAG: buffer_store_dword [[LOAD4]], off, s[0:3], s32 offset:20
159; GCN-DAG: buffer_store_dword [[LOAD5]], off, s[0:3], s32 offset:24
160; GCN-DAG: buffer_store_dword [[LOAD6]], off, s[0:3], s32 offset:28
161; GCN-DAG: buffer_store_dword [[LOAD7]], off, s[0:3], s32 offset:32
Matt Arsenaultb62a4eb2017-08-01 19:54:18 +0000162
163
164; GCN: s_swappc_b64
165; FIXME: Dead SP modfication
166; GCN-NEXT: s_sub_u32 s32, s32, 0x800{{$}}
167; GCN-NEXT: s_endpgm
168define amdgpu_kernel void @call_void_func_byval_struct_kernel() #0 {
169entry:
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
184}
185
186; GCN-LABEL: {{^}}call_void_func_byval_struct_kernel_no_frame_pointer_elim:
187define amdgpu_kernel void @call_void_func_byval_struct_kernel_no_frame_pointer_elim() #2 {
188entry:
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
203}
204
205declare void @external_void_func_void() #0
206
207declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #3
208declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #3
209
210attributes #0 = { nounwind }
211attributes #1 = { noinline norecurse nounwind }
212attributes #2 = { nounwind norecurse "no-frame-pointer-elim"="true" }