mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
7622646303
The X86 tail call eligibility logic was correct when it was written, but the addition of inalloca and argument copy elision broke its assumptions. It was assuming that fixed stack objects were immutable. Currently, we aim to emit a tail call if no arguments have to be re-arranged in memory. This code would trace the outgoing argument values back to check if they are loads from an incoming stack object. If the stack argument is immutable, then we won't need to store it back to the stack when we tail call. Fortunately, stack objects track their mutability, so we can just make the obvious check to fix the bug. This was http://crbug.com/749826 llvm-svn: 309343
43 lines
1.3 KiB
LLVM
43 lines
1.3 KiB
LLVM
; RUN: llc < %s | FileCheck %s
|
|
|
|
; Make sure we check that forwarded memory arguments are not modified when tail
|
|
; calling. inalloca and copy arg elimination make argument slots mutable.
|
|
|
|
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
|
target triple = "i386-pc-windows-msvc19.0.24215"
|
|
|
|
declare x86_stdcallcc void @tail_std(i32)
|
|
declare void @capture(i32*)
|
|
|
|
define x86_thiscallcc void @inalloca(i32* %this, i32* inalloca %args) {
|
|
entry:
|
|
%val = load i32, i32* %args
|
|
store i32 0, i32* %args
|
|
tail call x86_stdcallcc void @tail_std(i32 %val)
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: _inalloca: # @inalloca
|
|
; CHECK: movl 4(%esp), %[[reg:[^ ]*]]
|
|
; CHECK: movl $0, 4(%esp)
|
|
; CHECK: pushl %[[reg]]
|
|
; CHECK: calll _tail_std@4
|
|
; CHECK: retl $4
|
|
|
|
define x86_stdcallcc void @copy_elide(i32 %arg) {
|
|
entry:
|
|
%arg.ptr = alloca i32
|
|
store i32 %arg, i32* %arg.ptr
|
|
call void @capture(i32* %arg.ptr)
|
|
tail call x86_stdcallcc void @tail_std(i32 %arg)
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: _copy_elide@4: # @copy_elide
|
|
; CHECK: leal {{[0-9]+}}(%esp), %[[reg:[^ ]*]]
|
|
; CHECK: pushl %[[reg]]
|
|
; CHECK: calll _capture
|
|
; ...
|
|
; CHECK: calll _tail_std@4
|
|
; CHECK: retl $4
|