1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -amdgpu-fixed-function-abi -mtriple=amdgcn-amd-amdhsa -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+4
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+4
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
200; FIXME
201; define void @test_indirect_call_vgpr_ptr(void()* %fptr) {
202;   call void %fptr()
203;   ret void
204; }
205
206; define void @test_indirect_call_vgpr_ptr_arg(void(i32)* %fptr) {
207;   call void %fptr(i32 123)
208;   ret void
209; }
210