1; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=TOSGPR -check-prefix=ALL %s
2
3; FIXME: Vectorization can increase required SGPR count beyond limit.
4
5; ALL-LABEL: {{^}}max_9_sgprs:
6
7; ALL: SGPRBlocks: 1
8; ALL: NumSGPRsForWavesPerEU: 9
9define amdgpu_kernel void @max_9_sgprs() #0 {
10  %one = load volatile i32, i32 addrspace(4)* undef
11  %two = load volatile i32, i32 addrspace(4)* undef
12  %three = load volatile i32, i32 addrspace(4)* undef
13  %four = load volatile i32, i32 addrspace(4)* undef
14  %five = load volatile i32, i32 addrspace(4)* undef
15  %six = load volatile i32, i32 addrspace(4)* undef
16  %seven = load volatile i32, i32 addrspace(4)* undef
17  %eight = load volatile i32, i32 addrspace(4)* undef
18  %nine = load volatile i32, i32 addrspace(4)* undef
19  %ten = load volatile i32, i32 addrspace(4)* undef
20  call void asm sideeffect "", "s,s,s,s,s,s,s,s,s"(i32 %one, i32 %two, i32 %three, i32 %four, i32 %five, i32 %six, i32 %seven, i32 %eight, i32 %nine)
21  store volatile i32 %one, i32 addrspace(1)* undef
22  store volatile i32 %two, i32 addrspace(1)* undef
23  store volatile i32 %three, i32 addrspace(1)* undef
24  store volatile i32 %four, i32 addrspace(1)* undef
25  store volatile i32 %five, i32 addrspace(1)* undef
26  store volatile i32 %six, i32 addrspace(1)* undef
27  store volatile i32 %seven, i32 addrspace(1)* undef
28  store volatile i32 %eight, i32 addrspace(1)* undef
29  store volatile i32 %nine, i32 addrspace(1)* undef
30  store volatile i32 %ten, i32 addrspace(1)* undef
31  ret void
32}
33
34; private resource: 4
35; scratch wave offset: 1
36; workgroup ids: 3
37; dispatch id: 2
38; queue ptr: 2
39; flat scratch init: 2
40; ---------------------
41; total: 14
42
43; + reserved vcc = 16
44
45; Because we can't handle re-using the last few input registers as the
46; special vcc etc. registers (as well as decide to not use the unused
47; features when the number of registers is frozen), this ends up using
48; more than expected.
49
50; XALL-LABEL: {{^}}max_12_sgprs_14_input_sgprs:
51; XTOSGPR: SGPRBlocks: 1
52; XTOSGPR: NumSGPRsForWavesPerEU: 16
53
54; This test case is disabled: When calculating the spillslot addresses AMDGPU
55; creates an extra vreg to save/restore m0 which in a point of maximum register
56; pressure would trigger an endless loop; the compiler aborts earlier with
57; "Incomplete scavenging after 2nd pass" in practice.
58;define amdgpu_kernel void @max_12_sgprs_14_input_sgprs(i32 addrspace(1)* %out1,
59;                                        i32 addrspace(1)* %out2,
60;                                        i32 addrspace(1)* %out3,
61;                                        i32 addrspace(1)* %out4,
62;                                        i32 %one, i32 %two, i32 %three, i32 %four) #2 {
63;  %x.0 = call i32 @llvm.amdgcn.workgroup.id.x()
64;  %x.1 = call i32 @llvm.amdgcn.workgroup.id.y()
65;  %x.2 = call i32 @llvm.amdgcn.workgroup.id.z()
66;  %x.3 = call i64 @llvm.amdgcn.dispatch.id()
67;  %x.4 = call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr()
68;  %x.5 = call i8 addrspace(4)* @llvm.amdgcn.queue.ptr()
69;  store volatile i32 0, i32* undef
70;  br label %stores
71;
72;stores:
73;  store volatile i32 %x.0, i32 addrspace(1)* undef
74;  store volatile i32 %x.0, i32 addrspace(1)* undef
75;  store volatile i32 %x.0, i32 addrspace(1)* undef
76;  store volatile i64 %x.3, i64 addrspace(1)* undef
77;  store volatile i8 addrspace(4)* %x.4, i8 addrspace(4)* addrspace(1)* undef
78;  store volatile i8 addrspace(4)* %x.5, i8 addrspace(4)* addrspace(1)* undef
79;
80;  store i32 %one, i32 addrspace(1)* %out1
81;  store i32 %two, i32 addrspace(1)* %out2
82;  store i32 %three, i32 addrspace(1)* %out3
83;  store i32 %four, i32 addrspace(1)* %out4
84;  ret void
85;}
86
87; The following test is commented out for now; http://llvm.org/PR31230
88; XALL-LABEL: max_12_sgprs_12_input_sgprs{{$}}
89; ; Make sure copies for input buffer are not clobbered. This requires
90; ; swapping the order the registers are copied from what normally
91; ; happens.
92
93; XALL: SGPRBlocks: 2
94; XALL: NumSGPRsForWavesPerEU: 18
95;define amdgpu_kernel void @max_12_sgprs_12_input_sgprs(i32 addrspace(1)* %out1,
96;                                        i32 addrspace(1)* %out2,
97;                                        i32 addrspace(1)* %out3,
98;                                        i32 addrspace(1)* %out4,
99;                                        i32 %one, i32 %two, i32 %three, i32 %four) #2 {
100;  store volatile i32 0, i32* undef
101;  %x.0 = call i32 @llvm.amdgcn.workgroup.id.x()
102;  store volatile i32 %x.0, i32 addrspace(1)* undef
103;  %x.1 = call i32 @llvm.amdgcn.workgroup.id.y()
104;  store volatile i32 %x.0, i32 addrspace(1)* undef
105;  %x.2 = call i32 @llvm.amdgcn.workgroup.id.z()
106;  store volatile i32 %x.0, i32 addrspace(1)* undef
107;  %x.3 = call i64 @llvm.amdgcn.dispatch.id()
108;  store volatile i64 %x.3, i64 addrspace(1)* undef
109;  %x.4 = call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr()
110;  store volatile i8 addrspace(4)* %x.4, i8 addrspace(4)* addrspace(1)* undef
111;
112;  store i32 %one, i32 addrspace(1)* %out1
113;  store i32 %two, i32 addrspace(1)* %out2
114;  store i32 %three, i32 addrspace(1)* %out3
115;  store i32 %four, i32 addrspace(1)* %out4
116;  ret void
117;}
118
119declare i32 @llvm.amdgcn.workgroup.id.x() #1
120declare i32 @llvm.amdgcn.workgroup.id.y() #1
121declare i32 @llvm.amdgcn.workgroup.id.z() #1
122declare i64 @llvm.amdgcn.dispatch.id() #1
123declare i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr() #1
124declare i8 addrspace(4)* @llvm.amdgcn.queue.ptr() #1
125
126attributes #0 = { nounwind "amdgpu-num-sgpr"="14" }
127attributes #1 = { nounwind readnone }
128attributes #2 = { nounwind "amdgpu-num-sgpr"="12" }
129attributes #3 = { nounwind "amdgpu-num-sgpr"="11" }
130