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