diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 8fb33512fc67..15a09ee61bbb 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -5411,18 +5411,7 @@ MachineInstr *X86InstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI, case X86::VPCOMWri: case X86::VPCOMUWri: { // Flip comparison mode immediate (if necessary). unsigned Imm = MI.getOperand(3).getImm() & 0x7; - switch (Imm) { - default: llvm_unreachable("Unreachable!"); - case 0x00: Imm = 0x02; break; // LT -> GT - case 0x01: Imm = 0x03; break; // LE -> GE - case 0x02: Imm = 0x00; break; // GT -> LT - case 0x03: Imm = 0x01; break; // GE -> LE - case 0x04: // EQ - case 0x05: // NE - case 0x06: // FALSE - case 0x07: // TRUE - break; - } + Imm = X86::getSwappedVPCOMImm(Imm); auto &WorkingMI = cloneIfNew(MI); WorkingMI.getOperand(3).setImm(Imm); return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, @@ -6140,6 +6129,24 @@ unsigned X86::getSwappedVPCMPImm(unsigned Imm) { return Imm; } +/// \brief Get the VPCOM immediate if the opcodes are swapped. +unsigned X86::getSwappedVPCOMImm(unsigned Imm) { + switch (Imm) { + default: llvm_unreachable("Unreachable!"); + case 0x00: Imm = 0x02; break; // LT -> GT + case 0x01: Imm = 0x03; break; // LE -> GE + case 0x02: Imm = 0x00; break; // GT -> LT + case 0x03: Imm = 0x01; break; // GE -> LE + case 0x04: // EQ + case 0x05: // NE + case 0x06: // FALSE + case 0x07: // TRUE + break; + } + + return Imm; +} + bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { if (!MI.isTerminator()) return false; diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 5a2e00152e84..8bb90eb4ffe5 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -87,6 +87,9 @@ CondCode GetOppositeBranchCondition(CondCode CC); /// \brief Get the VPCMP immediate if the opcodes are swapped. unsigned getSwappedVPCMPImm(unsigned Imm); +/// \brief Get the VPCOM immediate if the opcodes are swapped. +unsigned getSwappedVPCOMImm(unsigned Imm); + } // namespace X86 /// isGlobalStubReference - Return true if the specified TargetFlag operand is diff --git a/llvm/lib/Target/X86/X86InstrXOP.td b/llvm/lib/Target/X86/X86InstrXOP.td index 435dd2498ce4..7f776a6c7601 100644 --- a/llvm/lib/Target/X86/X86InstrXOP.td +++ b/llvm/lib/Target/X86/X86InstrXOP.td @@ -211,51 +211,64 @@ let Predicates = [HasXOP] in { (VPMADCSWDrr VR128:$src1, VR128:$src2, VR128:$src3)>; } +// Transforms to swizzle an immediate to help matching memory operand in first +// operand. +def CommuteVPCOMCC : SDNodeXFormgetZExtValue() & 0x7; + Imm = X86::getSwappedVPCOMImm(Imm); + return getI8Imm(Imm, SDLoc(N)); +}]>; + // Instruction where second source can be memory, third must be imm8 multiclass xopvpcom opc, string Suffix, SDNode OpNode, ValueType vt128> { - let isCommutable = 1 in - def ri : IXOPi8, - XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - def mi : IXOPi8, - XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - let isAsmParserOnly = 1, hasSideEffects = 0 in { - def ri_alt : IXOPi8, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - let mayLoad = 1 in - def mi_alt : IXOPi8, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let ExeDomain = SSEPackedInt in { // SSE integer instructions + let isCommutable = 1 in + def ri : IXOPi8, + XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + def mi : IXOPi8, + XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let isAsmParserOnly = 1, hasSideEffects = 0 in { + def ri_alt : IXOPi8, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let mayLoad = 1 in + def mi_alt : IXOPi8, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + } } + + def : Pat<(OpNode (bitconvert (loadv2i64 addr:$src2)), + (vt128 VR128:$src1), imm:$cc), + (!cast(NAME#"mi") VR128:$src1, addr:$src2, + (CommuteVPCOMCC imm:$cc))>; } -let ExeDomain = SSEPackedInt in { // SSE integer instructions - defm VPCOMB : xopvpcom<0xCC, "b", X86vpcom, v16i8>; - defm VPCOMW : xopvpcom<0xCD, "w", X86vpcom, v8i16>; - defm VPCOMD : xopvpcom<0xCE, "d", X86vpcom, v4i32>; - defm VPCOMQ : xopvpcom<0xCF, "q", X86vpcom, v2i64>; - defm VPCOMUB : xopvpcom<0xEC, "ub", X86vpcomu, v16i8>; - defm VPCOMUW : xopvpcom<0xED, "uw", X86vpcomu, v8i16>; - defm VPCOMUD : xopvpcom<0xEE, "ud", X86vpcomu, v4i32>; - defm VPCOMUQ : xopvpcom<0xEF, "uq", X86vpcomu, v2i64>; -} +defm VPCOMB : xopvpcom<0xCC, "b", X86vpcom, v16i8>; +defm VPCOMW : xopvpcom<0xCD, "w", X86vpcom, v8i16>; +defm VPCOMD : xopvpcom<0xCE, "d", X86vpcom, v4i32>; +defm VPCOMQ : xopvpcom<0xCF, "q", X86vpcom, v2i64>; +defm VPCOMUB : xopvpcom<0xEC, "ub", X86vpcomu, v16i8>; +defm VPCOMUW : xopvpcom<0xED, "uw", X86vpcomu, v8i16>; +defm VPCOMUD : xopvpcom<0xEE, "ud", X86vpcomu, v4i32>; +defm VPCOMUQ : xopvpcom<0xEF, "uq", X86vpcomu, v2i64>; multiclass xop4op opc, string OpcodeStr, SDNode OpNode, ValueType vt128> {