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