Index: llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1648,8 +1648,8 @@ bool validateDivScale(const MCInst &Inst); bool validateCoherencyBits(const MCInst &Inst, const OperandVector &Operands, const SMLoc &IDLoc); - bool validateFlatLdsDMA(const MCInst &Inst, const OperandVector &Operands, - const SMLoc &IDLoc); + bool validateLdsDMA(uint64_t Enc, const MCInst &Inst, + const OperandVector &Operands, const SMLoc &IDLoc); bool validateExeczVcczOperands(const OperandVector &Operands); Optional validateLdsDirect(const MCInst &Inst); unsigned getConstantBusLimit(unsigned Opcode) const; @@ -4487,25 +4487,31 @@ return true; } -bool AMDGPUAsmParser::validateFlatLdsDMA(const MCInst &Inst, - const OperandVector &Operands, - const SMLoc &IDLoc) { - if (isGFX940()) +bool AMDGPUAsmParser::validateLdsDMA(uint64_t Enc, const MCInst &Inst, + const OperandVector &Operands, + const SMLoc &IDLoc) { + assert(Enc == SIInstrFlags::FLAT || Enc == SIInstrFlags::MUBUF); + + // Exclude cases when there are separate DMA opcodes. + // In these cases, incorrect opcode selection is not possible. + if (Enc == SIInstrFlags::FLAT && isGFX940()) + return true; + if (Enc == SIInstrFlags::MUBUF && isGFX11Plus()) return true; uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags; - if ((TSFlags & (SIInstrFlags::VALU | SIInstrFlags::FLAT)) != - (SIInstrFlags::VALU | SIInstrFlags::FLAT)) + if ((TSFlags & (SIInstrFlags::VALU | Enc)) != + (SIInstrFlags::VALU | Enc)) return true; - // This is FLAT LDS DMA. + // This is FLAT/MUBUF LDS DMA. SMLoc S = getImmLoc(AMDGPUOperand::ImmTyLDS, Operands); StringRef CStr(S.getPointer()); if (!CStr.startswith("lds")) { - // This is incorrectly selected LDS DMA version of a FLAT load opcode. - // And LDS version should have 'lds' modifier, but it follows optional - // operands so its absense is ignored by the matcher. - Error(IDLoc, "invalid operands for instruction"); + // This is incorrectly selected LDS DMA version of a FLAT/MUBUF load + // opcode. And LDS version should have 'lds' modifier, but it follows + // optional operands so its absense is ignored by the matcher. + Error(IDLoc, "missing dst operand or lds modifier"); return false; } @@ -4643,7 +4649,11 @@ return false; } - if (!validateFlatLdsDMA(Inst, Operands, IDLoc)) { + if (!validateLdsDMA(SIInstrFlags::FLAT, Inst, Operands, IDLoc)) { + return false; + } + + if (!validateLdsDMA(SIInstrFlags::MUBUF, Inst, Operands, IDLoc)) { return false; } Index: llvm/test/MC/AMDGPU/gfx10_err_pos.s =================================================================== --- llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -989,6 +989,19 @@ // CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0) // CHECK-NEXT:{{^}} ^ +//============================================================================== +// missing dst operand or lds modifier + +buffer_load_dword off, s[8:11], s3 +// CHECK: error: missing dst operand or lds modifier +// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 +// CHECK-NEXT:{{^}}^ + +buffer_load_dword off, s[8:11], s3 offset:1 +// CHECK: error: missing dst operand or lds modifier +// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1 +// CHECK-NEXT:{{^}}^ + //============================================================================== // missing message operation Index: llvm/test/MC/AMDGPU/gfx9-asm-err.s =================================================================== --- llvm/test/MC/AMDGPU/gfx9-asm-err.s +++ llvm/test/MC/AMDGPU/gfx9-asm-err.s @@ -37,7 +37,7 @@ // GFX9ERR: error: instruction not supported on this GPU global_load_dword v[2:3], off -// GFX9ERR: error: invalid operands for instruction +// GFX9ERR: error: missing dst operand or lds modifier scratch_load_dword v2, off, offset:256 -// GFX9ERR: error: invalid operands for instruction +// GFX9ERR: error: missing dst operand or lds modifier Index: llvm/test/MC/AMDGPU/gfx9_err_pos.s =================================================================== --- llvm/test/MC/AMDGPU/gfx9_err_pos.s +++ llvm/test/MC/AMDGPU/gfx9_err_pos.s @@ -178,6 +178,19 @@ // CHECK-NEXT:{{^}}v_add_i16 v5, 0.5, v2 // CHECK-NEXT:{{^}} ^ +//============================================================================== +// missing dst operand or lds modifier + +buffer_load_dword off, s[8:11], s3 +// CHECK: error: missing dst operand or lds modifier +// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 +// CHECK-NEXT:{{^}}^ + +buffer_load_dword off, s[8:11], s3 offset:1 +// CHECK: error: missing dst operand or lds modifier +// CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1 +// CHECK-NEXT:{{^}}^ + //============================================================================== // r128 modifier is not supported on this GPU Index: llvm/test/MC/AMDGPU/mubuf.s =================================================================== --- llvm/test/MC/AMDGPU/mubuf.s +++ llvm/test/MC/AMDGPU/mubuf.s @@ -860,3 +860,9 @@ buffer_store_lds_dword s[4:7], s8 offset:4 tfe lds // NOSICI: error: instruction not supported on this GPU // NOVI: error: invalid operand for instruction + +buffer_load_dword off, s[8:11], s3 +// NOSICIVI: error: missing dst operand or lds modifier + +buffer_load_dword off, s[8:11], s3 offset:1 +// NOSICIVI: error: missing dst operand or lds modifier