diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt --- a/llvm/lib/Target/X86/CMakeLists.txt +++ b/llvm/lib/Target/X86/CMakeLists.txt @@ -19,7 +19,7 @@ tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) if (X86_GEN_FOLD_TABLES) - tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables) + tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1) endif() add_public_tablegen_target(X86CommonTableGen) diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp --- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp +++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp @@ -317,15 +317,26 @@ // matches the EVEX instruction of this object. class IsMatch { const CodeGenInstruction *MemInst; + unsigned Variant; public: - IsMatch(const CodeGenInstruction *Inst, const RecordKeeper &Records) - : MemInst(Inst) {} + IsMatch(const CodeGenInstruction *Inst, unsigned V) + : MemInst(Inst), Variant(V) {} bool operator()(const CodeGenInstruction *RegInst) { Record *MemRec = MemInst->TheDef; Record *RegRec = RegInst->TheDef; + // X86 encoding is crazy, e.g + // + // f3 0f c7 30 vmxon (%rax) + // f3 0f c7 f0 senduipi %rax + // + // This two instruction have similiar encoding fileds but are unrelated + if (X86Disassembler::getMnemonic(MemInst, Variant) != + X86Disassembler::getMnemonic(RegInst, Variant)) + return false; + // Return false if one (at least) of the encoding fields of both // instructions do not match. if (RegRec->getValueAsDef("OpEnc") != MemRec->getValueAsDef("OpEnc") || @@ -616,6 +627,8 @@ } } + Record *AsmWriter = Target.getAsmWriter(); + unsigned Variant = AsmWriter->getValueAsInt("Variant"); // For each memory form instruction, try to find its register form // instruction. for (const CodeGenInstruction *MemInst : MemInsts) { @@ -631,7 +644,7 @@ // opcode. std::vector &OpcRegInsts = RegInstsIt->second; - auto Match = find_if(OpcRegInsts, IsMatch(MemInst, Records)); + auto Match = find_if(OpcRegInsts, IsMatch(MemInst, Variant)); if (Match != OpcRegInsts.end()) { const CodeGenInstruction *RegInst = *Match; // If the matched instruction has it's "FoldGenRegForm" set, map the