X86: Emit Win64 SaveXMM opcodes at the right offset in the right order

Walk the instructions marked FrameSetup and consider any stores of XMM
registers to the stack as needing a SaveXMM opcode.

This fixes PR22521.

Differential Revision: http://reviews.llvm.org/D7527

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228724 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2015-02-10 19:01:47 +00:00
parent 241ede07b0
commit 3163865f01
2 changed files with 18 additions and 19 deletions

View File

@ -909,18 +909,15 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
.setMIFlag(MachineInstr::FrameSetup);
}
// Skip the rest of register spilling code
while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup))
while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) {
const MachineInstr *FrameInstr = &*MBBI;
++MBBI;
if (NeedsWinEH) {
for (const CalleeSavedInfo &Info : MFI->getCalleeSavedInfo()) {
unsigned Reg = Info.getReg();
if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg))
continue;
assert(X86::FR64RegClass.contains(Reg) && "Unexpected register class");
int Offset = getFrameIndexOffset(MF, Info.getFrameIdx());
int FI;
if (unsigned Reg = TII.isStoreToStackSlot(FrameInstr, FI)) {
if (X86::FR64RegClass.contains(Reg)) {
int Offset = getFrameIndexOffset(MF, FI);
Offset += SEHFrameOffset;
BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SaveXMM))
@ -928,10 +925,13 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
.addImm(Offset)
.setMIFlag(MachineInstr::FrameSetup);
}
}
}
}
if (NeedsWinEH)
BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_EndPrologue))
.setMIFlag(MachineInstr::FrameSetup);
}
// Realign stack after we spilled callee-saved registers (so that we'll be
// able to calculate their offsets from the frame pointer).
@ -1468,8 +1468,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters(
// It can be done by spilling XMMs to stack frame.
for (unsigned i = CSI.size(); i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
if (X86::GR64RegClass.contains(Reg) ||
X86::GR32RegClass.contains(Reg))
if (X86::GR64RegClass.contains(Reg) || X86::GR32RegClass.contains(Reg))
continue;
// Add the callee-saved register as live-in. It's killed at the spill.
MBB.addLiveIn(Reg);

View File

@ -155,9 +155,9 @@ entry:
; WIN64: leaq 128(%rsp), %rbp
; WIN64: .seh_setframe 5, 128
; WIN64: movaps %xmm7, -32(%rbp) # 16-byte Spill
; WIN64: .seh_savexmm 7, 96
; WIN64: movaps %xmm6, -48(%rbp) # 16-byte Spill
; WIN64: .seh_savexmm 6, 80
; WIN64: .seh_savexmm 7, 96
; WIN64: .seh_endprologue
; WIN64: andq $-64, %rsp
; WIN64: movaps -48(%rbp), %xmm6 # 16-byte Reload