1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -amdgpu-fixed-function-abi -mtriple=amdgcn-amd-amdhsa --amdhsa-code-object-version=2 -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
3
4@gv.fptr0 = external hidden unnamed_addr addrspace(4) constant void()*, align 4
5@gv.fptr1 = external hidden unnamed_addr addrspace(4) constant void(i32)*, align 4
6
7define amdgpu_kernel void @test_indirect_call_sgpr_ptr() {
8; GCN-LABEL: test_indirect_call_sgpr_ptr:
9; GCN:         .amd_kernel_code_t
10; GCN-NEXT:     amd_code_version_major = 1
11; GCN-NEXT:     amd_code_version_minor = 2
12; GCN-NEXT:     amd_machine_kind = 1
13; GCN-NEXT:     amd_machine_version_major = 7
14; GCN-NEXT:     amd_machine_version_minor = 0
15; GCN-NEXT:     amd_machine_version_stepping = 0
16; GCN-NEXT:     kernel_code_entry_byte_offset = 256
17; GCN-NEXT:     kernel_code_prefetch_byte_size = 0
18; GCN-NEXT:     granulated_workitem_vgpr_count = 7
19; GCN-NEXT:     granulated_wavefront_sgpr_count = 5
20; GCN-NEXT:     priority = 0
21; GCN-NEXT:     float_mode = 240
22; GCN-NEXT:     priv = 0
23; GCN-NEXT:     enable_dx10_clamp = 1
24; GCN-NEXT:     debug_mode = 0
25; GCN-NEXT:     enable_ieee_mode = 1
26; GCN-NEXT:     enable_wgp_mode = 0
27; GCN-NEXT:     enable_mem_ordered = 0
28; GCN-NEXT:     enable_fwd_progress = 0
29; GCN-NEXT:     enable_sgpr_private_segment_wave_byte_offset = 1
30; GCN-NEXT:     user_sgpr_count = 14
31; GCN-NEXT:     enable_trap_handler = 0
32; GCN-NEXT:     enable_sgpr_workgroup_id_x = 1
33; GCN-NEXT:     enable_sgpr_workgroup_id_y = 1
34; GCN-NEXT:     enable_sgpr_workgroup_id_z = 1
35; GCN-NEXT:     enable_sgpr_workgroup_info = 0
36; GCN-NEXT:     enable_vgpr_workitem_id = 2
37; GCN-NEXT:     enable_exception_msb = 0
38; GCN-NEXT:     granulated_lds_size = 0
39; GCN-NEXT:     enable_exception = 0
40; GCN-NEXT:     enable_sgpr_private_segment_buffer = 1
41; GCN-NEXT:     enable_sgpr_dispatch_ptr = 1
42; GCN-NEXT:     enable_sgpr_queue_ptr = 1
43; GCN-NEXT:     enable_sgpr_kernarg_segment_ptr = 1
44; GCN-NEXT:     enable_sgpr_dispatch_id = 1
45; GCN-NEXT:     enable_sgpr_flat_scratch_init = 1
46; GCN-NEXT:     enable_sgpr_private_segment_size = 0
47; GCN-NEXT:     enable_sgpr_grid_workgroup_count_x = 0
48; GCN-NEXT:     enable_sgpr_grid_workgroup_count_y = 0
49; GCN-NEXT:     enable_sgpr_grid_workgroup_count_z = 0
50; GCN-NEXT:     enable_wavefront_size32 = 0
51; GCN-NEXT:     enable_ordered_append_gds = 0
52; GCN-NEXT:     private_element_size = 1
53; GCN-NEXT:     is_ptr64 = 1
54; GCN-NEXT:     is_dynamic_callstack = 1
55; GCN-NEXT:     is_debug_enabled = 0
56; GCN-NEXT:     is_xnack_enabled = 1
57; GCN-NEXT:     workitem_private_segment_byte_size = 16384
58; GCN-NEXT:     workgroup_group_segment_byte_size = 0
59; GCN-NEXT:     gds_segment_byte_size = 0
60; GCN-NEXT:     kernarg_segment_byte_size = 0
61; GCN-NEXT:     workgroup_fbarrier_count = 0
62; GCN-NEXT:     wavefront_sgpr_count = 48
63; GCN-NEXT:     workitem_vgpr_count = 32
64; GCN-NEXT:     reserved_vgpr_first = 0
65; GCN-NEXT:     reserved_vgpr_count = 0
66; GCN-NEXT:     reserved_sgpr_first = 0
67; GCN-NEXT:     reserved_sgpr_count = 0
68; GCN-NEXT:     debug_wavefront_private_segment_offset_sgpr = 0
69; GCN-NEXT:     debug_private_segment_buffer_sgpr = 0
70; GCN-NEXT:     kernarg_segment_alignment = 4
71; GCN-NEXT:     group_segment_alignment = 4
72; GCN-NEXT:     private_segment_alignment = 4
73; GCN-NEXT:     wavefront_size = 6
74; GCN-NEXT:     call_convention = -1
75; GCN-NEXT:     runtime_loader_kernel_symbol = 0
76; GCN-NEXT:    .end_amd_kernel_code_t
77; GCN-NEXT:  ; %bb.0:
78; GCN-NEXT:    s_mov_b32 s32, 0
79; GCN-NEXT:    s_mov_b32 flat_scratch_lo, s13
80; GCN-NEXT:    s_add_u32 s12, s12, s17
81; GCN-NEXT:    s_lshr_b32 flat_scratch_hi, s12, 8
82; GCN-NEXT:    s_add_u32 s0, s0, s17
83; GCN-NEXT:    s_addc_u32 s1, s1, 0
84; GCN-NEXT:    s_mov_b32 s13, s15
85; GCN-NEXT:    s_mov_b32 s12, s14
86; GCN-NEXT:    s_getpc_b64 s[14:15]
87; GCN-NEXT:    s_add_u32 s14, s14, gv.fptr0@rel32@lo+4
88; GCN-NEXT:    s_addc_u32 s15, s15, gv.fptr0@rel32@hi+12
89; GCN-NEXT:    s_load_dwordx2 s[18:19], s[14:15], 0x0
90; GCN-NEXT:    v_lshlrev_b32_e32 v2, 20, v2
91; GCN-NEXT:    v_lshlrev_b32_e32 v1, 10, v1
92; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
93; GCN-NEXT:    v_or_b32_e32 v31, v0, v2
94; GCN-NEXT:    s_mov_b32 s14, s16
95; GCN-NEXT:    s_waitcnt lgkmcnt(0)
96; GCN-NEXT:    s_swappc_b64 s[30:31], s[18:19]
97; GCN-NEXT:    s_endpgm
98  %fptr = load void()*, void()* addrspace(4)* @gv.fptr0
99  call void %fptr()
100  ret void
101}
102
103define amdgpu_kernel void @test_indirect_call_sgpr_ptr_arg() {
104; GCN-LABEL: test_indirect_call_sgpr_ptr_arg:
105; GCN:         .amd_kernel_code_t
106; GCN-NEXT:     amd_code_version_major = 1
107; GCN-NEXT:     amd_code_version_minor = 2
108; GCN-NEXT:     amd_machine_kind = 1
109; GCN-NEXT:     amd_machine_version_major = 7
110; GCN-NEXT:     amd_machine_version_minor = 0
111; GCN-NEXT:     amd_machine_version_stepping = 0
112; GCN-NEXT:     kernel_code_entry_byte_offset = 256
113; GCN-NEXT:     kernel_code_prefetch_byte_size = 0
114; GCN-NEXT:     granulated_workitem_vgpr_count = 7
115; GCN-NEXT:     granulated_wavefront_sgpr_count = 5
116; GCN-NEXT:     priority = 0
117; GCN-NEXT:     float_mode = 240
118; GCN-NEXT:     priv = 0
119; GCN-NEXT:     enable_dx10_clamp = 1
120; GCN-NEXT:     debug_mode = 0
121; GCN-NEXT:     enable_ieee_mode = 1
122; GCN-NEXT:     enable_wgp_mode = 0
123; GCN-NEXT:     enable_mem_ordered = 0
124; GCN-NEXT:     enable_fwd_progress = 0
125; GCN-NEXT:     enable_sgpr_private_segment_wave_byte_offset = 1
126; GCN-NEXT:     user_sgpr_count = 14
127; GCN-NEXT:     enable_trap_handler = 0
128; GCN-NEXT:     enable_sgpr_workgroup_id_x = 1
129; GCN-NEXT:     enable_sgpr_workgroup_id_y = 1
130; GCN-NEXT:     enable_sgpr_workgroup_id_z = 1
131; GCN-NEXT:     enable_sgpr_workgroup_info = 0
132; GCN-NEXT:     enable_vgpr_workitem_id = 2
133; GCN-NEXT:     enable_exception_msb = 0
134; GCN-NEXT:     granulated_lds_size = 0
135; GCN-NEXT:     enable_exception = 0
136; GCN-NEXT:     enable_sgpr_private_segment_buffer = 1
137; GCN-NEXT:     enable_sgpr_dispatch_ptr = 1
138; GCN-NEXT:     enable_sgpr_queue_ptr = 1
139; GCN-NEXT:     enable_sgpr_kernarg_segment_ptr = 1
140; GCN-NEXT:     enable_sgpr_dispatch_id = 1
141; GCN-NEXT:     enable_sgpr_flat_scratch_init = 1
142; GCN-NEXT:     enable_sgpr_private_segment_size = 0
143; GCN-NEXT:     enable_sgpr_grid_workgroup_count_x = 0
144; GCN-NEXT:     enable_sgpr_grid_workgroup_count_y = 0
145; GCN-NEXT:     enable_sgpr_grid_workgroup_count_z = 0
146; GCN-NEXT:     enable_wavefront_size32 = 0
147; GCN-NEXT:     enable_ordered_append_gds = 0
148; GCN-NEXT:     private_element_size = 1
149; GCN-NEXT:     is_ptr64 = 1
150; GCN-NEXT:     is_dynamic_callstack = 1
151; GCN-NEXT:     is_debug_enabled = 0
152; GCN-NEXT:     is_xnack_enabled = 1
153; GCN-NEXT:     workitem_private_segment_byte_size = 16384
154; GCN-NEXT:     workgroup_group_segment_byte_size = 0
155; GCN-NEXT:     gds_segment_byte_size = 0
156; GCN-NEXT:     kernarg_segment_byte_size = 0
157; GCN-NEXT:     workgroup_fbarrier_count = 0
158; GCN-NEXT:     wavefront_sgpr_count = 48
159; GCN-NEXT:     workitem_vgpr_count = 32
160; GCN-NEXT:     reserved_vgpr_first = 0
161; GCN-NEXT:     reserved_vgpr_count = 0
162; GCN-NEXT:     reserved_sgpr_first = 0
163; GCN-NEXT:     reserved_sgpr_count = 0
164; GCN-NEXT:     debug_wavefront_private_segment_offset_sgpr = 0
165; GCN-NEXT:     debug_private_segment_buffer_sgpr = 0
166; GCN-NEXT:     kernarg_segment_alignment = 4
167; GCN-NEXT:     group_segment_alignment = 4
168; GCN-NEXT:     private_segment_alignment = 4
169; GCN-NEXT:     wavefront_size = 6
170; GCN-NEXT:     call_convention = -1
171; GCN-NEXT:     runtime_loader_kernel_symbol = 0
172; GCN-NEXT:    .end_amd_kernel_code_t
173; GCN-NEXT:  ; %bb.0:
174; GCN-NEXT:    s_mov_b32 s32, 0
175; GCN-NEXT:    s_mov_b32 flat_scratch_lo, s13
176; GCN-NEXT:    s_add_u32 s12, s12, s17
177; GCN-NEXT:    s_lshr_b32 flat_scratch_hi, s12, 8
178; GCN-NEXT:    s_add_u32 s0, s0, s17
179; GCN-NEXT:    s_addc_u32 s1, s1, 0
180; GCN-NEXT:    s_mov_b32 s13, s15
181; GCN-NEXT:    s_mov_b32 s12, s14
182; GCN-NEXT:    s_getpc_b64 s[14:15]
183; GCN-NEXT:    s_add_u32 s14, s14, gv.fptr1@rel32@lo+4
184; GCN-NEXT:    s_addc_u32 s15, s15, gv.fptr1@rel32@hi+12
185; GCN-NEXT:    v_lshlrev_b32_e32 v2, 20, v2
186; GCN-NEXT:    s_load_dwordx2 s[18:19], s[14:15], 0x0
187; GCN-NEXT:    v_lshlrev_b32_e32 v1, 10, v1
188; GCN-NEXT:    v_or_b32_e32 v0, v0, v1
189; GCN-NEXT:    v_or_b32_e32 v31, v0, v2
190; GCN-NEXT:    v_mov_b32_e32 v0, 0x7b
191; GCN-NEXT:    s_mov_b32 s14, s16
192; GCN-NEXT:    s_waitcnt lgkmcnt(0)
193; GCN-NEXT:    s_swappc_b64 s[30:31], s[18:19]
194; GCN-NEXT:    s_endpgm
195  %fptr = load void(i32)*, void(i32)* addrspace(4)* @gv.fptr1
196  call void %fptr(i32 123)
197  ret void
198}
199
200define void @test_indirect_call_vgpr_ptr(void()* %fptr) {
201; GCN-LABEL: test_indirect_call_vgpr_ptr:
202; GCN:       ; %bb.0:
203; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
204; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
205; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
206; GCN-NEXT:    s_mov_b64 exec, s[16:17]
207; GCN-NEXT:    v_writelane_b32 v43, s33, 17
208; GCN-NEXT:    s_mov_b32 s33, s32
209; GCN-NEXT:    s_add_u32 s32, s32, 0x800
210; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
211; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
212; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
213; GCN-NEXT:    v_writelane_b32 v43, s34, 0
214; GCN-NEXT:    v_writelane_b32 v43, s35, 1
215; GCN-NEXT:    v_writelane_b32 v43, s36, 2
216; GCN-NEXT:    v_writelane_b32 v43, s38, 3
217; GCN-NEXT:    v_writelane_b32 v43, s39, 4
218; GCN-NEXT:    v_writelane_b32 v43, s40, 5
219; GCN-NEXT:    v_writelane_b32 v43, s41, 6
220; GCN-NEXT:    v_writelane_b32 v43, s42, 7
221; GCN-NEXT:    v_writelane_b32 v43, s43, 8
222; GCN-NEXT:    v_writelane_b32 v43, s44, 9
223; GCN-NEXT:    v_writelane_b32 v43, s45, 10
224; GCN-NEXT:    v_writelane_b32 v43, s46, 11
225; GCN-NEXT:    v_writelane_b32 v43, s47, 12
226; GCN-NEXT:    v_writelane_b32 v43, s48, 13
227; GCN-NEXT:    v_writelane_b32 v43, s49, 14
228; GCN-NEXT:    v_writelane_b32 v43, s30, 15
229; GCN-NEXT:    v_writelane_b32 v43, s31, 16
230; GCN-NEXT:    v_mov_b32_e32 v40, v31
231; GCN-NEXT:    s_mov_b32 s34, s14
232; GCN-NEXT:    s_mov_b32 s35, s13
233; GCN-NEXT:    s_mov_b32 s36, s12
234; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
235; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
236; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
237; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
238; GCN-NEXT:    v_mov_b32_e32 v42, v1
239; GCN-NEXT:    v_mov_b32_e32 v41, v0
240; GCN-NEXT:    s_mov_b64 s[46:47], exec
241; GCN-NEXT:  BB2_1: ; =>This Inner Loop Header: Depth=1
242; GCN-NEXT:    v_readfirstlane_b32 s16, v41
243; GCN-NEXT:    v_readfirstlane_b32 s17, v42
244; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
245; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
246; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
247; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
248; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
249; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
250; GCN-NEXT:    s_mov_b32 s12, s36
251; GCN-NEXT:    s_mov_b32 s13, s35
252; GCN-NEXT:    s_mov_b32 s14, s34
253; GCN-NEXT:    v_mov_b32_e32 v31, v40
254; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
255; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
256; GCN-NEXT:    s_cbranch_execnz BB2_1
257; GCN-NEXT:  ; %bb.2:
258; GCN-NEXT:    s_mov_b64 exec, s[46:47]
259; GCN-NEXT:    v_readlane_b32 s4, v43, 15
260; GCN-NEXT:    v_readlane_b32 s5, v43, 16
261; GCN-NEXT:    v_readlane_b32 s49, v43, 14
262; GCN-NEXT:    v_readlane_b32 s48, v43, 13
263; GCN-NEXT:    v_readlane_b32 s47, v43, 12
264; GCN-NEXT:    v_readlane_b32 s46, v43, 11
265; GCN-NEXT:    v_readlane_b32 s45, v43, 10
266; GCN-NEXT:    v_readlane_b32 s44, v43, 9
267; GCN-NEXT:    v_readlane_b32 s43, v43, 8
268; GCN-NEXT:    v_readlane_b32 s42, v43, 7
269; GCN-NEXT:    v_readlane_b32 s41, v43, 6
270; GCN-NEXT:    v_readlane_b32 s40, v43, 5
271; GCN-NEXT:    v_readlane_b32 s39, v43, 4
272; GCN-NEXT:    v_readlane_b32 s38, v43, 3
273; GCN-NEXT:    v_readlane_b32 s36, v43, 2
274; GCN-NEXT:    v_readlane_b32 s35, v43, 1
275; GCN-NEXT:    v_readlane_b32 s34, v43, 0
276; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
277; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
278; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
279; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
280; GCN-NEXT:    v_readlane_b32 s33, v43, 17
281; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
282; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
283; GCN-NEXT:    s_mov_b64 exec, s[6:7]
284; GCN-NEXT:    s_waitcnt vmcnt(0)
285; GCN-NEXT:    s_setpc_b64 s[4:5]
286  call void %fptr()
287  ret void
288}
289
290define void @test_indirect_call_vgpr_ptr_arg(void(i32)* %fptr) {
291; GCN-LABEL: test_indirect_call_vgpr_ptr_arg:
292; GCN:       ; %bb.0:
293; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
294; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
295; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
296; GCN-NEXT:    s_mov_b64 exec, s[16:17]
297; GCN-NEXT:    v_writelane_b32 v43, s33, 17
298; GCN-NEXT:    s_mov_b32 s33, s32
299; GCN-NEXT:    s_add_u32 s32, s32, 0x800
300; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
301; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
302; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
303; GCN-NEXT:    v_writelane_b32 v43, s34, 0
304; GCN-NEXT:    v_writelane_b32 v43, s35, 1
305; GCN-NEXT:    v_writelane_b32 v43, s36, 2
306; GCN-NEXT:    v_writelane_b32 v43, s38, 3
307; GCN-NEXT:    v_writelane_b32 v43, s39, 4
308; GCN-NEXT:    v_writelane_b32 v43, s40, 5
309; GCN-NEXT:    v_writelane_b32 v43, s41, 6
310; GCN-NEXT:    v_writelane_b32 v43, s42, 7
311; GCN-NEXT:    v_writelane_b32 v43, s43, 8
312; GCN-NEXT:    v_writelane_b32 v43, s44, 9
313; GCN-NEXT:    v_writelane_b32 v43, s45, 10
314; GCN-NEXT:    v_writelane_b32 v43, s46, 11
315; GCN-NEXT:    v_writelane_b32 v43, s47, 12
316; GCN-NEXT:    v_writelane_b32 v43, s48, 13
317; GCN-NEXT:    v_writelane_b32 v43, s49, 14
318; GCN-NEXT:    v_writelane_b32 v43, s30, 15
319; GCN-NEXT:    v_writelane_b32 v43, s31, 16
320; GCN-NEXT:    v_mov_b32_e32 v40, v31
321; GCN-NEXT:    s_mov_b32 s34, s14
322; GCN-NEXT:    s_mov_b32 s35, s13
323; GCN-NEXT:    s_mov_b32 s36, s12
324; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
325; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
326; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
327; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
328; GCN-NEXT:    v_mov_b32_e32 v42, v1
329; GCN-NEXT:    v_mov_b32_e32 v41, v0
330; GCN-NEXT:    s_mov_b64 s[46:47], exec
331; GCN-NEXT:  BB3_1: ; =>This Inner Loop Header: Depth=1
332; GCN-NEXT:    v_readfirstlane_b32 s16, v41
333; GCN-NEXT:    v_readfirstlane_b32 s17, v42
334; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
335; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
336; GCN-NEXT:    v_mov_b32_e32 v0, 0x7b
337; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
338; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
339; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
340; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
341; GCN-NEXT:    s_mov_b32 s12, s36
342; GCN-NEXT:    s_mov_b32 s13, s35
343; GCN-NEXT:    s_mov_b32 s14, s34
344; GCN-NEXT:    v_mov_b32_e32 v31, v40
345; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
346; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
347; GCN-NEXT:    s_cbranch_execnz BB3_1
348; GCN-NEXT:  ; %bb.2:
349; GCN-NEXT:    s_mov_b64 exec, s[46:47]
350; GCN-NEXT:    v_readlane_b32 s4, v43, 15
351; GCN-NEXT:    v_readlane_b32 s5, v43, 16
352; GCN-NEXT:    v_readlane_b32 s49, v43, 14
353; GCN-NEXT:    v_readlane_b32 s48, v43, 13
354; GCN-NEXT:    v_readlane_b32 s47, v43, 12
355; GCN-NEXT:    v_readlane_b32 s46, v43, 11
356; GCN-NEXT:    v_readlane_b32 s45, v43, 10
357; GCN-NEXT:    v_readlane_b32 s44, v43, 9
358; GCN-NEXT:    v_readlane_b32 s43, v43, 8
359; GCN-NEXT:    v_readlane_b32 s42, v43, 7
360; GCN-NEXT:    v_readlane_b32 s41, v43, 6
361; GCN-NEXT:    v_readlane_b32 s40, v43, 5
362; GCN-NEXT:    v_readlane_b32 s39, v43, 4
363; GCN-NEXT:    v_readlane_b32 s38, v43, 3
364; GCN-NEXT:    v_readlane_b32 s36, v43, 2
365; GCN-NEXT:    v_readlane_b32 s35, v43, 1
366; GCN-NEXT:    v_readlane_b32 s34, v43, 0
367; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
368; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
369; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
370; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
371; GCN-NEXT:    v_readlane_b32 s33, v43, 17
372; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
373; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
374; GCN-NEXT:    s_mov_b64 exec, s[6:7]
375; GCN-NEXT:    s_waitcnt vmcnt(0)
376; GCN-NEXT:    s_setpc_b64 s[4:5]
377  call void %fptr(i32 123)
378  ret void
379}
380
381define i32 @test_indirect_call_vgpr_ptr_ret(i32()* %fptr) {
382; GCN-LABEL: test_indirect_call_vgpr_ptr_ret:
383; GCN:       ; %bb.0:
384; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
385; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
386; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
387; GCN-NEXT:    s_mov_b64 exec, s[16:17]
388; GCN-NEXT:    v_writelane_b32 v43, s33, 17
389; GCN-NEXT:    s_mov_b32 s33, s32
390; GCN-NEXT:    s_add_u32 s32, s32, 0x800
391; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
392; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
393; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
394; GCN-NEXT:    v_writelane_b32 v43, s34, 0
395; GCN-NEXT:    v_writelane_b32 v43, s35, 1
396; GCN-NEXT:    v_writelane_b32 v43, s36, 2
397; GCN-NEXT:    v_writelane_b32 v43, s38, 3
398; GCN-NEXT:    v_writelane_b32 v43, s39, 4
399; GCN-NEXT:    v_writelane_b32 v43, s40, 5
400; GCN-NEXT:    v_writelane_b32 v43, s41, 6
401; GCN-NEXT:    v_writelane_b32 v43, s42, 7
402; GCN-NEXT:    v_writelane_b32 v43, s43, 8
403; GCN-NEXT:    v_writelane_b32 v43, s44, 9
404; GCN-NEXT:    v_writelane_b32 v43, s45, 10
405; GCN-NEXT:    v_writelane_b32 v43, s46, 11
406; GCN-NEXT:    v_writelane_b32 v43, s47, 12
407; GCN-NEXT:    v_writelane_b32 v43, s48, 13
408; GCN-NEXT:    v_writelane_b32 v43, s49, 14
409; GCN-NEXT:    v_writelane_b32 v43, s30, 15
410; GCN-NEXT:    v_writelane_b32 v43, s31, 16
411; GCN-NEXT:    v_mov_b32_e32 v40, v31
412; GCN-NEXT:    s_mov_b32 s34, s14
413; GCN-NEXT:    s_mov_b32 s35, s13
414; GCN-NEXT:    s_mov_b32 s36, s12
415; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
416; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
417; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
418; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
419; GCN-NEXT:    v_mov_b32_e32 v42, v1
420; GCN-NEXT:    v_mov_b32_e32 v41, v0
421; GCN-NEXT:    s_mov_b64 s[46:47], exec
422; GCN-NEXT:  BB4_1: ; =>This Inner Loop Header: Depth=1
423; GCN-NEXT:    v_readfirstlane_b32 s16, v41
424; GCN-NEXT:    v_readfirstlane_b32 s17, v42
425; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
426; GCN-NEXT:    s_and_saveexec_b64 s[48:49], vcc
427; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
428; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
429; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
430; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
431; GCN-NEXT:    s_mov_b32 s12, s36
432; GCN-NEXT:    s_mov_b32 s13, s35
433; GCN-NEXT:    s_mov_b32 s14, s34
434; GCN-NEXT:    v_mov_b32_e32 v31, v40
435; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
436; GCN-NEXT:    s_xor_b64 exec, exec, s[48:49]
437; GCN-NEXT:    s_cbranch_execnz BB4_1
438; GCN-NEXT:  ; %bb.2:
439; GCN-NEXT:    s_mov_b64 exec, s[46:47]
440; GCN-NEXT:    v_add_i32_e32 v0, vcc, 1, v0
441; GCN-NEXT:    v_readlane_b32 s4, v43, 15
442; GCN-NEXT:    v_readlane_b32 s5, v43, 16
443; GCN-NEXT:    v_readlane_b32 s49, v43, 14
444; GCN-NEXT:    v_readlane_b32 s48, v43, 13
445; GCN-NEXT:    v_readlane_b32 s47, v43, 12
446; GCN-NEXT:    v_readlane_b32 s46, v43, 11
447; GCN-NEXT:    v_readlane_b32 s45, v43, 10
448; GCN-NEXT:    v_readlane_b32 s44, v43, 9
449; GCN-NEXT:    v_readlane_b32 s43, v43, 8
450; GCN-NEXT:    v_readlane_b32 s42, v43, 7
451; GCN-NEXT:    v_readlane_b32 s41, v43, 6
452; GCN-NEXT:    v_readlane_b32 s40, v43, 5
453; GCN-NEXT:    v_readlane_b32 s39, v43, 4
454; GCN-NEXT:    v_readlane_b32 s38, v43, 3
455; GCN-NEXT:    v_readlane_b32 s36, v43, 2
456; GCN-NEXT:    v_readlane_b32 s35, v43, 1
457; GCN-NEXT:    v_readlane_b32 s34, v43, 0
458; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
459; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
460; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
461; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
462; GCN-NEXT:    v_readlane_b32 s33, v43, 17
463; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
464; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
465; GCN-NEXT:    s_mov_b64 exec, s[6:7]
466; GCN-NEXT:    s_waitcnt vmcnt(0)
467; GCN-NEXT:    s_setpc_b64 s[4:5]
468  %a = call i32 %fptr()
469  %b = add i32 %a, 1
470  ret i32 %b
471}
472
473define void @test_indirect_call_vgpr_ptr_in_branch(void()* %fptr, i1 %cond) {
474; GCN-LABEL: test_indirect_call_vgpr_ptr_in_branch:
475; GCN:       ; %bb.0: ; %bb0
476; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
477; GCN-NEXT:    s_or_saveexec_b64 s[16:17], -1
478; GCN-NEXT:    buffer_store_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
479; GCN-NEXT:    s_mov_b64 exec, s[16:17]
480; GCN-NEXT:    v_writelane_b32 v43, s33, 19
481; GCN-NEXT:    s_mov_b32 s33, s32
482; GCN-NEXT:    s_add_u32 s32, s32, 0x800
483; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Spill
484; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
485; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s33 ; 4-byte Folded Spill
486; GCN-NEXT:    v_writelane_b32 v43, s34, 0
487; GCN-NEXT:    v_writelane_b32 v43, s35, 1
488; GCN-NEXT:    v_writelane_b32 v43, s36, 2
489; GCN-NEXT:    v_writelane_b32 v43, s38, 3
490; GCN-NEXT:    v_writelane_b32 v43, s39, 4
491; GCN-NEXT:    v_writelane_b32 v43, s40, 5
492; GCN-NEXT:    v_writelane_b32 v43, s41, 6
493; GCN-NEXT:    v_writelane_b32 v43, s42, 7
494; GCN-NEXT:    v_writelane_b32 v43, s43, 8
495; GCN-NEXT:    v_writelane_b32 v43, s44, 9
496; GCN-NEXT:    v_writelane_b32 v43, s45, 10
497; GCN-NEXT:    v_writelane_b32 v43, s46, 11
498; GCN-NEXT:    v_writelane_b32 v43, s47, 12
499; GCN-NEXT:    v_writelane_b32 v43, s48, 13
500; GCN-NEXT:    v_writelane_b32 v43, s49, 14
501; GCN-NEXT:    v_writelane_b32 v43, s50, 15
502; GCN-NEXT:    v_writelane_b32 v43, s51, 16
503; GCN-NEXT:    v_mov_b32_e32 v40, v31
504; GCN-NEXT:    s_mov_b32 s34, s14
505; GCN-NEXT:    s_mov_b32 s35, s13
506; GCN-NEXT:    s_mov_b32 s36, s12
507; GCN-NEXT:    s_mov_b64 s[38:39], s[10:11]
508; GCN-NEXT:    s_mov_b64 s[40:41], s[8:9]
509; GCN-NEXT:    s_mov_b64 s[42:43], s[6:7]
510; GCN-NEXT:    s_mov_b64 s[44:45], s[4:5]
511; GCN-NEXT:    v_mov_b32_e32 v42, v1
512; GCN-NEXT:    v_mov_b32_e32 v41, v0
513; GCN-NEXT:    v_and_b32_e32 v0, 1, v2
514; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 1, v0
515; GCN-NEXT:    s_and_saveexec_b64 s[46:47], vcc
516; GCN-NEXT:    s_cbranch_execz BB5_4
517; GCN-NEXT:  ; %bb.1: ; %bb1
518; GCN-NEXT:    v_writelane_b32 v43, s30, 17
519; GCN-NEXT:    v_writelane_b32 v43, s31, 18
520; GCN-NEXT:    s_mov_b64 s[48:49], exec
521; GCN-NEXT:  BB5_2: ; =>This Inner Loop Header: Depth=1
522; GCN-NEXT:    v_readfirstlane_b32 s16, v41
523; GCN-NEXT:    v_readfirstlane_b32 s17, v42
524; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[16:17], v[41:42]
525; GCN-NEXT:    s_and_saveexec_b64 s[50:51], vcc
526; GCN-NEXT:    s_mov_b64 s[4:5], s[44:45]
527; GCN-NEXT:    s_mov_b64 s[6:7], s[42:43]
528; GCN-NEXT:    s_mov_b64 s[8:9], s[40:41]
529; GCN-NEXT:    s_mov_b64 s[10:11], s[38:39]
530; GCN-NEXT:    s_mov_b32 s12, s36
531; GCN-NEXT:    s_mov_b32 s13, s35
532; GCN-NEXT:    s_mov_b32 s14, s34
533; GCN-NEXT:    v_mov_b32_e32 v31, v40
534; GCN-NEXT:    s_swappc_b64 s[30:31], s[16:17]
535; GCN-NEXT:    s_xor_b64 exec, exec, s[50:51]
536; GCN-NEXT:    s_cbranch_execnz BB5_2
537; GCN-NEXT:  ; %bb.3:
538; GCN-NEXT:    s_mov_b64 exec, s[48:49]
539; GCN-NEXT:    v_readlane_b32 s30, v43, 17
540; GCN-NEXT:    v_readlane_b32 s31, v43, 18
541; GCN-NEXT:  BB5_4: ; %bb2
542; GCN-NEXT:    s_or_b64 exec, exec, s[46:47]
543; GCN-NEXT:    v_readlane_b32 s51, v43, 16
544; GCN-NEXT:    v_readlane_b32 s50, v43, 15
545; GCN-NEXT:    v_readlane_b32 s49, v43, 14
546; GCN-NEXT:    v_readlane_b32 s48, v43, 13
547; GCN-NEXT:    v_readlane_b32 s47, v43, 12
548; GCN-NEXT:    v_readlane_b32 s46, v43, 11
549; GCN-NEXT:    v_readlane_b32 s45, v43, 10
550; GCN-NEXT:    v_readlane_b32 s44, v43, 9
551; GCN-NEXT:    v_readlane_b32 s43, v43, 8
552; GCN-NEXT:    v_readlane_b32 s42, v43, 7
553; GCN-NEXT:    v_readlane_b32 s41, v43, 6
554; GCN-NEXT:    v_readlane_b32 s40, v43, 5
555; GCN-NEXT:    v_readlane_b32 s39, v43, 4
556; GCN-NEXT:    v_readlane_b32 s38, v43, 3
557; GCN-NEXT:    v_readlane_b32 s36, v43, 2
558; GCN-NEXT:    v_readlane_b32 s35, v43, 1
559; GCN-NEXT:    v_readlane_b32 s34, v43, 0
560; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s33 ; 4-byte Folded Reload
561; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
562; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:8 ; 4-byte Folded Reload
563; GCN-NEXT:    s_sub_u32 s32, s32, 0x800
564; GCN-NEXT:    v_readlane_b32 s33, v43, 19
565; GCN-NEXT:    s_or_saveexec_b64 s[4:5], -1
566; GCN-NEXT:    buffer_load_dword v43, off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
567; GCN-NEXT:    s_mov_b64 exec, s[4:5]
568; GCN-NEXT:    s_waitcnt vmcnt(0)
569; GCN-NEXT:    s_setpc_b64 s[30:31]
570bb0:
571  br i1 %cond, label %bb1, label %bb2
572
573bb1:
574  call void %fptr()
575  br label %bb2
576
577bb2:
578  ret void
579}
580
581define void @test_indirect_call_vgpr_ptr_inreg_arg(void(i32)* %fptr) {
582; GCN-LABEL: test_indirect_call_vgpr_ptr_inreg_arg:
583; GCN:       ; %bb.0:
584; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
585; GCN-NEXT:    s_or_saveexec_b64 s[4:5], -1
586; GCN-NEXT:    buffer_store_dword v42, off, s[0:3], s32 offset:8 ; 4-byte Folded Spill
587; GCN-NEXT:    s_mov_b64 exec, s[4:5]
588; GCN-NEXT:    v_writelane_b32 v42, s33, 6
589; GCN-NEXT:    s_mov_b32 s33, s32
590; GCN-NEXT:    s_add_u32 s32, s32, 0x400
591; GCN-NEXT:    buffer_store_dword v40, off, s[0:3], s33 offset:4 ; 4-byte Folded Spill
592; GCN-NEXT:    buffer_store_dword v41, off, s[0:3], s33 ; 4-byte Folded Spill
593; GCN-NEXT:    v_writelane_b32 v42, s34, 0
594; GCN-NEXT:    v_writelane_b32 v42, s35, 1
595; GCN-NEXT:    v_writelane_b32 v42, s36, 2
596; GCN-NEXT:    v_writelane_b32 v42, s37, 3
597; GCN-NEXT:    v_writelane_b32 v42, s30, 4
598; GCN-NEXT:    v_writelane_b32 v42, s31, 5
599; GCN-NEXT:    v_mov_b32_e32 v41, v1
600; GCN-NEXT:    v_mov_b32_e32 v40, v0
601; GCN-NEXT:    s_mov_b64 s[34:35], exec
602; GCN-NEXT:  BB6_1: ; =>This Inner Loop Header: Depth=1
603; GCN-NEXT:    v_readfirstlane_b32 s6, v40
604; GCN-NEXT:    v_readfirstlane_b32 s7, v41
605; GCN-NEXT:    v_cmp_eq_u64_e32 vcc, s[6:7], v[40:41]
606; GCN-NEXT:    s_and_saveexec_b64 s[36:37], vcc
607; GCN-NEXT:    s_movk_i32 s4, 0x7b
608; GCN-NEXT:    s_swappc_b64 s[30:31], s[6:7]
609; GCN-NEXT:    s_xor_b64 exec, exec, s[36:37]
610; GCN-NEXT:    s_cbranch_execnz BB6_1
611; GCN-NEXT:  ; %bb.2:
612; GCN-NEXT:    s_mov_b64 exec, s[34:35]
613; GCN-NEXT:    v_readlane_b32 s4, v42, 4
614; GCN-NEXT:    v_readlane_b32 s5, v42, 5
615; GCN-NEXT:    v_readlane_b32 s37, v42, 3
616; GCN-NEXT:    v_readlane_b32 s36, v42, 2
617; GCN-NEXT:    v_readlane_b32 s35, v42, 1
618; GCN-NEXT:    v_readlane_b32 s34, v42, 0
619; GCN-NEXT:    buffer_load_dword v41, off, s[0:3], s33 ; 4-byte Folded Reload
620; GCN-NEXT:    buffer_load_dword v40, off, s[0:3], s33 offset:4 ; 4-byte Folded Reload
621; GCN-NEXT:    s_sub_u32 s32, s32, 0x400
622; GCN-NEXT:    v_readlane_b32 s33, v42, 6
623; GCN-NEXT:    s_or_saveexec_b64 s[6:7], -1
624; GCN-NEXT:    buffer_load_dword v42, off, s[0:3], s32 offset:8 ; 4-byte Folded Reload
625; GCN-NEXT:    s_mov_b64 exec, s[6:7]
626; GCN-NEXT:    s_waitcnt vmcnt(0)
627; GCN-NEXT:    s_setpc_b64 s[4:5]
628  call amdgpu_gfx void %fptr(i32 inreg 123)
629  ret void
630}
631