1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck -enable-var-scope -check-prefix=GCN %s
3
4; Load argument depends on waitcnt which should be skipped.
5define amdgpu_kernel void @call_memory_arg_load(i32 addrspace(3)* %ptr, i32) #0 {
6; GCN-LABEL: call_memory_arg_load:
7; GCN:       ; %bb.0:
8; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17
9; GCN-NEXT: s_mov_b32 s12, s14
10; GCN-NEXT: s_load_dword s14, s[8:9], 0x0
11; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0
12; GCN-NEXT: s_add_u32 s0, s0, s17
13; GCN-NEXT: s_addc_u32 s1, s1, 0
14; GCN-NEXT: s_add_u32 s8, s8, 8
15; GCN-NEXT: s_waitcnt lgkmcnt(0)
16; GCN-NEXT: v_mov_b32_e32 v3, s14
17; GCN-NEXT: ds_read_b32 v3, v3
18; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2
19; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1
20; GCN-NEXT: s_addc_u32 s9, s9, 0
21; GCN-NEXT: v_or3_b32 v31, v0, v1, v2
22; GCN-NEXT: s_mov_b32 s13, s15
23; GCN-NEXT: s_mov_b32 s14, s16
24; GCN-NEXT: s_waitcnt lgkmcnt(0)
25; GCN-NEXT: v_mov_b32_e32 v0, v3
26; GCN-NEXT: s_getpc_b64 s[18:19]
27; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4
28; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12
29; GCN-NEXT: s_mov_b32 s32, 0
30; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19]
31; GCN-NEXT: s_endpgm
32  %vgpr = load volatile i32, i32 addrspace(3)* %ptr
33  call void @func(i32 %vgpr)
34  ret void
35}
36
37; Memory waitcnt with no register dependence on the call
38define amdgpu_kernel void @call_memory_no_dep(i32 addrspace(1)* %ptr, i32) #0 {
39; GCN-LABEL: call_memory_no_dep:
40; GCN:       ; %bb.0:
41; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17
42; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0
43; GCN-NEXT: s_mov_b32 s13, s15
44; GCN-NEXT: s_mov_b32 s12, s14
45; GCN-NEXT: s_load_dwordx2 s[14:15], s[8:9], 0x0
46; GCN-NEXT: s_add_u32 s0, s0, s17
47; GCN-NEXT: s_addc_u32 s1, s1, 0
48; GCN-NEXT: s_add_u32 s8, s8, 16
49; GCN-NEXT: v_mov_b32_e32 v3, 0
50; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2
51; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1
52; GCN-NEXT: s_addc_u32 s9, s9, 0
53; GCN-NEXT: s_waitcnt lgkmcnt(0)
54; GCN-NEXT: global_store_dword v3, v3, s[14:15]
55; GCN-NEXT: v_or3_b32 v31, v0, v1, v2
56; GCN-NEXT: s_mov_b32 s14, s16
57; GCN-NEXT: v_mov_b32_e32 v0, 0
58; GCN-NEXT: s_getpc_b64 s[18:19]
59; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4
60; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12
61; GCN-NEXT: s_mov_b32 s32, 0
62; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19]
63; GCN-NEXT: s_endpgm
64  store i32 0, i32 addrspace(1)* %ptr
65  call void @func(i32 0)
66  ret void
67}
68
69; Should not wait after the call before memory
70define amdgpu_kernel void @call_no_wait_after_call(i32 addrspace(1)* %ptr, i32) #0 {
71; GCN-LABEL: call_no_wait_after_call:
72; GCN:      %bb.0:
73; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17
74; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0
75; GCN-NEXT: s_add_u32 s0, s0, s17
76; GCN-NEXT: s_load_dwordx2 s[34:35], s[8:9], 0x0
77; GCN-NEXT: s_addc_u32 s1, s1, 0
78; GCN-NEXT: s_add_u32 s8, s8, 16
79; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2
80; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1
81; GCN-NEXT: s_addc_u32 s9, s9, 0
82; GCN-NEXT: s_mov_b32 s12, s14
83; GCN-NEXT: v_or3_b32 v31, v0, v1, v2
84; GCN-NEXT: s_mov_b32 s13, s15
85; GCN-NEXT: s_mov_b32 s14, s16
86; GCN-NEXT: v_mov_b32_e32 v0, 0
87; GCN-NEXT: s_getpc_b64 s[18:19]
88; GCN-NEXT: s_add_u32 s18, s18, func@rel32@lo+4
89; GCN-NEXT: s_addc_u32 s19, s19, func@rel32@hi+12
90; GCN-NEXT: s_mov_b32 s32, 0
91; GCN-NEXT: v_mov_b32_e32 v40, 0
92; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19]
93; GCN-NEXT: global_store_dword v40, v40, s[34:35]
94; GCN-NEXT: s_endpgm
95  call void @func(i32 0)
96  store i32 0, i32 addrspace(1)* %ptr
97  ret void
98}
99
100define amdgpu_kernel void @call_no_wait_after_call_return_val(i32 addrspace(1)* %ptr, i32) #0 {
101; GCN-LABEL: call_no_wait_after_call_return_val:
102; GCN:       ; %bb.0:
103; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17
104; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0
105; GCN-NEXT: s_add_u32 s0, s0, s17
106; GCN-NEXT: s_load_dwordx2 s[34:35], s[8:9], 0x0
107; GCN-NEXT: s_addc_u32 s1, s1, 0
108; GCN-NEXT: s_add_u32 s8, s8, 16
109; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2
110; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1
111; GCN-NEXT: s_addc_u32 s9, s9, 0
112; GCN-NEXT: s_mov_b32 s12, s14
113; GCN-NEXT: v_or3_b32 v31, v0, v1, v2
114; GCN-NEXT: s_mov_b32 s13, s15
115; GCN-NEXT: s_mov_b32 s14, s16
116; GCN-NEXT: v_mov_b32_e32 v0, 0
117; GCN-NEXT: s_getpc_b64 s[18:19]
118; GCN-NEXT: s_add_u32 s18, s18, func.return@rel32@lo+4
119; GCN-NEXT: s_addc_u32 s19, s19, func.return@rel32@hi+12
120; GCN-NEXT: s_mov_b32 s32, 0
121; GCN-NEXT: v_mov_b32_e32 v40, 0
122; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19]
123; GCN-NEXT: global_store_dword v40, v0, s[34:35]
124; GCN-NEXT: s_endpgm
125  %rv = call i32 @func.return(i32 0)
126  store i32 %rv, i32 addrspace(1)* %ptr
127  ret void
128}
129
130; Need to wait for the address dependency
131define amdgpu_kernel void @call_got_load(i32 addrspace(1)* %ptr, i32) #0 {
132; GCN-LABEL: call_got_load:
133; GCN:       ; %bb.0:
134; GCN-NEXT: s_add_u32 flat_scratch_lo, s12, s17
135; GCN-NEXT: s_addc_u32 flat_scratch_hi, s13, 0
136; GCN-NEXT: s_add_u32 s0, s0, s17
137; GCN-NEXT: s_addc_u32 s1, s1, 0
138; GCN-NEXT: s_add_u32 s8, s8, 16
139; GCN-NEXT: s_addc_u32 s9, s9, 0
140; GCN-NEXT: s_mov_b32 s13, s15
141; GCN-NEXT: s_mov_b32 s12, s14
142; GCN-NEXT: s_getpc_b64 s[14:15]
143; GCN-NEXT: s_add_u32 s14, s14, got.func@gotpcrel32@lo+4
144; GCN-NEXT: s_addc_u32 s15, s15, got.func@gotpcrel32@hi+12
145; GCN-NEXT: s_load_dwordx2 s[18:19], s[14:15], 0x0
146; GCN-NEXT: v_lshlrev_b32_e32 v2, 20, v2
147; GCN-NEXT: v_lshlrev_b32_e32 v1, 10, v1
148; GCN-NEXT: v_or3_b32 v31, v0, v1, v2
149; GCN-NEXT: s_mov_b32 s14, s16
150; GCN-NEXT: v_mov_b32_e32 v0, 0
151; GCN-NEXT: s_mov_b32 s32, 0
152; GCN-NEXT: s_waitcnt lgkmcnt(0)
153; GCN-NEXT: s_swappc_b64 s[30:31], s[18:19]
154; GCN-NEXT: s_endpgm
155  call void @got.func(i32 0)
156  ret void
157}
158
159; Need to wait for the address dependency
160define void @tailcall_got_load(i32 addrspace(1)* %ptr, i32) #0 {
161; GCN-LABEL: tailcall_got_load:
162; GCN:       ; %bb.0:
163; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
164; GCN-NEXT: s_getpc_b64 s[16:17]
165; GCN-NEXT: s_add_u32 s16, s16, got.func@gotpcrel32@lo+4
166; GCN-NEXT: s_addc_u32 s17, s17, got.func@gotpcrel32@hi+12
167; GCN-NEXT: s_load_dwordx2 s[16:17], s[16:17], 0x0
168; GCN-NEXT: v_mov_b32_e32 v0, 0
169; GCN-NEXT: s_waitcnt lgkmcnt(0)
170; GCN-NEXT: s_setpc_b64 s[16:17]
171  tail call void @got.func(i32 0)
172  ret void
173}
174
175; No need to wait for the load.
176define void @tail_call_memory_arg_load(i32 addrspace(3)* %ptr, i32) #0 {
177; GCN-LABEL: tail_call_memory_arg_load:
178; GCN:       ; %bb.0:
179; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
180; GCN-NEXT: ds_read_b32 v0, v0
181; GCN-NEXT: s_getpc_b64 s[16:17]
182; GCN-NEXT: s_add_u32 s16, s16, func@rel32@lo+4
183; GCN-NEXT: s_addc_u32 s17, s17, func@rel32@hi+12
184; GCN-NEXT: s_setpc_b64 s[16:17]
185  %vgpr = load volatile i32, i32 addrspace(3)* %ptr
186  tail call void @func(i32 %vgpr)
187  ret void
188}
189
190declare hidden void @func(i32) #0
191declare hidden i32 @func.return(i32) #0
192declare void @got.func(i32) #0
193
194attributes #0 = { nounwind }
195