mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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. llvm-svn: 233137
This commit is contained in:
parent
8352e8c769
commit
b3c593a951
@ -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");
|
||||
|
@ -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<const X86FrameLowering *>(TFI)
|
||||
->getFrameIndexOffsetFromSP(MF, FrameIndex);
|
||||
else
|
||||
Offset += SlotSize;
|
||||
Offset = TFI->getFrameIndexOffset(MF, FrameIndex);
|
||||
FI.ChangeToImmediate(Offset);
|
||||
return;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user