Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -march=arm64 -mcpu=cyclone -enable-misched=false | FileCheck %s
      2 ; RUN: llc < %s -O0 | FileCheck -check-prefix=FAST %s
      3 target triple = "arm64-apple-darwin"
      4 
      5 ; rdar://12648441
      6 ; Generated from arm64-arguments.c with -O2.
      7 ; Test passing structs with size < 8, < 16 and > 16
      8 ; with alignment of 16 and without
      9 
     10 ; Structs with size < 8
     11 %struct.s38 = type { i32, i16 }
     12 ; With alignment of 16, the size will be padded to multiple of 16 bytes.
     13 %struct.s39 = type { i32, i16, [10 x i8] }
     14 ; Structs with size < 16
     15 %struct.s40 = type { i32, i16, i32, i16 }
     16 %struct.s41 = type { i32, i16, i32, i16 }
     17 ; Structs with size > 16
     18 %struct.s42 = type { i32, i16, i32, i16, i32, i16 }
     19 %struct.s43 = type { i32, i16, i32, i16, i32, i16, [10 x i8] }
     20 
     21 @g38 = common global %struct.s38 zeroinitializer, align 4
     22 @g38_2 = common global %struct.s38 zeroinitializer, align 4
     23 @g39 = common global %struct.s39 zeroinitializer, align 16
     24 @g39_2 = common global %struct.s39 zeroinitializer, align 16
     25 @g40 = common global %struct.s40 zeroinitializer, align 4
     26 @g40_2 = common global %struct.s40 zeroinitializer, align 4
     27 @g41 = common global %struct.s41 zeroinitializer, align 16
     28 @g41_2 = common global %struct.s41 zeroinitializer, align 16
     29 @g42 = common global %struct.s42 zeroinitializer, align 4
     30 @g42_2 = common global %struct.s42 zeroinitializer, align 4
     31 @g43 = common global %struct.s43 zeroinitializer, align 16
     32 @g43_2 = common global %struct.s43 zeroinitializer, align 16
     33 
     34 ; structs with size < 8 bytes, passed via i64 in x1 and x2
     35 define i32 @f38(i32 %i, i64 %s1.coerce, i64 %s2.coerce) #0 {
     36 entry:
     37 ; CHECK-LABEL: f38
     38 ; CHECK: add w[[A:[0-9]+]], w1, w0
     39 ; CHECK: add {{w[0-9]+}}, w[[A]], w2
     40   %s1.sroa.0.0.extract.trunc = trunc i64 %s1.coerce to i32
     41   %s1.sroa.1.4.extract.shift = lshr i64 %s1.coerce, 32
     42   %s2.sroa.0.0.extract.trunc = trunc i64 %s2.coerce to i32
     43   %s2.sroa.1.4.extract.shift = lshr i64 %s2.coerce, 32
     44   %sext8 = shl nuw nsw i64 %s1.sroa.1.4.extract.shift, 16
     45   %sext = trunc i64 %sext8 to i32
     46   %conv = ashr exact i32 %sext, 16
     47   %sext1011 = shl nuw nsw i64 %s2.sroa.1.4.extract.shift, 16
     48   %sext10 = trunc i64 %sext1011 to i32
     49   %conv6 = ashr exact i32 %sext10, 16
     50   %add = add i32 %s1.sroa.0.0.extract.trunc, %i
     51   %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
     52   %add4 = add i32 %add3, %conv
     53   %add7 = add i32 %add4, %conv6
     54   ret i32 %add7
     55 }
     56 
     57 define i32 @caller38() #1 {
     58 entry:
     59 ; CHECK-LABEL: caller38
     60 ; CHECK: ldr x1,
     61 ; CHECK: ldr x2,
     62   %0 = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 4
     63   %1 = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 4
     64   %call = tail call i32 @f38(i32 3, i64 %0, i64 %1) #5
     65   ret i32 %call
     66 }
     67 
     68 declare i32 @f38_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
     69                 i32 %i7, i32 %i8, i32 %i9, i64 %s1.coerce, i64 %s2.coerce) #0
     70 
     71 ; structs with size < 8 bytes, passed on stack at [sp+8] and [sp+16]
     72 ; i9 at [sp]
     73 define i32 @caller38_stack() #1 {
     74 entry:
     75 ; CHECK-LABEL: caller38_stack
     76 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]
     77 ; CHECK: movz w[[C:[0-9]+]], #0x9
     78 ; CHECK: str w[[C]], [sp]
     79   %0 = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 4
     80   %1 = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 4
     81   %call = tail call i32 @f38_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
     82                                    i32 7, i32 8, i32 9, i64 %0, i64 %1) #5
     83   ret i32 %call
     84 }
     85 
     86 ; structs with size < 8 bytes, alignment of 16
     87 ; passed via i128 in x1 and x3
     88 define i32 @f39(i32 %i, i128 %s1.coerce, i128 %s2.coerce) #0 {
     89 entry:
     90 ; CHECK-LABEL: f39
     91 ; CHECK: add w[[A:[0-9]+]], w1, w0
     92 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
     93   %s1.sroa.0.0.extract.trunc = trunc i128 %s1.coerce to i32
     94   %s1.sroa.1.4.extract.shift = lshr i128 %s1.coerce, 32
     95   %s2.sroa.0.0.extract.trunc = trunc i128 %s2.coerce to i32
     96   %s2.sroa.1.4.extract.shift = lshr i128 %s2.coerce, 32
     97   %sext8 = shl nuw nsw i128 %s1.sroa.1.4.extract.shift, 16
     98   %sext = trunc i128 %sext8 to i32
     99   %conv = ashr exact i32 %sext, 16
    100   %sext1011 = shl nuw nsw i128 %s2.sroa.1.4.extract.shift, 16
    101   %sext10 = trunc i128 %sext1011 to i32
    102   %conv6 = ashr exact i32 %sext10, 16
    103   %add = add i32 %s1.sroa.0.0.extract.trunc, %i
    104   %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
    105   %add4 = add i32 %add3, %conv
    106   %add7 = add i32 %add4, %conv6
    107   ret i32 %add7
    108 }
    109 
    110 define i32 @caller39() #1 {
    111 entry:
    112 ; CHECK-LABEL: caller39
    113 ; CHECK: ldp x1, x2,
    114 ; CHECK: ldp x3, x4,
    115   %0 = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 16
    116   %1 = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 16
    117   %call = tail call i32 @f39(i32 3, i128 %0, i128 %1) #5
    118   ret i32 %call
    119 }
    120 
    121 declare i32 @f39_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
    122                 i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) #0
    123 
    124 ; structs with size < 8 bytes, alignment 16
    125 ; passed on stack at [sp+16] and [sp+32]
    126 define i32 @caller39_stack() #1 {
    127 entry:
    128 ; CHECK-LABEL: caller39_stack
    129 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #32]
    130 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
    131 ; CHECK: movz w[[C:[0-9]+]], #0x9
    132 ; CHECK: str w[[C]], [sp]
    133   %0 = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 16
    134   %1 = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 16
    135   %call = tail call i32 @f39_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
    136                                    i32 7, i32 8, i32 9, i128 %0, i128 %1) #5
    137   ret i32 %call
    138 }
    139 
    140 ; structs with size < 16 bytes
    141 ; passed via i128 in x1 and x3
    142 define i32 @f40(i32 %i, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) #0 {
    143 entry:
    144 ; CHECK-LABEL: f40
    145 ; CHECK: add w[[A:[0-9]+]], w1, w0
    146 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
    147   %s1.coerce.fca.0.extract = extractvalue [2 x i64] %s1.coerce, 0
    148   %s2.coerce.fca.0.extract = extractvalue [2 x i64] %s2.coerce, 0
    149   %s1.sroa.0.0.extract.trunc = trunc i64 %s1.coerce.fca.0.extract to i32
    150   %s2.sroa.0.0.extract.trunc = trunc i64 %s2.coerce.fca.0.extract to i32
    151   %s1.sroa.0.4.extract.shift = lshr i64 %s1.coerce.fca.0.extract, 32
    152   %sext8 = shl nuw nsw i64 %s1.sroa.0.4.extract.shift, 16
    153   %sext = trunc i64 %sext8 to i32
    154   %conv = ashr exact i32 %sext, 16
    155   %s2.sroa.0.4.extract.shift = lshr i64 %s2.coerce.fca.0.extract, 32
    156   %sext1011 = shl nuw nsw i64 %s2.sroa.0.4.extract.shift, 16
    157   %sext10 = trunc i64 %sext1011 to i32
    158   %conv6 = ashr exact i32 %sext10, 16
    159   %add = add i32 %s1.sroa.0.0.extract.trunc, %i
    160   %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
    161   %add4 = add i32 %add3, %conv
    162   %add7 = add i32 %add4, %conv6
    163   ret i32 %add7
    164 }
    165 
    166 define i32 @caller40() #1 {
    167 entry:
    168 ; CHECK-LABEL: caller40
    169 ; CHECK: ldp x1, x2,
    170 ; CHECK: ldp x3, x4,
    171   %0 = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 4
    172   %1 = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 4
    173   %call = tail call i32 @f40(i32 3, [2 x i64] %0, [2 x i64] %1) #5
    174   ret i32 %call
    175 }
    176 
    177 declare i32 @f40_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
    178                 i32 %i7, i32 %i8, i32 %i9, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) #0
    179 
    180 ; structs with size < 16 bytes
    181 ; passed on stack at [sp+8] and [sp+24]
    182 define i32 @caller40_stack() #1 {
    183 entry:
    184 ; CHECK-LABEL: caller40_stack
    185 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #24]
    186 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]
    187 ; CHECK: movz w[[C:[0-9]+]], #0x9
    188 ; CHECK: str w[[C]], [sp]
    189   %0 = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 4
    190   %1 = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 4
    191   %call = tail call i32 @f40_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
    192                          i32 7, i32 8, i32 9, [2 x i64] %0, [2 x i64] %1) #5
    193   ret i32 %call
    194 }
    195 
    196 ; structs with size < 16 bytes, alignment of 16
    197 ; passed via i128 in x1 and x3
    198 define i32 @f41(i32 %i, i128 %s1.coerce, i128 %s2.coerce) #0 {
    199 entry:
    200 ; CHECK-LABEL: f41
    201 ; CHECK: add w[[A:[0-9]+]], w1, w0
    202 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
    203   %s1.sroa.0.0.extract.trunc = trunc i128 %s1.coerce to i32
    204   %s1.sroa.1.4.extract.shift = lshr i128 %s1.coerce, 32
    205   %s2.sroa.0.0.extract.trunc = trunc i128 %s2.coerce to i32
    206   %s2.sroa.1.4.extract.shift = lshr i128 %s2.coerce, 32
    207   %sext8 = shl nuw nsw i128 %s1.sroa.1.4.extract.shift, 16
    208   %sext = trunc i128 %sext8 to i32
    209   %conv = ashr exact i32 %sext, 16
    210   %sext1011 = shl nuw nsw i128 %s2.sroa.1.4.extract.shift, 16
    211   %sext10 = trunc i128 %sext1011 to i32
    212   %conv6 = ashr exact i32 %sext10, 16
    213   %add = add i32 %s1.sroa.0.0.extract.trunc, %i
    214   %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
    215   %add4 = add i32 %add3, %conv
    216   %add7 = add i32 %add4, %conv6
    217   ret i32 %add7
    218 }
    219 
    220 define i32 @caller41() #1 {
    221 entry:
    222 ; CHECK-LABEL: caller41
    223 ; CHECK: ldp x1, x2,
    224 ; CHECK: ldp x3, x4,
    225   %0 = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 16
    226   %1 = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 16
    227   %call = tail call i32 @f41(i32 3, i128 %0, i128 %1) #5
    228   ret i32 %call
    229 }
    230 
    231 declare i32 @f41_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
    232                 i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) #0
    233 
    234 ; structs with size < 16 bytes, alignment of 16
    235 ; passed on stack at [sp+16] and [sp+32]
    236 define i32 @caller41_stack() #1 {
    237 entry:
    238 ; CHECK-LABEL: caller41_stack
    239 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #32]
    240 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
    241 ; CHECK: movz w[[C:[0-9]+]], #0x9
    242 ; CHECK: str w[[C]], [sp]
    243   %0 = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 16
    244   %1 = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 16
    245   %call = tail call i32 @f41_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
    246                             i32 7, i32 8, i32 9, i128 %0, i128 %1) #5
    247   ret i32 %call
    248 }
    249 
    250 ; structs with size of 22 bytes, passed indirectly in x1 and x2
    251 define i32 @f42(i32 %i, %struct.s42* nocapture %s1, %struct.s42* nocapture %s2) #2 {
    252 entry:
    253 ; CHECK-LABEL: f42
    254 ; CHECK: ldr w[[A:[0-9]+]], [x1]
    255 ; CHECK: ldr w[[B:[0-9]+]], [x2]
    256 ; CHECK: add w[[C:[0-9]+]], w[[A]], w0
    257 ; CHECK: add {{w[0-9]+}}, w[[C]], w[[B]]
    258 ; FAST: f42
    259 ; FAST: ldr w[[A:[0-9]+]], [x1]
    260 ; FAST: ldr w[[B:[0-9]+]], [x2]
    261 ; FAST: add w[[C:[0-9]+]], w[[A]], w0
    262 ; FAST: add {{w[0-9]+}}, w[[C]], w[[B]]
    263   %i1 = getelementptr inbounds %struct.s42, %struct.s42* %s1, i64 0, i32 0
    264   %0 = load i32, i32* %i1, align 4, !tbaa !0
    265   %i2 = getelementptr inbounds %struct.s42, %struct.s42* %s2, i64 0, i32 0
    266   %1 = load i32, i32* %i2, align 4, !tbaa !0
    267   %s = getelementptr inbounds %struct.s42, %struct.s42* %s1, i64 0, i32 1
    268   %2 = load i16, i16* %s, align 2, !tbaa !3
    269   %conv = sext i16 %2 to i32
    270   %s5 = getelementptr inbounds %struct.s42, %struct.s42* %s2, i64 0, i32 1
    271   %3 = load i16, i16* %s5, align 2, !tbaa !3
    272   %conv6 = sext i16 %3 to i32
    273   %add = add i32 %0, %i
    274   %add3 = add i32 %add, %1
    275   %add4 = add i32 %add3, %conv
    276   %add7 = add i32 %add4, %conv6
    277   ret i32 %add7
    278 }
    279 
    280 ; For s1, we allocate a 22-byte space, pass its address via x1
    281 define i32 @caller42() #3 {
    282 entry:
    283 ; CHECK-LABEL: caller42
    284 ; CHECK: str {{x[0-9]+}}, [sp, #48]
    285 ; CHECK: str {{q[0-9]+}}, [sp, #32]
    286 ; CHECK: str {{x[0-9]+}}, [sp, #16]
    287 ; CHECK: str {{q[0-9]+}}, [sp]
    288 ; CHECK: add x1, sp, #32
    289 ; CHECK: mov x2, sp
    290 ; Space for s1 is allocated at sp+32
    291 ; Space for s2 is allocated at sp
    292 
    293 ; FAST-LABEL: caller42
    294 ; FAST: sub sp, sp, #96
    295 ; Space for s1 is allocated at fp-24 = sp+72
    296 ; Space for s2 is allocated at sp+48
    297 ; FAST: sub x[[A:[0-9]+]], x29, #24
    298 ; FAST: add x[[A:[0-9]+]], sp, #48
    299 ; Call memcpy with size = 24 (0x18)
    300 ; FAST: orr {{x[0-9]+}}, xzr, #0x18
    301   %tmp = alloca %struct.s42, align 4
    302   %tmp1 = alloca %struct.s42, align 4
    303   %0 = bitcast %struct.s42* %tmp to i8*
    304   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s42* @g42 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
    305   %1 = bitcast %struct.s42* %tmp1 to i8*
    306   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s42* @g42_2 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
    307   %call = call i32 @f42(i32 3, %struct.s42* %tmp, %struct.s42* %tmp1) #5
    308   ret i32 %call
    309 }
    310 
    311 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #4
    312 
    313 declare i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
    314                        i32 %i7, i32 %i8, i32 %i9, %struct.s42* nocapture %s1,
    315                        %struct.s42* nocapture %s2) #2
    316 
    317 define i32 @caller42_stack() #3 {
    318 entry:
    319 ; CHECK-LABEL: caller42_stack
    320 ; CHECK: mov x29, sp
    321 ; CHECK: sub sp, sp, #96
    322 ; CHECK: stur {{x[0-9]+}}, [x29, #-16]
    323 ; CHECK: stur {{q[0-9]+}}, [x29, #-32]
    324 ; CHECK: str {{x[0-9]+}}, [sp, #48]
    325 ; CHECK: str {{q[0-9]+}}, [sp, #32]
    326 ; Space for s1 is allocated at x29-32 = sp+64
    327 ; Space for s2 is allocated at sp+32
    328 ; CHECK: add x[[B:[0-9]+]], sp, #32
    329 ; CHECK: str x[[B]], [sp, #16]
    330 ; CHECK: sub x[[A:[0-9]+]], x29, #32
    331 ; Address of s1 is passed on stack at sp+8
    332 ; CHECK: str x[[A]], [sp, #8]
    333 ; CHECK: movz w[[C:[0-9]+]], #0x9
    334 ; CHECK: str w[[C]], [sp]
    335 
    336 ; FAST-LABEL: caller42_stack
    337 ; Space for s1 is allocated at fp-24
    338 ; Space for s2 is allocated at fp-48
    339 ; FAST: sub x[[A:[0-9]+]], x29, #24
    340 ; FAST: sub x[[B:[0-9]+]], x29, #48
    341 ; Call memcpy with size = 24 (0x18)
    342 ; FAST: orr {{x[0-9]+}}, xzr, #0x18
    343 ; FAST: str {{w[0-9]+}}, [sp]
    344 ; Address of s1 is passed on stack at sp+8
    345 ; FAST: str {{x[0-9]+}}, [sp, #8]
    346 ; FAST: str {{x[0-9]+}}, [sp, #16]
    347   %tmp = alloca %struct.s42, align 4
    348   %tmp1 = alloca %struct.s42, align 4
    349   %0 = bitcast %struct.s42* %tmp to i8*
    350   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s42* @g42 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
    351   %1 = bitcast %struct.s42* %tmp1 to i8*
    352   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s42* @g42_2 to i8*), i64 24, i32 4, i1 false), !tbaa.struct !4
    353   %call = call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
    354                        i32 8, i32 9, %struct.s42* %tmp, %struct.s42* %tmp1) #5
    355   ret i32 %call
    356 }
    357 
    358 ; structs with size of 22 bytes, alignment of 16
    359 ; passed indirectly in x1 and x2
    360 define i32 @f43(i32 %i, %struct.s43* nocapture %s1, %struct.s43* nocapture %s2) #2 {
    361 entry:
    362 ; CHECK-LABEL: f43
    363 ; CHECK: ldr w[[A:[0-9]+]], [x1]
    364 ; CHECK: ldr w[[B:[0-9]+]], [x2]
    365 ; CHECK: add w[[C:[0-9]+]], w[[A]], w0
    366 ; CHECK: add {{w[0-9]+}}, w[[C]], w[[B]]
    367 ; FAST-LABEL: f43
    368 ; FAST: ldr w[[A:[0-9]+]], [x1]
    369 ; FAST: ldr w[[B:[0-9]+]], [x2]
    370 ; FAST: add w[[C:[0-9]+]], w[[A]], w0
    371 ; FAST: add {{w[0-9]+}}, w[[C]], w[[B]]
    372   %i1 = getelementptr inbounds %struct.s43, %struct.s43* %s1, i64 0, i32 0
    373   %0 = load i32, i32* %i1, align 4, !tbaa !0
    374   %i2 = getelementptr inbounds %struct.s43, %struct.s43* %s2, i64 0, i32 0
    375   %1 = load i32, i32* %i2, align 4, !tbaa !0
    376   %s = getelementptr inbounds %struct.s43, %struct.s43* %s1, i64 0, i32 1
    377   %2 = load i16, i16* %s, align 2, !tbaa !3
    378   %conv = sext i16 %2 to i32
    379   %s5 = getelementptr inbounds %struct.s43, %struct.s43* %s2, i64 0, i32 1
    380   %3 = load i16, i16* %s5, align 2, !tbaa !3
    381   %conv6 = sext i16 %3 to i32
    382   %add = add i32 %0, %i
    383   %add3 = add i32 %add, %1
    384   %add4 = add i32 %add3, %conv
    385   %add7 = add i32 %add4, %conv6
    386   ret i32 %add7
    387 }
    388 
    389 define i32 @caller43() #3 {
    390 entry:
    391 ; CHECK-LABEL: caller43
    392 ; CHECK: str {{q[0-9]+}}, [sp, #48]
    393 ; CHECK: str {{q[0-9]+}}, [sp, #32]
    394 ; CHECK: str {{q[0-9]+}}, [sp, #16]
    395 ; CHECK: str {{q[0-9]+}}, [sp]
    396 ; CHECK: add x1, sp, #32
    397 ; CHECK: mov x2, sp
    398 ; Space for s1 is allocated at sp+32
    399 ; Space for s2 is allocated at sp
    400 
    401 ; FAST-LABEL: caller43
    402 ; FAST: mov x29, sp
    403 ; Space for s1 is allocated at sp+32
    404 ; Space for s2 is allocated at sp
    405 ; FAST: add x1, sp, #32
    406 ; FAST: mov x2, sp
    407 ; FAST: str {{x[0-9]+}}, [sp, #32]
    408 ; FAST: str {{x[0-9]+}}, [sp, #40]
    409 ; FAST: str {{x[0-9]+}}, [sp, #48]
    410 ; FAST: str {{x[0-9]+}}, [sp, #56]
    411 ; FAST: str {{x[0-9]+}}, [sp]
    412 ; FAST: str {{x[0-9]+}}, [sp, #8]
    413 ; FAST: str {{x[0-9]+}}, [sp, #16]
    414 ; FAST: str {{x[0-9]+}}, [sp, #24]
    415   %tmp = alloca %struct.s43, align 16
    416   %tmp1 = alloca %struct.s43, align 16
    417   %0 = bitcast %struct.s43* %tmp to i8*
    418   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s43* @g43 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
    419   %1 = bitcast %struct.s43* %tmp1 to i8*
    420   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s43* @g43_2 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
    421   %call = call i32 @f43(i32 3, %struct.s43* %tmp, %struct.s43* %tmp1) #5
    422   ret i32 %call
    423 }
    424 
    425 declare i32 @f43_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
    426                        i32 %i7, i32 %i8, i32 %i9, %struct.s43* nocapture %s1,
    427                        %struct.s43* nocapture %s2) #2
    428 
    429 define i32 @caller43_stack() #3 {
    430 entry:
    431 ; CHECK-LABEL: caller43_stack
    432 ; CHECK: mov x29, sp
    433 ; CHECK: sub sp, sp, #96
    434 ; CHECK: stur {{q[0-9]+}}, [x29, #-16]
    435 ; CHECK: stur {{q[0-9]+}}, [x29, #-32]
    436 ; CHECK: str {{q[0-9]+}}, [sp, #48]
    437 ; CHECK: str {{q[0-9]+}}, [sp, #32]
    438 ; Space for s1 is allocated at x29-32 = sp+64
    439 ; Space for s2 is allocated at sp+32
    440 ; CHECK: add x[[B:[0-9]+]], sp, #32
    441 ; CHECK: str x[[B]], [sp, #16]
    442 ; CHECK: sub x[[A:[0-9]+]], x29, #32
    443 ; Address of s1 is passed on stack at sp+8
    444 ; CHECK: str x[[A]], [sp, #8]
    445 ; CHECK: movz w[[C:[0-9]+]], #0x9
    446 ; CHECK: str w[[C]], [sp]
    447 
    448 ; FAST-LABEL: caller43_stack
    449 ; FAST: sub sp, sp, #96
    450 ; Space for s1 is allocated at fp-32 = sp+64
    451 ; Space for s2 is allocated at sp+32
    452 ; FAST: sub x[[A:[0-9]+]], x29, #32
    453 ; FAST: add x[[B:[0-9]+]], sp, #32
    454 ; FAST: stur {{x[0-9]+}}, [x29, #-32]
    455 ; FAST: stur {{x[0-9]+}}, [x29, #-24]
    456 ; FAST: stur {{x[0-9]+}}, [x29, #-16]
    457 ; FAST: stur {{x[0-9]+}}, [x29, #-8]
    458 ; FAST: str {{x[0-9]+}}, [sp, #32]
    459 ; FAST: str {{x[0-9]+}}, [sp, #40]
    460 ; FAST: str {{x[0-9]+}}, [sp, #48]
    461 ; FAST: str {{x[0-9]+}}, [sp, #56]
    462 ; FAST: str {{w[0-9]+}}, [sp]
    463 ; Address of s1 is passed on stack at sp+8
    464 ; FAST: str {{x[0-9]+}}, [sp, #8]
    465 ; FAST: str {{x[0-9]+}}, [sp, #16]
    466   %tmp = alloca %struct.s43, align 16
    467   %tmp1 = alloca %struct.s43, align 16
    468   %0 = bitcast %struct.s43* %tmp to i8*
    469   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast (%struct.s43* @g43 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
    470   %1 = bitcast %struct.s43* %tmp1 to i8*
    471   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.s43* @g43_2 to i8*), i64 32, i32 16, i1 false), !tbaa.struct !4
    472   %call = call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
    473                        i32 8, i32 9, %struct.s43* %tmp, %struct.s43* %tmp1) #5
    474   ret i32 %call
    475 }
    476 
    477 ; rdar://13668927
    478 ; Check that we don't split an i128.
    479 declare i32 @callee_i128_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5,
    480                                i32 %i6, i32 %i7, i128 %s1, i32 %i8)
    481 
    482 define i32 @i128_split() {
    483 entry:
    484 ; CHECK-LABEL: i128_split
    485 ; "i128 %0" should be on stack at [sp].
    486 ; "i32 8" should be on stack at [sp, #16].
    487 ; CHECK: str {{w[0-9]+}}, [sp, #16]
    488 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp]
    489 ; FAST-LABEL: i128_split
    490 ; FAST: sub sp, sp
    491 ; FAST: mov x[[ADDR:[0-9]+]], sp
    492 ; FAST: str {{w[0-9]+}}, [x[[ADDR]], #16]
    493 ; Load/Store opt is disabled with -O0, so the i128 is split.
    494 ; FAST: str {{x[0-9]+}}, [x[[ADDR]], #8]
    495 ; FAST: str {{x[0-9]+}}, [x[[ADDR]]]
    496   %0 = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 16
    497   %call = tail call i32 @callee_i128_split(i32 1, i32 2, i32 3, i32 4, i32 5,
    498                                            i32 6, i32 7, i128 %0, i32 8) #5
    499   ret i32 %call
    500 }
    501 
    502 declare i32 @callee_i64(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5,
    503                                i32 %i6, i32 %i7, i64 %s1, i32 %i8)
    504 
    505 define i32 @i64_split() {
    506 entry:
    507 ; CHECK-LABEL: i64_split
    508 ; "i64 %0" should be in register x7.
    509 ; "i32 8" should be on stack at [sp].
    510 ; CHECK: ldr x7, [{{x[0-9]+}}]
    511 ; CHECK: str {{w[0-9]+}}, [sp, #-16]!
    512 ; FAST-LABEL: i64_split
    513 ; FAST: ldr x7, [{{x[0-9]+}}]
    514 ; FAST: mov x[[R0:[0-9]+]], sp
    515 ; FAST: orr w[[R1:[0-9]+]], wzr, #0x8
    516 ; FAST: str w[[R1]], {{\[}}x[[R0]]{{\]}}
    517   %0 = load i64, i64* bitcast (%struct.s41* @g41 to i64*), align 16
    518   %call = tail call i32 @callee_i64(i32 1, i32 2, i32 3, i32 4, i32 5,
    519                                     i32 6, i32 7, i64 %0, i32 8) #5
    520   ret i32 %call
    521 }
    522 
    523 attributes #0 = { noinline nounwind readnone "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
    524 attributes #1 = { nounwind readonly "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
    525 attributes #2 = { noinline nounwind readonly "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
    526 attributes #3 = { nounwind "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
    527 attributes #4 = { nounwind }
    528 attributes #5 = { nobuiltin }
    529 
    530 !0 = !{!"int", !1}
    531 !1 = !{!"omnipotent char", !2}
    532 !2 = !{!"Simple C/C++ TBAA"}
    533 !3 = !{!"short", !1}
    534 !4 = !{i64 0, i64 4, !0, i64 4, i64 2, !3, i64 8, i64 4, !0, i64 12, i64 2, !3, i64 16, i64 4, !0, i64 20, i64 2, !3}
    535