diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2014-03-05 15:25:27 +0000 |
---|---|---|
committer | Oliver Stannard <oliver.stannard@arm.com> | 2014-03-05 15:25:27 +0000 |
commit | 0d31d1e61271ad4d93c1c567a97fef4077124b8c (patch) | |
tree | 3801e9922bd9730ec5034115f9a233c9f950f820 /test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll | |
parent | f6003a6337e362432591509d151482cf245f4734 (diff) |
ARM: Correctly align arguments after a byval struct is passed on the stack
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202985 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll')
-rw-r--r-- | test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll b/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll new file mode 100644 index 00000000000..054a45ced1d --- /dev/null +++ b/test/CodeGen/ARM/2014-02-21-byval-reg-split-alignment.ll @@ -0,0 +1,114 @@ +; RUN: llc -mtriple=arm-linux-gnueabihf < %s | FileCheck %s + +%struct4bytes = type { i32 } +%struct8bytes8align = type { i64 } +%struct12bytes = type { i32, i32, i32 } + +declare void @useIntPtr(%struct4bytes*) +declare void @useLong(i64) +declare void @usePtr(%struct8bytes8align*) + +; a -> r0 +; b -> r1..r3 +; c -> sp+0..sp+7 +define void @foo1(i32 %a, %struct12bytes* byval %b, i64 %c) { +; CHECK-LABEL: foo1 +; CHECK: sub sp, sp, #16 +; CHECK: push {r11, lr} +; CHECK: add [[SCRATCH:r[0-9]+]], sp, #12 +; CHECK: stm [[SCRATCH]], {r1, r2, r3} +; CHECK: ldr r0, [sp, #24] +; CHECK: ldr r1, [sp, #28] +; CHECK: bl useLong +; CHECK: pop {r11, lr} +; CHECK: add sp, sp, #16 + + tail call void @useLong(i64 %c) + ret void +} + +; a -> r0 +; b -> r2..r3 +define void @foo2(i32 %a, %struct8bytes8align* byval %b) { +; CHECK-LABEL: foo2 +; CHECK: sub sp, sp, #8 +; CHECK: push {r11, lr} +; CHECK: add r0, sp, #8 +; CHECK: str r3, [sp, #12] +; CHECK: str r2, [sp, #8] +; CHECK: bl usePtr +; CHECK: pop {r11, lr} +; CHECK: add sp, sp, #8 + + tail call void @usePtr(%struct8bytes8align* %b) + ret void +} + +; a -> r0..r1 +; b -> r2 +define void @foo3(%struct8bytes8align* byval %a, %struct4bytes* byval %b) { +; CHECK-LABEL: foo3 +; CHECK: sub sp, sp, #16 +; CHECK: push {r11, lr} +; CHECK: add [[SCRATCH:r[0-9]+]], sp, #8 +; CHECK: stm [[SCRATCH]], {r0, r1, r2} +; CHECK: add r0, sp, #8 +; CHECK: bl usePtr +; CHECK: pop {r11, lr} +; CHECK: add sp, sp, #16 + + tail call void @usePtr(%struct8bytes8align* %a) + ret void +} + +; a -> r0 +; b -> r2..r3 +define void @foo4(%struct4bytes* byval %a, %struct8bytes8align* byval %b) { +; CHECK-LABEL: foo4 +; CHECK: sub sp, sp, #16 +; CHECK: push {r11, lr} +; CHECK: str r0, [sp, #8] +; CHECK: add r0, sp, #16 +; CHECK: str r3, [sp, #20] +; CHECK: str r2, [sp, #16] +; CHECK: bl usePtr +; CHECK: pop {r11, lr} +; CHECK: add sp, sp, #16 +; CHECK: mov pc, lr + + tail call void @usePtr(%struct8bytes8align* %b) + ret void +} + +; a -> r0..r1 +; b -> r2 +; c -> r3 +define void @foo5(%struct8bytes8align* byval %a, %struct4bytes* byval %b, %struct4bytes* byval %c) { +; CHECK-LABEL: foo5 +; CHECK: sub sp, sp, #16 +; CHECK: push {r11, lr} +; CHECK: add [[SCRATCH:r[0-9]+]], sp, #8 +; CHECK: stm [[SCRATCH]], {r0, r1, r2, r3} +; CHECK: add r0, sp, #8 +; CHECK: bl usePtr +; CHECK: pop {r11, lr} +; CHECK: add sp, sp, #16 +; CHECK: mov pc, lr + + tail call void @usePtr(%struct8bytes8align* %a) + ret void +} + +; a..c -> r0..r2 +; d -> sp+0..sp+7 +define void @foo6(i32 %a, i32 %b, i32 %c, %struct8bytes8align* byval %d) { +; CHECK-LABEL: foo6 +; CHECK: push {r11, lr} +; CHECK: add r0, sp, #8 +; CHECK: bl usePtr +; CHECK: pop {r11, lr} +; CHECK: mov pc, lr + + tail call void @usePtr(%struct8bytes8align* %d) + ret void +} |