diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -4294,13 +4294,22 @@ continue; } - if (RI.hasAGPRs(MRI.getRegClass(MO.getReg())) && - !isOperandLegal(MI, Idx, &MO)) { + bool IsSGPR = false; + bool IsAGPR = false; + if (MO.getReg().isVirtual()) { + IsAGPR = RI.hasAGPRs(MRI.getRegClass(MO.getReg())); + IsSGPR = RI.isSGPRClass(MRI.getRegClass(MO.getReg())); + } else { + IsAGPR = RI.isAGPR(MRI, MO.getReg()); + IsAGPR = RI.isSGPRReg(MRI, MO.getReg()); + } + + if (IsAGPR && !isOperandLegal(MI, Idx, &MO)) { legalizeOpWithMove(MI, Idx); continue; } - if (!RI.isSGPRClass(MRI.getRegClass(MO.getReg()))) + if (!IsSGPR) continue; // VGPRs are legal // We can use one SGPR in each VOP3 instruction prior to GFX10 @@ -5929,9 +5938,14 @@ // If this could be a VGPR or an SGPR, Check the dynamic register class. Register Reg = MO.getReg(); - const TargetRegisterClass *RegRC = MRI.getRegClass(Reg); - if (RI.isSGPRClass(RegRC)) - UsedSGPRs[i] = Reg; + if (Reg.isVirtual()) { + const TargetRegisterClass *RegRC = MRI.getRegClass(Reg); + if (RI.isSGPRClass(RegRC)) + UsedSGPRs[i] = Reg; + } else { + if (RI.isSGPRReg(MRI, Reg)) + UsedSGPRs[i] = Reg; + } } // We don't have a required SGPR operand, so we have a bit more freedom in diff --git a/llvm/test/CodeGen/AMDGPU/vop3-physical-reg.mir b/llvm/test/CodeGen/AMDGPU/vop3-physical-reg.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/vop3-physical-reg.mir @@ -0,0 +1,42 @@ +# RUN: llc -march=amdgcn -mcpu=kaveri -run-pass=si-peephole-sdwa -o - %s | FileCheck -check-prefix=CI -check-prefix=GCN %s +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=si-peephole-sdwa -o - %s | FileCheck -check-prefix=VI -check-prefix=GCN %s +# RUN: llc -march=amdgcn -mcpu=gfx900 -run-pass=si-peephole-sdwa -o - %s | FileCheck -check-prefix=GFX9 -check-prefix=GCN %s +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=si-peephole-sdwa -o - %s | FileCheck -check-prefix=GFX10 -check-prefix=GCN %s + +# Allow physical registers as vop3 operands + +# GCN-LABEL: {{^}}name: vop3_reg + +# GCN: %{{[0-9]+}}:vgpr_32 = V_BCNT_U32_B32_e64 $exec_lo, 0, implicit-def $vcc, implicit $exec +# GCN: %{{[0-9]+}}:vgpr_32 = V_BCNT_U32_B32_e64 $exec_hi, 0, implicit-def $vcc, implicit $exec +# GCN: %{{[0-9]+}}:vgpr_32 = V_MBCNT_LO_U32_B32_e64 $exec_lo, 0, implicit-def $vcc, implicit $exec +# GCN: %{{[0-9]+}}:vgpr_32 = V_MBCNT_HI_U32_B32_e64 $exec_hi, %{{[0-9]+}}, implicit-def $vcc, implicit $exec + +--- +name: vop3_reg +tracksRegLiveness: true +registers: + - { id: 0, class: vreg_64 } + - { id: 1, class: vgpr_32 } + - { id: 2, class: vgpr_32 } + - { id: 3, class: vgpr_32 } + - { id: 4, class: vgpr_32 } + - { id: 9, class: sreg_64 } +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2, $sgpr30_sgpr31 + + %9 = COPY $sgpr30_sgpr31 + %0 = COPY $vgpr0_vgpr1 + + %1 = V_BCNT_U32_B32_e64 $exec_lo, 0, implicit-def $vcc, implicit $exec + %2 = V_BCNT_U32_B32_e64 $exec_hi, 0, implicit-def $vcc, implicit $exec + %3 = V_MBCNT_LO_U32_B32_e64 $exec_lo, 0, implicit-def $vcc, implicit $exec + %4 = V_MBCNT_HI_U32_B32_e64 $exec_hi, %3, implicit-def $vcc, implicit $exec + + FLAT_STORE_DWORD %0, %1, 0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store 4) + FLAT_STORE_DWORD %0, %2, 0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store 4) + FLAT_STORE_DWORD %0, %3, 0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store 4) + FLAT_STORE_DWORD %0, %4, 0, 0, 0, 0, implicit $exec, implicit $flat_scr :: (store 4) + $sgpr30_sgpr31 = COPY %9 + S_SETPC_B64_return $sgpr30_sgpr31