mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
8418cd3680
Summary: musttail calls should not require allocating extra stack for arguments. Updates to arguments passed in memory should happen in place before the epilogue. This bug was mostly a missed optimization, unless inalloca was used and store to push conversion fired. If a reserved call frame was used for an inalloca musttail call, the call setup and teardown instructions would be deleted, and SP adjustments would be inserted in the prologue and epilogue. You can see these are removed from several test cases in this change. In the case where the stack frame was not reserved, i.e. call frame optimization fires and turns argument stores into pushes, then the imbalanced call frame setup instructions created for inalloca calls become a problem. They remain in the instruction stream, resulting in a call setup that allocates zero bytes (expected for inalloca), and a call teardown that deallocates the inalloca pack. This deallocation was unbalanced, leading to subsequent crashes. Reviewers: hans Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71097
93 lines
2.7 KiB
LLVM
93 lines
2.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s -check-prefix=X64
|
|
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s -check-prefix=X32
|
|
|
|
; tailcc will turn all of these musttail calls into tail calls.
|
|
|
|
declare tailcc i32 @tailcallee(i32 %a1, i32 %a2)
|
|
|
|
define tailcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind {
|
|
; X64-LABEL: tailcaller:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: jmp tailcallee # TAILCALL
|
|
;
|
|
; X32-LABEL: tailcaller:
|
|
; X32: # %bb.0: # %entry
|
|
; X32-NEXT: jmp tailcallee # TAILCALL
|
|
entry:
|
|
%tmp11 = musttail call tailcc i32 @tailcallee(i32 %in1, i32 %in2)
|
|
ret i32 %tmp11
|
|
}
|
|
|
|
declare tailcc i8* @alias_callee()
|
|
|
|
define tailcc noalias i8* @noalias_caller() nounwind {
|
|
; X64-LABEL: noalias_caller:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: jmp alias_callee # TAILCALL
|
|
;
|
|
; X32-LABEL: noalias_caller:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: jmp alias_callee # TAILCALL
|
|
%p = musttail call tailcc i8* @alias_callee()
|
|
ret i8* %p
|
|
}
|
|
|
|
declare tailcc noalias i8* @noalias_callee()
|
|
|
|
define tailcc i8* @alias_caller() nounwind {
|
|
; X64-LABEL: alias_caller:
|
|
; X64: # %bb.0:
|
|
; X64-NEXT: jmp noalias_callee # TAILCALL
|
|
;
|
|
; X32-LABEL: alias_caller:
|
|
; X32: # %bb.0:
|
|
; X32-NEXT: jmp noalias_callee # TAILCALL
|
|
%p = musttail call tailcc noalias i8* @noalias_callee()
|
|
ret i8* %p
|
|
}
|
|
|
|
define tailcc void @void_test(i32, i32, i32, i32) {
|
|
; X64-LABEL: void_test:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: jmp void_test # TAILCALL
|
|
;
|
|
; X32-LABEL: void_test:
|
|
; X32: # %bb.0: # %entry
|
|
; X32-NEXT: pushl %esi
|
|
; X32-NEXT: .cfi_def_cfa_offset 8
|
|
; X32-NEXT: .cfi_offset %esi, -8
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
|
; X32-NEXT: movl %esi, {{[0-9]+}}(%esp)
|
|
; X32-NEXT: movl %eax, {{[0-9]+}}(%esp)
|
|
; X32-NEXT: popl %esi
|
|
; X32-NEXT: .cfi_def_cfa_offset 4
|
|
; X32-NEXT: jmp void_test # TAILCALL
|
|
entry:
|
|
musttail call tailcc void @void_test( i32 %0, i32 %1, i32 %2, i32 %3)
|
|
ret void
|
|
}
|
|
|
|
define tailcc i1 @i1test(i32, i32, i32, i32) {
|
|
; X64-LABEL: i1test:
|
|
; X64: # %bb.0: # %entry
|
|
; X64-NEXT: jmp i1test # TAILCALL
|
|
;
|
|
; X32-LABEL: i1test:
|
|
; X32: # %bb.0: # %entry
|
|
; X32-NEXT: pushl %esi
|
|
; X32-NEXT: .cfi_def_cfa_offset 8
|
|
; X32-NEXT: .cfi_offset %esi, -8
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
|
|
; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
|
|
; X32-NEXT: movl %esi, {{[0-9]+}}(%esp)
|
|
; X32-NEXT: movl %eax, {{[0-9]+}}(%esp)
|
|
; X32-NEXT: popl %esi
|
|
; X32-NEXT: .cfi_def_cfa_offset 4
|
|
; X32-NEXT: jmp i1test # TAILCALL
|
|
entry:
|
|
%4 = musttail call tailcc i1 @i1test( i32 %0, i32 %1, i32 %2, i32 %3)
|
|
ret i1 %4
|
|
}
|