From: Reid Kleckner Date: Tue, 24 Mar 2015 23:46:01 +0000 (+0000) Subject: X86: Fix frameescape when not using an FP X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=d639e1975d9360ee0cf9ce9a458ae890eebea0de X86: Fix frameescape when not using an FP We can't use TargetFrameLowering::getFrameIndexOffset directly, because Win64 really wants the offset from the stack pointer at the end of the prologue. Instead, use X86FrameLowering::getFrameIndexOffsetFromSP(), which is a pretty close approximiation of that. It fails to handle cases with interestingly large stack alignments, which is pretty uncommon on Win64 and is TODO. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233137 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 9c90334c712..6ceace8696c 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -584,14 +584,6 @@ int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size, return -++NumFixedObjects; } -int MachineFrameInfo::CreateFrameAllocation(uint64_t Size) { - // Force the use of a frame pointer. The intention is that this intrinsic be - // used in conjunction with unwind mechanisms that leak the frame pointer. - setFrameAddressIsTaken(true); - Size = RoundUpToAlignment(Size, StackAlignment); - return CreateStackObject(Size, StackAlignment, false); -} - BitVector MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const { assert(MBB && "MBB must be valid"); diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 6d031830b42..06545bc2096 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "X86RegisterInfo.h" +#include "X86FrameLowering.h" #include "X86InstrBuilder.h" #include "X86MachineFunctionInfo.h" #include "X86Subtarget.h" @@ -507,15 +508,14 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // offset is from the SP at the end of the prologue, not the FP location. This // matches the behavior of llvm.frameaddress. if (Opc == TargetOpcode::FRAME_ALLOC) { - assert(TFI->hasFP(MF) && "frame alloc requires FP"); MachineOperand &FI = MI.getOperand(FIOperandNum); - const MachineFrameInfo *MFI = MF.getFrameInfo(); - int Offset = MFI->getObjectOffset(FrameIndex) - TFI->getOffsetOfLocalArea(); bool IsWinEH = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); + int Offset; if (IsWinEH) - Offset += MFI->getStackSize(); + Offset = static_cast(TFI) + ->getFrameIndexOffsetFromSP(MF, FrameIndex); else - Offset += SlotSize; + Offset = TFI->getFrameIndexOffset(MF, FrameIndex); FI.ChangeToImmediate(Offset); return; } diff --git a/test/CodeGen/X86/frameescape.ll b/test/CodeGen/X86/frameescape.ll index 6e27a7624c7..40eeb0e0d72 100644 --- a/test/CodeGen/X86/frameescape.ll +++ b/test/CodeGen/X86/frameescape.ll @@ -1,4 +1,5 @@ -; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s +; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=X86 +; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X64 declare void @llvm.frameescape(...) declare i8* @llvm.frameaddress(i32) @@ -20,17 +21,34 @@ define void @print_framealloc_from_fp(i8* %fp) { ret void } -; CHECK-LABEL: print_framealloc_from_fp: -; CHECK: movq %rcx, %[[parent_fp:[a-z]+]] -; CHECK: movl .Lalloc_func$frame_escape_0(%[[parent_fp]]), %edx -; CHECK: leaq {{.*}}(%rip), %[[str:[a-z]+]] -; CHECK: movq %[[str]], %rcx -; CHECK: callq printf -; CHECK: movl .Lalloc_func$frame_escape_1(%[[parent_fp]]), %edx -; CHECK: movq %[[str]], %rcx -; CHECK: callq printf -; CHECK: movl $42, .Lalloc_func$frame_escape_1(%[[parent_fp]]) -; CHECK: retq +; X64-LABEL: print_framealloc_from_fp: +; X64: movq %rcx, %[[parent_fp:[a-z]+]] +; X64: movl .Lalloc_func$frame_escape_0(%[[parent_fp]]), %edx +; X64: leaq {{.*}}(%rip), %[[str:[a-z]+]] +; X64: movq %[[str]], %rcx +; X64: callq printf +; X64: movl .Lalloc_func$frame_escape_1(%[[parent_fp]]), %edx +; X64: movq %[[str]], %rcx +; X64: callq printf +; X64: movl $42, .Lalloc_func$frame_escape_1(%[[parent_fp]]) +; X64: retq + +; X86-LABEL: print_framealloc_from_fp: +; X86: pushl %esi +; X86: subl $8, %esp +; X86: movl 16(%esp), %esi +; X86: movl _Lalloc_func$frame_escape_0(%esi), %eax +; X86: movl %eax, 4(%esp) +; X86: movl $_str, (%esp) +; X86: calll _printf +; X86: movl _Lalloc_func$frame_escape_1(%esi), %eax +; X86: movl %eax, 4(%esp) +; X86: movl $_str, (%esp) +; X86: calll _printf +; X86: movl $42, _Lalloc_func$frame_escape_1(%esi) +; X86: addl $8, %esp +; X86: popl %esi +; X86: retl define void @alloc_func() { %a = alloca i32 @@ -43,21 +61,58 @@ define void @alloc_func() { ret void } -; CHECK-LABEL: alloc_func: -; CHECK: subq $48, %rsp -; CHECK: .seh_stackalloc 48 -; CHECK: leaq 48(%rsp), %rbp -; CHECK: .seh_setframe 5, 48 -; CHECK: .Lalloc_func$frame_escape_0 = 44 -; CHECK: .Lalloc_func$frame_escape_1 = 40 -; CHECK: movl $42, -4(%rbp) -; CHECK: movl $13, -8(%rbp) -; CHECK: leaq -48(%rbp), %rcx -; CHECK: callq print_framealloc_from_fp -; CHECK: retq +; X64-LABEL: alloc_func: +; X64: subq $48, %rsp +; X64: .seh_stackalloc 48 +; X64: leaq 48(%rsp), %rbp +; X64: .seh_setframe 5, 48 +; X64: .Lalloc_func$frame_escape_0 = 44 +; X64: .Lalloc_func$frame_escape_1 = 40 +; X64: movl $42, -4(%rbp) +; X64: movl $13, -8(%rbp) +; X64: leaq -48(%rbp), %rcx +; X64: callq print_framealloc_from_fp +; X64: retq + +; X86-LABEL: alloc_func: +; X86: pushl %ebp +; X86: movl %esp, %ebp +; X86: subl $12, %esp +; X86: Lalloc_func$frame_escape_0 = -4 +; X86: Lalloc_func$frame_escape_1 = -8 +; X86: movl $42, -4(%ebp) +; X86: movl $13, -8(%ebp) +; X86: movl %ebp, (%esp) +; X86: calll _print_framealloc_from_fp +; X86: addl $12, %esp +; X86: popl %ebp +; X86: retl ; Helper to make this a complete program so it can be compiled and tested. define i32 @main() { call void @alloc_func() ret i32 0 } + +define void @alloc_func_no_frameaddr() { + %a = alloca i32 + %b = alloca i32 + call void (...)* @llvm.frameescape(i32* %a, i32* %b) + store i32 42, i32* %a + store i32 13, i32* %b + call void @print_framealloc_from_fp(i8* null) + ret void +} + +; X64-LABEL: alloc_func_no_frameaddr: +; X64: subq $40, %rsp +; X64: .seh_stackalloc 40 +; X64: .seh_endprologue +; X64: .Lalloc_func_no_frameaddr$frame_escape_0 = 36 +; X64: .Lalloc_func_no_frameaddr$frame_escape_1 = 32 +; X64: movl $42, 36(%rsp) +; X64: movl $13, 32(%rsp) +; X64: xorl %ecx, %ecx +; X64: callq print_framealloc_from_fp +; X64: addq $40, %rsp +; X64: retq