[AMDGPU][MC] Corrected error position for hwreg() and sendmsg()

Partially fixes bug 47518 (https://bugs.llvm.org/show_bug.cgi?id=47518)

Reviewers: rampitec

Differential Revision: https://reviews.llvm.org/D91407
This commit is contained in:
Dmitry Preobrazhensky 2020-11-16 14:23:29 +03:00
parent 58abbf821c
commit 89df8fc0d7
2 changed files with 75 additions and 53 deletions

View File

@ -1330,6 +1330,7 @@ public:
private:
struct OperandInfoTy {
SMLoc Loc;
int64_t Id;
bool IsSymbolic = false;
bool IsDefined = false;
@ -1340,14 +1341,14 @@ private:
bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream);
bool validateSendMsg(const OperandInfoTy &Msg,
const OperandInfoTy &Op,
const OperandInfoTy &Stream,
const SMLoc Loc);
const OperandInfoTy &Stream);
bool parseHwregBody(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width);
bool parseHwregBody(OperandInfoTy &HwReg,
OperandInfoTy &Offset,
OperandInfoTy &Width);
bool validateHwreg(const OperandInfoTy &HwReg,
const int64_t Offset,
const int64_t Width,
const SMLoc Loc);
const OperandInfoTy &Offset,
const OperandInfoTy &Width);
OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
SMLoc getFlatOffsetLoc(const OperandVector &Operands) const;
@ -5582,11 +5583,12 @@ AMDGPUOperand::isSWaitCnt() const {
bool
AMDGPUAsmParser::parseHwregBody(OperandInfoTy &HwReg,
int64_t &Offset,
int64_t &Width) {
OperandInfoTy &Offset,
OperandInfoTy &Width) {
using namespace llvm::AMDGPU::Hwreg;
// The register may be specified by name or using a numeric code
HwReg.Loc = getLoc();
if (isToken(AsmToken::Identifier) &&
(HwReg.Id = getHwregId(getTokenStr())) >= 0) {
HwReg.IsSymbolic = true;
@ -5599,33 +5601,45 @@ AMDGPUAsmParser::parseHwregBody(OperandInfoTy &HwReg,
return true;
// parse optional params
return
skipToken(AsmToken::Comma, "expected a comma or a closing parenthesis") &&
parseExpr(Offset) &&
skipToken(AsmToken::Comma, "expected a comma") &&
parseExpr(Width) &&
skipToken(AsmToken::RParen, "expected a closing parenthesis");
if (!skipToken(AsmToken::Comma, "expected a comma or a closing parenthesis"))
return false;
Offset.Loc = getLoc();
if (!parseExpr(Offset.Id))
return false;
if (!skipToken(AsmToken::Comma, "expected a comma"))
return false;
Width.Loc = getLoc();
return parseExpr(Width.Id) &&
skipToken(AsmToken::RParen, "expected a closing parenthesis");
}
bool
AMDGPUAsmParser::validateHwreg(const OperandInfoTy &HwReg,
const int64_t Offset,
const int64_t Width,
const SMLoc Loc) {
const OperandInfoTy &Offset,
const OperandInfoTy &Width) {
using namespace llvm::AMDGPU::Hwreg;
if (HwReg.IsSymbolic && !isValidHwreg(HwReg.Id, getSTI())) {
Error(Loc, "specified hardware register is not supported on this GPU");
Error(HwReg.Loc,
"specified hardware register is not supported on this GPU");
return false;
} else if (!isValidHwreg(HwReg.Id)) {
Error(Loc, "invalid code of hardware register: only 6-bit values are legal");
}
if (!isValidHwreg(HwReg.Id)) {
Error(HwReg.Loc,
"invalid code of hardware register: only 6-bit values are legal");
return false;
} else if (!isValidHwregOffset(Offset)) {
Error(Loc, "invalid bit offset: only 5-bit values are legal");
}
if (!isValidHwregOffset(Offset.Id)) {
Error(Offset.Loc, "invalid bit offset: only 5-bit values are legal");
return false;
} else if (!isValidHwregWidth(Width)) {
Error(Loc, "invalid bitfield width: only values from 1 to 32 are legal");
}
if (!isValidHwregWidth(Width.Id)) {
Error(Width.Loc,
"invalid bitfield width: only values from 1 to 32 are legal");
return false;
}
return true;
@ -5640,11 +5654,11 @@ AMDGPUAsmParser::parseHwreg(OperandVector &Operands) {
if (trySkipId("hwreg", AsmToken::LParen)) {
OperandInfoTy HwReg(ID_UNKNOWN_);
int64_t Offset = OFFSET_DEFAULT_;
int64_t Width = WIDTH_DEFAULT_;
OperandInfoTy Offset(OFFSET_DEFAULT_);
OperandInfoTy Width(WIDTH_DEFAULT_);
if (parseHwregBody(HwReg, Offset, Width) &&
validateHwreg(HwReg, Offset, Width, Loc)) {
ImmVal = encodeHwreg(HwReg.Id, Offset, Width);
validateHwreg(HwReg, Offset, Width)) {
ImmVal = encodeHwreg(HwReg.Id, Offset.Id, Width.Id);
} else {
return MatchOperand_ParseFail;
}
@ -5675,6 +5689,7 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
OperandInfoTy &Stream) {
using namespace llvm::AMDGPU::SendMsg;
Msg.Loc = getLoc();
if (isToken(AsmToken::Identifier) && (Msg.Id = getMsgId(getTokenStr())) >= 0) {
Msg.IsSymbolic = true;
lex(); // skip message name
@ -5684,6 +5699,7 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
if (trySkipToken(AsmToken::Comma)) {
Op.IsDefined = true;
Op.Loc = getLoc();
if (isToken(AsmToken::Identifier) &&
(Op.Id = getMsgOpId(Msg.Id, getTokenStr())) >= 0) {
lex(); // skip operation name
@ -5693,6 +5709,7 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
if (trySkipToken(AsmToken::Comma)) {
Stream.IsDefined = true;
Stream.Loc = getLoc();
if (!parseExpr(Stream.Id))
return false;
}
@ -5704,8 +5721,7 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
bool
AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
const OperandInfoTy &Op,
const OperandInfoTy &Stream,
const SMLoc S) {
const OperandInfoTy &Stream) {
using namespace llvm::AMDGPU::SendMsg;
// Validation strictness depends on whether message is specified
@ -5714,21 +5730,27 @@ AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
bool Strict = Msg.IsSymbolic;
if (!isValidMsgId(Msg.Id, getSTI(), Strict)) {
Error(S, "invalid message id");
Error(Msg.Loc, "invalid message id");
return false;
} else if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) {
Error(S, Op.IsDefined ?
"message does not support operations" :
"missing message operation");
}
if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) {
if (Op.IsDefined) {
Error(Op.Loc, "message does not support operations");
} else {
Error(Msg.Loc, "missing message operation");
}
return false;
} else if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) {
Error(S, "invalid operation id");
}
if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) {
Error(Op.Loc, "invalid operation id");
return false;
} else if (Strict && !msgSupportsStream(Msg.Id, Op.Id) && Stream.IsDefined) {
Error(S, "message operation does not support streams");
}
if (Strict && !msgSupportsStream(Msg.Id, Op.Id) && Stream.IsDefined) {
Error(Stream.Loc, "message operation does not support streams");
return false;
} else if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) {
Error(S, "invalid message stream id");
}
if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) {
Error(Stream.Loc, "invalid message stream id");
return false;
}
return true;
@ -5746,7 +5768,7 @@ AMDGPUAsmParser::parseSendMsgOp(OperandVector &Operands) {
OperandInfoTy Op(OP_NONE_);
OperandInfoTy Stream(STREAM_ID_NONE_);
if (parseSendMsgBody(Msg, Op, Stream) &&
validateSendMsg(Msg, Op, Stream, Loc)) {
validateSendMsg(Msg, Op, Stream)) {
ImmVal = encodeMsg(Msg.Id, Op.Id, Stream.Id);
} else {
return MatchOperand_ParseFail;

View File

@ -485,7 +485,7 @@ s_cbranch_join 1
s_getreg_b32 s2, hwreg(3,32,32)
// CHECK: error: invalid bit offset: only 5-bit values are legal
// CHECK-NEXT:{{^}}s_getreg_b32 s2, hwreg(3,32,32)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid bitfield width: only values from 1 to 32 are legal
@ -493,7 +493,7 @@ s_getreg_b32 s2, hwreg(3,32,32)
s_setreg_b32 hwreg(3,0,33), s2
// CHECK: error: invalid bitfield width: only values from 1 to 32 are legal
// CHECK-NEXT:{{^}}s_setreg_b32 hwreg(3,0,33), s2
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid code of hardware register: only 6-bit values are legal
@ -501,7 +501,7 @@ s_setreg_b32 hwreg(3,0,33), s2
s_setreg_b32 hwreg(0x40), s2
// CHECK: error: invalid code of hardware register: only 6-bit values are legal
// CHECK-NEXT:{{^}}s_setreg_b32 hwreg(0x40), s2
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid counter name x
@ -567,7 +567,7 @@ ds_swizzle_b32 v8, v2 offset:swizzle(BITMASK_PERM, "pppi2")
s_sendmsg sendmsg(-1)
// CHECK: error: invalid message id
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(-1)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid message stream id
@ -575,12 +575,12 @@ s_sendmsg sendmsg(-1)
s_sendmsg sendmsg(2, 2, 4)
// CHECK: error: invalid message stream id
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(2, 2, 4)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4)
// CHECK: error: invalid message stream id
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid mul value.
@ -648,7 +648,7 @@ v_cmp_eq_f32 s[0:1], private_base, s0
s_sendmsg sendmsg(15, -1)
// CHECK: error: invalid operation id
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(15, -1)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid or unsupported register size
@ -717,7 +717,7 @@ ds_swizzle_b32 v8, v2 offset:swizzle(BROADCAST,2,-1)
s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0)
// CHECK: error: message does not support operations
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// message operation does not support streams
@ -725,7 +725,7 @@ s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0)
s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
// CHECK: error: message operation does not support streams
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// missing message operation
@ -733,7 +733,7 @@ s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0)
s_sendmsg sendmsg(MSG_SYSMSG)
// CHECK: error: missing message operation
// CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_SYSMSG)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// missing register index
@ -874,7 +874,7 @@ v_movrels_b32_sdwa v0, 1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD
s_getreg_b32 s2, hwreg(HW_REG_SHADER_CYCLES)
// CHECK: error: specified hardware register is not supported on this GPU
// CHECK-NEXT:{{^}}s_getreg_b32 s2, hwreg(HW_REG_SHADER_CYCLES)
// CHECK-NEXT:{{^}} ^
// CHECK-NEXT:{{^}} ^
//==============================================================================
// too few operands for instruction