From 5fd79d0560570fed977788a86fa038b898564dfa Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 8 Feb 2008 21:20:40 +0000 Subject: It's not always safe to fold movsd into xorpd, etc. Check the alignment of the load address first to make sure it's 16 byte aligned. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46893 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.cpp | 9 ++++--- lib/Target/ARM/ARMInstrInfo.h | 6 +++-- lib/Target/Alpha/AlphaInstrInfo.cpp | 7 ++--- lib/Target/Alpha/AlphaInstrInfo.h | 6 +++-- lib/Target/CellSPU/SPUInstrInfo.cpp | 7 ++--- lib/Target/CellSPU/SPUInstrInfo.h | 6 +++-- lib/Target/Mips/MipsInstrInfo.cpp | 3 ++- lib/Target/Mips/MipsInstrInfo.h | 6 +++-- lib/Target/PowerPC/PPCInstrInfo.cpp | 5 ++-- lib/Target/PowerPC/PPCInstrInfo.h | 6 +++-- lib/Target/Sparc/SparcInstrInfo.cpp | 7 ++--- lib/Target/Sparc/SparcInstrInfo.h | 6 +++-- lib/Target/X86/X86InstrInfo.cpp | 54 ++++++++++++++++++++++++++++++++++--- lib/Target/X86/X86InstrInfo.h | 6 +++-- 14 files changed, 101 insertions(+), 33 deletions(-) (limited to 'lib/Target') diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index 9ecd7c7..4d1819d 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -640,9 +640,10 @@ bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return true; } -MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops, - int FI) const { +MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, + SmallVectorImpl &Ops, + int FI) const { if (Ops.size() != 1) return NULL; unsigned OpNum = Ops[0]; @@ -721,7 +722,7 @@ MachineInstr *ARMInstrInfo::foldMemoryOperand(MachineInstr *MI, } bool ARMInstrInfo::canFoldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops) const { + SmallVectorImpl &Ops) const { if (Ops.size() != 1) return false; unsigned OpNum = Ops[0]; diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index 60d9640..31216e4 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -191,11 +191,13 @@ public: MachineBasicBlock::iterator MI, const std::vector &CSI) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp index 53d7104..48e23f9 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.cpp +++ b/lib/Target/Alpha/AlphaInstrInfo.cpp @@ -250,9 +250,10 @@ void AlphaInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, NewMIs.push_back(MIB); } -MachineInstr *AlphaInstrInfo::foldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops, - int FrameIndex) const { +MachineInstr *AlphaInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, + SmallVectorImpl &Ops, + int FrameIndex) const { if (Ops.size() != 1) return NULL; // Make sure this is a reg-reg copy. diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h index 3477ae0..20d6388 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.h +++ b/lib/Target/Alpha/AlphaInstrInfo.h @@ -67,11 +67,13 @@ public: const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; diff --git a/lib/Target/CellSPU/SPUInstrInfo.cpp b/lib/Target/CellSPU/SPUInstrInfo.cpp index ac9b9b8..64f6225 100644 --- a/lib/Target/CellSPU/SPUInstrInfo.cpp +++ b/lib/Target/CellSPU/SPUInstrInfo.cpp @@ -391,9 +391,10 @@ void SPUInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, /// foldMemoryOperand - SPU, like PPC, can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr * -SPUInstrInfo::foldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops, - int FrameIndex) const +SPUInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, + SmallVectorImpl &Ops, + int FrameIndex) const { #if SOMEDAY_SCOTT_LOOKS_AT_ME_AGAIN if (Ops.size() != 1) return NULL; diff --git a/lib/Target/CellSPU/SPUInstrInfo.h b/lib/Target/CellSPU/SPUInstrInfo.h index 10c39a0..39237ee 100644 --- a/lib/Target/CellSPU/SPUInstrInfo.h +++ b/lib/Target/CellSPU/SPUInstrInfo.h @@ -77,12 +77,14 @@ namespace llvm { SmallVectorImpl &NewMIs) const; //! Fold spills into load/store instructions - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; //! Fold any load/store to an operand - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 85c1048..fa5d8b3 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -370,7 +370,8 @@ void MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, } MachineInstr *MipsInstrInfo:: -foldMemoryOperand(MachineInstr* MI, +foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FI) const { if (Ops.size() != 1) return NULL; diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 69ab795..d894b20 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -106,11 +106,13 @@ public: const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 47e2871..81c1003 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -536,7 +536,8 @@ void PPCInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. -MachineInstr *PPCInstrInfo::foldMemoryOperand(MachineInstr *MI, +MachineInstr *PPCInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr *MI, SmallVectorImpl &Ops, int FrameIndex) const { if (Ops.size() != 1) return NULL; @@ -594,7 +595,7 @@ MachineInstr *PPCInstrInfo::foldMemoryOperand(MachineInstr *MI, } bool PPCInstrInfo::canFoldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops) const { + SmallVectorImpl &Ops) const { if (Ops.size() != 1) return false; // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because diff --git a/lib/Target/PowerPC/PPCInstrInfo.h b/lib/Target/PowerPC/PPCInstrInfo.h index 02d8bba..9f289e4 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.h +++ b/lib/Target/PowerPC/PPCInstrInfo.h @@ -131,11 +131,13 @@ public: /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; diff --git a/lib/Target/Sparc/SparcInstrInfo.cpp b/lib/Target/Sparc/SparcInstrInfo.cpp index 56727bb..79fc912 100644 --- a/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/lib/Target/Sparc/SparcInstrInfo.cpp @@ -222,9 +222,10 @@ void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, return; } -MachineInstr *SparcInstrInfo::foldMemoryOperand(MachineInstr* MI, - SmallVectorImpl &Ops, - int FI) const { +MachineInstr *SparcInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + SmallVectorImpl &Ops, + int FI) const { if (Ops.size() != 1) return NULL; unsigned OpNum = Ops[0]; diff --git a/lib/Target/Sparc/SparcInstrInfo.h b/lib/Target/Sparc/SparcInstrInfo.h index 0ed7fab..14c3b4a 100644 --- a/lib/Target/Sparc/SparcInstrInfo.h +++ b/lib/Target/Sparc/SparcInstrInfo.h @@ -94,11 +94,13 @@ public: const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const { return 0; 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 &MOs) const { + SmallVector &MOs) const { const DenseMap *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 &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 &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()) { diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 68f1664..4a62e9e 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -324,14 +324,16 @@ public: /// folding and return true, otherwise it should return false. If it folds /// the instruction, it is likely that the MachineInstruction the iterator /// references has been changed. - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, int FrameIndex) const; /// foldMemoryOperand - Same as the previous version except it allows folding /// of any load and store from / to any address, not just from a specific /// stack slot. - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, SmallVectorImpl &Ops, MachineInstr* LoadMI) const; -- cgit v1.1