diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index d02899a7a389..0ab8bba527d2 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -1449,6 +1449,14 @@ bool GCNTargetMachine::parseMachineFunctionInfo( 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, diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp index 1c772c0342a4..c07511b92989 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -589,6 +589,9 @@ yaml::SIMachineFunctionInfo::SIMachineFunctionInfo( 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()); diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index 3a981f182234..9056865094d1 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -283,6 +283,8 @@ struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { // 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 @@ template <> struct MappingTraits { YamlIO.mapOptional("highBitsOf32BitAddress", MFI.HighBitsOf32BitAddress, 0u); YamlIO.mapOptional("occupancy", MFI.Occupancy, 0); + YamlIO.mapOptional("wwmReservedRegs", MFI.WWMReservedRegs); YamlIO.mapOptional("scavengeFI", MFI.ScavengeFI); } }; diff --git a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll index eceab5cec042..a3a6f0898101 100644 --- a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll +++ b/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 @@ define amdgpu_ps void @high_address_bits() #4 { 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 } diff --git a/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-invalid-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-invalid-reg.mir new file mode 100644 index 000000000000..cd1ac22e85be --- /dev/null +++ b/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 + +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-not-a-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs-not-a-reg.mir new file mode 100644 index 000000000000..d1c08791d1fa --- /dev/null +++ b/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 + +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs.mir b/llvm/test/CodeGen/MIR/AMDGPU/wwm-reserved-regs.mir new file mode 100644 index 000000000000..128e73f2f44e --- /dev/null +++ b/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 + +...