diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h --- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -315,6 +315,7 @@ Match_MnemonicFail, Match_Success, Match_NearMisses, + Match_NotPerfect, FIRST_TARGET_MATCH_RESULT_TY }; diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -4270,23 +4270,13 @@ ForcedVEXEncoding != VEXEncoding_VEX3)) return Match_Unsupported; - // These instructions match ambiguously with their VEX encoded counterparts - // and appear first in the matching table. Reject them unless we're forcing - // EVEX encoding. - // FIXME: We really need a way to break the ambiguity. - switch (Opc) { - case X86::VCVTSD2SIZrm_Int: - case X86::VCVTSD2SI64Zrm_Int: - case X86::VCVTSS2SIZrm_Int: - case X86::VCVTSS2SI64Zrm_Int: - case X86::VCVTTSD2SIZrm: case X86::VCVTTSD2SIZrm_Int: - case X86::VCVTTSD2SI64Zrm: case X86::VCVTTSD2SI64Zrm_Int: - case X86::VCVTTSS2SIZrm: case X86::VCVTTSS2SIZrm_Int: - case X86::VCVTTSS2SI64Zrm: case X86::VCVTTSS2SI64Zrm_Int: - if (ForcedVEXEncoding != VEXEncoding_EVEX) - return Match_Unsupported; - break; - } + // We prefer vex encoding instead of evex by default. For some instructions + // evex instruction is ahead of vex in the matching table. We give a chance + // to match vex instruction for those cases (e.g. VCVTSD2SIZrm_Int, + // VCVTTSD2SIZrm, VCVTTSS2SI64Zrm). + if (ForcedVEXEncoding == VEXEncoding_Default && + (MCID.TSFlags & X86II::EncodingMask) == X86II::EVEX) + return Match_NotPerfect; return Match_Success; } diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -3544,6 +3544,7 @@ OS << " }\n\n"; } + OS << " SmallVector Candidates;\n"; // Emit code to get the available features. OS << " // Get the current feature set.\n"; OS << " const FeatureBitset &AvailableFeatures = getAvailableFeatures();\n\n"; @@ -3868,11 +3869,15 @@ << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" << " Match_Success) {\n" << " DEBUG_WITH_TYPE(\"asm-matcher\",\n" - << " dbgs() << \"Target match predicate failed with diag code \"\n" + << " dbgs() << \"Target match predicate failed with " + "diag code \"\n" << " << MatchResult << \"\\n\");\n" + << " if (MatchResult == Match_NotPerfect)\n" + << " Candidates.push_back(Inst);\n" << " Inst.clear();\n"; if (ReportMultipleNearMisses) { - OS << " LatePredicateNearMiss = NearMissInfo::getMissedPredicate(MatchResult);\n"; + OS << " LatePredicateNearMiss = " + "NearMissInfo::getMissedPredicate(MatchResult);\n"; } else { OS << " RetCode = MatchResult;\n" << " HadMatchOtherThanPredicate = true;\n" @@ -3937,6 +3942,14 @@ OS << " return Match_Success;\n"; OS << " }\n\n"; + OS << " if (!Candidates.empty()) {\n"; + OS << " // TODO Just pick up the lasted candidate, we can fine grain it " + "later\n"; + OS << " auto Candidate = Candidates.back();\n"; + OS << " Inst = Candidate;\n"; + OS << " return Match_Success;\n"; + OS << " }\n"; + if (ReportMultipleNearMisses) { OS << " // No instruction variants matched exactly.\n"; OS << " return Match_NearMisses;\n";