xref: /llvm-project/llvm/test/CodeGen/ARM/byval-align.ll (revision bed1c7f061aa12417aa081e334afdba45767b938)
1; RUN: llc -mtriple=thumbv7-apple-ios8.0 %s -o - | FileCheck %s
2
3; This checks that alignments greater than 4 are respected by APCS
4; targets. Mostly here to make sure *some* correct code is created after some
5; simplifying refactoring; at the time of writing there were no actual APCS
6; users of byval alignments > 4, so no real calls for ABI stability.
7
8; "byval align 16" can't fit in any regs with an ptr taking up r0.
9define i32 @test_align16(ptr, ptr byval([4 x i32]) align 16 %b) {
10; CHECK-LABEL: test_align16:
11; CHECK-NOT: sub sp
12; CHECK: push {r4, r7, lr}
13; CHECK: add r7, sp, #4
14
15; CHECK: ldr r0, [r7, #8]
16
17  call void @bar()
18  %val = load i32, ptr %b
19  ret i32 %val
20}
21
22; byval align 8 can, but we used to incorrectly set r7 here (miscalculating the
23; space taken up by arg regs).
24define i32 @test_align8(ptr, ptr byval([4 x i32]) align 8 %b) {
25; CHECK-LABEL: test_align8:
26; CHECK: sub sp, #8
27; CHECK: push {r4, r7, lr}
28; CHECK: add r7, sp, #4
29
30; CHECK: strd r2, r3, [r7, #8]
31
32; CHECK: ldr r0, [r7, #8]
33
34  call void @bar()
35  %val = load i32, ptr %b
36  ret i32 %val
37}
38
39; "byval align 32" can't fit in regs no matter what: it would be misaligned
40; unless the incoming stack was deliberately misaligned.
41define i32 @test_align32(ptr, ptr byval([4 x i32]) align 32 %b) {
42; CHECK-LABEL: test_align32:
43; CHECK-NOT: sub sp
44; CHECK: push {r4, r7, lr}
45; CHECK: add r7, sp, #4
46
47; CHECK: ldr r0, [r7, #8]
48
49  call void @bar()
50  %val = load i32, ptr %b
51  ret i32 %val
52}
53
54; When passing an object "byval align N", the stack must be at least N-aligned.
55define void @test_call_align16() {
56; CHECK-LABEL: test_call_align16:
57; CHECK: push {r4, r7, lr}
58; CHECK: add r7, sp, #4
59
60; CHECK: mov [[TMP:r[0-9]+]], sp
61; CHECK: bfc [[TMP]], #0, #4
62; CHECK: mov sp, [[TMP]]
63
64; While we're here, make sure the caller also puts it at sp
65  ; CHECK: mov r[[BASE:[0-9]+]], sp
66  ; CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r[[BASE]]]
67  call i32 @test_align16(ptr null, ptr byval([4 x i32]) align 16 @var)
68  ret void
69}
70
71@var = global [4 x i32] zeroinitializer
72declare void @bar()
73