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 @@ -1236,6 +1236,7 @@ public: enum X86MatchResultTy { Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY, + Match_NotPerfect, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "X86GenAsmMatcher.inc" }; @@ -4270,23 +4271,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"; @@ -3862,24 +3863,6 @@ } OS << "\n"; - // Verify the instruction with the target-specific match predicate function. - OS << " // We have a potential match. Check the target predicate to\n" - << " // handle any context sensitive constraints.\n" - << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" - << " Match_Success) {\n" - << " DEBUG_WITH_TYPE(\"asm-matcher\",\n" - << " dbgs() << \"Target match predicate failed with diag code \"\n" - << " << MatchResult << \"\\n\");\n" - << " Inst.clear();\n"; - if (ReportMultipleNearMisses) { - OS << " LatePredicateNearMiss = NearMissInfo::getMissedPredicate(MatchResult);\n"; - } else { - OS << " RetCode = MatchResult;\n" - << " HadMatchOtherThanPredicate = true;\n" - << " continue;\n"; - } - OS << " }\n\n"; - if (ReportMultipleNearMisses) { OS << " int NumNearMisses = ((int)(bool)OperandNearMiss +\n"; OS << " (int)(bool)FeaturesNearMiss +\n"; @@ -3931,12 +3914,42 @@ OS << "\n"; } + // Verify the instruction with the target-specific match predicate function. + OS << " // We have a potential match. Check the target predicate to\n" + << " // handle any context sensitive constraints.\n" + << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" + << " Match_Success) {\n" + << " DEBUG_WITH_TYPE(\"asm-matcher\",\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"; + } else { + OS << " RetCode = MatchResult;\n" + << " HadMatchOtherThanPredicate = true;\n" + << " continue;\n"; + } + OS << " }\n\n"; + OS << " DEBUG_WITH_TYPE(\n"; OS << " \"asm-matcher\",\n"; OS << " dbgs() << \"Opcode result: complete match, selecting this opcode\\n\");\n"; 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";