Home | History | Annotate | Download | only in AArch64
      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
      5 define 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 {
      6 entry:
      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 
     41 define i32 @i8i16caller() nounwind readnone {
     42 entry:
     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
     63 define 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 }
     69 declare 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.
     74 define double @fixed_4i(<4 x i32>* nocapture %in) nounwind {
     75 entry:
     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 }
     86 declare 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
     91 define 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 {
     93 entry:
     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.
    108 define 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 {
    110 entry:
    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.
    128 define double @test3(<2 x i32>* nocapture %in) nounwind {
    129 entry:
    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 }
    142 declare 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 
    145 define double @test4(double* nocapture %in) nounwind {
    146 entry:
    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 }
    157 declare double @args_f64(double, double, double, double, double, double, double,
    158                double, float, double, i8 signext)
    159 
    160 define i64 @test5(i64* nocapture %in) nounwind {
    161 entry:
    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 }
    171 declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64,
    172              i8 signext)
    173 
    174 define i32 @test6(float* nocapture %in) nounwind {
    175 entry:
    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 }
    187 declare 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 
    191 define i32 @test7(i32* nocapture %in) nounwind {
    192 entry:
    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 }
    202 declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32,
    203              i8 signext)
    204 
    205 define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind {
    206 entry:
    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 
    226 declare 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 
    230 define 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