diff options
author | Jiangning Liu <jiangning.liu@arm.com> | 2014-05-15 01:33:17 +0000 |
---|---|---|
committer | Jiangning Liu <jiangning.liu@arm.com> | 2014-05-15 01:33:17 +0000 |
commit | 66b123f0d889ed5bd6d4b66f209617d596da9a0c (patch) | |
tree | d7b439d9698e083d58228754bfce72e77e2d3656 /test/CodeGen/AArch64 | |
parent | cea72fe7634afc8d0cdb860924e6f51d2a64b842 (diff) | |
download | llvm-66b123f0d889ed5bd6d4b66f209617d596da9a0c.tar.gz llvm-66b123f0d889ed5bd6d4b66f209617d596da9a0c.tar.bz2 llvm-66b123f0d889ed5bd6d4b66f209617d596da9a0c.tar.xz |
[ARM64] Support aggressive fastcc/tailcallopt breaking ABI by popping out argument stack from callee.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208837 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/AArch64')
-rw-r--r-- | test/CodeGen/AArch64/fastcc-reserved.ll | 16 | ||||
-rw-r--r-- | test/CodeGen/AArch64/fastcc.ll | 105 | ||||
-rw-r--r-- | test/CodeGen/AArch64/tail-call.ll | 59 |
3 files changed, 176 insertions, 4 deletions
diff --git a/test/CodeGen/AArch64/fastcc-reserved.ll b/test/CodeGen/AArch64/fastcc-reserved.ll index c6c050570d..97410aa502 100644 --- a/test/CodeGen/AArch64/fastcc-reserved.ll +++ b/test/CodeGen/AArch64/fastcc-reserved.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=arm64-none-linux-gnu -tailcallopt | FileCheck %s --check-prefix=CHECK-ARM64 ; This test is designed to be run in the situation where the ; call-frame is not reserved (hence disable-fp-elim), but where @@ -14,20 +15,28 @@ define fastcc void @foo(i32 %in) { ; Normal frame setup stuff: ; CHECK: sub sp, sp, ; CHECK: stp x29, x30 +; CHECK-ARM64: stp x29, x30, [sp, #-16]! +; CHECK-ARM64: mov x29, sp ; Reserve space for call-frame: ; CHECK: sub sp, sp, #16 +; CHECK-ARM64: sub sp, sp, #16 call fastcc void @will_pop([8 x i32] undef, i32 42) ; CHECK: bl will_pop +; CHECK-ARM64: bl will_pop ; Since @will_pop is fastcc with tailcallopt, it will put the stack ; back where it needs to be, we shouldn't duplicate that ; CHECK-NOT: sub sp, sp, #16 ; CHECK-NOT: add sp, sp, +; CHECK-ARM64-NOT: sub sp, sp, #16 +; CHECK-ARM64-NOT: add sp, sp, ; CHECK: ldp x29, x30 ; CHECK: add sp, sp, +; CHECK-ARM64: mov sp, x29 +; CHECK-ARM64: ldp x29, x30, [sp], #16 ret void } @@ -40,19 +49,26 @@ define void @foo1(i32 %in) { ; Normal frame setup again ; CHECK: sub sp, sp, ; CHECK: stp x29, x30 +; CHECK-ARM64: stp x29, x30, [sp, #-16]! +; CHECK-ARM64: mov x29, sp ; Reserve space for call-frame ; CHECK: sub sp, sp, #16 +; CHECK-ARM64: sub sp, sp, #16 call void @wont_pop([8 x i32] undef, i32 42) ; CHECK: bl wont_pop +; CHECK-ARM64: bl wont_pop ; This time we *do* need to unreserve the call-frame ; CHECK: add sp, sp, #16 +; CHECK-ARM64: add sp, sp, #16 ; Check for epilogue (primarily to make sure sp spotted above wasn't ; part of it). ; CHECK: ldp x29, x30 ; CHECK: add sp, sp, +; CHECK-ARM64: mov sp, x29 +; CHECK-ARM64: ldp x29, x30, [sp], #16 ret void } diff --git a/test/CodeGen/AArch64/fastcc.ll b/test/CodeGen/AArch64/fastcc.ll index a4cd37858e..fb9b4ac57e 100644 --- a/test/CodeGen/AArch64/fastcc.ll +++ b/test/CodeGen/AArch64/fastcc.ll @@ -1,5 +1,7 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s -check-prefix CHECK-TAIL +; RUN: llc -verify-machineinstrs < %s -mtriple=arm64-none-linux-gnu -tailcallopt | FileCheck %s -check-prefix CHECK-ARM64-TAIL ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=arm64-none-linux-gnu | FileCheck --check-prefix=CHECK-ARM64 %s ; Without tailcallopt fastcc still means the caller cleans up the ; stack, so try to make sure this is respected. @@ -8,116 +10,219 @@ define fastcc void @func_stack0() { ; CHECK-LABEL: func_stack0: ; CHECK: sub sp, sp, #48 +; CHECK-ARM64-LABEL: func_stack0: +; CHECK-ARM64: stp x29, x30, [sp, #-16]! +; CHECK-ARM64-NEXT: mov x29, sp +; CHECK-ARM64-NEXT: sub sp, sp, #32 + ; CHECK-TAIL-LABEL: func_stack0: ; CHECK-TAIL: sub sp, sp, #48 +; CHECK-ARM64-TAIL-LABEL: func_stack0: +; CHECK-ARM64-TAIL: stp x29, x30, [sp, #-16]! +; CHECK-ARM64-TAIL-NEXT: mov x29, sp +; CHECK-ARM64-TAIL-NEXT: sub sp, sp, #32 + call fastcc void @func_stack8([8 x i32] undef, i32 42) ; CHECK: bl func_stack8 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack8 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack8 ; CHECK-TAIL: sub sp, sp, #16 +; CHECK-ARM64-TAIL: bl func_stack8 +; CHECK-ARM64-TAIL: sub sp, sp, #16 + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) ; CHECK: bl func_stack32 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack32 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack32 ; CHECK-TAIL: sub sp, sp, #32 +; CHECK-ARM64-TAIL: bl func_stack32 +; CHECK-ARM64-TAIL: sub sp, sp, #32 + call fastcc void @func_stack0() ; CHECK: bl func_stack0 ; CHECK-NOT: sub sp, sp +; CHECK-ARM64: bl func_stack0 +; CHECK-ARM64-NOT: sub sp, sp + ; CHECK-TAIL: bl func_stack0 ; CHECK-TAIL-NOT: sub sp, sp +; CHECK-ARM64-TAIL: bl func_stack0 +; CHECK-ARM64-TAIL-NOT: sub sp, sp + ret void ; CHECK: add sp, sp, #48 ; CHECK-NEXT: ret +; CHECK-ARM64: mov sp, x29 +; CHECK-ARM64-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-NEXT: ret + ; CHECK-TAIL: add sp, sp, #48 ; CHECK-TAIL-NEXT: ret +; CHECK-ARM64-TAIL: mov sp, x29 +; CHECK-ARM64-TAIL-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-TAIL-NEXT: ret } define fastcc void @func_stack8([8 x i32], i32 %stacked) { ; CHECK-LABEL: func_stack8: ; CHECK: sub sp, sp, #48 +; CHECK-ARM64-LABEL: func_stack8: +; CHECK-ARM64: stp x29, x30, [sp, #-16]! +; CHECK-ARM64: mov x29, sp +; CHECK-ARM64: sub sp, sp, #32 + ; CHECK-TAIL-LABEL: func_stack8: ; CHECK-TAIL: sub sp, sp, #48 +; CHECK-ARM64-TAIL-LABEL: func_stack8: +; CHECK-ARM64-TAIL: stp x29, x30, [sp, #-16]! +; CHECK-ARM64-TAIL: mov x29, sp +; CHECK-ARM64-TAIL: sub sp, sp, #32 + call fastcc void @func_stack8([8 x i32] undef, i32 42) ; CHECK: bl func_stack8 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack8 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack8 ; CHECK-TAIL: sub sp, sp, #16 +; CHECK-ARM64-TAIL: bl func_stack8 +; CHECK-ARM64-TAIL: sub sp, sp, #16 + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) ; CHECK: bl func_stack32 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack32 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack32 ; CHECK-TAIL: sub sp, sp, #32 +; CHECK-ARM64-TAIL: bl func_stack32 +; CHECK-ARM64-TAIL: sub sp, sp, #32 + call fastcc void @func_stack0() ; CHECK: bl func_stack0 ; CHECK-NOT: sub sp, sp +; CHECK-ARM64: bl func_stack0 +; CHECK-ARM64-NOT: sub sp, sp + ; CHECK-TAIL: bl func_stack0 ; CHECK-TAIL-NOT: sub sp, sp +; CHECK-ARM64-TAIL: bl func_stack0 +; CHECK-ARM64-TAIL-NOT: sub sp, sp + ret void ; CHECK: add sp, sp, #48 ; CHECK-NEXT: ret +; CHECK-ARM64: mov sp, x29 +; CHECK-ARM64-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-NEXT: ret + ; CHECK-TAIL: add sp, sp, #64 ; CHECK-TAIL-NEXT: ret + +; CHECK-ARM64-TAIL: mov sp, x29 +; CHECK-ARM64-TAIL-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-TAIL-NEXT: ret } define fastcc void @func_stack32([8 x i32], i128 %stacked0, i128 %stacked1) { ; CHECK-LABEL: func_stack32: ; CHECK: sub sp, sp, #48 +; CHECK-ARM64-LABEL: func_stack32: +; CHECK-ARM64: mov x29, sp + ; CHECK-TAIL-LABEL: func_stack32: ; CHECK-TAIL: sub sp, sp, #48 +; CHECK-ARM64-TAIL-LABEL: func_stack32: +; CHECK-ARM64-TAIL: mov x29, sp + call fastcc void @func_stack8([8 x i32] undef, i32 42) ; CHECK: bl func_stack8 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack8 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack8 ; CHECK-TAIL: sub sp, sp, #16 +; CHECK-ARM64-TAIL: bl func_stack8 +; CHECK-ARM64-TAIL: sub sp, sp, #16 + call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) ; CHECK: bl func_stack32 ; CHECK-NOT: sub sp, sp, +; CHECK-ARM64: bl func_stack32 +; CHECK-ARM64-NOT: sub sp, sp, + ; CHECK-TAIL: bl func_stack32 ; CHECK-TAIL: sub sp, sp, #32 +; CHECK-ARM64-TAIL: bl func_stack32 +; CHECK-ARM64-TAIL: sub sp, sp, #32 + call fastcc void @func_stack0() ; CHECK: bl func_stack0 ; CHECK-NOT: sub sp, sp +; CHECK-ARM64: bl func_stack0 +; CHECK-ARM64-NOT: sub sp, sp + ; CHECK-TAIL: bl func_stack0 ; CHECK-TAIL-NOT: sub sp, sp +; CHECK-ARM64-TAIL: bl func_stack0 +; CHECK-ARM64-TAIL-NOT: sub sp, sp + ret void ; CHECK: add sp, sp, #48 ; CHECK-NEXT: ret +; CHECK-ARM64: mov sp, x29 +; CHECK-ARM64-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-NEXT: ret + ; CHECK-TAIL: add sp, sp, #80 ; CHECK-TAIL-NEXT: ret + +; CHECK-ARM64-TAIL: mov sp, x29 +; CHECK-ARM64-TAIL-NEXT: ldp x29, x30, [sp], #16 +; CHECK-ARM64-TAIL-NEXT: ret } diff --git a/test/CodeGen/AArch64/tail-call.ll b/test/CodeGen/AArch64/tail-call.ll index 81885f1085..da05848dcc 100644 --- a/test/CodeGen/AArch64/tail-call.ll +++ b/test/CodeGen/AArch64/tail-call.ll @@ -1,4 +1,5 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=arm64-none-linux-gnu -tailcallopt | FileCheck --check-prefix=CHECK-ARM64 %s declare fastcc void @callee_stack0() declare fastcc void @callee_stack8([8 x i32], i64) @@ -7,57 +8,92 @@ declare fastcc void @callee_stack16([8 x i32], i64, i64) define fastcc void @caller_to0_from0() nounwind { ; CHECK-LABEL: caller_to0_from0: ; CHECK-NEXT: // BB + +; CHECK-ARM64-LABEL: caller_to0_from0: +; CHECK-ARM64-NEXT: // BB + tail call fastcc void @callee_stack0() ret void + ; CHECK-NEXT: b callee_stack0 + +; CHECK-ARM64-NEXT: b callee_stack0 } define fastcc void @caller_to0_from8([8 x i32], i64) { ; CHECK-LABEL: caller_to0_from8: +; CHECK-ARM64-LABEL: caller_to0_from8: + tail call fastcc void @callee_stack0() ret void + ; CHECK: add sp, sp, #16 ; CHECK-NEXT: b callee_stack0 + +; CHECK-ARM64: add sp, sp, #16 +; CHECK-ARM64-NEXT: b callee_stack0 } define fastcc void @caller_to8_from0() { ; CHECK-LABEL: caller_to8_from0: ; CHECK: sub sp, sp, #32 +; CHECK-ARM64-LABEL: caller_to8_from0: +; CHECK-ARM64: sub sp, sp, #32 + ; Key point is that the "42" should go #16 below incoming stack ; pointer (we didn't have arg space to reuse). tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) ret void + ; CHECK: str {{x[0-9]+}}, [sp, #16] ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: b callee_stack8 + +; CHECK-ARM64: str {{x[0-9]+}}, [sp, #16]! +; CHECK-ARM64-NEXT: b callee_stack8 } define fastcc void @caller_to8_from8([8 x i32], i64 %a) { ; CHECK-LABEL: caller_to8_from8: ; CHECK: sub sp, sp, #16 +; CHECK-ARM64-LABEL: caller_to8_from8: +; CHECK-ARM64: sub sp, sp, #16 + ; Key point is that the "%a" should go where at SP on entry. tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) ret void + ; CHECK: str {{x[0-9]+}}, [sp, #16] ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: b callee_stack8 + +; CHECK-ARM64: str {{x[0-9]+}}, [sp, #16]! +; CHECK-ARM64-NEXT: b callee_stack8 } define fastcc void @caller_to16_from8([8 x i32], i64 %a) { ; CHECK-LABEL: caller_to16_from8: ; CHECK: sub sp, sp, #16 +; CHECK-ARM64-LABEL: caller_to16_from8: +; CHECK-ARM64: sub sp, sp, #16 + ; Important point is that the call reuses the "dead" argument space ; above %a on the stack. If it tries to go below incoming-SP then the ; callee will not deallocate the space, even in fastcc. tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2) + ; CHECK: str {{x[0-9]+}}, [sp, #24] ; CHECK: str {{x[0-9]+}}, [sp, #16] -; CHECK: add sp, sp, #16 -; CHECK: b callee_stack16 +; CHECK-NEXT: add sp, sp, #16 +; CHECK-NEXT: b callee_stack16 + +; CHECK-ARM64: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16] +; CHECK-ARM64-NEXT: add sp, sp, #16 +; CHECK-ARM64-NEXT: b callee_stack16 ret void } @@ -66,12 +102,19 @@ define fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) { ; CHECK-LABEL: caller_to8_from24: ; CHECK: sub sp, sp, #16 +; CHECK-ARM64-LABEL: caller_to8_from24: +; CHECK-ARM64: sub sp, sp, #16 + ; Key point is that the "%a" should go where at #16 above SP on entry. tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) ret void + ; CHECK: str {{x[0-9]+}}, [sp, #32] ; CHECK-NEXT: add sp, sp, #32 ; CHECK-NEXT: b callee_stack8 + +; CHECK-ARM64: str {{x[0-9]+}}, [sp, #32]! +; CHECK-ARM64-NEXT: b callee_stack8 } @@ -79,6 +122,9 @@ define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { ; CHECK-LABEL: caller_to16_from16: ; CHECK: sub sp, sp, #16 +; CHECK-ARM64-LABEL: caller_to16_from16: +; CHECK-ARM64: sub sp, sp, #16 + ; Here we want to make sure that both loads happen before the stores: ; otherwise either %a or %b will be wrongly clobbered. tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a) @@ -89,6 +135,11 @@ define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { ; CHECK: str x1, ; CHECK: str x0, -; CHECK: add sp, sp, #16 -; CHECK: b callee_stack16 +; CHECK-NEXT: add sp, sp, #16 +; CHECK-NEXT: b callee_stack16 + +; CHECK-ARM64: ldp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16] +; CHECK-ARM64: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16] +; CHECK-ARM64-NEXT: add sp, sp, #16 +; CHECK-ARM64-NEXT: b callee_stack16 } |