diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -35,6 +35,8 @@ #define DEBUG_TYPE "wasm-asm-parser" +static const char *getSubtargetFeatureName(uint64_t Val); + namespace { /// WebAssemblyOperand - Instances of this class represent the operands in a @@ -836,8 +838,9 @@ bool MatchingInlineAsm) override { MCInst Inst; Inst.setLoc(IDLoc); - unsigned MatchResult = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); + FeatureBitset MissingFeatures; + unsigned MatchResult = MatchInstructionImpl( + Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm); switch (MatchResult) { case Match_Success: { ensureLocals(Out); @@ -866,9 +869,17 @@ } return false; } - case Match_MissingFeature: - return Parser.Error( - IDLoc, "instruction requires a Wasm feature not currently enabled"); + case Match_MissingFeature: { + auto NumMissing = MissingFeatures.count(); + assert(NumMissing > 0 && "Expected missing features"); + SmallString<128> Message; + raw_svector_ostream OS(Message); + OS << "instruction requires:"; + for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) + if (MissingFeatures.test(i)) + OS << ' ' << getSubtargetFeatureName(i); + return Parser.Error(IDLoc, Message); + } case Match_MnemonicFail: return Parser.Error(IDLoc, "invalid instruction"); case Match_NearMisses: @@ -932,5 +943,6 @@ } #define GET_REGISTER_MATCHER +#define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION #include "WebAssemblyGenAsmMatcher.inc" diff --git a/llvm/test/MC/WebAssembly/missing-features.s b/llvm/test/MC/WebAssembly/missing-features.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/WebAssembly/missing-features.s @@ -0,0 +1,11 @@ +# RUN: not llvm-mc -triple=wasm32-unknown-unknown < %s 2>&1 | FileCheck %s + +# Check that missing features are named in the error message + +# CHECK: error: instruction requires: simd128 +needs_simd: + .functype needs_simd () -> (v128) + i32.const 42 + i32x4.splat + drop + end_function