From 3163865f01793ce7652b37ff8294db62aa6c6e42 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 10 Feb 2015 19:01:47 +0000 Subject: [PATCH] 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 --- lib/Target/X86/X86FrameLowering.cpp | 35 ++++++++++++++--------------- test/CodeGen/X86/win64_eh.ll | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 8b79a9f1ebd..adeb46df8d5 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -909,29 +909,29 @@ 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"); + if (NeedsWinEH) { + int FI; + if (unsigned Reg = TII.isStoreToStackSlot(FrameInstr, FI)) { + if (X86::FR64RegClass.contains(Reg)) { + int Offset = getFrameIndexOffset(MF, FI); + Offset += SEHFrameOffset; - int Offset = getFrameIndexOffset(MF, Info.getFrameIdx()); - Offset += SEHFrameOffset; - - BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SaveXMM)) - .addImm(Reg) - .addImm(Offset) - .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_SaveXMM)) + .addImm(Reg) + .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); diff --git a/test/CodeGen/X86/win64_eh.ll b/test/CodeGen/X86/win64_eh.ll index ed3a6e19ef1..681023de1d2 100644 --- a/test/CodeGen/X86/win64_eh.ll +++ b/test/CodeGen/X86/win64_eh.ll @@ -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