aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/X86InstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86InstrInfo.cpp')
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp54
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()) {