summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2017-12-20 18:52:57 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2017-12-20 18:52:57 +0000
commitf7f59b529293136d0f711b86dbfccb525d0677d4 (patch)
treeeec6b78bee4c3844d544d0f410d7fa333b9b8bd0
parent75449671085b5d861e600c57937337c3857b9d75 (diff)
downloadbcm5719-llvm-f7f59b529293136d0f711b86dbfccb525d0677d4.tar.gz
bcm5719-llvm-f7f59b529293136d0f711b86dbfccb525d0677d4.zip
[AMDGPU, AsmParser] Enable the mnemonic spell corrector.
Patch by Dmitry Venikov llvm-svn: 321202
-rw-r--r--llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp17
-rw-r--r--llvm/test/MC/AMDGPU/invalid-instructions-spellcheck.s48
-rw-r--r--llvm/test/MC/AMDGPU/vop1-gfx9-err.s12
3 files changed, 70 insertions, 7 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 2acd7f78fae..02ccfe852e1 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -536,6 +536,10 @@ public:
return EndLoc;
}
+ SMRange getLocRange() const {
+ return SMRange(StartLoc, EndLoc);
+ }
+
Modifiers getModifiers() const {
assert(isRegKind() || isImmTy(ImmTyNone));
return isRegKind() ? Reg.Mods : Imm.Mods;
@@ -2244,6 +2248,9 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
return true;
}
+static std::string AMDGPUMnemonicSpellCheck(StringRef S, uint64_t FBS,
+ unsigned VariantID = 0);
+
bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out,
@@ -2286,8 +2293,13 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_MissingFeature:
return Error(IDLoc, "instruction not supported on this GPU");
- case Match_MnemonicFail:
- return Error(IDLoc, "unrecognized instruction mnemonic");
+ case Match_MnemonicFail: {
+ uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
+ std::string Suggestion = AMDGPUMnemonicSpellCheck(
+ ((AMDGPUOperand &)*Operands[0]).getToken(), FBS);
+ return Error(IDLoc, "invalid instruction" + Suggestion,
+ ((AMDGPUOperand &)*Operands[0]).getLocRange());
+ }
case Match_InvalidOperand: {
SMLoc ErrorLoc = IDLoc;
@@ -4786,6 +4798,7 @@ extern "C" void LLVMInitializeAMDGPUAsmParser() {
#define GET_REGISTER_MATCHER
#define GET_MATCHER_IMPLEMENTATION
+#define GET_MNEMONIC_SPELL_CHECKER
#include "AMDGPUGenAsmMatcher.inc"
// This fuction should be defined after auto-generated include so that we have
diff --git a/llvm/test/MC/AMDGPU/invalid-instructions-spellcheck.s b/llvm/test/MC/AMDGPU/invalid-instructions-spellcheck.s
new file mode 100644
index 00000000000..f4198f10f4b
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/invalid-instructions-spellcheck.s
@@ -0,0 +1,48 @@
+# RUN: not llvm-mc -triple amdgcn < %s 2>&1 | FileCheck %s
+
+# This tests the mnemonic spell checker.
+
+# First check what happens when an instruction is omitted:
+
+v2, v4, v6
+
+# CHECK: unknown token in expression
+# CHECK-NEXT: v2, v4, v6
+# CHECK-NEXT: ^
+
+# CHECK: error: not a valid operand.
+# CHECK-NEXT: v2, v4, v6
+# CHECK-NEXT: ^
+
+# We don't want to see a suggestion here; the edit distance is too large to
+# give sensible suggestions:
+
+aaaaaaaaaaaaaaa v1, v2, v3
+
+# CHECK: error: invalid instruction
+# CHECK-NEXT: aaaaaaaaaaaaaaa v1, v2, v3
+# CHECK-NEXT: ^
+
+# Check that we get one suggestion: 'dsc_write_src2_b64' is 1 edit away, i.e. an deletion.
+
+dsc_write_src2_b64 v1, v2, v3
+
+# CHECK: error: invalid instruction, did you mean: ds_write_src2_b64?
+# CHECK-NEXT: dsc_write_src2_b64 v1, v2, v3
+# CHECK-NEXT: ^
+
+# Check edit distance 1 and 2, just insertions:
+
+s_mov_b v1, v2
+
+# CHECK: error: invalid instruction, did you mean: s_mov_b32, s_mov_b64?
+# CHECK-NEXT: s_mov_b v1, v2
+# CHECK-NEXT: ^
+
+# Check an instruction that is 2 edits away, and also has a lot of candidates:
+
+s_load_dwordx v1, v2, v3
+
+# CHECK: error: invalid instruction, did you mean: s_load_dword, s_load_dwordx16, s_load_dwordx2, s_load_dwordx4, s_load_dwordx8?
+# CHECK-NEXT: s_load_dwordx v1, v2, v3
+# CHECK-NEXT: ^
diff --git a/llvm/test/MC/AMDGPU/vop1-gfx9-err.s b/llvm/test/MC/AMDGPU/vop1-gfx9-err.s
index 0036b79c71b..61bf5f66175 100644
--- a/llvm/test/MC/AMDGPU/vop1-gfx9-err.s
+++ b/llvm/test/MC/AMDGPU/vop1-gfx9-err.s
@@ -1,6 +1,6 @@
-// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN %s
-// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN %s
-// RUN: not llvm-mc -arch=amdgcn -mcpu=hawaii -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN %s
+// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck -check-prefixes=GCN,GFX9 %s
+// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck -check-prefixes=GCN,VI %s
+// RUN: not llvm-mc -arch=amdgcn -mcpu=hawaii -show-encoding %s 2>&1 | FileCheck -check-prefixes=GCN,CI %s
v_swap_b32 v1, 1
// GCN: :16: error: invalid operand for instruction
@@ -10,7 +10,9 @@ v_swap_b32 v1, s0
// FIXME: Better error for it requiring VOP1 encoding
v_swap_b32_e64 v1, v2
-// GCN: :1: error: unrecognized instruction mnemonic
+// GFX9: :1: error: invalid instruction, did you mean: v_swap_b32?
+// CI: :1: error: invalid instruction
+// VI: :1: error: invalid instruction
v_swap_b32 v1, v2, v1
// GCN: :20: error: invalid operand for instruction
@@ -22,4 +24,4 @@ v_swap_b32 v1, v2, v2, v2
// GCN: :20: error: invalid operand for instruction
v_swap_codegen_pseudo_b32 v1, v2
-// GCN: :1: error: unrecognized instruction mnemonic
+// GCN: :1: error: invalid instruction
OpenPOWER on IntegriCloud