Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple aarch64--none-eabi -mcpu=cortex-a57 -verify-machineinstrs -enable-narrow-ld-merge=true | FileCheck %s --check-prefix=CHECK --check-prefix=LE
      2 ; RUN: llc < %s -mtriple aarch64_be--none-eabi -mcpu=cortex-a57 -verify-machineinstrs -enable-narrow-ld-merge=true | FileCheck %s --check-prefix=CHECK --check-prefix=BE
      3 ; RUN: llc < %s -mtriple aarch64--none-eabi -mcpu=kryo -verify-machineinstrs -enable-narrow-ld-merge=true | FileCheck %s --check-prefix=CHECK --check-prefix=LE
      4 
      5 ; CHECK-LABEL: Ldrh_merge
      6 ; CHECK-NOT: ldrh
      7 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
      8 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
      9 ; CHECK-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
     10 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
     11 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
     12 define i16 @Ldrh_merge(i16* nocapture readonly %p) {
     13   %1 = load i16, i16* %p, align 2
     14   %arrayidx2 = getelementptr inbounds i16, i16* %p, i64 1
     15   %2 = load i16, i16* %arrayidx2, align 2
     16   %add = sub nuw nsw i16 %1, %2
     17   ret i16 %add
     18 }
     19 
     20 ; CHECK-LABEL: Ldurh_merge
     21 ; CHECK-NOT: ldurh
     22 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
     23 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
     24 ; CHECK-DAG: lsr  [[HI_PART:w[0-9]+]], [[NEW_DEST]]
     25 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
     26 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
     27 define i16 @Ldurh_merge(i16* nocapture readonly %p)  {
     28 entry:
     29   %arrayidx = getelementptr inbounds i16, i16* %p, i64 -2
     30   %0 = load i16, i16* %arrayidx
     31   %arrayidx3 = getelementptr inbounds i16, i16* %p, i64 -1
     32   %1 = load i16, i16* %arrayidx3
     33   %add = sub nuw nsw i16 %0, %1
     34   ret i16 %add
     35 }
     36 
     37 ; CHECK-LABEL: Ldrh_4_merge
     38 ; CHECK-NOT: ldrh
     39 ; CHECK: ldp [[WORD1:w[0-9]+]], [[WORD2:w[0-9]+]], [x0]
     40 ; CHECK-DAG: and [[WORD1LO:w[0-9]+]], [[WORD1]], #0xffff
     41 ; CHECK-DAG: lsr [[WORD1HI:w[0-9]+]], [[WORD1]], #16
     42 ; CHECK-DAG: and [[WORD2LO:w[0-9]+]], [[WORD2]], #0xffff
     43 ; CHECK-DAG: lsr [[WORD2HI:w[0-9]+]], [[WORD2]], #16
     44 ; LE-DAG: sub [[TEMP1:w[0-9]+]], [[WORD1HI]], [[WORD1LO]]
     45 ; BE-DAG: sub [[TEMP1:w[0-9]+]], [[WORD1LO]], [[WORD1HI]]
     46 ; LE: udiv [[TEMP2:w[0-9]+]], [[TEMP1]], [[WORD2LO]]
     47 ; BE: udiv [[TEMP2:w[0-9]+]], [[TEMP1]], [[WORD2HI]]
     48 ; LE: sub w0, [[TEMP2]], [[WORD2HI]]
     49 ; BE: sub w0, [[TEMP2]], [[WORD2LO]]
     50 define i16 @Ldrh_4_merge(i16* nocapture readonly %P) {
     51   %arrayidx = getelementptr inbounds i16, i16* %P, i64 0
     52   %l0 = load i16, i16* %arrayidx
     53   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 1
     54   %l1 = load i16, i16* %arrayidx2
     55   %arrayidx7 = getelementptr inbounds i16, i16* %P, i64 2
     56   %l2 = load i16, i16* %arrayidx7
     57   %arrayidx12 = getelementptr inbounds i16, i16* %P, i64 3
     58   %l3 = load i16, i16* %arrayidx12
     59   %add4 = sub nuw nsw i16 %l1, %l0
     60   %add9 = udiv i16 %add4, %l2
     61   %add14 = sub nuw nsw i16 %add9, %l3
     62   ret i16 %add14
     63 }
     64 
     65 ; CHECK-LABEL: Ldrsh_merge
     66 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
     67 ; CHECK-DAG: asr [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
     68 ; CHECK-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
     69 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
     70 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
     71 
     72 define i32 @Ldrsh_merge(i16* %p) nounwind {
     73   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
     74   %tmp = load i16, i16* %add.ptr0
     75   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
     76   %tmp1 = load i16, i16* %add.ptr
     77   %sexttmp = sext i16 %tmp to i32
     78   %sexttmp1 = sext i16 %tmp1 to i32
     79   %add = sub nsw i32 %sexttmp1, %sexttmp
     80   ret i32 %add
     81 }
     82 
     83 ; CHECK-LABEL: Ldrsh_zsext_merge
     84 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
     85 ; LE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
     86 ; LE-DAG: asr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
     87 ; BE-DAG: sxth [[LO_PART:w[0-9]+]], [[NEW_DEST]]
     88 ; BE-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
     89 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
     90 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
     91 define i32 @Ldrsh_zsext_merge(i16* %p) nounwind {
     92   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
     93   %tmp = load i16, i16* %add.ptr0
     94   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
     95   %tmp1 = load i16, i16* %add.ptr
     96   %sexttmp = zext i16 %tmp to i32
     97   %sexttmp1 = sext i16 %tmp1 to i32
     98   %add = sub nsw i32 %sexttmp, %sexttmp1
     99   ret i32 %add
    100 }
    101 
    102 ; CHECK-LABEL: Ldrsh_szext_merge
    103 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
    104 ; LE-DAG: sxth [[LO_PART:w[0-9]+]], [[NEW_DEST]]
    105 ; LE-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
    106 ; BE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
    107 ; BE-DAG: asr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
    108 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    109 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    110 define i32 @Ldrsh_szext_merge(i16* %p) nounwind {
    111   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
    112   %tmp = load i16, i16* %add.ptr0
    113   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
    114   %tmp1 = load i16, i16* %add.ptr
    115   %sexttmp = sext i16 %tmp to i32
    116   %sexttmp1 = zext i16 %tmp1 to i32
    117   %add = sub nsw i32 %sexttmp, %sexttmp1
    118   ret i32 %add
    119 }
    120 
    121 ; CHECK-LABEL: Ldrb_merge
    122 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
    123 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    124 ; CHECK-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    125 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    126 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    127 define i32 @Ldrb_merge(i8* %p) nounwind {
    128   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
    129   %tmp = load i8, i8* %add.ptr0
    130   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
    131   %tmp1 = load i8, i8* %add.ptr
    132   %sexttmp = zext i8 %tmp to i32
    133   %sexttmp1 = zext i8 %tmp1 to i32
    134   %add = sub nsw i32 %sexttmp, %sexttmp1
    135   ret i32 %add
    136 }
    137 
    138 ; CHECK-LABEL: Ldrsb_merge
    139 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
    140 ; CHECK-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
    141 ; CHECK-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    142 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    143 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    144 define i32 @Ldrsb_merge(i8* %p) nounwind {
    145   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
    146   %tmp = load i8, i8* %add.ptr0
    147   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
    148   %tmp1 = load i8, i8* %add.ptr
    149   %sexttmp = sext i8 %tmp to i32
    150   %sexttmp1 = sext i8 %tmp1 to i32
    151   %add = sub nsw i32 %sexttmp, %sexttmp1
    152   ret i32 %add
    153 }
    154 
    155 ; CHECK-LABEL: Ldrsb_zsext_merge
    156 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
    157 ; LE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    158 ; LE-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    159 ; BE-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
    160 ; BE-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    161 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    162 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    163 define i32 @Ldrsb_zsext_merge(i8* %p) nounwind {
    164   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
    165   %tmp = load i8, i8* %add.ptr0
    166   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
    167   %tmp1 = load i8, i8* %add.ptr
    168   %sexttmp = zext i8 %tmp to i32
    169   %sexttmp1 = sext i8 %tmp1 to i32
    170   %add = sub nsw i32 %sexttmp, %sexttmp1
    171   ret i32 %add
    172 }
    173 
    174 ; CHECK-LABEL: Ldrsb_szext_merge
    175 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
    176 ; LE-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
    177 ; LE-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    178 ; BE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    179 ; BE-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    180 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    181 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    182 define i32 @Ldrsb_szext_merge(i8* %p) nounwind {
    183   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
    184   %tmp = load i8, i8* %add.ptr0
    185   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
    186   %tmp1 = load i8, i8* %add.ptr
    187   %sexttmp = sext i8 %tmp to i32
    188   %sexttmp1 = zext i8 %tmp1 to i32
    189   %add = sub nsw i32 %sexttmp, %sexttmp1
    190   ret i32 %add
    191 }
    192 
    193 ; CHECK-LABEL: Ldursh_merge
    194 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
    195 ; CHECK-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
    196 ; CHECK-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    197 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    198 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    199 define i32 @Ldursh_merge(i16* %p) nounwind {
    200   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
    201   %tmp = load i16, i16* %add.ptr0
    202   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
    203   %tmp1 = load i16, i16* %add.ptr
    204   %sexttmp = sext i16 %tmp to i32
    205   %sexttmp1 = sext i16 %tmp1 to i32
    206   %add = sub nsw i32 %sexttmp, %sexttmp1
    207   ret i32 %add
    208 }
    209 
    210 ; CHECK-LABEL: Ldursh_zsext_merge
    211 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
    212 ; LE-DAG: lsr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
    213 ; LE-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    214 ; BE-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
    215 ; BE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
    216 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    217 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    218 define i32 @Ldursh_zsext_merge(i16* %p) nounwind {
    219   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
    220   %tmp = load i16, i16* %add.ptr0
    221   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
    222   %tmp1 = load i16, i16* %add.ptr
    223   %sexttmp = zext i16 %tmp to i32
    224   %sexttmp1 = sext i16 %tmp1 to i32
    225   %add = sub nsw i32 %sexttmp, %sexttmp1
    226   ret i32 %add
    227 }
    228 
    229 ; CHECK-LABEL: Ldursh_szext_merge
    230 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
    231 ; LE-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
    232 ; LE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
    233 ; BE-DAG: lsr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
    234 ; BE-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    235 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    236 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    237 define i32 @Ldursh_szext_merge(i16* %p) nounwind {
    238   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
    239   %tmp = load i16, i16* %add.ptr0
    240   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
    241   %tmp1 = load i16, i16* %add.ptr
    242   %sexttmp = sext i16 %tmp to i32
    243   %sexttmp1 = zext i16 %tmp1 to i32
    244   %add = sub nsw i32 %sexttmp, %sexttmp1
    245   ret i32 %add
    246 }
    247 
    248 ; CHECK-LABEL: Ldurb_merge
    249 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
    250 ; CHECK-DAG: ubfx  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    251 ; CHECK-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    252 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    253 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    254 define i32 @Ldurb_merge(i8* %p) nounwind {
    255   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
    256   %tmp = load i8, i8* %add.ptr0
    257   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
    258   %tmp1 = load i8, i8* %add.ptr
    259   %sexttmp = zext i8 %tmp to i32
    260   %sexttmp1 = zext i8 %tmp1 to i32
    261   %add = sub nsw i32 %sexttmp, %sexttmp1
    262   ret i32 %add
    263 }
    264 
    265 ; CHECK-LABEL: Ldursb_merge
    266 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
    267 ; CHECK-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    268 ; CHECK-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    269 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    270 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    271 define i32 @Ldursb_merge(i8* %p) nounwind {
    272   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
    273   %tmp = load i8, i8* %add.ptr0
    274   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
    275   %tmp1 = load i8, i8* %add.ptr
    276   %sexttmp = sext i8 %tmp to i32
    277   %sexttmp1 = sext i8 %tmp1 to i32
    278   %add = sub nsw i32 %sexttmp, %sexttmp1
    279   ret i32 %add
    280 }
    281 
    282 ; CHECK-LABEL: Ldursb_zsext_merge
    283 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
    284 ; LE-DAG: ubfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    285 ; LE-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    286 ; BE-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    287 ; BE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    288 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    289 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    290 define i32 @Ldursb_zsext_merge(i8* %p) nounwind {
    291   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
    292   %tmp = load i8, i8* %add.ptr0
    293   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
    294   %tmp1 = load i8, i8* %add.ptr
    295   %sexttmp = zext i8 %tmp to i32
    296   %sexttmp1 = sext i8 %tmp1 to i32
    297   %add = sub nsw i32 %sexttmp, %sexttmp1
    298   ret i32 %add
    299 }
    300 
    301 ; CHECK-LABEL: Ldursb_szext_merge
    302 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
    303 ; LE-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    304 ; LE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
    305 ; BE-DAG: ubfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
    306 ; BE-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
    307 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
    308 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
    309 define i32 @Ldursb_szext_merge(i8* %p) nounwind {
    310   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
    311   %tmp = load i8, i8* %add.ptr0
    312   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
    313   %tmp1 = load i8, i8* %add.ptr
    314   %sexttmp = sext i8 %tmp to i32
    315   %sexttmp1 = zext i8 %tmp1 to i32
    316   %add = sub nsw i32 %sexttmp, %sexttmp1
    317   ret i32 %add
    318 }
    319 
    320 ; CHECK-LABEL: Strh_zero
    321 ; CHECK: str wzr
    322 define void @Strh_zero(i16* nocapture %P, i32 %n) {
    323 entry:
    324  %idxprom = sext i32 %n to i64
    325   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
    326  store i16 0, i16* %arrayidx
    327   %add = add nsw i32 %n, 1
    328   %idxprom1 = sext i32 %add to i64
    329   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 %idxprom1
    330   store i16 0, i16* %arrayidx2
    331   ret void
    332 }
    333 
    334 ; CHECK-LABEL: Strh_zero_4
    335 ; CHECK: stp wzr, wzr
    336 define void @Strh_zero_4(i16* nocapture %P, i32 %n) {
    337 entry:
    338   %idxprom = sext i32 %n to i64
    339   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
    340   store i16 0, i16* %arrayidx
    341   %add = add nsw i32 %n, 1
    342   %idxprom1 = sext i32 %add to i64
    343   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 %idxprom1
    344   store i16 0, i16* %arrayidx2
    345   %add3 = add nsw i32 %n, 2
    346   %idxprom4 = sext i32 %add3 to i64
    347   %arrayidx5 = getelementptr inbounds i16, i16* %P, i64 %idxprom4
    348   store i16 0, i16* %arrayidx5
    349   %add6 = add nsw i32 %n, 3
    350   %idxprom7 = sext i32 %add6 to i64
    351   %arrayidx8 = getelementptr inbounds i16, i16* %P, i64 %idxprom7
    352   store i16 0, i16* %arrayidx8
    353   ret void
    354 }
    355 
    356 ; CHECK-LABEL: Strw_zero
    357 ; CHECK: str xzr
    358 define void @Strw_zero(i32* nocapture %P, i32 %n) {
    359 entry:
    360   %idxprom = sext i32 %n to i64
    361   %arrayidx = getelementptr inbounds i32, i32* %P, i64 %idxprom
    362   store i32 0, i32* %arrayidx
    363   %add = add nsw i32 %n, 1
    364   %idxprom1 = sext i32 %add to i64
    365   %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 %idxprom1
    366   store i32 0, i32* %arrayidx2
    367   ret void
    368 }
    369 
    370 ; CHECK-LABEL: Strw_zero_nonzero
    371 ; CHECK: stp wzr, w1
    372 define void @Strw_zero_nonzero(i32* nocapture %P, i32 %n)  {
    373 entry:
    374   %idxprom = sext i32 %n to i64
    375   %arrayidx = getelementptr inbounds i32, i32* %P, i64 %idxprom
    376   store i32 0, i32* %arrayidx
    377   %add = add nsw i32 %n, 1
    378   %idxprom1 = sext i32 %add to i64
    379   %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 %idxprom1
    380   store i32 %n, i32* %arrayidx2
    381   ret void
    382 }
    383 
    384 ; CHECK-LABEL: Strw_zero_4
    385 ; CHECK: stp xzr
    386 define void @Strw_zero_4(i32* nocapture %P, i32 %n) {
    387 entry:
    388   %idxprom = sext i32 %n to i64
    389   %arrayidx = getelementptr inbounds i32, i32* %P, i64 %idxprom
    390   store i32 0, i32* %arrayidx
    391   %add = add nsw i32 %n, 1
    392   %idxprom1 = sext i32 %add to i64
    393   %arrayidx2 = getelementptr inbounds i32, i32* %P, i64 %idxprom1
    394   store i32 0, i32* %arrayidx2
    395   %add3 = add nsw i32 %n, 2
    396   %idxprom4 = sext i32 %add3 to i64
    397   %arrayidx5 = getelementptr inbounds i32, i32* %P, i64 %idxprom4
    398   store i32 0, i32* %arrayidx5
    399   %add6 = add nsw i32 %n, 3
    400   %idxprom7 = sext i32 %add6 to i64
    401   %arrayidx8 = getelementptr inbounds i32, i32* %P, i64 %idxprom7
    402   store i32 0, i32* %arrayidx8
    403   ret void
    404 }
    405 
    406 ; CHECK-LABEL: Sturb_zero
    407 ; CHECK: sturh wzr
    408 define void @Sturb_zero(i8* nocapture %P, i32 %n) #0 {
    409 entry:
    410   %sub = add nsw i32 %n, -2
    411   %idxprom = sext i32 %sub to i64
    412   %arrayidx = getelementptr inbounds i8, i8* %P, i64 %idxprom
    413   store i8 0, i8* %arrayidx
    414   %sub2= add nsw i32 %n, -1
    415   %idxprom1 = sext i32 %sub2 to i64
    416   %arrayidx2 = getelementptr inbounds i8, i8* %P, i64 %idxprom1
    417   store i8 0, i8* %arrayidx2
    418   ret void
    419 }
    420 
    421 ; CHECK-LABEL: Sturh_zero
    422 ; CHECK: stur wzr
    423 define void @Sturh_zero(i16* nocapture %P, i32 %n) {
    424 entry:
    425   %sub = add nsw i32 %n, -2
    426   %idxprom = sext i32 %sub to i64
    427   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
    428   store i16 0, i16* %arrayidx
    429   %sub1 = add nsw i32 %n, -3
    430   %idxprom2 = sext i32 %sub1 to i64
    431   %arrayidx3 = getelementptr inbounds i16, i16* %P, i64 %idxprom2
    432   store i16 0, i16* %arrayidx3
    433   ret void
    434 }
    435 
    436 ; CHECK-LABEL: Sturh_zero_4
    437 ; CHECK: stp wzr, wzr
    438 define void @Sturh_zero_4(i16* nocapture %P, i32 %n) {
    439 entry:
    440   %sub = add nsw i32 %n, -3
    441   %idxprom = sext i32 %sub to i64
    442   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
    443   store i16 0, i16* %arrayidx
    444   %sub1 = add nsw i32 %n, -4
    445   %idxprom2 = sext i32 %sub1 to i64
    446   %arrayidx3 = getelementptr inbounds i16, i16* %P, i64 %idxprom2
    447   store i16 0, i16* %arrayidx3
    448   %sub4 = add nsw i32 %n, -2
    449   %idxprom5 = sext i32 %sub4 to i64
    450   %arrayidx6 = getelementptr inbounds i16, i16* %P, i64 %idxprom5
    451   store i16 0, i16* %arrayidx6
    452   %sub7 = add nsw i32 %n, -1
    453   %idxprom8 = sext i32 %sub7 to i64
    454   %arrayidx9 = getelementptr inbounds i16, i16* %P, i64 %idxprom8
    455   store i16 0, i16* %arrayidx9
    456   ret void
    457 }
    458 
    459 ; CHECK-LABEL: Sturw_zero
    460 ; CHECK: stur xzr
    461 define void @Sturw_zero(i32* nocapture %P, i32 %n) {
    462 entry:
    463   %sub = add nsw i32 %n, -3
    464   %idxprom = sext i32 %sub to i64
    465   %arrayidx = getelementptr inbounds i32, i32* %P, i64 %idxprom
    466   store i32 0, i32* %arrayidx
    467   %sub1 = add nsw i32 %n, -4
    468   %idxprom2 = sext i32 %sub1 to i64
    469   %arrayidx3 = getelementptr inbounds i32, i32* %P, i64 %idxprom2
    470   store i32 0, i32* %arrayidx3
    471   ret void
    472 }
    473 
    474 ; CHECK-LABEL: Sturw_zero_4
    475 ; CHECK: stp xzr, xzr
    476 define void @Sturw_zero_4(i32* nocapture %P, i32 %n) {
    477 entry:
    478   %sub = add nsw i32 %n, -3
    479   %idxprom = sext i32 %sub to i64
    480   %arrayidx = getelementptr inbounds i32, i32* %P, i64 %idxprom
    481   store i32 0, i32* %arrayidx
    482   %sub1 = add nsw i32 %n, -4
    483   %idxprom2 = sext i32 %sub1 to i64
    484   %arrayidx3 = getelementptr inbounds i32, i32* %P, i64 %idxprom2
    485   store i32 0, i32* %arrayidx3
    486   %sub4 = add nsw i32 %n, -2
    487   %idxprom5 = sext i32 %sub4 to i64
    488   %arrayidx6 = getelementptr inbounds i32, i32* %P, i64 %idxprom5
    489   store i32 0, i32* %arrayidx6
    490   %sub7 = add nsw i32 %n, -1
    491   %idxprom8 = sext i32 %sub7 to i64
    492   %arrayidx9 = getelementptr inbounds i32, i32* %P, i64 %idxprom8
    493   store i32 0, i32* %arrayidx9
    494   ret void
    495 }
    496 
    497