Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple aarch64-apple-darwin -asm-verbose=false -disable-post-ra | FileCheck %s
      2 
      3 define void @test_stnp_v4i64(<4 x i64>* %p, <4 x i64> %v) #0 {
      4 ; CHECK-LABEL: test_stnp_v4i64:
      5 ; CHECK-NEXT:  mov d[[HI1:[0-9]+]], v1[1]
      6 ; CHECK-NEXT:  mov d[[HI0:[0-9]+]], v0[1]
      7 ; CHECK-NEXT:  stnp d1, d[[HI1]], [x0, #16]
      8 ; CHECK-NEXT:  stnp d0, d[[HI0]], [x0]
      9 ; CHECK-NEXT:  ret
     10   store <4 x i64> %v, <4 x i64>* %p, align 1, !nontemporal !0
     11   ret void
     12 }
     13 
     14 define void @test_stnp_v4i32(<4 x i32>* %p, <4 x i32> %v) #0 {
     15 ; CHECK-LABEL: test_stnp_v4i32:
     16 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
     17 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
     18 ; CHECK-NEXT:  ret
     19   store <4 x i32> %v, <4 x i32>* %p, align 1, !nontemporal !0
     20   ret void
     21 }
     22 
     23 define void @test_stnp_v8i16(<8 x i16>* %p, <8 x i16> %v) #0 {
     24 ; CHECK-LABEL: test_stnp_v8i16:
     25 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
     26 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
     27 ; CHECK-NEXT:  ret
     28   store <8 x i16> %v, <8 x i16>* %p, align 1, !nontemporal !0
     29   ret void
     30 }
     31 
     32 define void @test_stnp_v16i8(<16 x i8>* %p, <16 x i8> %v) #0 {
     33 ; CHECK-LABEL: test_stnp_v16i8:
     34 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
     35 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
     36 ; CHECK-NEXT:  ret
     37   store <16 x i8> %v, <16 x i8>* %p, align 1, !nontemporal !0
     38   ret void
     39 }
     40 
     41 define void @test_stnp_v2i32(<2 x i32>* %p, <2 x i32> %v) #0 {
     42 ; CHECK-LABEL: test_stnp_v2i32:
     43 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
     44 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
     45 ; CHECK-NEXT:  ret
     46   store <2 x i32> %v, <2 x i32>* %p, align 1, !nontemporal !0
     47   ret void
     48 }
     49 
     50 define void @test_stnp_v4i16(<4 x i16>* %p, <4 x i16> %v) #0 {
     51 ; CHECK-LABEL: test_stnp_v4i16:
     52 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
     53 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
     54 ; CHECK-NEXT:  ret
     55   store <4 x i16> %v, <4 x i16>* %p, align 1, !nontemporal !0
     56   ret void
     57 }
     58 
     59 define void @test_stnp_v8i8(<8 x i8>* %p, <8 x i8> %v) #0 {
     60 ; CHECK-LABEL: test_stnp_v8i8:
     61 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
     62 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
     63 ; CHECK-NEXT:  ret
     64   store <8 x i8> %v, <8 x i8>* %p, align 1, !nontemporal !0
     65   ret void
     66 }
     67 
     68 define void @test_stnp_v2f64(<2 x double>* %p, <2 x double> %v) #0 {
     69 ; CHECK-LABEL: test_stnp_v2f64:
     70 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
     71 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
     72 ; CHECK-NEXT:  ret
     73   store <2 x double> %v, <2 x double>* %p, align 1, !nontemporal !0
     74   ret void
     75 }
     76 
     77 define void @test_stnp_v4f32(<4 x float>* %p, <4 x float> %v) #0 {
     78 ; CHECK-LABEL: test_stnp_v4f32:
     79 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
     80 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
     81 ; CHECK-NEXT:  ret
     82   store <4 x float> %v, <4 x float>* %p, align 1, !nontemporal !0
     83   ret void
     84 }
     85 
     86 define void @test_stnp_v2f32(<2 x float>* %p, <2 x float> %v) #0 {
     87 ; CHECK-LABEL: test_stnp_v2f32:
     88 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
     89 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
     90 ; CHECK-NEXT:  ret
     91   store <2 x float> %v, <2 x float>* %p, align 1, !nontemporal !0
     92   ret void
     93 }
     94 
     95 define void @test_stnp_v1f64(<1 x double>* %p, <1 x double> %v) #0 {
     96 ; CHECK-LABEL: test_stnp_v1f64:
     97 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
     98 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
     99 ; CHECK-NEXT:  ret
    100   store <1 x double> %v, <1 x double>* %p, align 1, !nontemporal !0
    101   ret void
    102 }
    103 
    104 define void @test_stnp_v1i64(<1 x i64>* %p, <1 x i64> %v) #0 {
    105 ; CHECK-LABEL: test_stnp_v1i64:
    106 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    107 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
    108 ; CHECK-NEXT:  ret
    109   store <1 x i64> %v, <1 x i64>* %p, align 1, !nontemporal !0
    110   ret void
    111 }
    112 
    113 define void @test_stnp_i64(i64* %p, i64 %v) #0 {
    114 ; CHECK-LABEL: test_stnp_i64:
    115 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
    116 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0]
    117 ; CHECK-NEXT:  ret
    118   store i64 %v, i64* %p, align 1, !nontemporal !0
    119   ret void
    120 }
    121 
    122 
    123 define void @test_stnp_v2f64_offset(<2 x double>* %p, <2 x double> %v) #0 {
    124 ; CHECK-LABEL: test_stnp_v2f64_offset:
    125 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    126 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #16]
    127 ; CHECK-NEXT:  ret
    128   %tmp0 = getelementptr <2 x double>, <2 x double>* %p, i32 1
    129   store <2 x double> %v, <2 x double>* %tmp0, align 1, !nontemporal !0
    130   ret void
    131 }
    132 
    133 define void @test_stnp_v2f64_offset_neg(<2 x double>* %p, <2 x double> %v) #0 {
    134 ; CHECK-LABEL: test_stnp_v2f64_offset_neg:
    135 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    136 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #-16]
    137 ; CHECK-NEXT:  ret
    138   %tmp0 = getelementptr <2 x double>, <2 x double>* %p, i32 -1
    139   store <2 x double> %v, <2 x double>* %tmp0, align 1, !nontemporal !0
    140   ret void
    141 }
    142 
    143 define void @test_stnp_v2f32_offset(<2 x float>* %p, <2 x float> %v) #0 {
    144 ; CHECK-LABEL: test_stnp_v2f32_offset:
    145 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    146 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #8]
    147 ; CHECK-NEXT:  ret
    148   %tmp0 = getelementptr <2 x float>, <2 x float>* %p, i32 1
    149   store <2 x float> %v, <2 x float>* %tmp0, align 1, !nontemporal !0
    150   ret void
    151 }
    152 
    153 define void @test_stnp_v2f32_offset_neg(<2 x float>* %p, <2 x float> %v) #0 {
    154 ; CHECK-LABEL: test_stnp_v2f32_offset_neg:
    155 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    156 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #-8]
    157 ; CHECK-NEXT:  ret
    158   %tmp0 = getelementptr <2 x float>, <2 x float>* %p, i32 -1
    159   store <2 x float> %v, <2 x float>* %tmp0, align 1, !nontemporal !0
    160   ret void
    161 }
    162 
    163 define void @test_stnp_i64_offset(i64* %p, i64 %v) #0 {
    164 ; CHECK-LABEL: test_stnp_i64_offset:
    165 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
    166 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0, #8]
    167 ; CHECK-NEXT:  ret
    168   %tmp0 = getelementptr i64, i64* %p, i32 1
    169   store i64 %v, i64* %tmp0, align 1, !nontemporal !0
    170   ret void
    171 }
    172 
    173 define void @test_stnp_i64_offset_neg(i64* %p, i64 %v) #0 {
    174 ; CHECK-LABEL: test_stnp_i64_offset_neg:
    175 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
    176 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0, #-8]
    177 ; CHECK-NEXT:  ret
    178   %tmp0 = getelementptr i64, i64* %p, i32 -1
    179   store i64 %v, i64* %tmp0, align 1, !nontemporal !0
    180   ret void
    181 }
    182 
    183 define void @test_stnp_v4f32_invalid_offset_4(i8* %p, <4 x float> %v) #0 {
    184 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_4:
    185 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #4
    186 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    187 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
    188 ; CHECK-NEXT:  ret
    189   %tmp0 = getelementptr i8, i8* %p, i32 4
    190   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    191   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    192   ret void
    193 }
    194 
    195 define void @test_stnp_v4f32_invalid_offset_neg_4(i8* %p, <4 x float> %v) #0 {
    196 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_neg_4:
    197 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #4
    198 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    199 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
    200 ; CHECK-NEXT:  ret
    201   %tmp0 = getelementptr i8, i8* %p, i32 -4
    202   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    203   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    204   ret void
    205 }
    206 
    207 define void @test_stnp_v4f32_invalid_offset_512(i8* %p, <4 x float> %v) #0 {
    208 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_512:
    209 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #512
    210 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    211 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
    212 ; CHECK-NEXT:  ret
    213   %tmp0 = getelementptr i8, i8* %p, i32 512
    214   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    215   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    216   ret void
    217 }
    218 
    219 define void @test_stnp_v4f32_offset_504(i8* %p, <4 x float> %v) #0 {
    220 ; CHECK-LABEL: test_stnp_v4f32_offset_504:
    221 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    222 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #504]
    223 ; CHECK-NEXT:  ret
    224   %tmp0 = getelementptr i8, i8* %p, i32 504
    225   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    226   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    227   ret void
    228 }
    229 
    230 define void @test_stnp_v4f32_invalid_offset_508(i8* %p, <4 x float> %v) #0 {
    231 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_508:
    232 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #508
    233 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    234 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
    235 ; CHECK-NEXT:  ret
    236   %tmp0 = getelementptr i8, i8* %p, i32 508
    237   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    238   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    239   ret void
    240 }
    241 
    242 define void @test_stnp_v4f32_invalid_offset_neg_520(i8* %p, <4 x float> %v) #0 {
    243 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_neg_520:
    244 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #520
    245 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    246 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
    247 ; CHECK-NEXT:  ret
    248   %tmp0 = getelementptr i8, i8* %p, i32 -520
    249   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    250   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    251   ret void
    252 }
    253 
    254 define void @test_stnp_v4f32_offset_neg_512(i8* %p, <4 x float> %v) #0 {
    255 ; CHECK-LABEL: test_stnp_v4f32_offset_neg_512:
    256 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
    257 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #-512]
    258 ; CHECK-NEXT:  ret
    259   %tmp0 = getelementptr i8, i8* %p, i32 -512
    260   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
    261   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    262   ret void
    263 }
    264 
    265 
    266 define void @test_stnp_v2f32_invalid_offset_256(i8* %p, <2 x float> %v) #0 {
    267 ; CHECK-LABEL: test_stnp_v2f32_invalid_offset_256:
    268 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #256
    269 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    270 ; CHECK-NEXT:  stnp s0, s[[HI]], [x[[PTR]]]
    271 ; CHECK-NEXT:  ret
    272   %tmp0 = getelementptr i8, i8* %p, i32 256
    273   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
    274   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
    275   ret void
    276 }
    277 
    278 define void @test_stnp_v2f32_offset_252(i8* %p, <2 x float> %v) #0 {
    279 ; CHECK-LABEL: test_stnp_v2f32_offset_252:
    280 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    281 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #252]
    282 ; CHECK-NEXT:  ret
    283   %tmp0 = getelementptr i8, i8* %p, i32 252
    284   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
    285   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
    286   ret void
    287 }
    288 
    289 define void @test_stnp_v2f32_invalid_offset_neg_260(i8* %p, <2 x float> %v) #0 {
    290 ; CHECK-LABEL: test_stnp_v2f32_invalid_offset_neg_260:
    291 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #260
    292 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    293 ; CHECK-NEXT:  stnp s0, s[[HI]], [x[[PTR]]]
    294 ; CHECK-NEXT:  ret
    295   %tmp0 = getelementptr i8, i8* %p, i32 -260
    296   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
    297   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
    298   ret void
    299 }
    300 
    301 define void @test_stnp_v2f32_offset_neg_256(i8* %p, <2 x float> %v) #0 {
    302 ; CHECK-LABEL: test_stnp_v2f32_offset_neg_256:
    303 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
    304 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #-256]
    305 ; CHECK-NEXT:  ret
    306   %tmp0 = getelementptr i8, i8* %p, i32 -256
    307   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
    308   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
    309   ret void
    310 }
    311 
    312 declare void @dummy(<4 x float>*)
    313 
    314 define void @test_stnp_v4f32_offset_alloca(<4 x float> %v) #0 {
    315 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca:
    316 ; CHECK:       stnp d0, d{{.*}}, [sp]
    317 ; CHECK-NEXT:  mov x0, sp
    318 ; CHECK-NEXT:  bl _dummy
    319   %tmp0 = alloca <4 x float>
    320   store <4 x float> %v, <4 x float>* %tmp0, align 1, !nontemporal !0
    321   call void @dummy(<4 x float>* %tmp0)
    322   ret void
    323 }
    324 
    325 define void @test_stnp_v4f32_offset_alloca_2(<4 x float> %v) #0 {
    326 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca_2:
    327 ; CHECK:       stnp d0, d{{.*}}, [sp, #16]
    328 ; CHECK-NEXT:  mov x0, sp
    329 ; CHECK-NEXT:  bl _dummy
    330   %tmp0 = alloca <4 x float>, i32 2
    331   %tmp1 = getelementptr <4 x float>, <4 x float>* %tmp0, i32 1
    332   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
    333   call void @dummy(<4 x float>* %tmp0)
    334   ret void
    335 }
    336 
    337 !0 = !{ i32 1 }
    338 
    339 attributes #0 = { nounwind }
    340