diff --git a/lib/Target/X86/X86InstrAVX512.td b/lib/Target/X86/X86InstrAVX512.td index 10360dec6eb..109c44650c7 100644 --- a/lib/Target/X86/X86InstrAVX512.td +++ b/lib/Target/X86/X86InstrAVX512.td @@ -4733,7 +4733,8 @@ defm VPMULLD : avx512_binop_rm_vl_d<0x40, "vpmulld", mul, defm VPMULLW : avx512_binop_rm_vl_w<0xD5, "vpmullw", mul, SchedWriteVecIMul, HasBWI, 1>; defm VPMULLQ : avx512_binop_rm_vl_q<0x40, "vpmullq", mul, - SchedWriteVecIMul, HasDQI, 1>, T8PD; + SchedWriteVecIMul, HasDQI, 1>, T8PD, + NotEVEX2VEXConvertible; defm VPMULHW : avx512_binop_rm_vl_w<0xE5, "vpmulhw", mulhs, SchedWriteVecIMul, HasBWI, 1>; defm VPMULHUW : avx512_binop_rm_vl_w<0xE4, "vpmulhuw", mulhu, SchedWriteVecIMul, @@ -4875,29 +4876,41 @@ defm VPMAXSB : avx512_binop_rm_vl_b<0x3C, "vpmaxsb", smax, SchedWriteVecALU, HasBWI, 1>, T8PD; defm VPMAXSW : avx512_binop_rm_vl_w<0xEE, "vpmaxsw", smax, SchedWriteVecALU, HasBWI, 1>; -defm VPMAXS : avx512_binop_rm_vl_dq<0x3D, 0x3D, "vpmaxs", smax, +defm VPMAXSD : avx512_binop_rm_vl_d<0x3D, "vpmaxsd", smax, SchedWriteVecALU, HasAVX512, 1>, T8PD; +defm VPMAXSQ : avx512_binop_rm_vl_q<0x3D, "vpmaxsq", smax, + SchedWriteVecALU, HasAVX512, 1>, T8PD, + NotEVEX2VEXConvertible; defm VPMAXUB : avx512_binop_rm_vl_b<0xDE, "vpmaxub", umax, SchedWriteVecALU, HasBWI, 1>; defm VPMAXUW : avx512_binop_rm_vl_w<0x3E, "vpmaxuw", umax, SchedWriteVecALU, HasBWI, 1>, T8PD; -defm VPMAXU : avx512_binop_rm_vl_dq<0x3F, 0x3F, "vpmaxu", umax, +defm VPMAXUD : avx512_binop_rm_vl_d<0x3F, "vpmaxud", umax, SchedWriteVecALU, HasAVX512, 1>, T8PD; +defm VPMAXUQ : avx512_binop_rm_vl_q<0x3F, "vpmaxuq", umax, + SchedWriteVecALU, HasAVX512, 1>, T8PD, + NotEVEX2VEXConvertible; defm VPMINSB : avx512_binop_rm_vl_b<0x38, "vpminsb", smin, SchedWriteVecALU, HasBWI, 1>, T8PD; defm VPMINSW : avx512_binop_rm_vl_w<0xEA, "vpminsw", smin, SchedWriteVecALU, HasBWI, 1>; -defm VPMINS : avx512_binop_rm_vl_dq<0x39, 0x39, "vpmins", smin, +defm VPMINSD : avx512_binop_rm_vl_d<0x39, "vpminsd", smin, SchedWriteVecALU, HasAVX512, 1>, T8PD; +defm VPMINSQ : avx512_binop_rm_vl_q<0x39, "vpminsq", smin, + SchedWriteVecALU, HasAVX512, 1>, T8PD, + NotEVEX2VEXConvertible; defm VPMINUB : avx512_binop_rm_vl_b<0xDA, "vpminub", umin, SchedWriteVecALU, HasBWI, 1>; defm VPMINUW : avx512_binop_rm_vl_w<0x3A, "vpminuw", umin, SchedWriteVecALU, HasBWI, 1>, T8PD; -defm VPMINU : avx512_binop_rm_vl_dq<0x3B, 0x3B, "vpminu", umin, +defm VPMINUD : avx512_binop_rm_vl_d<0x3B, "vpminud", umin, SchedWriteVecALU, HasAVX512, 1>, T8PD; +defm VPMINUQ : avx512_binop_rm_vl_q<0x3B, "vpminuq", umin, + SchedWriteVecALU, HasAVX512, 1>, T8PD, + NotEVEX2VEXConvertible; // PMULLQ: Use 512bit version to implement 128/256 bit in case NoVLX. let Predicates = [HasDQI, NoVLX] in { @@ -5523,7 +5536,7 @@ multiclass avx512_fp_scalef_all opc, bits<8> opcScaler, string OpcodeStr } } defm VSCALEF : avx512_fp_scalef_all<0x2C, 0x2D, "vscalef", X86scalef, X86scalefs, - SchedWriteFAdd>, T8PD; + SchedWriteFAdd>, T8PD, NotEVEX2VEXConvertible; //===----------------------------------------------------------------------===// // AVX-512 VPTESTM instructions @@ -5765,9 +5778,11 @@ multiclass avx512_shift_sizes opc, string OpcodeStr, SDNode OpNode, multiclass avx512_shift_types opcd, bits<8> opcq, bits<8> opcw, string OpcodeStr, SDNode OpNode, - X86SchedWriteWidths sched> { + X86SchedWriteWidths sched, + bit NotEVEX2VEXConvertibleQ = 0> { defm D : avx512_shift_sizes; + let notEVEX2VEXConvertible = NotEVEX2VEXConvertibleQ in defm Q : avx512_shift_sizes, VEX_W; defm W : avx512_shift_sizes opcw, Format ImmFormR, Format ImmFormM, multiclass avx512_shift_rmi_dq opcd, bits<8> opcq, Format ImmFormR, Format ImmFormM, string OpcodeStr, SDNode OpNode, - X86SchedWriteWidths sched> { + X86SchedWriteWidths sched, + bit NotEVEX2VEXConvertibleQ = 0> { defm D: avx512_shift_rmi_sizes, EVEX_CD8<32, CD8VF>; + let notEVEX2VEXConvertible = NotEVEX2VEXConvertibleQ in defm Q: avx512_shift_rmi_sizes, EVEX_CD8<64, CD8VF>, VEX_W; } @@ -5830,7 +5847,7 @@ defm VPSLL : avx512_shift_rmi_dq<0x72, 0x73, MRM6r, MRM6m, "vpsll", X86vshli, SchedWriteVecShiftImm>, AVX512BIi8Base, EVEX_4V; defm VPSRA : avx512_shift_rmi_dq<0x72, 0x72, MRM4r, MRM4m, "vpsra", X86vsrai, - SchedWriteVecShiftImm>, + SchedWriteVecShiftImm, 1>, avx512_shift_rmi_w<0x71, MRM4r, MRM4m, "vpsraw", X86vsrai, SchedWriteVecShiftImm>, AVX512BIi8Base, EVEX_4V; @@ -5842,7 +5859,7 @@ defm VPROL : avx512_shift_rmi_dq<0x72, 0x72, MRM1r, MRM1m, "vprol", X86vrotli, defm VPSLL : avx512_shift_types<0xF2, 0xF3, 0xF1, "vpsll", X86vshl, SchedWriteVecShift>; defm VPSRA : avx512_shift_types<0xE2, 0xE2, 0xE1, "vpsra", X86vsra, - SchedWriteVecShift>; + SchedWriteVecShift, 1>; defm VPSRL : avx512_shift_types<0xD2, 0xD3, 0xD1, "vpsrl", X86vsrl, SchedWriteVecShift>; @@ -7701,9 +7718,9 @@ multiclass avx512_cvtqq2pd opc, string OpcodeStr, SDNode OpNode, } let Predicates = [HasDQI, HasVLX] in { defm Z128 : avx512_vcvt_fp, EVEX_V128; + sched.XMM>, EVEX_V128, NotEVEX2VEXConvertible; defm Z256 : avx512_vcvt_fp, EVEX_V256; + sched.YMM>, EVEX_V256, NotEVEX2VEXConvertible; } } @@ -7760,9 +7777,11 @@ multiclass avx512_cvtqq2ps opc, string OpcodeStr, SDNode OpNode, // dest type - 'v4i32x_info'. We also specify the broadcast string explicitly // due to the same reason. defm Z128 : avx512_vcvt_fp, EVEX_V128; + sched.XMM, "{1to2}", "{x}">, EVEX_V128, + NotEVEX2VEXConvertible; defm Z256 : avx512_vcvt_fp, EVEX_V256; + sched.YMM, "{1to4}", "{y}">, EVEX_V256, + NotEVEX2VEXConvertible; def : InstAlias(NAME # "Z128rr") VR128X:$dst, VR128X:$src), 0>; @@ -10263,7 +10282,7 @@ let Predicates = [HasVLX, HasBWI] in { defm VDBPSADBW: avx512_common_3Op_rm_imm8<0x42, X86dbpsadbw, "vdbpsadbw", SchedWritePSADBW, avx512vl_i16_info, avx512vl_i8_info>, - EVEX_CD8<8, CD8VF>; + EVEX_CD8<8, CD8VF>, NotEVEX2VEXConvertible; multiclass avx512_unary_rm opc, string OpcodeStr, SDNode OpNode, X86FoldableSchedWrite sched, X86VectorVTInfo _> { diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index 712eded1f91..aa504fcf0cf 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -241,6 +241,9 @@ class FoldGenData { // Mark the instruction as "illegal to memory fold/unfold" class NotMemoryFoldable { bit isMemoryFoldable = 0; } +// Prevent EVEX->VEX conversion from considering this instruction. +class NotEVEX2VEXConvertible { bit notEVEX2VEXConvertible = 1; } + class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, string AsmStr, Domain d = GenericDomain> : Instruction { @@ -321,6 +324,7 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, string FoldGenRegForm = ?; bit isMemoryFoldable = 1; // Is it allowed to memory fold/unfold this instruction? + bit notEVEX2VEXConvertible = 0; // Prevent EVEX->VEX conversion. // TSFlags layout should be kept in sync with X86BaseInfo.h. let TSFlags{6-0} = FormBits; diff --git a/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp b/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp index 20637cb8df0..c4c545f404f 100644 --- a/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp +++ b/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp @@ -52,35 +52,11 @@ private: // Prints the given table as a C++ array of type // X86EvexToVexCompressTableEntry void printTable(const std::vector &Table, raw_ostream &OS); - - bool inExceptionList(const CodeGenInstruction *Inst) { - // List of EVEX instructions that match VEX instructions by the encoding - // but do not perform the same operation. - static constexpr const char *ExceptionList[] = { - "VCVTQQ2PD", - "VCVTQQ2PS", - "VPMAXSQ", - "VPMAXUQ", - "VPMINSQ", - "VPMINUQ", - "VPMULLQ", - "VPSRAQ", - "VDBPSADBW", - "VSCALEFPS" - }; - // Instruction's name starts with one of the entries in the exception list - for (StringRef InstStr : ExceptionList) { - if (Inst->TheDef->getName().startswith(InstStr)) - return true; - } - return false; - } - }; void X86EVEX2VEXTablesEmitter::printTable(const std::vector &Table, raw_ostream &OS) { - std::string Size = (Table == EVEX2VEX128) ? "128" : "256"; + StringRef Size = (Table == EVEX2VEX128) ? "128" : "256"; OS << "// X86 EVEX encoded instructions that have a VEX " << Size << " encoding\n" @@ -332,7 +308,7 @@ void X86EVEX2VEXTablesEmitter::run(raw_ostream &OS) { !Inst->TheDef->getValueAsBit("hasEVEX_B") && getValueFromBitsInit(Inst->TheDef-> getValueAsBitsInit("EVEX_LL")) != 2 && - !inExceptionList(Inst)) + !Inst->TheDef->getValueAsBit("notEVEX2VEXConvertible")) EVEXInsts.push_back(Inst); }