Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -mtriple=aarch64-apple-darwin                             -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
      2 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
      3 
      4 ; Load / Store Base Register only
      5 define zeroext i1 @load_breg_i1(i1* %a) {
      6 ; CHECK-LABEL: load_breg_i1
      7 ; CHECK:       ldrb {{w[0-9]+}}, [x0]
      8   %1 = load i1, i1* %a
      9   ret i1 %1
     10 }
     11 
     12 define zeroext i8 @load_breg_i8(i8* %a) {
     13 ; CHECK-LABEL: load_breg_i8
     14 ; CHECK:       ldrb {{w[0-9]+}}, [x0]
     15   %1 = load i8, i8* %a
     16   ret i8 %1
     17 }
     18 
     19 define zeroext i16 @load_breg_i16(i16* %a) {
     20 ; CHECK-LABEL: load_breg_i16
     21 ; CHECK:       ldrh {{w[0-9]+}}, [x0]
     22   %1 = load i16, i16* %a
     23   ret i16 %1
     24 }
     25 
     26 define i32 @load_breg_i32(i32* %a) {
     27 ; CHECK-LABEL: load_breg_i32
     28 ; CHECK:       ldr {{w[0-9]+}}, [x0]
     29   %1 = load i32, i32* %a
     30   ret i32 %1
     31 }
     32 
     33 define i64 @load_breg_i64(i64* %a) {
     34 ; CHECK-LABEL: load_breg_i64
     35 ; CHECK:       ldr {{x[0-9]+}}, [x0]
     36   %1 = load i64, i64* %a
     37   ret i64 %1
     38 }
     39 
     40 define float @load_breg_f32(float* %a) {
     41 ; CHECK-LABEL: load_breg_f32
     42 ; CHECK:       ldr {{s[0-9]+}}, [x0]
     43   %1 = load float, float* %a
     44   ret float %1
     45 }
     46 
     47 define double @load_breg_f64(double* %a) {
     48 ; CHECK-LABEL: load_breg_f64
     49 ; CHECK:       ldr {{d[0-9]+}}, [x0]
     50   %1 = load double, double* %a
     51   ret double %1
     52 }
     53 
     54 define void @store_breg_i1(i1* %a) {
     55 ; CHECK-LABEL: store_breg_i1
     56 ; CHECK:       strb wzr, [x0]
     57   store i1 0, i1* %a
     58   ret void
     59 }
     60 
     61 define void @store_breg_i1_2(i1* %a) {
     62 ; CHECK-LABEL: store_breg_i1_2
     63 ; CHECK:       strb {{w[0-9]+}}, [x0]
     64   store i1 true, i1* %a
     65   ret void
     66 }
     67 
     68 define void @store_breg_i8(i8* %a) {
     69 ; CHECK-LABEL: store_breg_i8
     70 ; CHECK:       strb wzr, [x0]
     71   store i8 0, i8* %a
     72   ret void
     73 }
     74 
     75 define void @store_breg_i16(i16* %a) {
     76 ; CHECK-LABEL: store_breg_i16
     77 ; CHECK:       strh wzr, [x0]
     78   store i16 0, i16* %a
     79   ret void
     80 }
     81 
     82 define void @store_breg_i32(i32* %a) {
     83 ; CHECK-LABEL: store_breg_i32
     84 ; CHECK:       str wzr, [x0]
     85   store i32 0, i32* %a
     86   ret void
     87 }
     88 
     89 define void @store_breg_i64(i64* %a) {
     90 ; CHECK-LABEL: store_breg_i64
     91 ; CHECK:       str xzr, [x0]
     92   store i64 0, i64* %a
     93   ret void
     94 }
     95 
     96 define void @store_breg_f32(float* %a) {
     97 ; CHECK-LABEL: store_breg_f32
     98 ; CHECK:       str wzr, [x0]
     99   store float 0.0, float* %a
    100   ret void
    101 }
    102 
    103 define void @store_breg_f64(double* %a) {
    104 ; CHECK-LABEL: store_breg_f64
    105 ; CHECK:       str xzr, [x0]
    106   store double 0.0, double* %a
    107   ret void
    108 }
    109 
    110 ; Load Immediate
    111 define i32 @load_immoff_1() {
    112 ; CHECK-LABEL: load_immoff_1
    113 ; CHECK:       orr {{w|x}}[[REG:[0-9]+]], {{wzr|xzr}}, #0x80
    114 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}x[[REG]]{{\]}}
    115   %1 = inttoptr i64 128 to i32*
    116   %2 = load i32, i32* %1
    117   ret i32 %2
    118 }
    119 
    120 ; Load / Store Base Register + Immediate Offset
    121 ; Max supported negative offset
    122 define i32 @load_breg_immoff_1(i64 %a) {
    123 ; CHECK-LABEL: load_breg_immoff_1
    124 ; CHECK:       ldur {{w[0-9]+}}, [x0, #-256]
    125   %1 = add i64 %a, -256
    126   %2 = inttoptr i64 %1 to i32*
    127   %3 = load i32, i32* %2
    128   ret i32 %3
    129 }
    130 
    131 ; Min not-supported negative offset
    132 define i32 @load_breg_immoff_2(i64 %a) {
    133 ; CHECK-LABEL: load_breg_immoff_2
    134 ; CHECK:       sub [[REG:x[0-9]+]], x0, #257
    135 ; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
    136   %1 = add i64 %a, -257
    137   %2 = inttoptr i64 %1 to i32*
    138   %3 = load i32, i32* %2
    139   ret i32 %3
    140 }
    141 
    142 ; Max supported unscaled offset
    143 define i32 @load_breg_immoff_3(i64 %a) {
    144 ; CHECK-LABEL: load_breg_immoff_3
    145 ; CHECK:       ldur {{w[0-9]+}}, [x0, #255]
    146   %1 = add i64 %a, 255
    147   %2 = inttoptr i64 %1 to i32*
    148   %3 = load i32, i32* %2
    149   ret i32 %3
    150 }
    151 
    152 ; Min un-supported unscaled offset
    153 define i32 @load_breg_immoff_4(i64 %a) {
    154 ; CHECK-LABEL: load_breg_immoff_4
    155 ; CHECK:       add [[REG:x[0-9]+]], x0, #257
    156 ; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
    157   %1 = add i64 %a, 257
    158   %2 = inttoptr i64 %1 to i32*
    159   %3 = load i32, i32* %2
    160   ret i32 %3
    161 }
    162 
    163 ; Max supported scaled offset
    164 define i32 @load_breg_immoff_5(i64 %a) {
    165 ; CHECK-LABEL: load_breg_immoff_5
    166 ; CHECK:       ldr {{w[0-9]+}}, [x0, #16380]
    167   %1 = add i64 %a, 16380
    168   %2 = inttoptr i64 %1 to i32*
    169   %3 = load i32, i32* %2
    170   ret i32 %3
    171 }
    172 
    173 ; Min un-supported scaled offset
    174 define i32 @load_breg_immoff_6(i64 %a) {
    175 ; SDAG-LABEL: load_breg_immoff_6
    176 ; SDAG:       orr	w[[NUM:[0-9]+]], wzr, #0x4000
    177 ; SDAG-NEXT:  ldr {{w[0-9]+}}, [x0, x[[NUM]]]
    178 ; FAST-LABEL: load_breg_immoff_6
    179 ; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
    180 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
    181   %1 = add i64 %a, 16384
    182   %2 = inttoptr i64 %1 to i32*
    183   %3 = load i32, i32* %2
    184   ret i32 %3
    185 }
    186 
    187 ; Max supported negative offset
    188 define void @store_breg_immoff_1(i64 %a) {
    189 ; CHECK-LABEL: store_breg_immoff_1
    190 ; CHECK:       stur wzr, [x0, #-256]
    191   %1 = add i64 %a, -256
    192   %2 = inttoptr i64 %1 to i32*
    193   store i32 0, i32* %2
    194   ret void
    195 }
    196 
    197 ; Min not-supported negative offset
    198 define void @store_breg_immoff_2(i64 %a) {
    199 ; CHECK-LABEL: store_breg_immoff_2
    200 ; CHECK:       sub [[REG:x[0-9]+]], x0, #257
    201 ; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
    202   %1 = add i64 %a, -257
    203   %2 = inttoptr i64 %1 to i32*
    204   store i32 0, i32* %2
    205   ret void
    206 }
    207 
    208 ; Max supported unscaled offset
    209 define void @store_breg_immoff_3(i64 %a) {
    210 ; CHECK-LABEL: store_breg_immoff_3
    211 ; CHECK:       stur wzr, [x0, #255]
    212   %1 = add i64 %a, 255
    213   %2 = inttoptr i64 %1 to i32*
    214   store i32 0, i32* %2
    215   ret void
    216 }
    217 
    218 ; Min un-supported unscaled offset
    219 define void @store_breg_immoff_4(i64 %a) {
    220 ; CHECK-LABEL: store_breg_immoff_4
    221 ; CHECK:       add [[REG:x[0-9]+]], x0, #257
    222 ; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
    223   %1 = add i64 %a, 257
    224   %2 = inttoptr i64 %1 to i32*
    225   store i32 0, i32* %2
    226   ret void
    227 }
    228 
    229 ; Max supported scaled offset
    230 define void @store_breg_immoff_5(i64 %a) {
    231 ; CHECK-LABEL: store_breg_immoff_5
    232 ; CHECK:       str wzr, [x0, #16380]
    233   %1 = add i64 %a, 16380
    234   %2 = inttoptr i64 %1 to i32*
    235   store i32 0, i32* %2
    236   ret void
    237 }
    238 
    239 ; Min un-supported scaled offset
    240 define void @store_breg_immoff_6(i64 %a) {
    241 ; SDAG-LABEL: store_breg_immoff_6
    242 ; SDAG:       orr	w[[NUM:[0-9]+]], wzr, #0x4000
    243 ; SDAG-NEXT:  str wzr, [x0, x[[NUM]]]
    244 ; FAST-LABEL: store_breg_immoff_6
    245 ; FAST:       add [[REG:x[0-9]+]], x0, #4, lsl #12
    246 ; FAST-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
    247   %1 = add i64 %a, 16384
    248   %2 = inttoptr i64 %1 to i32*
    249   store i32 0, i32* %2
    250   ret void
    251 }
    252 
    253 define i64 @load_breg_immoff_7(i64 %a) {
    254 ; CHECK-LABEL: load_breg_immoff_7
    255 ; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
    256   %1 = add i64 %a, 48
    257   %2 = inttoptr i64 %1 to i64*
    258   %3 = load i64, i64* %2
    259   ret i64 %3
    260 }
    261 
    262 ; Flip add operands
    263 define i64 @load_breg_immoff_8(i64 %a) {
    264 ; CHECK-LABEL: load_breg_immoff_8
    265 ; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
    266   %1 = add i64 48, %a
    267   %2 = inttoptr i64 %1 to i64*
    268   %3 = load i64, i64* %2
    269   ret i64 %3
    270 }
    271 
    272 ; Load Base Register + Register Offset
    273 define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
    274 ; CHECK-LABEL: load_breg_offreg_1
    275 ; CHECK:       ldr {{x[0-9]+}}, [x0, x1]
    276   %1 = add i64 %a, %b
    277   %2 = inttoptr i64 %1 to i64*
    278   %3 = load i64, i64* %2
    279   ret i64 %3
    280 }
    281 
    282 ; Flip add operands
    283 define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
    284 ; CHECK-LABEL: load_breg_offreg_2
    285 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0]
    286   %1 = add i64 %b, %a
    287   %2 = inttoptr i64 %1 to i64*
    288   %3 = load i64, i64* %2
    289   ret i64 %3
    290 }
    291 
    292 ; Load Base Register + Register Offset + Immediate Offset
    293 define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
    294 ; CHECK-LABEL: load_breg_offreg_immoff_1
    295 ; CHECK:       add [[REG:x[0-9]+]], x0, x1
    296 ; CHECK-NEXT:  ldr x0, {{\[}}[[REG]], #48{{\]}}
    297   %1 = add i64 %a, %b
    298   %2 = add i64 %1, 48
    299   %3 = inttoptr i64 %2 to i64*
    300   %4 = load i64, i64* %3
    301   ret i64 %4
    302 }
    303 
    304 define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
    305 ; SDAG-LABEL: load_breg_offreg_immoff_2
    306 ; SDAG:       add [[REG1:x[0-9]+]], x0, x1
    307 ; SDAG-NEXT:  orr w[[NUM:[0-9]+]], wzr, #0xf000
    308 ; SDAG-NEXT:  ldr x0, {{\[}}[[REG1]], x[[NUM]]]
    309 ; FAST-LABEL: load_breg_offreg_immoff_2
    310 ; FAST:       add [[REG:x[0-9]+]], x0, #15, lsl #12
    311 ; FAST-NEXT:  ldr x0, {{\[}}[[REG]], x1{{\]}}
    312   %1 = add i64 %a, %b
    313   %2 = add i64 %1, 61440
    314   %3 = inttoptr i64 %2 to i64*
    315   %4 = load i64, i64* %3
    316   ret i64 %4
    317 }
    318 
    319 ; Load Scaled Register Offset
    320 define i32 @load_shift_offreg_1(i64 %a) {
    321 ; CHECK-LABEL: load_shift_offreg_1
    322 ; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
    323 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
    324   %1 = shl i64 %a, 2
    325   %2 = inttoptr i64 %1 to i32*
    326   %3 = load i32, i32* %2
    327   ret i32 %3
    328 }
    329 
    330 define i32 @load_mul_offreg_1(i64 %a) {
    331 ; CHECK-LABEL: load_mul_offreg_1
    332 ; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
    333 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
    334   %1 = mul i64 %a, 4
    335   %2 = inttoptr i64 %1 to i32*
    336   %3 = load i32, i32* %2
    337   ret i32 %3
    338 }
    339 
    340 ; Load Base Register + Scaled Register Offset
    341 define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
    342 ; CHECK-LABEL: load_breg_shift_offreg_1
    343 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
    344   %1 = shl i64 %a, 2
    345   %2 = add i64 %1, %b
    346   %3 = inttoptr i64 %2 to i32*
    347   %4 = load i32, i32* %3
    348   ret i32 %4
    349 }
    350 
    351 define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
    352 ; CHECK-LABEL: load_breg_shift_offreg_2
    353 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
    354   %1 = shl i64 %a, 2
    355   %2 = add i64 %b, %1
    356   %3 = inttoptr i64 %2 to i32*
    357   %4 = load i32, i32* %3
    358   ret i32 %4
    359 }
    360 
    361 define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
    362 ; SDAG-LABEL: load_breg_shift_offreg_3
    363 ; SDAG:       lsl [[REG:x[0-9]+]], x0, #2
    364 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
    365 ; FAST-LABEL: load_breg_shift_offreg_3
    366 ; FAST:       lsl [[REG:x[0-9]+]], x1, #2
    367 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    368   %1 = shl i64 %a, 2
    369   %2 = shl i64 %b, 2
    370   %3 = add i64 %1, %2
    371   %4 = inttoptr i64 %3 to i32*
    372   %5 = load i32, i32* %4
    373   ret i32 %5
    374 }
    375 
    376 define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
    377 ; SDAG-LABEL: load_breg_shift_offreg_4
    378 ; SDAG:       lsl [[REG:x[0-9]+]], x1, #2
    379 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    380 ; FAST-LABEL: load_breg_shift_offreg_4
    381 ; FAST:       lsl [[REG:x[0-9]+]], x0, #2
    382 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
    383   %1 = shl i64 %a, 2
    384   %2 = shl i64 %b, 2
    385   %3 = add i64 %2, %1
    386   %4 = inttoptr i64 %3 to i32*
    387   %5 = load i32, i32* %4
    388   ret i32 %5
    389 }
    390 
    391 define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
    392 ; SDAG-LABEL: load_breg_shift_offreg_5
    393 ; SDAG:       lsl [[REG:x[0-9]+]], x1, #3
    394 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    395 ; FAST-LABEL: load_breg_shift_offreg_5
    396 ; FAST:       lsl [[REG:x[0-9]+]], x1, #3
    397 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    398   %1 = shl i64 %a, 2
    399   %2 = shl i64 %b, 3
    400   %3 = add i64 %1, %2
    401   %4 = inttoptr i64 %3 to i32*
    402   %5 = load i32, i32* %4
    403   ret i32 %5
    404 }
    405 
    406 define i32 @load_breg_mul_offreg_1(i64 %a, i64 %b) {
    407 ; CHECK-LABEL: load_breg_mul_offreg_1
    408 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
    409   %1 = mul i64 %a, 4
    410   %2 = add i64 %1, %b
    411   %3 = inttoptr i64 %2 to i32*
    412   %4 = load i32, i32* %3
    413   ret i32 %4
    414 }
    415 
    416 define zeroext i8 @load_breg_and_offreg_1(i64 %a, i64 %b) {
    417 ; CHECK-LABEL: load_breg_and_offreg_1
    418 ; CHECK:       ldrb {{w[0-9]+}}, [x1, w0, uxtw]
    419   %1 = and i64 %a, 4294967295
    420   %2 = add i64 %1, %b
    421   %3 = inttoptr i64 %2 to i8*
    422   %4 = load i8, i8* %3
    423   ret i8 %4
    424 }
    425 
    426 define zeroext i16 @load_breg_and_offreg_2(i64 %a, i64 %b) {
    427 ; CHECK-LABEL: load_breg_and_offreg_2
    428 ; CHECK:       ldrh {{w[0-9]+}}, [x1, w0, uxtw #1]
    429   %1 = and i64 %a, 4294967295
    430   %2 = shl i64 %1, 1
    431   %3 = add i64 %2, %b
    432   %4 = inttoptr i64 %3 to i16*
    433   %5 = load i16, i16* %4
    434   ret i16 %5
    435 }
    436 
    437 define i32 @load_breg_and_offreg_3(i64 %a, i64 %b) {
    438 ; CHECK-LABEL: load_breg_and_offreg_3
    439 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
    440   %1 = and i64 %a, 4294967295
    441   %2 = shl i64 %1, 2
    442   %3 = add i64 %2, %b
    443   %4 = inttoptr i64 %3 to i32*
    444   %5 = load i32, i32* %4
    445   ret i32 %5
    446 }
    447 
    448 define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) {
    449 ; CHECK-LABEL: load_breg_and_offreg_4
    450 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
    451   %1 = and i64 %a, 4294967295
    452   %2 = shl i64 %1, 3
    453   %3 = add i64 %2, %b
    454   %4 = inttoptr i64 %3 to i64*
    455   %5 = load i64, i64* %4
    456   ret i64 %5
    457 }
    458 
    459 ; Not all 'and' instructions have immediates.
    460 define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) {
    461 ; CHECK-LABEL: load_breg_and_offreg_5
    462 ; CHECK:       and [[REG:x[0-9]+]], x0, x2
    463 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], x1{{\]}}
    464   %1 = and i64 %a, %c
    465   %2 = add i64 %1, %b
    466   %3 = inttoptr i64 %2 to i64*
    467   %4 = load i64, i64* %3
    468   ret i64 %4
    469 }
    470 
    471 define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) {
    472 ; CHECK-LABEL: load_breg_and_offreg_6
    473 ; CHECK:       and [[REG:x[0-9]+]], x0, x2
    474 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}x1, [[REG]], lsl #3{{\]}}
    475   %1 = and i64 %a, %c
    476   %2 = shl i64 %1, 3
    477   %3 = add i64 %2, %b
    478   %4 = inttoptr i64 %3 to i64*
    479   %5 = load i64, i64* %4
    480   ret i64 %5
    481 }
    482 
    483 ; Load Base Register + Scaled Register Offset + Sign/Zero extension
    484 define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
    485 ; CHECK-LABEL: load_breg_zext_shift_offreg_1
    486 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
    487   %1 = zext i32 %a to i64
    488   %2 = shl i64 %1, 2
    489   %3 = add i64 %2, %b
    490   %4 = inttoptr i64 %3 to i32*
    491   %5 = load i32, i32* %4
    492   ret i32 %5
    493 }
    494 
    495 define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
    496 ; CHECK-LABEL: load_breg_zext_shift_offreg_2
    497 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
    498   %1 = zext i32 %a to i64
    499   %2 = shl i64 %1, 2
    500   %3 = add i64 %b, %2
    501   %4 = inttoptr i64 %3 to i32*
    502   %5 = load i32, i32* %4
    503   ret i32 %5
    504 }
    505 
    506 define i32 @load_breg_zext_mul_offreg_1(i32 %a, i64 %b) {
    507 ; CHECK-LABEL: load_breg_zext_mul_offreg_1
    508 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
    509   %1 = zext i32 %a to i64
    510   %2 = mul i64 %1, 4
    511   %3 = add i64 %2, %b
    512   %4 = inttoptr i64 %3 to i32*
    513   %5 = load i32, i32* %4
    514   ret i32 %5
    515 }
    516 
    517 define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
    518 ; CHECK-LABEL: load_breg_sext_shift_offreg_1
    519 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
    520   %1 = sext i32 %a to i64
    521   %2 = shl i64 %1, 2
    522   %3 = add i64 %2, %b
    523   %4 = inttoptr i64 %3 to i32*
    524   %5 = load i32, i32* %4
    525   ret i32 %5
    526 }
    527 
    528 define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
    529 ; CHECK-LABEL: load_breg_sext_shift_offreg_2
    530 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
    531   %1 = sext i32 %a to i64
    532   %2 = shl i64 %1, 2
    533   %3 = add i64 %b, %2
    534   %4 = inttoptr i64 %3 to i32*
    535   %5 = load i32, i32* %4
    536   ret i32 %5
    537 }
    538 
    539 ; Make sure that we don't drop the first 'add' instruction.
    540 define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) {
    541 ; CHECK-LABEL: load_breg_sext_shift_offreg_3
    542 ; CHECK:       add [[REG:w[0-9]+]], w0, #4
    543 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}x1, [[REG]], sxtw #2{{\]}}
    544   %1 = add i32 %a, 4
    545   %2 = sext i32 %1 to i64
    546   %3 = shl i64 %2, 2
    547   %4 = add i64 %b, %3
    548   %5 = inttoptr i64 %4 to i32*
    549   %6 = load i32, i32* %5
    550   ret i32 %6
    551 }
    552 
    553 
    554 define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {
    555 ; CHECK-LABEL: load_breg_sext_mul_offreg_1
    556 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
    557   %1 = sext i32 %a to i64
    558   %2 = mul i64 %1, 4
    559   %3 = add i64 %2, %b
    560   %4 = inttoptr i64 %3 to i32*
    561   %5 = load i32, i32* %4
    562   ret i32 %5
    563 }
    564 
    565 ; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension
    566 define i64 @load_sext_shift_offreg_imm1(i32 %a) {
    567 ; CHECK-LABEL: load_sext_shift_offreg_imm1
    568 ; CHECK:       sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32
    569 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
    570   %1 = sext i32 %a to i64
    571   %2 = shl i64 %1, 3
    572   %3 = add i64 %2, 8
    573   %4 = inttoptr i64 %3 to i64*
    574   %5 = load i64, i64* %4
    575   ret i64 %5
    576 }
    577 
    578 ; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension
    579 define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
    580 ; CHECK-LABEL: load_breg_sext_shift_offreg_imm1
    581 ; CHECK:       add [[REG:x[0-9]+]], x1, w0, sxtw #3
    582 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
    583   %1 = sext i32 %a to i64
    584   %2 = shl i64 %1, 3
    585   %3 = add i64 %b, %2
    586   %4 = add i64 %3, 8
    587   %5 = inttoptr i64 %4 to i64*
    588   %6 = load i64, i64* %5
    589   ret i64 %6
    590 }
    591 
    592 ; Test that the kill flag is not set - the machine instruction verifier does that for us.
    593 define i64 @kill_reg(i64 %a) {
    594   %1 = sub i64 %a, 8
    595   %2 = add i64 %1, 96
    596   %3 = inttoptr i64 %2 to i64*
    597   %4 = load i64, i64* %3
    598   %5 = add i64 %2, %4
    599   ret i64 %5
    600 }
    601 
    602 define void @store_fi(i64 %i) {
    603 ; CHECK-LABEL: store_fi
    604 ; CHECK:       mov [[REG:x[0-9]+]], sp
    605 ; CHECK:       str {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    606   %1 = alloca [8 x i32]
    607   %2 = ptrtoint [8 x i32]* %1 to i64
    608   %3 = mul i64 %i, 4
    609   %4 = add i64 %2, %3
    610   %5 = inttoptr i64 %4 to i32*
    611   store i32 47, i32* %5, align 4
    612   ret void
    613 }
    614 
    615 define i32 @load_fi(i64 %i) {
    616 ; CHECK-LABEL: load_fi
    617 ; CHECK:       mov [[REG:x[0-9]+]], sp
    618 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
    619   %1 = alloca [8 x i32]
    620   %2 = ptrtoint [8 x i32]* %1 to i64
    621   %3 = mul i64 %i, 4
    622   %4 = add i64 %2, %3
    623   %5 = inttoptr i64 %4 to i32*
    624   %6 = load i32, i32* %5, align 4
    625   ret i32 %6
    626 }
    627 
    628