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 @@ -1483,6 +1483,7 @@ void cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands); void cvtIntersectRay(MCInst &Inst, const OperandVector &Operands); + bool parseDimId(unsigned &Encoding); OperandMatchResultTy parseDim(OperandVector &Operands); OperandMatchResultTy parseDPP8(OperandVector &Operands); OperandMatchResultTy parseDPPCtrl(OperandVector &Operands); @@ -7177,44 +7178,64 @@ return isImm() && isUInt<16>(getImm()); } -OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) { - if (!isGFX10Plus()) - return MatchOperand_NoMatch; - - SMLoc S = getLoc(); - - if (!trySkipId("dim", AsmToken::Colon)) - return MatchOperand_NoMatch; +//===----------------------------------------------------------------------===// +// dim +//===----------------------------------------------------------------------===// - // We want to allow "dim:1D" etc., but the initial 1 is tokenized as an - // integer. +bool AMDGPUAsmParser::parseDimId(unsigned &Encoding) { + // We want to allow "dim:1D" etc., + // but the initial 1 is tokenized as an integer. std::string Token; if (isToken(AsmToken::Integer)) { SMLoc Loc = getToken().getEndLoc(); Token = std::string(getTokenStr()); lex(); if (getLoc() != Loc) - return MatchOperand_ParseFail; + return false; } - if (!isToken(AsmToken::Identifier)) - return MatchOperand_ParseFail; - Token += getTokenStr(); + + StringRef Suffix; + if (!parseId(Suffix)) + return false; + Token += Suffix; StringRef DimId = Token; if (DimId.startswith("SQ_RSRC_IMG_")) - DimId = DimId.substr(12); + DimId = DimId.drop_front(12); const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByAsmSuffix(DimId); if (!DimInfo) - return MatchOperand_ParseFail; + return false; + + Encoding = DimInfo->Encoding; + return true; +} + +OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) { + if (!isGFX10Plus()) + return MatchOperand_NoMatch; + + SMLoc S = getLoc(); + + if (!trySkipId("dim", AsmToken::Colon)) + return MatchOperand_NoMatch; - lex(); + unsigned Encoding; + SMLoc Loc = getLoc(); + if (!parseDimId(Encoding)) { + Error(Loc, "invalid dim value"); + return MatchOperand_ParseFail; + } - Operands.push_back(AMDGPUOperand::CreateImm(this, DimInfo->Encoding, S, + Operands.push_back(AMDGPUOperand::CreateImm(this, Encoding, S, AMDGPUOperand::ImmTyDim)); return MatchOperand_Success; } +//===----------------------------------------------------------------------===// +// dpp +//===----------------------------------------------------------------------===// + OperandMatchResultTy AMDGPUAsmParser::parseDPP8(OperandVector &Operands) { SMLoc S = getLoc(); diff --git a/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s b/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s --- a/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s +++ b/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s @@ -35,4 +35,4 @@ // NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: image address size does not match dim and a16 image_load v[0:1], v0, s[0:7] dmask:0x9 dim:1 D -// NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: failed parsing operand +// NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: invalid dim value diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -548,21 +548,11 @@ //============================================================================== // failed parsing operand. -image_load v[0:1], v0, s[0:7] dmask:0x9 dim:1 D -// CHECK: error: failed parsing operand. -// CHECK-NEXT:{{^}}image_load v[0:1], v0, s[0:7] dmask:0x9 dim:1 D -// CHECK-NEXT:{{^}} ^ - v_ceil_f16 v0, abs(neg(1)) // CHECK: error: failed parsing operand. // CHECK-NEXT:{{^}}v_ceil_f16 v0, abs(neg(1)) // CHECK-NEXT:{{^}} ^ -image_atomic_xor v4, v32, s[96:103] dmask:0x1 dim:, glc -// CHECK: error: failed parsing operand. -// CHECK-NEXT:{{^}}image_atomic_xor v4, v32, s[96:103] dmask:0x1 dim:, glc -// CHECK-NEXT:{{^}} ^ - //============================================================================== // first register index should not exceed second index @@ -669,6 +659,24 @@ // CHECK-NEXT:{{^}}s_waitcnt vmcnt(0) & expcnt(0) x(0) // CHECK-NEXT:{{^}} ^ +//============================================================================== +// invalid dim value + +image_load v[0:1], v0, s[0:7] dmask:0x9 dim:1 D +// CHECK: error: invalid dim value +// CHECK-NEXT:{{^}}image_load v[0:1], v0, s[0:7] dmask:0x9 dim:1 D +// CHECK-NEXT:{{^}} ^ + +image_atomic_xor v4, v32, s[96:103] dmask:0x1 dim:, glc +// CHECK: error: invalid dim value +// CHECK-NEXT:{{^}}image_atomic_xor v4, v32, s[96:103] dmask:0x1 dim:, glc +// CHECK-NEXT:{{^}} ^ + +image_load v[0:1], v0, s[0:7] dmask:0x9 dim:7D +// CHECK: error: invalid dim value +// CHECK-NEXT:{{^}}image_load v[0:1], v0, s[0:7] dmask:0x9 dim:7D +// CHECK-NEXT:{{^}} ^ + //============================================================================== // invalid dst_sel value