Index: llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -1449,6 +1449,14 @@ return diagnoseRegisterClass(YamlMFI.StackPtrOffsetReg); } + for (const auto &YamlReg : YamlMFI.WWMReservedRegs) { + Register ParsedReg; + if (parseRegister(YamlReg, ParsedReg)) + return true; + + MFI->reserveWWMRegister(ParsedReg); + } + auto parseAndCheckArgument = [&](const Optional &A, const TargetRegisterClass &RC, ArgDescriptor &Arg, unsigned UserSGPRs, Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -283,6 +283,8 @@ // TODO: 10 may be a better default since it's the maximum. unsigned Occupancy = 0; + SmallVector WWMReservedRegs; + StringValue ScratchRSrcReg = "$private_rsrc_reg"; StringValue FrameOffsetReg = "$fp_reg"; StringValue StackPtrOffsetReg = "$sp_reg"; @@ -324,6 +326,7 @@ YamlIO.mapOptional("highBitsOf32BitAddress", MFI.HighBitsOf32BitAddress, 0u); YamlIO.mapOptional("occupancy", MFI.Occupancy, 0); + YamlIO.mapOptional("wwmReservedRegs", MFI.WWMReservedRegs); YamlIO.mapOptional("scavengeFI", MFI.ScavengeFI); } }; Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -589,6 +589,9 @@ FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)), StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)), ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)), Mode(MFI.getMode()) { + for (Register Reg : MFI.WWMReservedRegs) + WWMReservedRegs.push_back(regToString(Reg, TRI)); + auto SFI = MFI.getOptionalScavengeFI(); if (SFI) ScavengeFI = yaml::FrameIndex(*SFI, MF.getFrameInfo()); Index: llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll =================================================================== --- llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll +++ llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=tahiti -stop-after finalize-isel -o %t.mir %s +; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=tahiti -stop-after=si-pre-allocate-wwm-regs -o %t.mir %s ; RUN: llc -run-pass=none -verify-machineinstrs %t.mir -o - | FileCheck %s ; Test that SIMachineFunctionInfo can be round trip serialized through @@ -200,8 +200,25 @@ ret void } +; CHECK-LABEL: {{^}}name: wwm_reserved_regs +; CHECK: wwmReservedRegs: +; CHECK-NEXT: - '$vgpr2' +; CHECK-NEXT: - '$vgpr3' +define amdgpu_cs void @wwm_reserved_regs(i32 addrspace(1)* %ptr, <4 x i32> inreg %tmp14) { + %ld0 = load volatile i32, i32 addrspace(1)* %ptr + %ld1 = load volatile i32, i32 addrspace(1)* %ptr + %inactive0 = tail call i32 @llvm.amdgcn.set.inactive.i32(i32 %ld1, i32 0) + %inactive1 = tail call i32 @llvm.amdgcn.set.inactive.i32(i32 %ld0, i32 0) + store volatile i32 %inactive0, i32 addrspace(1)* %ptr + store volatile i32 %inactive1, i32 addrspace(1)* %ptr + ret void +} + +declare i32 @llvm.amdgcn.set.inactive.i32(i32, i32) #5 + attributes #0 = { "no-signed-zeros-fp-math" = "true" } attributes #1 = { "amdgpu-dx10-clamp" = "false" } attributes #2 = { "amdgpu-ieee" = "false" } attributes #3 = { "amdgpu-dx10-clamp" = "false" "amdgpu-ieee" = "false" } attributes #4 = { "amdgpu-32bit-address-high-bits"="0xffff8000" } +attributes #5 = { convergent nounwind readnone willreturn } Index: llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-invalid-reg.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-invalid-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s + +--- +name: invalid_reg +machineFunctionInfo: +# ERR: [[@LINE+1]]:32: unknown register name 'notareg' + wwmReservedRegs: ['$vgpr0', '$notareg'] +body: | + bb.0: + S_ENDPGM 0 + +... Index: llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-not-a-reg.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-not-a-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s + +--- +name: invalid_reg +machineFunctionInfo: +# ERR: [[@LINE+1]]:21: expected a named register + wwmReservedRegs: [123] +body: | + bb.0: + S_ENDPGM 0 + +... Index: llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs.mir @@ -0,0 +1,44 @@ +# RUN: llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s + +# CHECK-LABEL: name: empty_wwm_regs{{$}} +# CHECK: machineFunctionInfo: +# CHECK-NOT: wwmReservedRegs +--- +name: empty_wwm_regs +machineFunctionInfo: + wwmReservedRegs: [] +body: | + bb.0: + S_ENDPGM 0 + +... + +# CHECK-LABEL: name: one_reg{{$}} +# CHECK: machineFunctionInfo: +# CHECK: wwmReservedRegs: +# CHECK-NEXT: - '$vgpr0' +--- +name: one_reg +machineFunctionInfo: + wwmReservedRegs: ['$vgpr0'] +body: | + bb.0: + S_ENDPGM 0 + +... + +# CHECK-LABEL: name: two_reg{{$}} +# CHECK: machineFunctionInfo: +# CHECK: wwmReservedRegs: +# CHECK-NEXT: - '$vgpr0' +# CHECK-NEXT: - '$vgpr1' +--- +name: two_reg +machineFunctionInfo: + wwmReservedRegs: ['$vgpr0', '$vgpr1'] +body: | + bb.0: + S_ENDPGM 0 + +...