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