[llvm-branch-commits] [llvm] 55c557a - [AMDGPU][MC] Refactored parsing of dpp ctrl
Dmitry Preobrazhensky via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jan 18 07:19:17 PST 2021
Author: Dmitry Preobrazhensky
Date: 2021-01-18T18:14:19+03:00
New Revision: 55c557a5d25fd0f4db55fc4a406a1ea74594cfad
URL: https://github.com/llvm/llvm-project/commit/55c557a5d25fd0f4db55fc4a406a1ea74594cfad
DIFF: https://github.com/llvm/llvm-project/commit/55c557a5d25fd0f4db55fc4a406a1ea74594cfad.diff
LOG: [AMDGPU][MC] Refactored parsing of dpp ctrl
Summary of changes:
- simplified code to improve maintainability;
- replaced lex() with higher level parser functions;
- improved errors handling.
Reviewers: rampitec
Differential Revision: https://reviews.llvm.org/D94777
Added:
Modified:
llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
llvm/test/MC/AMDGPU/gfx10_err_pos.s
llvm/test/MC/AMDGPU/regression/bug28538.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 99e7c0e2d6b8..b10ea9ae99b7 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -1485,6 +1485,9 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseDim(OperandVector &Operands);
OperandMatchResultTy parseDPP8(OperandVector &Operands);
OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
+ bool isSupportedDPPCtrl(StringRef Ctrl, const OperandVector &Operands);
+ int64_t parseDPPCtrlSel(StringRef Ctrl);
+ int64_t parseDPPCtrlPerm();
AMDGPUOperand::Ptr defaultRowMask() const;
AMDGPUOperand::Ptr defaultBankMask() const;
AMDGPUOperand::Ptr defaultBoundCtrl() const;
@@ -4952,7 +4955,7 @@ bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
Error(getLoc(), Msg);
}
while (!trySkipToken(AsmToken::EndOfStatement)) {
- Parser.Lex();
+ lex();
}
return true;
}
@@ -7227,7 +7230,7 @@ OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) {
if (isToken(AsmToken::Integer)) {
SMLoc Loc = getToken().getEndLoc();
Token = std::string(getTokenStr());
- Parser.Lex();
+ lex();
if (getLoc() != Loc)
return MatchOperand_ParseFail;
}
@@ -7243,7 +7246,7 @@ OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) {
if (!DimInfo)
return MatchOperand_ParseFail;
- Parser.Lex();
+ lex();
Operands.push_back(AMDGPUOperand::CreateImm(this, DimInfo->Encoding, S,
AMDGPUOperand::ImmTyDim));
@@ -7287,116 +7290,138 @@ OperandMatchResultTy AMDGPUAsmParser::parseDPP8(OperandVector &Operands) {
return MatchOperand_Success;
}
-OperandMatchResultTy
-AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
+bool
+AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
+ const OperandVector &Operands) {
+ if (Ctrl == "row_share" ||
+ Ctrl == "row_xmask")
+ return isGFX10Plus();
+
+ if (Ctrl == "wave_shl" ||
+ Ctrl == "wave_shr" ||
+ Ctrl == "wave_rol" ||
+ Ctrl == "wave_ror" ||
+ Ctrl == "row_bcast")
+ return isVI() || isGFX9();
+
+ return Ctrl == "row_mirror" ||
+ Ctrl == "row_half_mirror" ||
+ Ctrl == "quad_perm" ||
+ Ctrl == "row_shl" ||
+ Ctrl == "row_shr" ||
+ Ctrl == "row_ror";
+}
+
+int64_t
+AMDGPUAsmParser::parseDPPCtrlPerm() {
+ // quad_perm:[%d,%d,%d,%d]
+
+ if (!skipToken(AsmToken::LBrac, "expected an opening square bracket"))
+ return -1;
+
+ int64_t Val = 0;
+ for (int i = 0; i < 4; ++i) {
+ if (i > 0 && !skipToken(AsmToken::Comma, "expected a comma"))
+ return -1;
+
+ int64_t Temp;
+ SMLoc Loc = getLoc();
+ if (getParser().parseAbsoluteExpression(Temp))
+ return -1;
+ if (Temp < 0 || Temp > 3) {
+ Error(Loc, "expected a 2-bit value");
+ return -1;
+ }
+
+ Val += (Temp << i * 2);
+ }
+
+ if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
+ return -1;
+
+ return Val;
+}
+
+int64_t
+AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
using namespace AMDGPU::DPP;
- SMLoc S = getLoc();
- StringRef Prefix;
- int64_t Int;
+ // sel:%d
- if (isToken(AsmToken::Identifier)) {
- Prefix = getTokenStr();
+ int64_t Val;
+ SMLoc Loc = getLoc();
+
+ if (getParser().parseAbsoluteExpression(Val))
+ return -1;
+
+ struct DppCtrlCheck {
+ int64_t Ctrl;
+ int Lo;
+ int Hi;
+ };
+
+ DppCtrlCheck Check = StringSwitch<DppCtrlCheck>(Ctrl)
+ .Case("wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
+ .Case("wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
+ .Case("wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
+ .Case("wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
+ .Case("row_shl", {DppCtrl::ROW_SHL0, 1, 15})
+ .Case("row_shr", {DppCtrl::ROW_SHR0, 1, 15})
+ .Case("row_ror", {DppCtrl::ROW_ROR0, 1, 15})
+ .Case("row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
+ .Case("row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
+ .Default({-1});
+
+ bool Valid;
+ if (Check.Ctrl == -1) {
+ Valid = (Ctrl == "row_bcast" && (Val == 15 || Val == 31));
+ Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
} else {
- return MatchOperand_NoMatch;
+ Valid = Check.Lo <= Val && Val <= Check.Hi;
+ Val = (Check.Lo == Check.Hi) ? Check.Ctrl : (Check.Ctrl | Val);
}
- if (Prefix == "row_mirror") {
- Int = DppCtrl::ROW_MIRROR;
- Parser.Lex();
- } else if (Prefix == "row_half_mirror") {
- Int = DppCtrl::ROW_HALF_MIRROR;
- Parser.Lex();
- } else {
- // Check to prevent parseDPPCtrlOps from eating invalid tokens
- if (Prefix != "quad_perm"
- && Prefix != "row_shl"
- && Prefix != "row_shr"
- && Prefix != "row_ror"
- && Prefix != "wave_shl"
- && Prefix != "wave_rol"
- && Prefix != "wave_shr"
- && Prefix != "wave_ror"
- && Prefix != "row_bcast"
- && Prefix != "row_share"
- && Prefix != "row_xmask") {
- return MatchOperand_NoMatch;
- }
-
- if (!isGFX10Plus() && (Prefix == "row_share" || Prefix == "row_xmask"))
- return MatchOperand_NoMatch;
-
- if (!isVI() && !isGFX9() &&
- (Prefix == "wave_shl" || Prefix == "wave_shr" ||
- Prefix == "wave_rol" || Prefix == "wave_ror" ||
- Prefix == "row_bcast"))
- return MatchOperand_NoMatch;
-
- Parser.Lex();
- if (!isToken(AsmToken::Colon))
- return MatchOperand_ParseFail;
+ if (!Valid) {
+ Error(Loc, Twine("invalid ", Ctrl) + Twine(" value"));
+ return -1;
+ }
- if (Prefix == "quad_perm") {
- // quad_perm:[%d,%d,%d,%d]
- Parser.Lex();
- if (!trySkipToken(AsmToken::LBrac))
- return MatchOperand_ParseFail;
+ return Val;
+}
- if (getParser().parseAbsoluteExpression(Int) || !(0 <= Int && Int <=3))
- return MatchOperand_ParseFail;
+OperandMatchResultTy
+AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
+ using namespace AMDGPU::DPP;
- for (int i = 0; i < 3; ++i) {
- if (!trySkipToken(AsmToken::Comma))
- return MatchOperand_ParseFail;
+ if (!isToken(AsmToken::Identifier) ||
+ !isSupportedDPPCtrl(getTokenStr(), Operands))
+ return MatchOperand_NoMatch;
- int64_t Temp;
- if (getParser().parseAbsoluteExpression(Temp) || !(0 <= Temp && Temp <=3))
- return MatchOperand_ParseFail;
- const int shift = i*2 + 2;
- Int += (Temp << shift);
- }
+ SMLoc S = getLoc();
+ int64_t Val = -1;
+ StringRef Ctrl;
- if (!trySkipToken(AsmToken::RBrac))
- return MatchOperand_ParseFail;
- } else {
- // sel:%d
- Parser.Lex();
- if (getParser().parseAbsoluteExpression(Int))
- return MatchOperand_ParseFail;
+ parseId(Ctrl);
- if (Prefix == "row_shl" && 1 <= Int && Int <= 15) {
- Int |= DppCtrl::ROW_SHL0;
- } else if (Prefix == "row_shr" && 1 <= Int && Int <= 15) {
- Int |= DppCtrl::ROW_SHR0;
- } else if (Prefix == "row_ror" && 1 <= Int && Int <= 15) {
- Int |= DppCtrl::ROW_ROR0;
- } else if (Prefix == "wave_shl" && 1 == Int) {
- Int = DppCtrl::WAVE_SHL1;
- } else if (Prefix == "wave_rol" && 1 == Int) {
- Int = DppCtrl::WAVE_ROL1;
- } else if (Prefix == "wave_shr" && 1 == Int) {
- Int = DppCtrl::WAVE_SHR1;
- } else if (Prefix == "wave_ror" && 1 == Int) {
- Int = DppCtrl::WAVE_ROR1;
- } else if (Prefix == "row_bcast") {
- if (Int == 15) {
- Int = DppCtrl::BCAST15;
- } else if (Int == 31) {
- Int = DppCtrl::BCAST31;
- } else {
- return MatchOperand_ParseFail;
- }
- } else if (Prefix == "row_share" && 0 <= Int && Int <= 15) {
- Int |= DppCtrl::ROW_SHARE_FIRST;
- } else if (Prefix == "row_xmask" && 0 <= Int && Int <= 15) {
- Int |= DppCtrl::ROW_XMASK_FIRST;
+ if (Ctrl == "row_mirror") {
+ Val = DppCtrl::ROW_MIRROR;
+ } else if (Ctrl == "row_half_mirror") {
+ Val = DppCtrl::ROW_HALF_MIRROR;
+ } else {
+ if (skipToken(AsmToken::Colon, "expected a colon")) {
+ if (Ctrl == "quad_perm") {
+ Val = parseDPPCtrlPerm();
} else {
- return MatchOperand_ParseFail;
+ Val = parseDPPCtrlSel(Ctrl);
}
}
}
- Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, AMDGPUOperand::ImmTyDppCtrl));
+ if (Val == -1)
+ return MatchOperand_ParseFail;
+
+ Operands.push_back(
+ AMDGPUOperand::CreateImm(this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
return MatchOperand_Success;
}
diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s
index ae8e95105c33..cb4f9ae91153 100644
--- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s
+++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s
@@ -115,6 +115,19 @@ s_atomic_swap s5, s[2:3], 0x1FFFFF
// CHECK-NEXT:{{^}}s_atomic_swap s5, s[2:3], 0x1FFFFF
// CHECK-NEXT:{{^}} ^
+//==============================================================================
+// expected a 2-bit value
+
+v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,4] row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected a 2-bit value
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,4] row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
+v_mov_b32_dpp v5, v1 quad_perm:[3,-1,1,3] row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected a 2-bit value
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,-1,1,3] row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// expected a 3-bit value
@@ -210,6 +223,11 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}} ^
+v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,0) row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected a closing square bracket
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,0) row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// expected a colon
@@ -251,6 +269,11 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6]
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6]
// CHECK-NEXT:{{^}} ^
+v_mov_b32_dpp v5, v1 quad_perm:[3,2] row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected a comma
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2] row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// expected a comma or a closing parenthesis
@@ -379,6 +402,16 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,x,4,5,6,7]
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,x,4,5,6,7]
// CHECK-NEXT:{{^}} ^
+v_mov_b32_dpp v5, v1 quad_perm:[3,x,1,0] row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected absolute expression
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,x,1,0] row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
+v_mov_b32_dpp v5, v1 row_share:x row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected absolute expression
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:x row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// expected a message name or an absolute expression
@@ -458,6 +491,11 @@ v_mov_b32_dpp v5, v1 dpp8:(0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:(0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}} ^
+v_mov_b32_dpp v5, v1 quad_perm:(3,2,1,0) row_mask:0x0 bank_mask:0x0
+// CHECK: error: expected an opening square bracket
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:(3,2,1,0) row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// expected an operation name or an absolute expression
@@ -800,6 +838,19 @@ s_mov_b64 s[10:11], [x0,s1]
// CHECK-NEXT:{{^}}s_mov_b64 s[10:11], [x0,s1]
// CHECK-NEXT:{{^}} ^
+//==============================================================================
+// invalid row_share value
+
+v_mov_b32_dpp v5, v1 row_share:16 row_mask:0x0 bank_mask:0x0
+// CHECK: error: invalid row_share value
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:16 row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
+v_mov_b32_dpp v5, v1 row_share:-1 row_mask:0x0 bank_mask:0x0
+// CHECK: error: invalid row_share value
+// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:-1 row_mask:0x0 bank_mask:0x0
+// CHECK-NEXT:{{^}} ^
+
//==============================================================================
// invalid syntax, expected 'neg' modifier
diff --git a/llvm/test/MC/AMDGPU/regression/bug28538.s b/llvm/test/MC/AMDGPU/regression/bug28538.s
index 64fa1585d114..d5633ed272da 100644
--- a/llvm/test/MC/AMDGPU/regression/bug28538.s
+++ b/llvm/test/MC/AMDGPU/regression/bug28538.s
@@ -4,9 +4,9 @@
// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire %s 2>&1 | FileCheck %s --check-prefix=NOSICI --implicit-check-not=error:
// NOSICI: error: not a valid operand.
-// NOVI: error: failed parsing operand
+// NOVI: error: invalid row_bcast value
v_mov_b32 v0, v0 row_bcast:0
// NOSICI: error: not a valid operand.
-// NOVI: error: failed parsing operand
+// NOVI: error: invalid row_bcast value
v_mov_b32 v0, v0 row_bcast:13
More information about the llvm-branch-commits
mailing list