1; RUN: llc -march=amdgcn -mcpu=hawaii -verify-machineinstrs < %s | FileCheck  -enable-var-scope -check-prefixes=GCN,MUBUF %s
2; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck  -enable-var-scope -check-prefixes=GCN,MUBUF %s
3; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs -amdgpu-enable-flat-scratch < %s | FileCheck  -enable-var-scope -check-prefixes=GCN,FLATSCR %s
4
5; GCN-LABEL: {{^}}callee_no_stack:
6; GCN: ; %bb.0:
7; GCN-NEXT: s_waitcnt
8; GCN-NEXT: s_setpc_b64
9define void @callee_no_stack() #0 {
10  ret void
11}
12
13; GCN-LABEL: {{^}}callee_no_stack_no_fp_elim_all:
14; GCN: ; %bb.0:
15; GCN-NEXT: s_waitcnt
16; MUBUF-NEXT:   s_mov_b32 [[FP_COPY:s4]], s33
17; FLATSCR-NEXT: s_mov_b32 [[FP_COPY:s0]], s33
18; GCN-NEXT: s_mov_b32 s33, s32
19; GCN-NEXT: s_mov_b32 s33, [[FP_COPY]]
20; GCN-NEXT: s_setpc_b64
21define void @callee_no_stack_no_fp_elim_all() #1 {
22  ret void
23}
24
25; GCN-LABEL: {{^}}callee_no_stack_no_fp_elim_nonleaf:
26; GCN: ; %bb.0:
27; GCN-NEXT: s_waitcnt
28; GCN-NEXT: s_setpc_b64
29define void @callee_no_stack_no_fp_elim_nonleaf() #2 {
30  ret void
31}
32
33; GCN-LABEL: {{^}}callee_with_stack:
34; GCN: ; %bb.0:
35; GCN-NEXT: s_waitcnt
36; GCN-NEXT: v_mov_b32_e32 v0, 0{{$}}
37; MUBUF-NEXT:   buffer_store_dword v0, off, s[0:3], s32{{$}}
38; FLATSCR-NEXT: scratch_store_dword off, v0, s32
39; GCN-NEXT: s_waitcnt
40; GCN-NEXT: s_setpc_b64
41define void @callee_with_stack() #0 {
42  %alloca = alloca i32, addrspace(5)
43  store volatile i32 0, i32 addrspace(5)* %alloca
44  ret void
45}
46
47; Can use free call clobbered register to preserve original FP value.
48
49; GCN-LABEL: {{^}}callee_with_stack_no_fp_elim_all:
50; GCN: ; %bb.0:
51; GCN-NEXT: s_waitcnt
52; MUBUF-NEXT:   s_mov_b32 [[FP_COPY:s4]], s33
53; FLATSCR-NEXT: s_mov_b32 [[FP_COPY:s0]], s33
54; GCN-NEXT: s_mov_b32 s33, s32
55; MUBUF-NEXT:   s_addk_i32 s32, 0x200
56; FLATSCR-NEXT: s_add_i32 s32, s32, 8
57; GCN-NEXT: v_mov_b32_e32 v0, 0{{$}}
58; MUBUF-NEXT:   buffer_store_dword v0, off, s[0:3], s33 offset:4{{$}}
59; FLATSCR-NEXT: scratch_store_dword off, v0, s33 offset:4{{$}}
60; GCN-NEXT: s_waitcnt vmcnt(0)
61; MUBUF-NEXT:   s_addk_i32 s32, 0xfe00
62; FLATSCR-NEXT: s_add_i32 s32, s32, -8
63; GCN-NEXT: s_mov_b32 s33, [[FP_COPY]]
64; GCN-NEXT: s_setpc_b64
65define void @callee_with_stack_no_fp_elim_all() #1 {
66  %alloca = alloca i32, addrspace(5)
67  store volatile i32 0, i32 addrspace(5)* %alloca
68  ret void
69}
70
71; GCN-LABEL: {{^}}callee_with_stack_no_fp_elim_non_leaf:
72; GCN: ; %bb.0:
73; GCN-NEXT: s_waitcnt
74; GCN-NEXT: v_mov_b32_e32 v0, 0{{$}}
75; MUBUF-NEXT:   buffer_store_dword v0, off, s[0:3], s32{{$}}
76; FLATSCR-NEXT: scratch_store_dword off, v0, s32{{$}}
77; GCN-NEXT: s_waitcnt
78; GCN-NEXT: s_setpc_b64
79define void @callee_with_stack_no_fp_elim_non_leaf() #2 {
80  %alloca = alloca i32, addrspace(5)
81  store volatile i32 0, i32 addrspace(5)* %alloca
82  ret void
83}
84
85; GCN-LABEL: {{^}}callee_with_stack_and_call:
86; GCN: ; %bb.0:
87; GCN-NEXT: s_waitcnt
88; GCN: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
89; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 offset:4 ; 4-byte Folded Spill
90; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 offset:4 ; 4-byte Folded Spill
91; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
92; GCN: v_writelane_b32 [[CSR_VGPR]], s33, 2
93; GCN-DAG: s_mov_b32 s33, s32
94; MUBUF-DAG:   s_addk_i32 s32, 0x400{{$}}
95; FLATSCR-DAG: s_add_i32 s32, s32, 16{{$}}
96; GCN-DAG: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
97; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s30,
98; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s31,
99
100; MUBUF-DAG:   buffer_store_dword [[ZERO]], off, s[0:3], s33{{$}}
101; FLATSCR-DAG: scratch_store_dword off, [[ZERO]], s33{{$}}
102
103; GCN: s_swappc_b64
104
105; MUBUF-DAG: v_readlane_b32 s5, [[CSR_VGPR]]
106; MUBUF-DAG: v_readlane_b32 s4, [[CSR_VGPR]]
107; FLATSCR-DAG: v_readlane_b32 s0, [[CSR_VGPR]]
108; FLATSCR-DAG: v_readlane_b32 s1, [[CSR_VGPR]]
109
110; MUBUF:    s_addk_i32 s32, 0xfc00{{$}}
111; FLATSCR:  s_add_i32 s32, s32, -16{{$}}
112; GCN-NEXT: v_readlane_b32 s33, [[CSR_VGPR]], 2
113; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
114; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 offset:4 ; 4-byte Folded Reload
115; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 offset:4 ; 4-byte Folded Reload
116; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
117; GCN-NEXT: s_waitcnt vmcnt(0)
118
119; GCN-NEXT: s_setpc_b64
120define void @callee_with_stack_and_call() #0 {
121  %alloca = alloca i32, addrspace(5)
122  store volatile i32 0, i32 addrspace(5)* %alloca
123  call void @external_void_func_void()
124  ret void
125}
126
127; Should be able to copy incoming stack pointer directly to inner
128; call's stack pointer argument.
129
130; There is stack usage only because of the need to evict a VGPR for
131; spilling CSR SGPRs.
132
133; GCN-LABEL: {{^}}callee_no_stack_with_call:
134; GCN: s_waitcnt
135; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
136; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 ; 4-byte Folded Spill
137; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 ; 4-byte Folded Spill
138; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
139; MUBUF-DAG:   s_addk_i32 s32, 0x400
140; FLATSCR-DAG: s_add_i32 s32, s32, 16
141; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s33, [[FP_SPILL_LANE:[0-9]+]]
142
143; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s30, 0
144; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s31, 1
145; GCN: s_swappc_b64
146
147; MUBUF-DAG: v_readlane_b32 s4, v40, 0
148; MUBUF-DAG: v_readlane_b32 s5, v40, 1
149; FLATSCR-DAG: v_readlane_b32 s0, v40, 0
150; FLATSCR-DAG: v_readlane_b32 s1, v40, 1
151
152; MUBUF:   s_addk_i32 s32, 0xfc00
153; FLATSCR: s_add_i32 s32, s32, -16
154; GCN-NEXT: v_readlane_b32 s33, [[CSR_VGPR]], [[FP_SPILL_LANE]]
155; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
156; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 ; 4-byte Folded Reload
157; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 ; 4-byte Folded Reload
158; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
159; GCN-NEXT: s_waitcnt vmcnt(0)
160; GCN-NEXT: s_setpc_b64
161define void @callee_no_stack_with_call() #0 {
162  call void @external_void_func_void()
163  ret void
164}
165
166declare hidden void @external_void_func_void() #0
167
168; Make sure if a CSR vgpr is used for SGPR spilling, it is saved and
169; restored. No FP is required.
170;
171; GCN-LABEL: {{^}}callee_func_sgpr_spill_no_calls:
172; GCN: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
173; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 ; 4-byte Folded Spill
174; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 ; 4-byte Folded Spill
175; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
176; GCN: v_writelane_b32 [[CSR_VGPR]], s
177; GCN: v_writelane_b32 [[CSR_VGPR]], s
178
179; GCN: ;;#ASMSTART
180; GCN: v_readlane_b32 s{{[0-9]+}}, [[CSR_VGPR]]
181; GCN: v_readlane_b32 s{{[0-9]+}}, [[CSR_VGPR]]
182
183; GCN: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
184; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 ; 4-byte Folded Reload
185; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 ; 4-byte Folded Reload
186; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
187; GCN-NEXT: s_waitcnt
188; GCN-NEXT: s_setpc_b64
189define void @callee_func_sgpr_spill_no_calls(i32 %in) #0 {
190  call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7}"() #0
191  call void asm sideeffect "", "~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15}"() #0
192  call void asm sideeffect "", "~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23}"() #0
193  call void asm sideeffect "", "~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() #0
194  call void asm sideeffect "", "~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"() #0
195
196  %wide.sgpr0 = call <16 x i32> asm sideeffect "; def $0", "=s" () #0
197  %wide.sgpr1 = call <16 x i32> asm sideeffect "; def $0", "=s" () #0
198  %wide.sgpr2 = call <16 x i32> asm sideeffect "; def $0", "=s" () #0
199  %wide.sgpr5 = call <16 x i32> asm sideeffect "; def $0", "=s" () #0
200  %wide.sgpr3 = call <8 x i32> asm sideeffect "; def $0", "=s" () #0
201  %wide.sgpr4 = call <2 x i32> asm sideeffect "; def $0", "=s" () #0
202
203  call void asm sideeffect "; use $0", "s"(<16 x i32> %wide.sgpr0) #0
204  call void asm sideeffect "; use $0", "s"(<16 x i32> %wide.sgpr1) #0
205  call void asm sideeffect "; use $0", "s"(<16 x i32> %wide.sgpr2) #0
206  call void asm sideeffect "; use $0", "s"(<8 x i32> %wide.sgpr3) #0
207  call void asm sideeffect "; use $0", "s"(<2 x i32> %wide.sgpr4) #0
208  call void asm sideeffect "; use $0", "s"(<16 x i32> %wide.sgpr5) #0
209  ret void
210}
211
212; Has no spilled CSR VGPRs used for SGPR spilling, so no need to
213; enable all lanes and restore.
214
215; GCN-LABEL: {{^}}spill_only_csr_sgpr:
216; GCN: s_waitcnt
217; GCN-NEXT: s_or_saveexec_b64
218; MUBUF-NEXT: buffer_store_dword v0, off, s[0:3], s32 ; 4-byte Folded Spill
219; FLATSCR-NEXT: scratch_store_dword off, v0, s32 ; 4-byte Folded Spill
220; GCN-NEXT: s_mov_b64 exec,
221; GCN-NEXT: v_writelane_b32 v0, s42, 0
222; GCN-NEXT: ;;#ASMSTART
223; GCN-NEXT: ; clobber s42
224; GCN-NEXT: ;;#ASMEND
225; GCN-NEXT: v_readlane_b32 s42, v0, 0
226; GCN-NEXT: s_or_saveexec_b64
227; MUBUF-NEXT: buffer_load_dword v0, off, s[0:3], s32 ; 4-byte Folded Reload
228; FLATSCR-NEXT: scratch_load_dword v0, off, s32 ; 4-byte Folded Reload
229; GCN-NEXT: s_mov_b64 exec,
230; GCN-NEXT: s_waitcnt vmcnt(0)
231; GCN-NEXT: s_setpc_b64
232define void @spill_only_csr_sgpr() {
233  call void asm sideeffect "; clobber s42", "~{s42}"()
234  ret void
235}
236
237; TODO: Can the SP inc/deec be remvoed?
238; GCN-LABEL: {{^}}callee_with_stack_no_fp_elim_csr_vgpr:
239; GCN: s_waitcnt
240; GCN-NEXT:s_mov_b32 [[FP_COPY:s[0-9]+]], s33
241; GCN-NEXT: s_mov_b32 s33, s32
242; GCN: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0
243; MUBUF-DAG:   buffer_store_dword v41, off, s[0:3], s33 ; 4-byte Folded Spill
244; FLATSCR-DAG: scratch_store_dword off, v41, s33 ; 4-byte Folded Spill
245; MUBUF-DAG:   buffer_store_dword [[ZERO]], off, s[0:3], s33 offset:8
246; FLATSCR-DAG: scratch_store_dword off, [[ZERO]], s33 offset:8
247
248; GCN:	;;#ASMSTART
249; GCN-NEXT: ; clobber v41
250; GCN-NEXT: ;;#ASMEND
251
252; MUBUF:   buffer_load_dword v41, off, s[0:3], s33 ; 4-byte Folded Reload
253; FLATSCR: scratch_load_dword v41, off, s33 ; 4-byte Folded Reload
254; MUBUF:        s_addk_i32 s32, 0x300
255; MUBUF-NEXT:   s_addk_i32 s32, 0xfd00
256; MUBUF-NEXT:   s_mov_b32 s33, s4
257; FLATSCR:      s_add_i32 s32, s32, 12
258; FLATSCR-NEXT: s_add_i32 s32, s32, -12
259; FLATSCR-NEXT: s_mov_b32 s33, s0
260; GCN-NEXT: s_waitcnt vmcnt(0)
261; GCN-NEXT: s_setpc_b64
262define void @callee_with_stack_no_fp_elim_csr_vgpr() #1 {
263  %alloca = alloca i32, addrspace(5)
264  store volatile i32 0, i32 addrspace(5)* %alloca
265  call void asm sideeffect "; clobber v41", "~{v41}"()
266  ret void
267}
268
269; Use a copy to a free SGPR instead of introducing a second CSR VGPR.
270; GCN-LABEL: {{^}}last_lane_vgpr_for_fp_csr:
271; GCN: s_waitcnt
272; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
273; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
274; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 offset:12 ; 4-byte Folded Spill
275; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
276; GCN-NEXT: v_writelane_b32 v0, s33, 63
277; GCN-COUNT-60: v_writelane_b32 v0
278; GCN: s_mov_b32 s33, s32
279; GCN: v_writelane_b32 v0
280; MUBUF:   buffer_store_dword v41, off, s[0:3], s33 ; 4-byte Folded Spill
281; FLATSCR: scratch_store_dword off, v41, s33 ; 4-byte Folded Spill
282; GCN: v_writelane_b32 v0
283; MUBUF:   buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33 offset:8
284; FLATSCR: scratch_store_dword off, v{{[0-9]+}}, s33 offset:8
285; GCN: ;;#ASMSTART
286; GCN: v_writelane_b32 v0
287
288; MUBUF:        s_addk_i32 s32, 0x400
289; MUBUF:        s_addk_i32 s32, 0xfc00
290; FLATSCR:      s_add_i32 s32, s32, 16
291; FLATSCR:      s_add_i32 s32, s32, -16
292; GCN-NEXT: v_readlane_b32 s33, v0, 63
293; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
294; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
295; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 offset:12 ; 4-byte Folded Reload
296; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
297; GCN-NEXT: s_waitcnt vmcnt(0)
298; GCN-NEXT: s_setpc_b64
299define void @last_lane_vgpr_for_fp_csr() #1 {
300  %alloca = alloca i32, addrspace(5)
301  store volatile i32 0, i32 addrspace(5)* %alloca
302  call void asm sideeffect "; clobber v41", "~{v41}"()
303  call void asm sideeffect "",
304    "~{s40},~{s41},~{s42},~{s43},~{s44},~{s45},~{s46},~{s47},~{s48},~{s49}
305    ,~{s50},~{s51},~{s52},~{s53},~{s54},~{s55},~{s56},~{s57},~{s58},~{s59}
306    ,~{s60},~{s61},~{s62},~{s63},~{s64},~{s65},~{s66},~{s67},~{s68},~{s69}
307    ,~{s70},~{s71},~{s72},~{s73},~{s74},~{s75},~{s76},~{s77},~{s78},~{s79}
308    ,~{s80},~{s81},~{s82},~{s83},~{s84},~{s85},~{s86},~{s87},~{s88},~{s89}
309    ,~{s90},~{s91},~{s92},~{s93},~{s94},~{s95},~{s96},~{s97},~{s98},~{s99}
310    ,~{s100},~{s101},~{s102}"() #1
311
312  ret void
313}
314
315; Use a copy to a free SGPR instead of introducing a second CSR VGPR.
316; GCN-LABEL: {{^}}no_new_vgpr_for_fp_csr:
317; GCN: s_waitcnt
318; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
319; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 offset:12 ; 4-byte Folded Spill
320; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 offset:12 ; 4-byte Folded Spill
321; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
322; GCN-COUNT-61: v_writelane_b32 v0,
323; FLATSCR: s_mov_b32 [[FP_COPY:s[0-9]+]], s33
324; FLATSCR-NEXT: s_mov_b32 s33, s32
325; MUBUF: s_mov_b32 [[FP_COPY:s[0-9]+]], s33
326; MUBUF-NEXT: s_mov_b32 s33, s32
327; MUBUF:   buffer_store_dword v41, off, s[0:3], s33 ; 4-byte Folded Spill
328; FLATSCR: scratch_store_dword off, v41, s33 ; 4-byte Folded Spill
329; GCN: v_writelane_b32 v0,
330; MUBUF:   buffer_store_dword
331; FLATSCR: scratch_store_dword
332; GCN: ;;#ASMSTART
333; GCN: v_writelane_b32 v0,
334; MUBUF:   buffer_load_dword v41, off, s[0:3], s33 ; 4-byte Folded Reload
335; FLATSCR: scratch_load_dword v41, off, s33 ; 4-byte Folded Reload
336; MUBUF:        s_addk_i32 s32, 0x400
337; FLATSCR:      s_add_i32 s32, s32, 16
338; GCN-COUNT-64: v_readlane_b32 s{{[0-9]+}}, v0
339; MUBUF-NEXT:   s_addk_i32 s32, 0xfc00
340; FLATSCR-NEXT: s_add_i32 s32, s32, -16
341; GCN-NEXT: s_mov_b32 s33, [[FP_COPY]]
342; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
343; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 offset:12 ; 4-byte Folded Reload
344; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 offset:12 ; 4-byte Folded Reload
345; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
346; GCN-NEXT: s_waitcnt vmcnt(0)
347; GCN-NEXT: s_setpc_b64
348define void @no_new_vgpr_for_fp_csr() #1 {
349  %alloca = alloca i32, addrspace(5)
350  store volatile i32 0, i32 addrspace(5)* %alloca
351  call void asm sideeffect "; clobber v41", "~{v41}"()
352  call void asm sideeffect "",
353    "~{s39},~{s40},~{s41},~{s42},~{s43},~{s44},~{s45},~{s46},~{s47},~{s48},~{s49}
354    ,~{s50},~{s51},~{s52},~{s53},~{s54},~{s55},~{s56},~{s57},~{s58},~{s59}
355    ,~{s60},~{s61},~{s62},~{s63},~{s64},~{s65},~{s66},~{s67},~{s68},~{s69}
356    ,~{s70},~{s71},~{s72},~{s73},~{s74},~{s75},~{s76},~{s77},~{s78},~{s79}
357    ,~{s80},~{s81},~{s82},~{s83},~{s84},~{s85},~{s86},~{s87},~{s88},~{s89}
358    ,~{s90},~{s91},~{s92},~{s93},~{s94},~{s95},~{s96},~{s97},~{s98},~{s99}
359    ,~{s100},~{s101},~{s102}"() #1
360
361  ret void
362}
363
364; GCN-LABEL: {{^}}realign_stack_no_fp_elim:
365; GCN: s_waitcnt
366; MUBUF-NEXT:   s_mov_b32 [[FP_COPY:s4]], s33
367; FLATSCR-NEXT: s_mov_b32 [[FP_COPY:s0]], s33
368; MUBUF-NEXT:   s_add_i32 s33, s32, 0x7ffc0
369; FLATSCR-NEXT: s_add_i32 s33, s32, 0x1fff
370; MUBUF-NEXT:   s_and_b32 s33, s33, 0xfff80000
371; FLATSCR-NEXT: s_and_b32 s33, s33, 0xffffe000
372; MUBUF-NEXT:   s_add_i32 s32, s32, 0x100000
373; FLATSCR-NEXT: s_addk_i32 s32, 0x4000
374; GCN-NEXT:     v_mov_b32_e32 [[ZERO:v[0-9]+]], 0
375; MUBUF-NEXT:   buffer_store_dword [[ZERO]], off, s[0:3], s33
376; FLATSCR-NEXT: scratch_store_dword off, [[ZERO]], s33
377; GCN-NEXT: s_waitcnt vmcnt(0)
378; MUBUF-NEXT:   s_add_i32 s32, s32, 0xfff00000
379; FLATSCR-NEXT: s_addk_i32 s32, 0xc000
380; GCN-NEXT: s_mov_b32 s33, [[FP_COPY]]
381; GCN-NEXT: s_setpc_b64
382define void @realign_stack_no_fp_elim() #1 {
383  %alloca = alloca i32, align 8192, addrspace(5)
384  store volatile i32 0, i32 addrspace(5)* %alloca
385  ret void
386}
387
388; GCN-LABEL: {{^}}no_unused_non_csr_sgpr_for_fp:
389; GCN: s_waitcnt
390; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
391; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 offset:8 ; 4-byte Folded Spill
392; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 offset:8 ; 4-byte Folded Spill
393; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
394; GCN-NEXT: v_writelane_b32 v0, s33, 2
395; GCN-NEXT: s_mov_b32 s33, s32
396; GCN-NEXT: v_writelane_b32 v0, s30, 0
397; GCN: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0
398; GCN: v_writelane_b32 v0, s31, 1
399; MUBUF:   buffer_store_dword [[ZERO]], off, s[0:3], s33 offset:4
400; FLATSCR: scratch_store_dword off, [[ZERO]], s33 offset:4
401; GCN-NEXT:     s_waitcnt vmcnt(0)
402; GCN: ;;#ASMSTART
403; MUBUF:        s_addk_i32 s32, 0x300
404; MUBUF-NEXT:   v_readlane_b32 s4, v0, 0
405; MUBUF-NEXT:   v_readlane_b32 s5, v0, 1
406; FLATSCR:      s_add_i32 s32, s32, 12
407; FLATSCR-NEXT: v_readlane_b32 s0, v0, 0
408; FLATSCR-NEXT: v_readlane_b32 s1, v0, 1
409; MUBUF-NEXT:   s_addk_i32 s32, 0xfd00
410; FLATSCR-NEXT: s_add_i32 s32, s32, -12
411; GCN-NEXT:     v_readlane_b32 s33, v0, 2
412; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
413; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 offset:8 ; 4-byte Folded Reload
414; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 offset:8 ; 4-byte Folded Reload
415; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
416; GCN-NEXT: s_waitcnt vmcnt(0)
417; MUBUF-NEXT:   s_setpc_b64 s[4:5]
418; FLATSCR-NEXT: s_setpc_b64 s[0:1]
419define void @no_unused_non_csr_sgpr_for_fp() #1 {
420  %alloca = alloca i32, addrspace(5)
421  store volatile i32 0, i32 addrspace(5)* %alloca
422
423  ; Use all clobberable registers, so FP has to spill to a VGPR.
424  call void asm sideeffect "",
425    "~{s0},~{s1},~{s2},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
426    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
427    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
428    ,~{s30},~{s31}"() #0
429
430  ret void
431}
432
433; Need a new CSR VGPR to satisfy the FP spill.
434; GCN-LABEL: {{^}}no_unused_non_csr_sgpr_for_fp_no_scratch_vgpr:
435; GCN: s_waitcnt
436; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
437; MUBUF-NEXT:   buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], s32 offset:8 ; 4-byte Folded Spill
438; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], s32 offset:8 ; 4-byte Folded Spill
439; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
440; GCN-NEXT: v_writelane_b32 [[CSR_VGPR]], s33, 2
441; GCN-NEXT: s_mov_b32 s33, s32
442; GCN-NEXT: v_writelane_b32 [[CSR_VGPR]], s30, 0
443
444; GCN-DAG: v_writelane_b32 [[CSR_VGPR]], s31, 1
445; MUBUF-DAG:   buffer_store_dword
446; FLATSCR-DAG: scratch_store_dword
447; MUBUF:       s_addk_i32 s32, 0x300{{$}}
448; FLATSCR:     s_add_i32 s32, s32, 12{{$}}
449
450; MUBUF:        v_readlane_b32 s4, [[CSR_VGPR]], 0
451; FLATSCR:      v_readlane_b32 s0, [[CSR_VGPR]], 0
452; GCN: ;;#ASMSTART
453; MUBUF:        v_readlane_b32 s5, [[CSR_VGPR]], 1
454; FLATSCR:      v_readlane_b32 s1, [[CSR_VGPR]], 1
455; MUBUF-NEXT:   s_addk_i32 s32, 0xfd00{{$}}
456; FLATSCR-NEXT: s_add_i32 s32, s32, -12{{$}}
457; GCN-NEXT: v_readlane_b32 s33, [[CSR_VGPR]], 2
458; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
459; MUBUF-NEXT:   buffer_load_dword [[CSR_VGPR]], off, s[0:3], s32 offset:8 ; 4-byte Folded Reload
460; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, s32 offset:8 ; 4-byte Folded Reload
461; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
462; GCN-NEXT: s_waitcnt vmcnt(0)
463; GCN-NEXT: s_setpc_b64
464define void @no_unused_non_csr_sgpr_for_fp_no_scratch_vgpr() #1 {
465  %alloca = alloca i32, addrspace(5)
466  store volatile i32 0, i32 addrspace(5)* %alloca
467
468  ; Use all clobberable registers, so FP has to spill to a VGPR.
469  call void asm sideeffect "",
470    "~{s0},~{s1},~{s2},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
471    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
472    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
473    ,~{s30},~{s31}"() #0
474
475  call void asm sideeffect "; clobber nonpreserved initial VGPRs",
476    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
477    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
478    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
479    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"() #1
480
481  ret void
482}
483
484; The byval argument exceeds the MUBUF constant offset, so a scratch
485; register is needed to access the CSR VGPR slot.
486; GCN-LABEL: {{^}}scratch_reg_needed_mubuf_offset:
487; GCN: s_waitcnt
488; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC0:s\[[0-9]+:[0-9]+\]]], -1{{$}}
489; MUBUF-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x40200
490; MUBUF-NEXT: buffer_store_dword [[CSR_VGPR:v[0-9]+]], off, s[0:3], [[SCRATCH_SGPR]] ; 4-byte Folded Spill
491; FLATSCR-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x1008
492; FLATSCR-NEXT: scratch_store_dword off, [[CSR_VGPR:v[0-9]+]], [[SCRATCH_SGPR]] ; 4-byte Folded Spill
493; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC0]]
494; GCN-NEXT: v_writelane_b32 [[CSR_VGPR]], s33, 2
495; GCN-DAG:  v_writelane_b32 [[CSR_VGPR]], s30, 0
496; GCN-DAG:  s_mov_b32 s33, s32
497; GCN-DAG:  v_writelane_b32 [[CSR_VGPR]], s31, 1
498; MUBUF-DAG:   s_add_i32 s32, s32, 0x40300{{$}}
499; FLATSCR-DAG: s_addk_i32 s32, 0x100c{{$}}
500; MUBUF-DAG:   buffer_store_dword
501; FLATSCR-DAG: scratch_store_dword
502
503; MUBUF:   v_readlane_b32 s4, [[CSR_VGPR]], 0
504; FLATSCR: v_readlane_b32 s0, [[CSR_VGPR]], 0
505; GCN: ;;#ASMSTART
506; MUBUF:   v_readlane_b32 s5, [[CSR_VGPR]], 1
507; FLATSCR: v_readlane_b32 s1, [[CSR_VGPR]], 1
508; MUBUF-NEXT:   s_add_i32 s32, s32, 0xfffbfd00{{$}}
509; FLATSCR-NEXT: s_addk_i32 s32, 0xeff4{{$}}
510; GCN-NEXT: v_readlane_b32 s33, [[CSR_VGPR]], 2
511; GCN-NEXT: s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
512; MUBUF-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x40200
513; MUBUF-NEXT: buffer_load_dword [[CSR_VGPR]], off, s[0:3], [[SCRATCH_SGPR]] ; 4-byte Folded Reload
514; FLATSCR-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x1008
515; FLATSCR-NEXT: scratch_load_dword [[CSR_VGPR]], off, [[SCRATCH_SGPR]] ; 4-byte Folded Reload
516; GCN-NEXT: s_mov_b64 exec, [[COPY_EXEC1]]
517; GCN-NEXT: s_waitcnt vmcnt(0)
518; GCN-NEXT: s_setpc_b64
519define void @scratch_reg_needed_mubuf_offset([4096 x i8] addrspace(5)* byval([4096 x i8]) align 4 %arg) #1 {
520  %alloca = alloca i32, addrspace(5)
521  store volatile i32 0, i32 addrspace(5)* %alloca
522
523  ; Use all clobberable registers, so FP has to spill to a VGPR.
524  call void asm sideeffect "; clobber nonpreserved SGPRs",
525    "~{s0},~{s1},~{s2},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
526    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
527    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
528    ,~{s30},~{s31}"() #0
529
530  ; Use all clobberable VGPRs, so a CSR spill is needed for the VGPR
531  call void asm sideeffect "; clobber nonpreserved VGPRs",
532    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
533    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
534    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
535    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"() #1
536
537  ret void
538}
539
540; GCN-LABEL: {{^}}local_empty_func:
541; GCN: s_waitcnt
542; GCN-NEXT: s_setpc_b64
543define internal void @local_empty_func() #0 {
544  ret void
545}
546
547; An FP is needed, despite not needing any spills
548; TODO: Ccould see callee does not use stack and omit FP.
549; GCN-LABEL: {{^}}ipra_call_with_stack:
550; GCN: s_mov_b32 [[FP_COPY:s[0-9]+]], s33
551; GCN: s_mov_b32 s33, s32
552; MUBUF:   s_addk_i32 s32, 0x400
553; FLATSCR: s_add_i32 s32, s32, 16
554; MUBUF:   buffer_store_dword v{{[0-9]+}}, off, s[0:3], s33{{$}}
555; FLATSCR: scratch_store_dword off, v{{[0-9]+}}, s33{{$}}
556; GCN:     s_swappc_b64
557; MUBUF:   s_addk_i32 s32, 0xfc00
558; FLATSCR: s_add_i32 s32, s32, -16
559; GCN: s_mov_b32 s33, [[FP_COPY:s[0-9]+]]
560define void @ipra_call_with_stack() #0 {
561  %alloca = alloca i32, addrspace(5)
562  store volatile i32 0, i32 addrspace(5)* %alloca
563  call void @local_empty_func()
564  ret void
565}
566
567; With no free registers, we must spill the FP to memory.
568; GCN-LABEL: {{^}}callee_need_to_spill_fp_to_memory:
569; MUBUF:   v_mov_b32_e32 [[TMP_VGPR1:v[0-9]+]], s33
570; MUBUF:   buffer_store_dword [[TMP_VGPR1]], off, s[0:3], s32 offset:4
571; FLATSCR: s_mov_b32 s0, s33
572; GCN:     s_mov_b32 s33, s32
573; MUBUF:   buffer_load_dword [[TMP_VGPR2:v[0-9]+]], off, s[0:3], s32 offset:4
574; FLATSCR: s_mov_b32 s33, s0
575; MUBUF:   s_waitcnt vmcnt(0)
576; MUBUF:   v_readfirstlane_b32 s33, [[TMP_VGPR2]]
577; GCN:     s_setpc_b64
578; MUBUF:   ScratchSize: 8
579; FLATSCR: ScratchSize: 0
580define void @callee_need_to_spill_fp_to_memory() #3 {
581  call void asm sideeffect "; clobber nonpreserved SGPRs",
582    "~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
583    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
584    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
585    ,~{vcc}"()
586
587  call void asm sideeffect "; clobber all VGPRs",
588    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
589    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
590    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
591    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"()
592  ret void
593}
594
595; If we have a reserved VGPR that can be used for SGPR spills, we may still
596; need to spill the FP to memory if there are no free lanes in the reserved
597; VGPR.
598; GCN-LABEL: {{^}}callee_need_to_spill_fp_to_memory_full_reserved_vgpr:
599; MUBUF:   s_or_saveexec_b64 [[COPY_EXEC1:s\[[0-9]+:[0-9]+\]]], -1{{$}}
600; MUBUF:   s_mov_b64 exec, [[COPY_EXEC1]]
601; MUBUF:   v_mov_b32_e32 [[TMP_VGPR1:v[0-9]+]], s33
602; MUBUF:   buffer_store_dword [[TMP_VGPR1]], off, s[0:3], s32 offset:[[OFF:[0-9]+]]
603; GCN-NOT: v_writelane_b32 v40, s33
604; MUBUF:   s_mov_b32 s33, s32
605; FLATSCR: s_mov_b32 s33, s0
606; GCN-NOT: v_readlane_b32 s33, v40
607; MUBUF:   buffer_load_dword [[TMP_VGPR2:v[0-9]+]], off, s[0:3], s32 offset:[[OFF]]
608; MUBUF:   v_readfirstlane_b32 s33, [[TMP_VGPR2]]
609; MUBUF:   s_or_saveexec_b64 [[COPY_EXEC2:s\[[0-9]+:[0-9]+\]]], -1{{$}}
610; MUBUF:   s_mov_b64 exec, [[COPY_EXEC2]]
611; GCN:     s_setpc_b64
612define void @callee_need_to_spill_fp_to_memory_full_reserved_vgpr() #3 {
613  call void asm sideeffect "; clobber nonpreserved SGPRs and 64 CSRs",
614    "~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
615    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
616    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
617    ,~{s40},~{s41},~{s42},~{s43},~{s44},~{s45},~{s46},~{s47},~{s48},~{s49}
618    ,~{s50},~{s51},~{s52},~{s53},~{s54},~{s55},~{s56},~{s57},~{s58},~{s59}
619    ,~{s60},~{s61},~{s62},~{s63},~{s64},~{s65},~{s66},~{s67},~{s68},~{s69}
620    ,~{s70},~{s71},~{s72},~{s73},~{s74},~{s75},~{s76},~{s77},~{s78},~{s79}
621    ,~{s80},~{s81},~{s82},~{s83},~{s84},~{s85},~{s86},~{s87},~{s88},~{s89}
622    ,~{s90},~{s91},~{s92},~{s93},~{s94},~{s95},~{s96},~{s97},~{s98},~{s99}
623    ,~{s100},~{s101},~{s102},~{s39},~{vcc}"()
624
625  call void asm sideeffect "; clobber all VGPRs except CSR v40",
626    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
627    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
628    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
629    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38}"()
630  ret void
631}
632
633; When flat-scratch is enabled, we save the FP to s0. At the same time,
634; the exec register is saved to s0 when saving CSR in the function prolog.
635; Make sure that the FP save happens after restoring exec from the same
636; register.
637; GCN-LABEL: {{^}}callee_need_to_spill_fp_to_reg:
638; GCN-NOT: v_writelane_b32 v40, s33
639; FLATSCR: s_or_saveexec_b64 s[0:1], -1
640; FLATSCR: s_mov_b64 exec, s[0:1]
641; FLATSCR: s_mov_b32 s0, s33
642; FLATSCR: s_mov_b32 s33, s32
643; FLATSCR: s_mov_b32 s33, s0
644; FLATSCR: s_or_saveexec_b64 s[0:1], -1
645; GCN-NOT: v_readlane_b32 s33, v40
646; GCN:     s_setpc_b64
647define void @callee_need_to_spill_fp_to_reg() #1 {
648  call void asm sideeffect "; clobber nonpreserved SGPRs and 64 CSRs",
649    "~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
650    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
651    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
652    ,~{s40},~{s41},~{s42},~{s43},~{s44},~{s45},~{s46},~{s47},~{s48},~{s49}
653    ,~{s50},~{s51},~{s52},~{s53},~{s54},~{s55},~{s56},~{s57},~{s58},~{s59}
654    ,~{s60},~{s61},~{s62},~{s63},~{s64},~{s65},~{s66},~{s67},~{s68},~{s69}
655    ,~{s70},~{s71},~{s72},~{s73},~{s74},~{s75},~{s76},~{s77},~{s78},~{s79}
656    ,~{s80},~{s81},~{s82},~{s83},~{s84},~{s85},~{s86},~{s87},~{s88},~{s89}
657    ,~{s90},~{s91},~{s92},~{s93},~{s94},~{s95},~{s96},~{s97},~{s98},~{s99}
658    ,~{s100},~{s101},~{s102},~{s39},~{vcc}"()
659
660  call void asm sideeffect "; clobber all VGPRs except CSR v40",
661    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
662    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
663    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
664    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"()
665  ret void
666}
667
668; If the size of the offset exceeds the MUBUF offset field we need another
669; scratch VGPR to hold the offset.
670; GCN-LABEL: {{^}}spill_fp_to_memory_scratch_reg_needed_mubuf_offset
671; MUBUF: s_or_saveexec_b64 s[4:5], -1
672; MUBUF-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x40200
673; MUBUF-NEXT: buffer_store_dword v39, off, s[0:3], [[SCRATCH_SGPR]] ; 4-byte Folded Spill
674; MUBUF: v_mov_b32_e32 v0, s33
675; GCN-NOT: v_mov_b32_e32 v0, 0x100c
676; MUBUF-NEXT: s_add_i32 [[SCRATCH_SGPR:s[0-9]+]], s32, 0x40300
677; MUBUF: buffer_store_dword v0, off, s[0:3], [[SCRATCH_SGPR]] ; 4-byte Folded Spill
678; FLATSCR: v_mov_b32_e32 v0, 0
679; FLATSCR: s_add_i32 [[SOFF:s[0-9]+]], s33, 0x1004
680; FLATSCR: scratch_store_dword off, v0, [[SOFF]]
681define void @spill_fp_to_memory_scratch_reg_needed_mubuf_offset([4096 x i8] addrspace(5)* byval([4096 x i8]) align 4 %arg) #3 {
682  %alloca = alloca i32, addrspace(5)
683  store volatile i32 0, i32 addrspace(5)* %alloca
684
685  call void asm sideeffect "; clobber nonpreserved SGPRs and 64 CSRs",
686    "~{s4},~{s5},~{s6},~{s7},~{s8},~{s9}
687    ,~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19}
688    ,~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29}
689    ,~{s40},~{s41},~{s42},~{s43},~{s44},~{s45},~{s46},~{s47},~{s48},~{s49}
690    ,~{s50},~{s51},~{s52},~{s53},~{s54},~{s55},~{s56},~{s57},~{s58},~{s59}
691    ,~{s60},~{s61},~{s62},~{s63},~{s64},~{s65},~{s66},~{s67},~{s68},~{s69}
692    ,~{s70},~{s71},~{s72},~{s73},~{s74},~{s75},~{s76},~{s77},~{s78},~{s79}
693    ,~{s80},~{s81},~{s82},~{s83},~{s84},~{s85},~{s86},~{s87},~{s88},~{s89}
694    ,~{s90},~{s91},~{s92},~{s93},~{s94},~{s95},~{s96},~{s97},~{s98},~{s99}
695    ,~{s100},~{s101},~{s102},~{s39},~{vcc}"()
696
697  call void asm sideeffect "; clobber all VGPRs except CSR v40",
698    "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9}
699    ,~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19}
700    ,~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29}
701    ,~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38}"()
702  ret void
703}
704
705attributes #0 = { nounwind }
706attributes #1 = { nounwind "frame-pointer"="all" }
707attributes #2 = { nounwind "frame-pointer"="non-leaf" }
708attributes #3 = { nounwind "frame-pointer"="all" "amdgpu-waves-per-eu"="6,6" }
709