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/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -2851,7 +2851,7 @@ def TPAUSE : I<0xAE, MRM6r, (outs), (ins GR32orGR64:$src), "tpause\t$src", [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>, - PD, Requires<[HasWAITPKG]>, NotMemoryFoldable; + PD, Requires<[HasWAITPKG]>; } } // SchedRW @@ -3124,7 +3124,7 @@ let Predicates = [HasCLWB], SchedRW = [WriteLoad] in def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", - [(int_x86_clwb addr:$src)]>, PD, NotMemoryFoldable; + [(int_x86_clwb addr:$src)]>, PD; let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src", 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 @@ -252,10 +252,11 @@ // 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) { X86Disassembler::RecognizableInstrBase RegRI(*RegInst); @@ -272,6 +273,16 @@ if (!areOppositeForms(RegRI.Form, MemRI.Form)) return false; + // X86 encoding is crazy, e.g + // + // f3 0f c7 30 vmxon (%rax) + // f3 0f c7 f0 senduipi %rax + // + // This two instruction have similiar encoding fields 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 (RegRI.Encoding != MemRI.Encoding || RegRI.Opcode != MemRI.Opcode || @@ -533,6 +544,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) { @@ -548,7 +561,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