1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -stack-symbol-ordering=0 -mcpu=generic -march=x86-64 -mattr=+avx -mtriple=i686-apple-darwin10 | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -stack-symbol-ordering=0 -mcpu=generic -stackrealign -stack-alignment=32 -march=x86-64 -mattr=+avx -mtriple=i686-apple-darwin10 | FileCheck %s -check-prefix=FORCE-ALIGN 3*9880d681SAndroid Build Coastguard Worker; rdar://11496434 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; no VLAs or dynamic alignment 6*9880d681SAndroid Build Coastguard Workerdefine i32 @t1() nounwind uwtable ssp { 7*9880d681SAndroid Build Coastguard Workerentry: 8*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 9*9880d681SAndroid Build Coastguard Worker call void @t1_helper(i32* %a) nounwind 10*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 11*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 12*9880d681SAndroid Build Coastguard Worker ret i32 %add 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; CHECK: _t1 15*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: andq $-{{[0-9]+}}, %rsp 16*9880d681SAndroid Build Coastguard Worker; CHECK: leaq [[OFFSET:[0-9]*]](%rsp), %rdi 17*9880d681SAndroid Build Coastguard Worker; CHECK: callq _t1_helper 18*9880d681SAndroid Build Coastguard Worker; CHECK: movl [[OFFSET]](%rsp), %eax 19*9880d681SAndroid Build Coastguard Worker; CHECK: addl $13, %eax 20*9880d681SAndroid Build Coastguard Worker} 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerdeclare void @t1_helper(i32*) 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; dynamic realignment 25*9880d681SAndroid Build Coastguard Workerdefine i32 @t2() nounwind uwtable ssp { 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 28*9880d681SAndroid Build Coastguard Worker %v = alloca <8 x float>, align 32 29*9880d681SAndroid Build Coastguard Worker call void @t2_helper(i32* %a, <8 x float>* %v) nounwind 30*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 31*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 32*9880d681SAndroid Build Coastguard Worker ret i32 %add 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; CHECK: _t2 35*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbp 36*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbp 37*9880d681SAndroid Build Coastguard Worker; CHECK: andq $-32, %rsp 38*9880d681SAndroid Build Coastguard Worker; CHECK: subq ${{[0-9]+}}, %rsp 39*9880d681SAndroid Build Coastguard Worker; 40*9880d681SAndroid Build Coastguard Worker; CHECK: leaq {{[0-9]*}}(%rsp), %rdi 41*9880d681SAndroid Build Coastguard Worker; CHECK: leaq {{[0-9]*}}(%rsp), %rsi 42*9880d681SAndroid Build Coastguard Worker; CHECK: callq _t2_helper 43*9880d681SAndroid Build Coastguard Worker; 44*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rbp, %rsp 45*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbp 46*9880d681SAndroid Build Coastguard Worker} 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Workerdeclare void @t2_helper(i32*, <8 x float>*) 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; VLAs 51*9880d681SAndroid Build Coastguard Workerdefine i32 @t3(i64 %sz) nounwind uwtable ssp { 52*9880d681SAndroid Build Coastguard Workerentry: 53*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 54*9880d681SAndroid Build Coastguard Worker %vla = alloca i32, i64 %sz, align 16 55*9880d681SAndroid Build Coastguard Worker call void @t3_helper(i32* %a, i32* %vla) nounwind 56*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 57*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 58*9880d681SAndroid Build Coastguard Worker ret i32 %add 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker; CHECK: _t3 61*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbp 62*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbp 63*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: andq $-{{[0-9]+}}, %rsp 64*9880d681SAndroid Build Coastguard Worker; CHECK: subq ${{[0-9]+}}, %rsp 65*9880d681SAndroid Build Coastguard Worker; 66*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rbp, %rsp 67*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbp 68*9880d681SAndroid Build Coastguard Worker} 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Workerdeclare void @t3_helper(i32*, i32*) 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker; VLAs + Dynamic realignment 73*9880d681SAndroid Build Coastguard Workerdefine i32 @t4(i64 %sz) nounwind uwtable ssp { 74*9880d681SAndroid Build Coastguard Workerentry: 75*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 76*9880d681SAndroid Build Coastguard Worker %v = alloca <8 x float>, align 32 77*9880d681SAndroid Build Coastguard Worker %vla = alloca i32, i64 %sz, align 16 78*9880d681SAndroid Build Coastguard Worker call void @t4_helper(i32* %a, i32* %vla, <8 x float>* %v) nounwind 79*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 80*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 81*9880d681SAndroid Build Coastguard Worker ret i32 %add 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker; CHECK: _t4 84*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbp 85*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbp 86*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbx 87*9880d681SAndroid Build Coastguard Worker; CHECK: andq $-32, %rsp 88*9880d681SAndroid Build Coastguard Worker; CHECK: subq ${{[0-9]+}}, %rsp 89*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbx 90*9880d681SAndroid Build Coastguard Worker; 91*9880d681SAndroid Build Coastguard Worker; CHECK: leaq {{[0-9]*}}(%rbx), %rdi 92*9880d681SAndroid Build Coastguard Worker; CHECK: leaq {{[0-9]*}}(%rbx), %rdx 93*9880d681SAndroid Build Coastguard Worker; CHECK: callq _t4_helper 94*9880d681SAndroid Build Coastguard Worker; 95*9880d681SAndroid Build Coastguard Worker; CHECK: leaq -{{[0-9]+}}(%rbp), %rsp 96*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbx 97*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbp 98*9880d681SAndroid Build Coastguard Worker} 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerdeclare void @t4_helper(i32*, i32*, <8 x float>*) 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; Spilling an AVX register shouldn't cause dynamic realignment 103*9880d681SAndroid Build Coastguard Workerdefine i32 @t5(float* nocapture %f) nounwind uwtable ssp { 104*9880d681SAndroid Build Coastguard Workerentry: 105*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 106*9880d681SAndroid Build Coastguard Worker %0 = bitcast float* %f to <8 x float>* 107*9880d681SAndroid Build Coastguard Worker %1 = load <8 x float>, <8 x float>* %0, align 32 108*9880d681SAndroid Build Coastguard Worker call void @t5_helper1(i32* %a) nounwind 109*9880d681SAndroid Build Coastguard Worker call void @t5_helper2(<8 x float> %1) nounwind 110*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %a, align 4 111*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %2, 13 112*9880d681SAndroid Build Coastguard Worker ret i32 %add 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; CHECK: _t5 115*9880d681SAndroid Build Coastguard Worker; CHECK: subq ${{[0-9]+}}, %rsp 116*9880d681SAndroid Build Coastguard Worker; 117*9880d681SAndroid Build Coastguard Worker; CHECK: vmovaps (%rdi), [[AVXREG:%ymm[0-9]+]] 118*9880d681SAndroid Build Coastguard Worker; CHECK: vmovups [[AVXREG]], (%rsp) 119*9880d681SAndroid Build Coastguard Worker; CHECK: leaq {{[0-9]+}}(%rsp), %rdi 120*9880d681SAndroid Build Coastguard Worker; CHECK: callq _t5_helper1 121*9880d681SAndroid Build Coastguard Worker; CHECK: vmovups (%rsp), %ymm0 122*9880d681SAndroid Build Coastguard Worker; CHECK: callq _t5_helper2 123*9880d681SAndroid Build Coastguard Worker; CHECK: movl {{[0-9]+}}(%rsp), %eax 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdeclare void @t5_helper1(i32*) 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Workerdeclare void @t5_helper2(<8 x float>) 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker; VLAs + Dynamic realignment + Spill 131*9880d681SAndroid Build Coastguard Worker; FIXME: RA has already reserved RBX, so we can't do dynamic realignment. 132*9880d681SAndroid Build Coastguard Workerdefine i32 @t6(i64 %sz, float* nocapture %f) nounwind uwtable ssp { 133*9880d681SAndroid Build Coastguard Workerentry: 134*9880d681SAndroid Build Coastguard Worker; CHECK: _t6 135*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 136*9880d681SAndroid Build Coastguard Worker %0 = bitcast float* %f to <8 x float>* 137*9880d681SAndroid Build Coastguard Worker %1 = load <8 x float>, <8 x float>* %0, align 32 138*9880d681SAndroid Build Coastguard Worker %vla = alloca i32, i64 %sz, align 16 139*9880d681SAndroid Build Coastguard Worker call void @t6_helper1(i32* %a, i32* %vla) nounwind 140*9880d681SAndroid Build Coastguard Worker call void @t6_helper2(<8 x float> %1) nounwind 141*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %a, align 4 142*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %2, 13 143*9880d681SAndroid Build Coastguard Worker ret i32 %add 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Workerdeclare void @t6_helper1(i32*, i32*) 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Workerdeclare void @t6_helper2(<8 x float>) 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker; VLAs + Dynamic realignment + byval 151*9880d681SAndroid Build Coastguard Worker; The byval adjust the sp after the prolog, but if we're restoring the sp from 152*9880d681SAndroid Build Coastguard Worker; the base pointer we use the original adjustment. 153*9880d681SAndroid Build Coastguard Worker%struct.struct_t = type { [5 x i32] } 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerdefine void @t7(i32 %size, %struct.struct_t* byval align 8 %arg1) nounwind uwtable { 156*9880d681SAndroid Build Coastguard Workerentry: 157*9880d681SAndroid Build Coastguard Worker %x = alloca i32, align 32 158*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %x, align 32 159*9880d681SAndroid Build Coastguard Worker %0 = zext i32 %size to i64 160*9880d681SAndroid Build Coastguard Worker %vla = alloca i32, i64 %0, align 16 161*9880d681SAndroid Build Coastguard Worker %1 = load i32, i32* %x, align 32 162*9880d681SAndroid Build Coastguard Worker call void @bar(i32 %1, i32* %vla, %struct.struct_t* byval align 8 %arg1) 163*9880d681SAndroid Build Coastguard Worker ret void 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker; CHECK: _t7 166*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbp 167*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbp 168*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbx 169*9880d681SAndroid Build Coastguard Worker; CHECK: andq $-32, %rsp 170*9880d681SAndroid Build Coastguard Worker; CHECK: subq ${{[0-9]+}}, %rsp 171*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbx 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; Stack adjustment for byval 174*9880d681SAndroid Build Coastguard Worker; CHECK: subq {{.*}}, %rsp 175*9880d681SAndroid Build Coastguard Worker; CHECK: callq _bar 176*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addq {{.*}}, %rsp 177*9880d681SAndroid Build Coastguard Worker; CHECK: leaq -8(%rbp), %rsp 178*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbx 179*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbp 180*9880d681SAndroid Build Coastguard Worker} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.stacksave() nounwind 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i32, i32*, %struct.struct_t* byval align 8) 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.stackrestore(i8*) nounwind 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker; Test when forcing stack alignment 190*9880d681SAndroid Build Coastguard Workerdefine i32 @t8() nounwind uwtable { 191*9880d681SAndroid Build Coastguard Workerentry: 192*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 193*9880d681SAndroid Build Coastguard Worker call void @t1_helper(i32* %a) nounwind 194*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 195*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 196*9880d681SAndroid Build Coastguard Worker ret i32 %add 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: _t8 199*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: movq %rsp, %rbp 200*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: andq $-32, %rsp 201*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN-NEXT: subq $32, %rsp 202*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: movq %rbp, %rsp 203*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: popq %rbp 204*9880d681SAndroid Build Coastguard Worker} 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Worker; VLAs 207*9880d681SAndroid Build Coastguard Workerdefine i32 @t9(i64 %sz) nounwind uwtable { 208*9880d681SAndroid Build Coastguard Workerentry: 209*9880d681SAndroid Build Coastguard Worker %a = alloca i32, align 4 210*9880d681SAndroid Build Coastguard Worker %vla = alloca i32, i64 %sz, align 16 211*9880d681SAndroid Build Coastguard Worker call void @t3_helper(i32* %a, i32* %vla) nounwind 212*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %a, align 4 213*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %0, 13 214*9880d681SAndroid Build Coastguard Worker ret i32 %add 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: _t9 217*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: pushq %rbp 218*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: movq %rsp, %rbp 219*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: pushq %rbx 220*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: andq $-32, %rsp 221*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: subq $32, %rsp 222*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: movq %rsp, %rbx 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: leaq -8(%rbp), %rsp 225*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: popq %rbx 226*9880d681SAndroid Build Coastguard Worker; FORCE-ALIGN: popq %rbp 227*9880d681SAndroid Build Coastguard Worker} 228