diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-12-20 18:52:57 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-12-20 18:52:57 +0000 |
commit | f7f59b529293136d0f711b86dbfccb525d0677d4 (patch) | |
tree | eec6b78bee4c3844d544d0f410d7fa333b9b8bd0 | |
parent | 75449671085b5d861e600c57937337c3857b9d75 (diff) | |
download | bcm5719-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.cpp | 17 | ||||
-rw-r--r-- | llvm/test/MC/AMDGPU/invalid-instructions-spellcheck.s | 48 | ||||
-rw-r--r-- | llvm/test/MC/AMDGPU/vop1-gfx9-err.s | 12 |
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 |