diff options
Diffstat (limited to 'lib/Target/X86/X86InstrInfo.cpp')
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 0c9a5c6..42c994a 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1670,7 +1670,7 @@ static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, unsigned Opcode, MachineInstr* X86InstrInfo::foldMemoryOperand(MachineInstr *MI, unsigned i, - SmallVector<MachineOperand,4> &MOs) const { + SmallVector<MachineOperand,4> &MOs) const { const DenseMap<unsigned*, unsigned> *OpcodeTablePtr = NULL; bool isTwoAddrFold = false; unsigned NumOps = MI->getDesc().getNumOperands(); @@ -1730,12 +1730,33 @@ X86InstrInfo::foldMemoryOperand(MachineInstr *MI, unsigned i, } -MachineInstr* X86InstrInfo::foldMemoryOperand(MachineInstr *MI, +MachineInstr* X86InstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, SmallVectorImpl<unsigned> &Ops, int FrameIndex) const { // Check switch flag if (NoFusing) return NULL; + const MachineFrameInfo *MFI = MF.getFrameInfo(); + unsigned Alignment = MFI->getObjectAlignment(FrameIndex); + // FIXME: Move alignment requirement into tables? + if (Alignment < 16) { + switch (MI->getOpcode()) { + default: break; + // Not always safe to fold movsd into these instructions since their load + // folding variants expects the address to be 16 byte aligned. + case X86::FsANDNPDrr: + case X86::FsANDNPSrr: + case X86::FsANDPDrr: + case X86::FsANDPSrr: + case X86::FsORPDrr: + case X86::FsORPSrr: + case X86::FsXORPDrr: + case X86::FsXORPSrr: + return NULL; + } + } + if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { unsigned NewOpc = 0; switch (MI->getOpcode()) { @@ -1756,12 +1777,39 @@ MachineInstr* X86InstrInfo::foldMemoryOperand(MachineInstr *MI, return foldMemoryOperand(MI, Ops[0], MOs); } -MachineInstr* X86InstrInfo::foldMemoryOperand(MachineInstr *MI, +MachineInstr* X86InstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, SmallVectorImpl<unsigned> &Ops, MachineInstr *LoadMI) const { // Check switch flag if (NoFusing) return NULL; + unsigned Alignment = 0; + for (unsigned i = 0, e = LoadMI->getNumMemOperands(); i != e; ++i) { + const MemOperand &MRO = LoadMI->getMemOperand(i); + unsigned Align = MRO.getAlignment(); + if (Align > Alignment) + Alignment = Align; + } + + // FIXME: Move alignment requirement into tables? + if (Alignment < 16) { + switch (MI->getOpcode()) { + default: break; + // Not always safe to fold movsd into these instructions since their load + // folding variants expects the address to be 16 byte aligned. + case X86::FsANDNPDrr: + case X86::FsANDNPSrr: + case X86::FsANDPDrr: + case X86::FsANDPSrr: + case X86::FsORPDrr: + case X86::FsORPSrr: + case X86::FsXORPDrr: + case X86::FsXORPSrr: + return NULL; + } + } + if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { unsigned NewOpc = 0; switch (MI->getOpcode()) { |