xref: /aosp_15_r20/external/llvm/test/CodeGen/Thumb2/aligned-spill.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=cortex-a8 -align-neon-spills=0 | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=cortex-a8 -align-neon-spills=1 | FileCheck %s --check-prefix=NEON
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
4*9880d681SAndroid Build Coastguard Workertarget triple = "thumbv7-apple-ios"
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; CHECK: f
7*9880d681SAndroid Build Coastguard Worker; This function is forced to spill a double.
8*9880d681SAndroid Build Coastguard Worker; Verify that the spill slot is properly aligned.
9*9880d681SAndroid Build Coastguard Worker;
10*9880d681SAndroid Build Coastguard Worker; The caller-saved r4 is used as a scratch register for stack realignment.
11*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r7, lr}
12*9880d681SAndroid Build Coastguard Worker; CHECK: bfc r4, #0, #3
13*9880d681SAndroid Build Coastguard Worker; CHECK: mov sp, r4
14*9880d681SAndroid Build Coastguard Workerdefine void @f(double* nocapture %p) nounwind ssp {
15*9880d681SAndroid Build Coastguard Workerentry:
16*9880d681SAndroid Build Coastguard Worker  %0 = load double, double* %p, align 4
17*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"() nounwind
18*9880d681SAndroid Build Coastguard Worker  tail call void @g() nounwind
19*9880d681SAndroid Build Coastguard Worker  store double %0, double* %p, align 4
20*9880d681SAndroid Build Coastguard Worker  ret void
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; NEON: f
24*9880d681SAndroid Build Coastguard Worker; NEON: push {r4, r7, lr}
25*9880d681SAndroid Build Coastguard Worker; NEON: sub.w r4, sp, #64
26*9880d681SAndroid Build Coastguard Worker; NEON: bfc r4, #0, #4
27*9880d681SAndroid Build Coastguard Worker; Stack pointer must be updated before the spills.
28*9880d681SAndroid Build Coastguard Worker; NEON: mov sp, r4
29*9880d681SAndroid Build Coastguard Worker; NEON: vst1.64 {d8, d9, d10, d11}, [r4:128]!
30*9880d681SAndroid Build Coastguard Worker; NEON: vst1.64 {d12, d13, d14, d15}, [r4:128]
31*9880d681SAndroid Build Coastguard Worker; Stack pointer adjustment for the stack frame contents.
32*9880d681SAndroid Build Coastguard Worker; This could legally happen before the spills.
33*9880d681SAndroid Build Coastguard Worker; Since the spill slot is only 8 bytes, technically it would be fine to only
34*9880d681SAndroid Build Coastguard Worker; subtract #8 here. That would leave sp less aligned than some stack slots,
35*9880d681SAndroid Build Coastguard Worker; and would probably blow MFI's mind.
36*9880d681SAndroid Build Coastguard Worker; NEON: sub sp, #16
37*9880d681SAndroid Build Coastguard Worker; The epilog is free to use another scratch register than r4.
38*9880d681SAndroid Build Coastguard Worker; NEON: add r[[R4:[0-9]+]], sp, #16
39*9880d681SAndroid Build Coastguard Worker; NEON: vld1.64 {d8, d9, d10, d11}, [r[[R4]]:128]!
40*9880d681SAndroid Build Coastguard Worker; NEON: vld1.64 {d12, d13, d14, d15}, [r[[R4]]:128]
41*9880d681SAndroid Build Coastguard Worker; The stack pointer restore must happen after the reloads.
42*9880d681SAndroid Build Coastguard Worker; NEON: mov sp,
43*9880d681SAndroid Build Coastguard Worker; NEON: pop
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workerdeclare void @g()
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker; Spill 7 d-registers.
48*9880d681SAndroid Build Coastguard Workerdefine void @f7(double* nocapture %p) nounwind ssp {
49*9880d681SAndroid Build Coastguard Workerentry:
50*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14}"() nounwind
51*9880d681SAndroid Build Coastguard Worker  ret void
52*9880d681SAndroid Build Coastguard Worker}
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker; NEON: f7
55*9880d681SAndroid Build Coastguard Worker; NEON: push {r4, r7, lr}
56*9880d681SAndroid Build Coastguard Worker; NEON: sub.w r4, sp, #56
57*9880d681SAndroid Build Coastguard Worker; NEON: bfc r4, #0, #4
58*9880d681SAndroid Build Coastguard Worker; Stack pointer must be updated before the spills.
59*9880d681SAndroid Build Coastguard Worker; NEON: mov sp, r4
60*9880d681SAndroid Build Coastguard Worker; NEON: vst1.64 {d8, d9, d10, d11}, [r4:128]!
61*9880d681SAndroid Build Coastguard Worker; NEON: vst1.64 {d12, d13}, [r4:128]
62*9880d681SAndroid Build Coastguard Worker; NEON: vstr d14, [r4, #16]
63*9880d681SAndroid Build Coastguard Worker; Epilog
64*9880d681SAndroid Build Coastguard Worker; NEON: vld1.64 {d8, d9, d10, d11},
65*9880d681SAndroid Build Coastguard Worker; NEON: vld1.64 {d12, d13},
66*9880d681SAndroid Build Coastguard Worker; NEON: vldr d14,
67*9880d681SAndroid Build Coastguard Worker; The stack pointer restore must happen after the reloads.
68*9880d681SAndroid Build Coastguard Worker; NEON: mov sp,
69*9880d681SAndroid Build Coastguard Worker; NEON: pop
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker; Spill 7 d-registers, leave a hole.
72*9880d681SAndroid Build Coastguard Workerdefine void @f3plus4(double* nocapture %p) nounwind ssp {
73*9880d681SAndroid Build Coastguard Workerentry:
74*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d12},~{d13},~{d14},~{d15}"() nounwind
75*9880d681SAndroid Build Coastguard Worker  ret void
76*9880d681SAndroid Build Coastguard Worker}
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; Aligned spilling only works for contiguous ranges starting from d8.
79*9880d681SAndroid Build Coastguard Worker; The rest goes to the standard vpush instructions.
80*9880d681SAndroid Build Coastguard Worker; NEON: f3plus4
81*9880d681SAndroid Build Coastguard Worker; NEON: push {r4, r7, lr}
82*9880d681SAndroid Build Coastguard Worker; NEON: vpush {d12, d13, d14, d15}
83*9880d681SAndroid Build Coastguard Worker; NEON: sub.w r4, sp, #24
84*9880d681SAndroid Build Coastguard Worker; NEON: bfc r4, #0, #4
85*9880d681SAndroid Build Coastguard Worker; Stack pointer must be updated before the spills.
86*9880d681SAndroid Build Coastguard Worker; NEON: mov sp, r4
87*9880d681SAndroid Build Coastguard Worker; NEON: vst1.64 {d8, d9}, [r4:128]
88*9880d681SAndroid Build Coastguard Worker; NEON: vstr d10, [r4, #16]
89*9880d681SAndroid Build Coastguard Worker; Epilog
90*9880d681SAndroid Build Coastguard Worker; NEON: vld1.64 {d8, d9},
91*9880d681SAndroid Build Coastguard Worker; NEON: vldr d10, [{{.*}}, #16]
92*9880d681SAndroid Build Coastguard Worker; The stack pointer restore must happen after the reloads.
93*9880d681SAndroid Build Coastguard Worker; NEON: mov sp,
94*9880d681SAndroid Build Coastguard Worker; NEON: vpop {d12, d13, d14, d15}
95*9880d681SAndroid Build Coastguard Worker; NEON: pop
96