1 ; RUN: llc -march=amdgcn -mcpu=verde -enable-misched=0 -post-RA-scheduler=0 -amdgpu-spill-sgpr-to-vgpr=0 < %s | FileCheck -check-prefixes=CHECK,GFX6 %s
2 ; RUN: llc -sgpr-regalloc=basic -vgpr-regalloc=basic -march=amdgcn -mcpu=tonga -enable-misched=0 -post-RA-scheduler=0 -amdgpu-spill-sgpr-to-vgpr=0 < %s | FileCheck --check-prefix=CHECK %s
3 ; RUN: llc -march=amdgcn -mattr=-xnack,+enable-flat-scratch -mcpu=gfx900 -enable-misched=0 -post-RA-scheduler=0 -amdgpu-spill-sgpr-to-vgpr=0 < %s | FileCheck -check-prefixes=CHECK,GFX9-FLATSCR,FLATSCR %s
4 ; RUN: llc -march=amdgcn -mcpu=gfx1030 -enable-misched=0 -post-RA-scheduler=0 -amdgpu-spill-sgpr-to-vgpr=0 -mattr=+enable-flat-scratch < %s | FileCheck -check-prefixes=CHECK,GFX10-FLATSCR,FLATSCR %s
6 ; There is something about Tonga that causes this test to spend a lot of time
7 ; in the default register allocator.
10 ; When the offset of VGPR spills into scratch space gets too large, an additional SGPR
11 ; is used to calculate the scratch load/store address. Make sure that this
12 ; mechanism works even when many spills happen.
14 ; Just test that it compiles successfully.
17 ; GFX9-FLATSCR: s_mov_b32 [[SOFF1:s[0-9]+]], 4{{$}}
18 ; GFX9-FLATSCR: scratch_store_dwordx4 off, v[{{[0-9:]+}}], [[SOFF1]] ; 16-byte Folded Spill
19 ; GFX9-FLATSCR: ;;#ASMSTART
20 ; GFX9-FLATSCR: s_movk_i32 [[SOFF2:s[0-9]+]], 0x1{{[0-9a-f]+}}{{$}}
21 ; GFX9-FLATSCR: scratch_load_dwordx4 v[{{[0-9:]+}}], off, [[SOFF2]] ; 16-byte Folded Reload
23 ; GFX10-FLATSCR: scratch_store_dwordx4 off, v[{{[0-9:]+}}], off offset:{{[0-9]+}} ; 16-byte Folded Spill
24 ; GFX10-FLATSCR: scratch_load_dwordx4 v[{{[0-9:]+}}], off, off offset:{{[0-9]+}} ; 16-byte Folded Reload
25 define amdgpu_kernel void @test(<1280 x i32> addrspace(1)* %out, <1280 x i32> addrspace(1)* %in) {
27 %lo = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0)
28 %tid = call i32 @llvm.amdgcn.mbcnt.hi(i32 -1, i32 %lo)
30 %aptr = getelementptr <1280 x i32>, <1280 x i32> addrspace(1)* %in, i32 %tid
31 %a = load <1280 x i32>, <1280 x i32> addrspace(1)* %aptr
33 ; mark most VGPR registers as used to increase register pressure
34 call void asm sideeffect "", "~{v4},~{v8},~{v12},~{v16},~{v20},~{v24},~{v28},~{v32}" ()
35 call void asm sideeffect "", "~{v36},~{v40},~{v44},~{v48},~{v52},~{v56},~{v60},~{v64}" ()
36 call void asm sideeffect "", "~{v68},~{v72},~{v76},~{v80},~{v84},~{v88},~{v92},~{v96}" ()
37 call void asm sideeffect "", "~{v100},~{v104},~{v108},~{v112},~{v116},~{v120},~{v124},~{v128}" ()
38 call void asm sideeffect "", "~{v132},~{v136},~{v140},~{v144},~{v148},~{v152},~{v156},~{v160}" ()
39 call void asm sideeffect "", "~{v164},~{v168},~{v172},~{v176},~{v180},~{v184},~{v188},~{v192}" ()
40 call void asm sideeffect "", "~{v196},~{v200},~{v204},~{v208},~{v212},~{v216},~{v220},~{v224}" ()
42 %outptr = getelementptr <1280 x i32>, <1280 x i32> addrspace(1)* %out, i32 %tid
43 store <1280 x i32> %a, <1280 x i32> addrspace(1)* %outptr
48 ; CHECK-LABEL: test_limited_sgpr
50 ; GFX6: s_mov_b64 exec, 0xff
51 ; GFX6: buffer_store_dword [[SPILL_REG_0:v[0-9]+]]
52 ; GFX6-COUNT-8: v_writelane_b32 [[SPILL_REG_0]]
53 ; GFX6: v_mov_b32_e32 [[OFFSET_REG0:v[0-9]+]], 0x[[OFFSET0:[0-9a-f]+]]
54 ; GFX6: buffer_store_dword [[SPILL_REG_0]], [[OFFSET_REG0]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
55 ; GFX6: buffer_load_dword [[SPILL_REG_0]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
56 ; GFX6: s_mov_b64 exec, s
59 ; GFX6: s_mov_b64 exec, 0xff
60 ; GFX6: v_mov_b32_e32 [[RELOAD_OFFSET_REG0:v[0-9]+]], 0x[[RELOAD_OFFSET0:[0-9a-f]+]]
61 ; GFX6: buffer_store_dword [[RELOAD_REG_0:v[0-9]+]], off,
62 ; GFX6: buffer_load_dword [[RELOAD_REG_0]], [[RELOAD_OFFSET_REG0]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
63 ; GFX6-COUNT-8: v_readlane_b32 s{{[0-9]+}}, [[RELOAD_REG_0]]
64 ; GFX6: buffer_load_dword [[RELOAD_REG_0]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
65 ; GFX6: s_mov_b64 exec,
68 ; GFX6: s_mov_b64 exec, 0xff
69 ; GFX6: buffer_store_dword [[SPILL_REG_1:v[0-9]+]]
70 ; GFX6-COUNT-8: v_writelane_b32 [[SPILL_REG_1]]
71 ; GFX6: v_mov_b32_e32 [[OFFSET_REG1:v[0-9]+]], 0x[[OFFSET1:[0-9a-f]+]]
72 ; GFX6: buffer_store_dword [[SPILL_REG_1]], [[OFFSET_REG1]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
73 ; GFX6: buffer_load_dword [[SPILL_REG_1]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
74 ; GFX6: s_mov_b64 exec, s
77 ; GFX6: s_mov_b64 exec, 0xff
78 ; GFX6: v_mov_b32_e32 [[RELOAD_OFFSET_REG1:v[0-9]+]], 0x[[RELOAD_OFFSET1:[0-9a-f]+]]
79 ; GFX6: buffer_store_dword [[RELOAD_REG_1:v[0-9]+]], off,
80 ; GFX6: buffer_load_dword [[RELOAD_REG_1]], [[RELOAD_OFFSET_REG1]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
81 ; GFX6-COUNT-8: v_readlane_b32 s{{[0-9]+}}, [[RELOAD_REG_1]]
82 ; GFX6: buffer_load_dword [[RELOAD_REG_1]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
83 ; GFX6: s_mov_b64 exec,
86 ; GFX6: s_mov_b64 exec, 0xff
87 ; GFX6: buffer_store_dword [[SPILL_REG_2:v[0-9]+]]
88 ; GFX6-COUNT-8: v_writelane_b32 [[SPILL_REG_2]]
89 ; GFX6: v_mov_b32_e32 [[OFFSET_REG2:v[0-9]+]], 0x[[OFFSET2:[0-9a-f]+]]
90 ; GFX6: buffer_store_dword [[SPILL_REG_2]], [[OFFSET_REG2]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
91 ; GFX6: buffer_load_dword [[SPILL_REG_2]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
92 ; GFX6: s_mov_b64 exec, s
95 ; GFX6: s_mov_b64 exec, 0xff
96 ; GFX6: buffer_store_dword [[SPILL_REG_3:v[0-9]+]]
97 ; GFX6-COUNT-8: v_writelane_b32 [[SPILL_REG_3]]
98 ; GFX6: v_mov_b32_e32 [[OFFSET_REG3:v[0-9]+]], 0x[[OFFSET3:[0-9a-f]+]]
99 ; GFX6: buffer_store_dword [[SPILL_REG_3]], [[OFFSET_REG3]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
100 ; GFX6: buffer_load_dword [[SPILL_REG_3]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
101 ; GFX6: s_mov_b64 exec, s
104 ; GFX6: s_mov_b64 exec, 0xff
105 ; GFX6: buffer_store_dword [[SPILL_REG_4:v[0-9]+]]
106 ; GFX6-COUNT-4: v_writelane_b32 [[SPILL_REG_4]]
107 ; GFX6: v_mov_b32_e32 [[OFFSET_REG4:v[0-9]+]], 0x[[OFFSET4:[0-9a-f]+]]
108 ; GFX6: buffer_store_dword [[SPILL_REG_4]], [[OFFSET_REG4]], s{{\[[0-9]+:[0-9]+\]}}, 0 offen
109 ; GFX6: buffer_load_dword [[SPILL_REG_4]], off, s{{\[[0-9]+:[0-9]+\]}}, 0{{$}}
110 ; GFX6: s_mov_b64 exec, s
113 ; GFX6: ScratchSize: 8608
115 ; FLATSCR: s_movk_i32 [[SOFF1:s[0-9]+]], 0x
116 ; GFX9-FLATSCR: s_waitcnt vmcnt(0)
117 ; FLATSCR: scratch_store_dwordx4 off, v[{{[0-9:]+}}], [[SOFF1]] ; 16-byte Folded Spill
118 ; FLATSCR: s_movk_i32 [[SOFF2:s[0-9]+]], 0x
119 ; FLATSCR: scratch_load_dwordx4 v[{{[0-9:]+}}], off, [[SOFF2]] ; 16-byte Folded Reload
120 define amdgpu_kernel void @test_limited_sgpr(<64 x i32> addrspace(1)* %out, <64 x i32> addrspace(1)* %in) #0 {
122 %lo = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0)
123 %tid = call i32 @llvm.amdgcn.mbcnt.hi(i32 -1, i32 %lo)
125 ; allocate enough scratch to go beyond 2^12 addressing
126 %scratch = alloca <1280 x i32>, align 8, addrspace(5)
129 %aptr = getelementptr <64 x i32>, <64 x i32> addrspace(1)* %in, i32 %tid
130 %a = load <64 x i32>, <64 x i32> addrspace(1)* %aptr
132 ; make sure scratch is used
133 %x = extractelement <64 x i32> %a, i32 0
134 %sptr0 = getelementptr <1280 x i32>, <1280 x i32> addrspace(5)* %scratch, i32 %x, i32 0
135 store i32 1, i32 addrspace(5)* %sptr0
138 %sgpr0 = call <8 x i32> asm sideeffect "; def $0", "=s" ()
139 %sgpr1 = call <8 x i32> asm sideeffect "; def $0", "=s" ()
140 %sgpr2 = call <8 x i32> asm sideeffect "; def $0", "=s" ()
141 %sgpr3 = call <8 x i32> asm sideeffect "; def $0", "=s" ()
142 %sgpr4 = call <4 x i32> asm sideeffect "; def $0", "=s" ()
143 %sgpr5 = call <2 x i32> asm sideeffect "; def $0", "=s" ()
144 %sgpr6 = call <2 x i32> asm sideeffect "; def $0", "=s" ()
145 %sgpr7 = call i32 asm sideeffect "; def $0", "=s" ()
147 %cmp = icmp eq i32 %x, 0
148 br i1 %cmp, label %bb0, label %ret
151 ; create SGPR pressure
152 call void asm sideeffect "; use $0,$1,$2,$3,$4,$5,$6", "s,s,s,s,s,s,s,s"(<8 x i32> %sgpr0, <8 x i32> %sgpr1, <8 x i32> %sgpr2, <8 x i32> %sgpr3, <4 x i32> %sgpr4, <2 x i32> %sgpr5, <2 x i32> %sgpr6, i32 %sgpr7)
154 ; mark most VGPR registers as used to increase register pressure
155 call void asm sideeffect "", "~{v4},~{v8},~{v12},~{v16},~{v20},~{v24},~{v28},~{v32}" ()
156 call void asm sideeffect "", "~{v36},~{v40},~{v44},~{v48},~{v52},~{v56},~{v60},~{v64}" ()
157 call void asm sideeffect "", "~{v68},~{v72},~{v76},~{v80},~{v84},~{v88},~{v92},~{v96}" ()
158 call void asm sideeffect "", "~{v100},~{v104},~{v108},~{v112},~{v116},~{v120},~{v124},~{v128}" ()
159 call void asm sideeffect "", "~{v132},~{v136},~{v140},~{v144},~{v148},~{v152},~{v156},~{v160}" ()
160 call void asm sideeffect "", "~{v164},~{v168},~{v172},~{v176},~{v180},~{v184},~{v188},~{v192}" ()
161 call void asm sideeffect "", "~{v196},~{v200},~{v204},~{v208},~{v212},~{v216},~{v220},~{v224}" ()
165 %outptr = getelementptr <64 x i32>, <64 x i32> addrspace(1)* %out, i32 %tid
166 store <64 x i32> %a, <64 x i32> addrspace(1)* %outptr
171 declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #1
172 declare i32 @llvm.amdgcn.mbcnt.hi(i32, i32) #1
174 attributes #0 = { "amdgpu-waves-per-eu"="10,10" }
175 attributes #1 = { nounwind readnone }