Index: llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -1417,6 +1417,14 @@ return false; }; + auto parseOptionalRegister = [&](const yaml::StringValue &RegName, + Register &RegVal) { + return !RegName.Value.empty() && parseRegister(RegName, RegVal); + }; + + if (parseOptionalRegister(YamlMFI.VGPRForAGPRCopy, MFI->VGPRForAGPRCopy)) + return true; + auto diagnoseRegisterClass = [&](const yaml::StringValue &RegName) { // Create a diagnostic for a the register string literal. const MemoryBuffer &Buffer = Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -296,6 +296,7 @@ Optional ArgInfo; SIMode Mode; Optional ScavengeFI; + StringValue VGPRForAGPRCopy; SIMachineFunctionInfo() = default; SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &, @@ -335,6 +336,8 @@ YamlIO.mapOptional("occupancy", MFI.Occupancy, 0); YamlIO.mapOptional("wwmReservedRegs", MFI.WWMReservedRegs); YamlIO.mapOptional("scavengeFI", MFI.ScavengeFI); + YamlIO.mapOptional("vgprForAGPRCopy", MFI.VGPRForAGPRCopy, + StringValue()); // Don't print out when it's empty. } }; @@ -518,8 +521,6 @@ public: Register getVGPRForAGPRCopy() const { - assert(VGPRForAGPRCopy && - "Valid VGPR for AGPR copy must have been identified by now"); return VGPRForAGPRCopy; } Index: llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -590,6 +590,8 @@ for (Register Reg : MFI.WWMReservedRegs) WWMReservedRegs.push_back(regToString(Reg, TRI)); + if (MFI.getVGPRForAGPRCopy()) + VGPRForAGPRCopy = regToString(MFI.getVGPRForAGPRCopy(), TRI); auto SFI = MFI.getOptionalScavengeFI(); if (SFI) ScavengeFI = yaml::FrameIndex(*SFI, MF.getFrameInfo()); Index: llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-after-pei.ll =================================================================== --- llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-after-pei.ll +++ llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-after-pei.ll @@ -36,6 +36,7 @@ ; AFTER-PEI-NEXT: highBitsOf32BitAddress: 0 ; AFTER-PEI-NEXT: occupancy: 5 ; AFTER-PEI-NEXT: scavengeFI: '%fixed-stack.0' +; AFTER-PEI-NEXT: vgprForAGPRCopy: '' ; AFTER-PEI-NEXT: body: define amdgpu_kernel void @scavenge_fi(i32 addrspace(1)* %out, i32 %in) #0 { %wide.sgpr0 = call <32 x i32> asm sideeffect "; def $0", "=s" () #0 Index: llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir =================================================================== --- llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir +++ llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir @@ -44,6 +44,7 @@ # FULL-NEXT: fp64-fp16-output-denormals: true # FULL-NEXT: highBitsOf32BitAddress: 0 # FULL-NEXT: occupancy: 10 +# FULL-NEXT: vgprForAGPRCopy: '' # FULL-NEXT: body: # SIMPLE: machineFunctionInfo: @@ -139,6 +140,7 @@ # FULL-NEXT: fp64-fp16-output-denormals: true # FULL-NEXT: highBitsOf32BitAddress: 0 # FULL-NEXT: occupancy: 10 +# FULL-NEXT: vgprForAGPRCopy: '' # FULL-NEXT: body: # SIMPLE: machineFunctionInfo: @@ -205,6 +207,7 @@ # FULL-NEXT: fp64-fp16-output-denormals: true # FULL-NEXT: highBitsOf32BitAddress: 0 # FULL-NEXT: occupancy: 10 +# FULL-NEXT: vgprForAGPRCopy: '' # FULL-NEXT: body: # SIMPLE: machineFunctionInfo: @@ -272,6 +275,7 @@ # FULL-NEXT: fp64-fp16-output-denormals: true # FULL-NEXT: highBitsOf32BitAddress: 0 # FULL-NEXT: occupancy: 10 +# FULL-NEXT: vgprForAGPRCopy: '' # FULL-NEXT: body: # SIMPLE: machineFunctionInfo: @@ -491,3 +495,28 @@ SI_RETURN ... + +--- +# ALL-LABEL: name: vgpr_for_agpr_copy +# ALL: vgprForAGPRCopy: '$vgpr2' +name: vgpr_for_agpr_copy +machineFunctionInfo: + vgprForAGPRCopy: '$vgpr2' +body: | + bb.0: + SI_RETURN + +... + +--- +# ALL-LABEL: name: vgpr_for_agpr_copy_noreg +# FULL: vgprForAGPRCopy: '' +# SIMPLE-NOT: vgprForAGPRCopy +name: vgpr_for_agpr_copy_noreg +machineFunctionInfo: + vgprForAGPRCopy: '$noreg' +body: | + bb.0: + SI_RETURN + +... 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 @@ -39,6 +39,7 @@ ; CHECK-NEXT: fp64-fp16-output-denormals: true ; CHECK-NEXT: highBitsOf32BitAddress: 0 ; CHECK-NEXT: occupancy: 10 +; CHECK-NEXT: vgprForAGPRCopy: '' ; CHECK-NEXT: body: define amdgpu_kernel void @kernel(i32 %arg0, i64 %arg1, <16 x i32> %arg2) { %gep = getelementptr inbounds [512 x float], [512 x float] addrspace(3)* @lds, i32 0, i32 %arg0 @@ -78,6 +79,7 @@ ; CHECK-NEXT: fp64-fp16-output-denormals: true ; CHECK-NEXT: highBitsOf32BitAddress: 0 ; CHECK-NEXT: occupancy: 10 +; CHECK-NEXT: vgprForAGPRCopy: '' ; CHECK-NEXT: body: define amdgpu_ps void @ps_shader(i32 %arg0, i32 inreg %arg1) { %gep = getelementptr inbounds [128 x i32], [128 x i32] addrspace(2)* @gds, i32 0, i32 %arg0 @@ -130,6 +132,7 @@ ; CHECK-NEXT: fp64-fp16-output-denormals: true ; CHECK-NEXT: highBitsOf32BitAddress: 0 ; CHECK-NEXT: occupancy: 10 +; CHECK-NEXT: vgprForAGPRCopy: '' ; CHECK-NEXT: body: define void @function() { ret void @@ -174,6 +177,7 @@ ; CHECK-NEXT: fp64-fp16-output-denormals: true ; CHECK-NEXT: highBitsOf32BitAddress: 0 ; CHECK-NEXT: occupancy: 10 +; CHECK-NEXT: vgprForAGPRCopy: '' ; CHECK-NEXT: body: define void @function_nsz() #0 { ret void Index: llvm/test/CodeGen/MIR/AMDGPU/vgpr-for-agpr-copy-invalid-reg.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/MIR/AMDGPU/vgpr-for-agpr-copy-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]]:21: unknown register name 'arst' + vgprForAGPRCopy: '$arst' +body: | + bb.0: + S_ENDPGM 0 + +...