diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -3686,7 +3686,7 @@ auto Reg = mc2PseudoReg(Src0.getReg()); const MCRegisterInfo *TRI = getContext().getRegisterInfo(); - if (isSGPR(Reg, TRI)) { + if (!isGFX940() && isSGPR(Reg, TRI)) { Error(getRegLoc(Reg, Operands), "source operand must be either a VGPR or an inline constant"); return false; diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -385,14 +385,6 @@ return addOperand(Inst, DAsm->decodeOperand_SReg_32(Imm)); } -static DecodeStatus decodeOperand_VGPR_32(MCInst &Inst, - unsigned Imm, - uint64_t Addr, - const void *Decoder) { - auto DAsm = static_cast(Decoder); - return addOperand(Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW32, Imm)); -} - #define DECODE_SDWA(DecName) \ DECODE_OPERAND(decodeSDWA##DecName, decodeSDWA##DecName) 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 @@ -821,7 +821,8 @@ } if (RC == &AMDGPU::AGPR_32RegClass) { - if (AMDGPU::VGPR_32RegClass.contains(SrcReg)) { + if (AMDGPU::VGPR_32RegClass.contains(SrcReg) || + (ST.hasGFX940Insts() && AMDGPU::SReg_32RegClass.contains(SrcReg))) { BuildMI(MBB, MI, DL, get(AMDGPU::V_ACCVGPR_WRITE_B32_e64), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); return; @@ -947,7 +948,8 @@ if (RI.isAGPRClass(RC)) { if (ST.hasGFX90AInsts() && RI.isAGPRClass(SrcRC)) Opcode = AMDGPU::V_ACCVGPR_MOV_B32; - else if (RI.hasVGPRs(SrcRC)) + else if (RI.hasVGPRs(SrcRC) || + (ST.hasGFX940Insts() && RI.isSGPRClass(SrcRC))) Opcode = AMDGPU::V_ACCVGPR_WRITE_B32_e64; else Opcode = AMDGPU::INSTRUCTION_LIST_END; @@ -4650,6 +4652,16 @@ } } + if (MI.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64 && + !ST.hasGFX940Insts()) { + const MachineOperand *Src = getNamedOperand(MI, AMDGPU::OpName::src0); + if (Src->isReg() && RI.isSGPRReg(MRI, Src->getReg())) { + ErrInfo = "Invalid register class: " + "v_accvgpr_write with an SGPR is not supported on this GPU"; + return false; + } + } + if (Desc.getOpcode() == AMDGPU::G_AMDGPU_WAVE_ADDRESS) { const MachineOperand &SrcOp = MI.getOperand(1); if (!SrcOp.isReg() || SrcOp.getReg().isVirtual()) { @@ -5026,7 +5038,7 @@ RI.isAGPR(MRI, MI.getOperand(Data1Idx).getReg()) != IsAGPR) return false; } - if (Opc == AMDGPU::V_ACCVGPR_WRITE_B32_e64 && + if (Opc == AMDGPU::V_ACCVGPR_WRITE_B32_e64 && !ST.hasGFX940Insts() && (int)OpIdx == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0) && RI.isSGPRReg(MRI, MO->getReg())) return false; diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td --- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td @@ -370,7 +370,7 @@ def VOPProfileAccWrite : VOP3_Profile { let DstRC = ADst_32; - let Src0RC64 = VISrc_b32; + let Src0RC64 = VCSrc_b32; } class VOPProfileMAI&1 | FileCheck -check-prefix=GFX90A %s + +v_accvgpr_write_b32 a10, s20 +// GFX940: v_accvgpr_write_b32 a10, s20 ; encoding: [0x0a,0x40,0xd9,0xd3,0x14,0x00,0x00,0x18] +// GFX90A: error: source operand must be either a VGPR or an inline constant diff --git a/llvm/test/MC/Disassembler/AMDGPU/mai-gfx940.txt b/llvm/test/MC/Disassembler/AMDGPU/mai-gfx940.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AMDGPU/mai-gfx940.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc -arch=amdgcn -mcpu=gfx940 -show-encoding -disassemble %s | FileCheck -check-prefix=GFX940 %s + +# GFX940: v_accvgpr_write_b32 a10, s20 ; encoding: [0x0a,0x40,0xd9,0xd3,0x14,0x00,0x00,0x18] +0x0a,0x40,0xd9,0xd3,0x14,0x00,0x00,0x18