Index: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -4270,24 +4270,6 @@ 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; - } - return Match_Success; } Index: llvm/lib/Target/X86/AsmParser/X86Operand.h =================================================================== --- llvm/lib/Target/X86/AsmParser/X86Operand.h +++ llvm/lib/Target/X86/AsmParser/X86Operand.h @@ -301,9 +301,15 @@ bool isMem32() const { return Kind == Memory && (!Mem.Size || Mem.Size == 32); } + bool isMem32VEX() const { + return Kind == Memory && (!Mem.Size || Mem.Size == 32); + } bool isMem64() const { return Kind == Memory && (!Mem.Size || Mem.Size == 64); } + bool isMem64VEX() const { + return Kind == Memory && (!Mem.Size || Mem.Size == 64); + } bool isMem80() const { return Kind == Memory && (!Mem.Size || Mem.Size == 80); } Index: llvm/lib/Target/X86/X86InstrFragmentsSIMD.td =================================================================== --- llvm/lib/Target/X86/X86InstrFragmentsSIMD.td +++ llvm/lib/Target/X86/X86InstrFragmentsSIMD.td @@ -1030,6 +1030,9 @@ def ssmem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>; def sdmem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>; +def ssmem_vex : X86MemOperand<"printdwordmem", X86Mem32VEXAsmOperand>; +def sdmem_vex : X86MemOperand<"printqwordmem", X86Mem64VEXAsmOperand>; + def fp16imm0 : PatLeaf<(f16 fpimm), [{ return N->isExactlyValue(+0.0); }]>; Index: llvm/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.td +++ llvm/lib/Target/X86/X86InstrInfo.td @@ -383,6 +383,13 @@ def X86SibMemOperand : AsmOperandClass { let Name = "SibMem"; } } +let RenderMethod = "addMemOperands", SuperClasses = [X86Mem32AsmOperand] in { + def X86Mem32VEXAsmOperand : AsmOperandClass { let Name = "Mem32VEX"; } +} +let RenderMethod = "addMemOperands", SuperClasses = [X86Mem64AsmOperand] in { + def X86Mem64VEXAsmOperand : AsmOperandClass { let Name = "Mem64VEX"; } +} + def X86AbsMemAsmOperand : AsmOperandClass { let Name = "AbsMem"; let SuperClasses = [X86MemAsmOperand]; Index: llvm/lib/Target/X86/X86InstrSSE.td =================================================================== --- llvm/lib/Target/X86/X86InstrSSE.td +++ llvm/lib/Target/X86/X86InstrSSE.td @@ -1030,10 +1030,10 @@ let Uses = [MXCSR], mayRaiseFPException = 1 in { let Predicates = [UseAVX] in { defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, i32, v2f64, - X86cvts2si, sdmem, sse_load_f64, "cvtsd2si", + X86cvts2si, sdmem_vex, sse_load_f64, "cvtsd2si", WriteCvtSD2I, SSEPackedDouble>, XD, VEX, VEX_LIG; defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, i64, v2f64, - X86cvts2si, sdmem, sse_load_f64, "cvtsd2si", + X86cvts2si, sdmem_vex, sse_load_f64, "cvtsd2si", WriteCvtSD2I, SSEPackedDouble>, XD, VEX, VEX_W, VEX_LIG; } defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, i32, v2f64, X86cvts2si, @@ -1106,17 +1106,17 @@ // Aliases for intrinsics let Predicates = [UseAVX], Uses = [MXCSR], mayRaiseFPException = 1 in { defm VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, i32, v4f32, X86cvtts2Int, - ssmem, sse_load_f32, "cvttss2si", + ssmem_vex, sse_load_f32, "cvttss2si", WriteCvtSS2I, SSEPackedSingle>, XS, VEX, VEX_LIG; defm VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64, i64, v4f32, - X86cvtts2Int, ssmem, sse_load_f32, + X86cvtts2Int, ssmem_vex, sse_load_f32, "cvttss2si", WriteCvtSS2I, SSEPackedSingle>, XS, VEX, VEX_LIG, VEX_W; defm VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, i32, v2f64, X86cvtts2Int, - sdmem, sse_load_f64, "cvttsd2si", + sdmem_vex, sse_load_f64, "cvttsd2si", WriteCvtSS2I, SSEPackedDouble>, XD, VEX, VEX_LIG; defm VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64, i64, v2f64, - X86cvtts2Int, sdmem, sse_load_f64, + X86cvtts2Int, sdmem_vex, sse_load_f64, "cvttsd2si", WriteCvtSS2I, SSEPackedDouble>, XD, VEX, VEX_LIG, VEX_W; } @@ -1140,19 +1140,19 @@ def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}", (VCVTTSS2SIrr_Int GR32:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}", - (VCVTTSS2SIrm_Int GR32:$dst, f32mem:$src), 0, "att">; + (VCVTTSS2SIrm_Int GR32:$dst, ssmem_vex:$src), 0, "att">; def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}", (VCVTTSD2SIrr_Int GR32:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}", - (VCVTTSD2SIrm_Int GR32:$dst, f64mem:$src), 0, "att">; + (VCVTTSD2SIrm_Int GR32:$dst, sdmem_vex:$src), 0, "att">; def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}", (VCVTTSS2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}", - (VCVTTSS2SI64rm_Int GR64:$dst, f32mem:$src), 0, "att">; + (VCVTTSS2SI64rm_Int GR64:$dst, ssmem_vex:$src), 0, "att">; def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}", (VCVTTSD2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}", - (VCVTTSD2SI64rm_Int GR64:$dst, f64mem:$src), 0, "att">; + (VCVTTSD2SI64rm_Int GR64:$dst, sdmem_vex:$src), 0, "att">; def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}", (CVTTSS2SIrr_Int GR32:$dst, VR128:$src), 0, "att">; @@ -1173,10 +1173,10 @@ let Predicates = [UseAVX], Uses = [MXCSR], mayRaiseFPException = 1 in { defm VCVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, i32, v4f32, X86cvts2si, - ssmem, sse_load_f32, "cvtss2si", + ssmem_vex, sse_load_f32, "cvtss2si", WriteCvtSS2I, SSEPackedSingle>, XS, VEX, VEX_LIG; defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, i64, v4f32, X86cvts2si, - ssmem, sse_load_f32, "cvtss2si", + ssmem_vex, sse_load_f32, "cvtss2si", WriteCvtSS2I, SSEPackedSingle>, XS, VEX, VEX_W, VEX_LIG; } let Uses = [MXCSR], mayRaiseFPException = 1 in { @@ -1206,19 +1206,19 @@ def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}", (VCVTSS2SIrr_Int GR32:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}", - (VCVTSS2SIrm_Int GR32:$dst, ssmem:$src), 0, "att">; + (VCVTSS2SIrm_Int GR32:$dst, ssmem_vex:$src), 0, "att">; def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}", (VCVTSD2SIrr_Int GR32:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}", - (VCVTSD2SIrm_Int GR32:$dst, sdmem:$src), 0, "att">; + (VCVTSD2SIrm_Int GR32:$dst, sdmem_vex:$src), 0, "att">; def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}", (VCVTSS2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}", - (VCVTSS2SI64rm_Int GR64:$dst, ssmem:$src), 0, "att">; + (VCVTSS2SI64rm_Int GR64:$dst, ssmem_vex:$src), 0, "att">; def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}", (VCVTSD2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">; def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}", - (VCVTSD2SI64rm_Int GR64:$dst, sdmem:$src), 0, "att">; + (VCVTSD2SI64rm_Int GR64:$dst, sdmem_vex:$src), 0, "att">; // SSE aliases def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}", Index: llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp =================================================================== --- llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp +++ llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp @@ -149,7 +149,8 @@ if (getRegOperandSize(OpRec1) != getRegOperandSize(OpRec2)) return false; } else if (isMemoryOperand(OpRec1) && isMemoryOperand(OpRec2)) { - return false; + if (OpRec1->getValueAsString("PrintMethod") != OpRec2->getValueAsString("PrintMethod")) + return false; } else if (isImmediateOperand(OpRec1) && isImmediateOperand(OpRec2)) { if (OpRec1->getValueAsDef("Type") != OpRec2->getValueAsDef("Type")) { return false; Index: llvm/utils/TableGen/X86RecognizableInstr.cpp =================================================================== --- llvm/utils/TableGen/X86RecognizableInstr.cpp +++ llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -903,12 +903,14 @@ TYPE("FR64X", TYPE_XMM) TYPE("f64mem", TYPE_M) TYPE("sdmem", TYPE_M) + TYPE("sdmem_vex", TYPE_M) TYPE("FR16X", TYPE_XMM) TYPE("FR32", TYPE_XMM) TYPE("FR32X", TYPE_XMM) TYPE("f32mem", TYPE_M) TYPE("f16mem", TYPE_M) TYPE("ssmem", TYPE_M) + TYPE("ssmem_vex", TYPE_M) TYPE("shmem", TYPE_M) TYPE("RST", TYPE_ST) TYPE("RSTi", TYPE_ST) @@ -1171,7 +1173,9 @@ ENCODING("i8mem", ENCODING_RM) ENCODING("shmem", ENCODING_RM) ENCODING("ssmem", ENCODING_RM) + ENCODING("ssmem_vex", ENCODING_RM) ENCODING("sdmem", ENCODING_RM) + ENCODING("sdmem_vex", ENCODING_RM) ENCODING("f128mem", ENCODING_RM) ENCODING("f256mem", ENCODING_RM) ENCODING("f512mem", ENCODING_RM)