From d8eec01d7838b29d0c4cc6aeec5072cca6167985 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 20 Feb 2018 03:58:13 +0000 Subject: [PATCH] [X86] Make XOP VPCOM instructions commutable to fold loads during isel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325547 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstrInfo.cpp | 31 ++++++++------ lib/Target/X86/X86InstrInfo.h | 3 ++ lib/Target/X86/X86InstrXOP.td | 93 +++++++++++++++++++++++------------------ 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 8fb33512fc6..15a09ee61bb 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/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/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 5a2e00152e8..8bb90eb4ffe 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/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/lib/Target/X86/X86InstrXOP.td b/lib/Target/X86/X86InstrXOP.td index 435dd2498ce..7f776a6c760 100644 --- a/lib/Target/X86/X86InstrXOP.td +++ b/lib/Target/X86/X86InstrXOP.td @@ -211,52 +211,65 @@ 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]>; + } } -} -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>; + def : Pat<(OpNode (bitconvert (loadv2i64 addr:$src2)), + (vt128 VR128:$src1), imm:$cc), + (!cast(NAME#"mi") VR128:$src1, addr:$src2, + (CommuteVPCOMCC imm:$cc))>; } +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> { def rrr : IXOPi8Reg