diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 49aa0b7984c..e869aa64a1e 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -876,6 +876,52 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { case X86::MOVSX64rr32: SimplifyMOVSX(OutMI); break; + + case X86::VCMPPDrri: + case X86::VCMPPDYrri: + case X86::VCMPPSrri: + case X86::VCMPPSYrri: + case X86::VCMPSDrr: + case X86::VCMPSSrr: { + // Swap the operands if it will enable a 2 byte VEX encoding. + // FIXME: Change the immediate to improve opportunities? + if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg()) && + X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) { + unsigned Imm = MI->getOperand(3).getImm() & 0x7; + switch (Imm) { + default: break; + case 0x00: // EQUAL + case 0x03: // UNORDERED + case 0x04: // NOT EQUAL + case 0x07: // ORDERED + std::swap(OutMI.getOperand(1), OutMI.getOperand(2)); + break; + } + } + break; + } + + case X86::VMOVHLPSrr: + case X86::VUNPCKHPDrr: + // These are not truly commutable so hide them from the default case. + break; + + default: { + // If the instruction is a commutable arithmetic instruction we might be + // able to commute the operands to get a 2 byte VEX prefix. + uint64_t TSFlags = MI->getDesc().TSFlags; + if (MI->getDesc().isCommutable() && + (TSFlags & X86II::EncodingMask) == X86II::VEX && + (TSFlags & X86II::OpMapMask) == X86II::TB && + (TSFlags & X86II::FormMask) == X86II::MRMSrcReg && + !(TSFlags & X86II::VEX_W) && (TSFlags & X86II::VEX_4V) && + OutMI.getNumOperands() == 3) { + if (!X86II::isX86_64ExtendedReg(OutMI.getOperand(1).getReg()) && + X86II::isX86_64ExtendedReg(OutMI.getOperand(2).getReg())) + std::swap(OutMI.getOperand(1), OutMI.getOperand(2)); + } + break; + } } } |