1; RUN: llc -mtriple=arm64-apple-darwin -mcpu=cyclone -enable-misched=false < %s | FileCheck %s 2; RUN: llc -O0 -mtriple=arm64-apple-darwin < %s | FileCheck --check-prefix=FAST %s 3 4; rdar://9932559 5define i64 @i8i16callee(i64 %a1, i64 %a2, i64 %a3, i8 signext %a4, i16 signext %a5, i64 %a6, i64 %a7, i64 %a8, i8 signext %b1, i16 signext %b2, i8 signext %b3, i8 signext %b4) nounwind readnone noinline { 6entry: 7; CHECK-LABEL: i8i16callee: 8; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5. 9; They are i8, i16, i8 and i8. 10; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #5] 11; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #4] 12; CHECK-DAG: ldrsh {{w[0-9]+}}, [sp, #2] 13; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp] 14; FAST-LABEL: i8i16callee: 15; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #5] 16; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #4] 17; FAST-DAG: ldrsh {{w[0-9]+}}, [sp, #2] 18; FAST-DAG: ldrsb {{w[0-9]+}}, [sp] 19 %conv = sext i8 %a4 to i64 20 %conv3 = sext i16 %a5 to i64 21 %conv8 = sext i8 %b1 to i64 22 %conv9 = sext i16 %b2 to i64 23 %conv11 = sext i8 %b3 to i64 24 %conv13 = sext i8 %b4 to i64 25 %add10 = add i64 %a2, %a1 26 %add12 = add i64 %add10, %a3 27 %add14 = add i64 %add12, %conv 28 %add = add i64 %add14, %conv3 29 %add1 = add i64 %add, %a6 30 %add2 = add i64 %add1, %a7 31 %add4 = add i64 %add2, %a8 32 %add5 = add i64 %add4, %conv8 33 %add6 = add i64 %add5, %conv9 34 %add7 = add i64 %add6, %conv11 35 %add15 = add i64 %add7, %conv13 36 %sext = shl i64 %add15, 32 37 %conv17 = ashr exact i64 %sext, 32 38 ret i64 %conv17 39} 40 41define i32 @i8i16caller() nounwind readnone { 42entry: 43; CHECK-LABEL: i8i16caller 44; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5. 45; They are i8, i16, i8 and i8. 46; CHECK-DAG: strb {{w[0-9]+}}, [sp, #5] 47; CHECK-DAG: strb {{w[0-9]+}}, [sp, #4] 48; CHECK-DAG: strh {{w[0-9]+}}, [sp, #2] 49; CHECK-DAG: strb {{w[0-9]+}}, [sp] 50; CHECK: bl 51; FAST-LABEL: i8i16caller 52; FAST: strb {{w[0-9]+}}, [sp] 53; FAST: strh {{w[0-9]+}}, [sp, #2] 54; FAST: strb {{w[0-9]+}}, [sp, #4] 55; FAST: strb {{w[0-9]+}}, [sp, #5] 56; FAST: bl 57 %call = tail call i64 @i8i16callee(i64 0, i64 1, i64 2, i8 signext 3, i16 signext 4, i64 5, i64 6, i64 7, i8 signext 97, i16 signext 98, i8 signext 99, i8 signext 100) 58 %conv = trunc i64 %call to i32 59 ret i32 %conv 60} 61 62; rdar://12651543 63define double @circle_center([2 x float] %a) nounwind ssp { 64 %call = tail call double @ext([2 x float] %a) nounwind 65; CHECK-LABEL: circle_center 66; CHECK: bl 67 ret double %call 68} 69declare double @ext([2 x float]) 70 71; rdar://12656141 72; 16-byte vector should be aligned at 16-byte when passing on stack. 73; A double argument will be passed on stack, so vecotr should be at sp+16. 74define double @fixed_4i(<4 x i32>* nocapture %in) nounwind { 75entry: 76; CHECK-LABEL: fixed_4i 77; CHECK: str [[REG_1:q[0-9]+]], [sp, #16] 78; FAST-LABEL: fixed_4i 79; FAST: sub sp, sp 80; FAST: mov x[[ADDR:[0-9]+]], sp 81; FAST: str [[REG_1:q[0-9]+]], [x[[ADDR]], #16] 82 %0 = load <4 x i32>, <4 x i32>* %in, align 16 83 %call = tail call double @args_vec_4i(double 3.000000e+00, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, double 3.000000e+00, <4 x i32> %0, i8 signext 3) 84 ret double %call 85} 86declare double @args_vec_4i(double, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, double, <4 x i32>, i8 signext) 87 88; rdar://12695237 89; d8 at sp, i in register w0. 90@g_d = common global double 0.000000e+00, align 8 91define void @test1(float %f1, double %d1, double %d2, double %d3, double %d4, 92 double %d5, double %d6, double %d7, double %d8, i32 %i) nounwind ssp { 93entry: 94; CHECK-LABEL: test1 95; CHECK: ldr [[REG_1:d[0-9]+]], [sp] 96; CHECK: scvtf [[REG_2:s[0-9]+]], w0 97; CHECK: fadd s0, [[REG_2]], s0 98 %conv = sitofp i32 %i to float 99 %add = fadd float %conv, %f1 100 %conv1 = fpext float %add to double 101 %add2 = fadd double %conv1, %d7 102 %add3 = fadd double %add2, %d8 103 store double %add3, double* @g_d, align 8 104 ret void 105} 106 107; i9 at sp, d1 in register s0. 108define void @test2(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, 109 i32 %i7, i32 %i8, i32 %i9, float %d1) nounwind ssp { 110entry: 111; CHECK-LABEL: test2 112; CHECK: scvtf [[REG_2:s[0-9]+]], w0 113; CHECK: fadd s0, [[REG_2]], s0 114; CHECK: ldr [[REG_1:s[0-9]+]], [sp] 115 %conv = sitofp i32 %i1 to float 116 %add = fadd float %conv, %d1 117 %conv1 = fpext float %add to double 118 %conv2 = sitofp i32 %i8 to double 119 %add3 = fadd double %conv2, %conv1 120 %conv4 = sitofp i32 %i9 to double 121 %add5 = fadd double %conv4, %add3 122 store double %add5, double* @g_d, align 8 123 ret void 124} 125 126; rdar://12648441 127; Check alignment on stack for v64, f64, i64, f32, i32. 128define double @test3(<2 x i32>* nocapture %in) nounwind { 129entry: 130; CHECK-LABEL: test3 131; CHECK: str [[REG_1:d[0-9]+]], [sp, #8] 132; FAST-LABEL: test3 133; FAST: sub sp, sp, #32 134; FAST: mov x[[ADDR:[0-9]+]], sp 135; FAST: str [[REG_1:d[0-9]+]], [x[[ADDR]], #8] 136 %0 = load <2 x i32>, <2 x i32>* %in, align 8 137 %call = tail call double @args_vec_2i(double 3.000000e+00, <2 x i32> %0, 138 <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, 139 <2 x i32> %0, float 3.000000e+00, <2 x i32> %0, i8 signext 3) 140 ret double %call 141} 142declare double @args_vec_2i(double, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>, 143 <2 x i32>, <2 x i32>, <2 x i32>, float, <2 x i32>, i8 signext) 144 145define double @test4(double* nocapture %in) nounwind { 146entry: 147; CHECK-LABEL: test4 148; CHECK: str [[REG_1:d[0-9]+]], [sp, #8] 149; CHECK: str [[REG_2:w[0-9]+]], [sp] 150; CHECK: orr w0, wzr, #0x3 151 %0 = load double, double* %in, align 8 152 %call = tail call double @args_f64(double 3.000000e+00, double %0, double %0, 153 double %0, double %0, double %0, double %0, double %0, 154 float 3.000000e+00, double %0, i8 signext 3) 155 ret double %call 156} 157declare double @args_f64(double, double, double, double, double, double, double, 158 double, float, double, i8 signext) 159 160define i64 @test5(i64* nocapture %in) nounwind { 161entry: 162; CHECK-LABEL: test5 163; CHECK: strb [[REG_3:w[0-9]+]], [sp, #16] 164; CHECK: str [[REG_1:x[0-9]+]], [sp, #8] 165; CHECK: str [[REG_2:w[0-9]+]], [sp] 166 %0 = load i64, i64* %in, align 8 167 %call = tail call i64 @args_i64(i64 3, i64 %0, i64 %0, i64 %0, i64 %0, i64 %0, 168 i64 %0, i64 %0, i32 3, i64 %0, i8 signext 3) 169 ret i64 %call 170} 171declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64, 172 i8 signext) 173 174define i32 @test6(float* nocapture %in) nounwind { 175entry: 176; CHECK-LABEL: test6 177; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8] 178; CHECK: str [[REG_1:s[0-9]+]], [sp, #4] 179; CHECK: strh [[REG_3:w[0-9]+]], [sp] 180 %0 = load float, float* %in, align 4 181 %call = tail call i32 @args_f32(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, 182 i32 7, i32 8, float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, 183 float 6.0, float 7.0, float 8.0, i16 signext 3, float %0, 184 i8 signext 3) 185 ret i32 %call 186} 187declare i32 @args_f32(i32, i32, i32, i32, i32, i32, i32, i32, 188 float, float, float, float, float, float, float, float, 189 i16 signext, float, i8 signext) 190 191define i32 @test7(i32* nocapture %in) nounwind { 192entry: 193; CHECK-LABEL: test7 194; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8] 195; CHECK: str [[REG_1:w[0-9]+]], [sp, #4] 196; CHECK: strh [[REG_3:w[0-9]+]], [sp] 197 %0 = load i32, i32* %in, align 4 198 %call = tail call i32 @args_i32(i32 3, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0, 199 i32 %0, i32 %0, i16 signext 3, i32 %0, i8 signext 4) 200 ret i32 %call 201} 202declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32, 203 i8 signext) 204 205define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind { 206entry: 207; CHECK-LABEL: test8 208; CHECK: strb {{w[0-9]+}}, [sp, #3] 209; CHECK: strb wzr, [sp, #2] 210; CHECK: strb {{w[0-9]+}}, [sp, #1] 211; CHECK: strb wzr, [sp] 212; CHECK: bl 213; FAST-LABEL: test8 214; FAST: strb {{w[0-9]+}}, [sp] 215; FAST: strb {{w[0-9]+}}, [sp, #1] 216; FAST: strb {{w[0-9]+}}, [sp, #2] 217; FAST: strb {{w[0-9]+}}, [sp, #3] 218; FAST: bl 219 tail call void @args_i1(i1 zeroext false, i1 zeroext true, i1 zeroext false, 220 i1 zeroext true, i1 zeroext false, i1 zeroext true, 221 i1 zeroext false, i1 zeroext true, i1 zeroext false, 222 i1 zeroext true, i1 zeroext false, i1 zeroext true) 223 ret i32 0 224} 225 226declare void @args_i1(i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext, 227 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext, 228 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext) 229 230define i32 @i1_stack_incoming(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, 231 i64 %g, i64 %h, i64 %i, i1 zeroext %j) { 232; CHECK-LABEL: i1_stack_incoming: 233; CHECK: ldrb w0, [sp, #8] 234; CHECK: ret 235 %v = zext i1 %j to i32 236 ret i32 %v 237} 238