diff options
author | Craig Topper <craig.topper@gmail.com> | 2019-11-04 19:58:53 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2019-11-04 22:07:46 -0800 |
commit | f65493a83e3bdb402fb1dfa92bcc25707e961147 (patch) | |
tree | c2d35b679515fa7e4a0758a12f9797890bf1aa2d /llvm/lib | |
parent | abc04ff4012c62c98aa9f0d840114b2f56855dc8 (diff) | |
download | bcm5719-llvm-f65493a83e3bdb402fb1dfa92bcc25707e961147.tar.gz bcm5719-llvm-f65493a83e3bdb402fb1dfa92bcc25707e961147.zip |
[X86] Teach X86MCInstLower to swap operands of commutable instructions to enable 2-byte VEX encoding.
Summary:
The 2 source operands commutable instructions are encoded in the
VEX.VVVV field and the r/m field of the MODRM byte plus the VEX.B
field.
The VEX.B field is missing from the 2-byte VEX encoding. If the
VEX.VVVV source is 0-7 and the other register is 8-15 we can
swap them to avoid needing the VEX.B field. This works as long as
the VEX.W, VEX.mmmmm, and VEX.X fields are also not needed.
Fixes PR36706.
Reviewers: RKSimon, spatel
Reviewed By: RKSimon
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68550
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; + } } } |