diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86CompressEVEX.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86CompressEVEX.cpp | 95 |
1 files changed, 46 insertions, 49 deletions
diff --git a/llvm/lib/Target/X86/X86CompressEVEX.cpp b/llvm/lib/Target/X86/X86CompressEVEX.cpp index 11b2155e3f98..7343af1bdc9a 100644 --- a/llvm/lib/Target/X86/X86CompressEVEX.cpp +++ b/llvm/lib/Target/X86/X86CompressEVEX.cpp @@ -174,29 +174,6 @@ static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc) { return true; } -static bool isRedundantNewDataDest(MachineInstr &MI, const X86Subtarget &ST) { - // $rbx = ADD64rr_ND $rbx, $rax / $rbx = ADD64rr_ND $rax, $rbx - // -> - // $rbx = ADD64rr $rbx, $rax - const MCInstrDesc &Desc = MI.getDesc(); - Register Reg0 = MI.getOperand(0).getReg(); - const MachineOperand &Op1 = MI.getOperand(1); - if (!Op1.isReg() || X86::getFirstAddrOperandIdx(MI) == 1 || - X86::isCFCMOVCC(MI.getOpcode())) - return false; - Register Reg1 = Op1.getReg(); - if (Reg1 == Reg0) - return true; - - // Op1 and Op2 may be commutable for ND instructions. - if (!Desc.isCommutable() || Desc.getNumOperands() < 3 || - !MI.getOperand(2).isReg() || MI.getOperand(2).getReg() != Reg0) - return false; - // Opcode may change after commute, e.g. SHRD -> SHLD - ST.getInstrInfo()->commuteInstruction(MI, false, 1, 2); - return true; -} - static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) { uint64_t TSFlags = MI.getDesc().TSFlags; @@ -208,6 +185,30 @@ static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) { if (TSFlags & (X86II::EVEX_K | X86II::EVEX_L2)) return false; + auto IsRedundantNewDataDest = [&](unsigned &Opc) { + // $rbx = ADD64rr_ND $rbx, $rax / $rbx = ADD64rr_ND $rax, $rbx + // -> + // $rbx = ADD64rr $rbx, $rax + const MCInstrDesc &Desc = MI.getDesc(); + Register Reg0 = MI.getOperand(0).getReg(); + const MachineOperand &Op1 = MI.getOperand(1); + if (!Op1.isReg() || X86::getFirstAddrOperandIdx(MI) == 1 || + X86::isCFCMOVCC(MI.getOpcode())) + return false; + Register Reg1 = Op1.getReg(); + if (Reg1 == Reg0) + return true; + + // Op1 and Op2 may be commutable for ND instructions. + if (!Desc.isCommutable() || Desc.getNumOperands() < 3 || + !MI.getOperand(2).isReg() || MI.getOperand(2).getReg() != Reg0) + return false; + // Opcode may change after commute, e.g. SHRD -> SHLD + ST.getInstrInfo()->commuteInstruction(MI, false, 1, 2); + Opc = MI.getOpcode(); + return true; + }; + // EVEX_B has several meanings. // AVX512: // register form: rounding control or SAE @@ -218,40 +219,36 @@ static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) { // // For AVX512 cases, EVEX prefix is needed in order to carry this information // thus preventing the transformation to VEX encoding. - unsigned Opc = MI.getOpcode(); bool IsND = X86II::hasNewDataDest(TSFlags); if (TSFlags & X86II::EVEX_B && !IsND) return false; + unsigned Opc = MI.getOpcode(); // MOVBE*rr is special because it has semantic of NDD but not set EVEX_B. bool IsNDLike = IsND || Opc == X86::MOVBE32rr || Opc == X86::MOVBE64rr; - bool IsRedundantNDD = IsNDLike ? isRedundantNewDataDest(MI, ST) : false; - // NonNF -> NF only if it's not a compressible NDD instruction and eflags is - // dead. - unsigned NFOpc = (ST.hasNF() && !IsRedundantNDD && - MI.registerDefIsDead(X86::EFLAGS, /*TRI=*/nullptr)) - ? X86::getNFVariant(Opc) - : 0U; - if (IsNDLike && !IsRedundantNDD && !NFOpc) - return false; + bool IsRedundantNDD = IsNDLike ? IsRedundantNewDataDest(Opc) : false; - unsigned NewOpc = NFOpc; - if (!NewOpc) { + auto GetCompressedOpc = [&](unsigned Opc) -> unsigned { ArrayRef<X86TableEntry> Table = ArrayRef(X86CompressEVEXTable); - - Opc = MI.getOpcode(); const auto I = llvm::lower_bound(Table, Opc); - if (I == Table.end() || I->OldOpc != Opc) { - assert(!IsNDLike && "Missing entry for ND-like instruction"); - return false; - } - - if (!IsNDLike) { - if (usesExtendedRegister(MI) || !checkPredicate(I->NewOpc, &ST) || - !performCustomAdjustments(MI, I->NewOpc)) - return false; - } - NewOpc = I->NewOpc; - } + if (I == Table.end() || I->OldOpc != Opc) + return 0; + + if (usesExtendedRegister(MI) || !checkPredicate(I->NewOpc, &ST) || + !performCustomAdjustments(MI, I->NewOpc)) + return 0; + return I->NewOpc; + }; + // NonNF -> NF only if it's not a compressible NDD instruction and eflags is + // dead. + unsigned NewOpc = IsRedundantNDD + ? X86::getNonNDVariant(Opc) + : ((IsNDLike && ST.hasNF() && + MI.registerDefIsDead(X86::EFLAGS, /*TRI=*/nullptr)) + ? X86::getNFVariant(Opc) + : GetCompressedOpc(Opc)); + + if (!NewOpc) + return false; const MCInstrDesc &NewDesc = ST.getInstrInfo()->get(NewOpc); MI.setDesc(NewDesc); |
