Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -aarch64-atomic-cfg-tidy=false -disable-cgp-branch-opts -verify-machineinstrs < %s | FileCheck %s
      2 
      3 ;
      4 ; Test folding of the sign-/zero-extend into the load instruction.
      5 ;
      6 
      7 ; Unscaled
      8 define i32 @load_unscaled_zext_i8_to_i32(i64 %a) {
      9 ; CHECK-LABEL: load_unscaled_zext_i8_to_i32
     10 ; CHECK:       ldurb w0, [x0, #-8]
     11 ; CHECK-NOT:   uxtb
     12   %1 = sub i64 %a, 8
     13   %2 = inttoptr i64 %1 to i8*
     14   %3 = load i8, i8* %2
     15   br label %bb2
     16 
     17 bb2:
     18   %4 = zext i8 %3 to i32
     19   ret i32 %4
     20 }
     21 
     22 define i32 @load_unscaled_zext_i16_to_i32(i64 %a) {
     23 ; CHECK-LABEL: load_unscaled_zext_i16_to_i32
     24 ; CHECK:       ldurh w0, [x0, #-8]
     25 ; CHECK-NOT:   uxth
     26   %1 = sub i64 %a, 8
     27   %2 = inttoptr i64 %1 to i16*
     28   %3 = load i16, i16* %2
     29   br label %bb2
     30 
     31 bb2:
     32   %4 = zext i16 %3 to i32
     33   ret i32 %4
     34 }
     35 
     36 define i64 @load_unscaled_zext_i8_to_i64(i64 %a) {
     37 ; CHECK-LABEL: load_unscaled_zext_i8_to_i64
     38 ; CHECK:       ldurb w0, [x0, #-8]
     39 ; CHECK-NOT:   uxtb
     40   %1 = sub i64 %a, 8
     41   %2 = inttoptr i64 %1 to i8*
     42   %3 = load i8, i8* %2
     43   br label %bb2
     44 
     45 bb2:
     46   %4 = zext i8 %3 to i64
     47   ret i64 %4
     48 }
     49 
     50 define i64 @load_unscaled_zext_i16_to_i64(i64 %a) {
     51 ; CHECK-LABEL: load_unscaled_zext_i16_to_i64
     52 ; CHECK:       ldurh w0, [x0, #-8]
     53 ; CHECK-NOT:   uxth
     54   %1 = sub i64 %a, 8
     55   %2 = inttoptr i64 %1 to i16*
     56   %3 = load i16, i16* %2
     57   br label %bb2
     58 
     59 bb2:
     60   %4 = zext i16 %3 to i64
     61   ret i64 %4
     62 }
     63 
     64 define i64 @load_unscaled_zext_i32_to_i64(i64 %a) {
     65 ; CHECK-LABEL: load_unscaled_zext_i32_to_i64
     66 ; CHECK:       ldur w0, [x0, #-8]
     67 ; CHECK-NOT:   uxtw
     68   %1 = sub i64 %a, 8
     69   %2 = inttoptr i64 %1 to i32*
     70   %3 = load i32, i32* %2
     71   br label %bb2
     72 
     73 bb2:
     74   %4 = zext i32 %3 to i64
     75   ret i64 %4
     76 }
     77 
     78 define i32 @load_unscaled_sext_i8_to_i32(i64 %a) {
     79 ; CHECK-LABEL: load_unscaled_sext_i8_to_i32
     80 ; CHECK:       ldursb w0, [x0, #-8]
     81 ; CHECK-NOT:   sxtb
     82   %1 = sub i64 %a, 8
     83   %2 = inttoptr i64 %1 to i8*
     84   %3 = load i8, i8* %2
     85   br label %bb2
     86 
     87 bb2:
     88   %4 = sext i8 %3 to i32
     89   ret i32 %4
     90 }
     91 
     92 define i32 @load_unscaled_sext_i16_to_i32(i64 %a) {
     93 ; CHECK-LABEL: load_unscaled_sext_i16_to_i32
     94 ; CHECK:       ldursh w0, [x0, #-8]
     95 ; CHECK-NOT:   sxth
     96   %1 = sub i64 %a, 8
     97   %2 = inttoptr i64 %1 to i16*
     98   %3 = load i16, i16* %2
     99   br label %bb2
    100 
    101 bb2:
    102   %4 = sext i16 %3 to i32
    103   ret i32 %4
    104 }
    105 
    106 define i64 @load_unscaled_sext_i8_to_i64(i64 %a) {
    107 ; CHECK-LABEL: load_unscaled_sext_i8_to_i64
    108 ; CHECK:       ldursb x0, [x0, #-8]
    109 ; CHECK-NOT:   sxtb
    110   %1 = sub i64 %a, 8
    111   %2 = inttoptr i64 %1 to i8*
    112   %3 = load i8, i8* %2
    113   br label %bb2
    114 
    115 bb2:
    116   %4 = sext i8 %3 to i64
    117   ret i64 %4
    118 }
    119 
    120 define i64 @load_unscaled_sext_i16_to_i64(i64 %a) {
    121 ; CHECK-LABEL: load_unscaled_sext_i16_to_i64
    122 ; CHECK:       ldursh x0, [x0, #-8]
    123 ; CHECK-NOT:   sxth
    124   %1 = sub i64 %a, 8
    125   %2 = inttoptr i64 %1 to i16*
    126   %3 = load i16, i16* %2
    127   br label %bb2
    128 
    129 bb2:
    130   %4 = sext i16 %3 to i64
    131   ret i64 %4
    132 }
    133 
    134 define i64 @load_unscaled_sext_i32_to_i64(i64 %a) {
    135 ; CHECK-LABEL: load_unscaled_sext_i32_to_i64
    136 ; CHECK:       ldursw x0, [x0, #-8]
    137 ; CHECK-NOT:   sxtw
    138   %1 = sub i64 %a, 8
    139   %2 = inttoptr i64 %1 to i32*
    140   %3 = load i32, i32* %2
    141   br label %bb2
    142 
    143 bb2:
    144   %4 = sext i32 %3 to i64
    145   ret i64 %4
    146 }
    147 
    148 ; Register
    149 define i32 @load_register_zext_i8_to_i32(i64 %a, i64 %b) {
    150 ; CHECK-LABEL: load_register_zext_i8_to_i32
    151 ; CHECK:       ldrb w0, [x0, x1]
    152 ; CHECK-NOT:   uxtb
    153   %1 = add i64 %a, %b
    154   %2 = inttoptr i64 %1 to i8*
    155   %3 = load i8, i8* %2
    156   br label %bb2
    157 
    158 bb2:
    159   %4 = zext i8 %3 to i32
    160   ret i32 %4
    161 }
    162 
    163 define i32 @load_register_zext_i16_to_i32(i64 %a, i64 %b) {
    164 ; CHECK-LABEL: load_register_zext_i16_to_i32
    165 ; CHECK:       ldrh w0, [x0, x1]
    166 ; CHECK-NOT:   uxth
    167   %1 = add i64 %a, %b
    168   %2 = inttoptr i64 %1 to i16*
    169   %3 = load i16, i16* %2
    170   br label %bb2
    171 
    172 bb2:
    173   %4 = zext i16 %3 to i32
    174   ret i32 %4
    175 }
    176 
    177 define i64 @load_register_zext_i8_to_i64(i64 %a, i64 %b) {
    178 ; CHECK-LABEL: load_register_zext_i8_to_i64
    179 ; CHECK:       ldrb w0, [x0, x1]
    180 ; CHECK-NOT:   uxtb
    181   %1 = add i64 %a, %b
    182   %2 = inttoptr i64 %1 to i8*
    183   %3 = load i8, i8* %2
    184   br label %bb2
    185 
    186 bb2:
    187   %4 = zext i8 %3 to i64
    188   ret i64 %4
    189 }
    190 
    191 define i64 @load_register_zext_i16_to_i64(i64 %a, i64 %b) {
    192 ; CHECK-LABEL: load_register_zext_i16_to_i64
    193 ; CHECK:       ldrh w0, [x0, x1]
    194 ; CHECK-NOT:   uxth
    195   %1 = add i64 %a, %b
    196   %2 = inttoptr i64 %1 to i16*
    197   %3 = load i16, i16* %2
    198   br label %bb2
    199 
    200 bb2:
    201   %4 = zext i16 %3 to i64
    202   ret i64 %4
    203 }
    204 
    205 define i64 @load_register_zext_i32_to_i64(i64 %a, i64 %b) {
    206 ; CHECK-LABEL: load_register_zext_i32_to_i64
    207 ; CHECK:       ldr w0, [x0, x1]
    208 ; CHECK-NOT:   uxtw
    209   %1 = add i64 %a, %b
    210   %2 = inttoptr i64 %1 to i32*
    211   %3 = load i32, i32* %2
    212   br label %bb2
    213 
    214 bb2:
    215   %4 = zext i32 %3 to i64
    216   ret i64 %4
    217 }
    218 
    219 define i32 @load_register_sext_i8_to_i32(i64 %a, i64 %b) {
    220 ; CHECK-LABEL: load_register_sext_i8_to_i32
    221 ; CHECK:       ldrsb w0, [x0, x1]
    222 ; CHECK-NOT:   sxtb
    223   %1 = add i64 %a, %b
    224   %2 = inttoptr i64 %1 to i8*
    225   %3 = load i8, i8* %2
    226   br label %bb2
    227 
    228 bb2:
    229   %4 = sext i8 %3 to i32
    230   ret i32 %4
    231 }
    232 
    233 define i32 @load_register_sext_i16_to_i32(i64 %a, i64 %b) {
    234 ; CHECK-LABEL: load_register_sext_i16_to_i32
    235 ; CHECK:       ldrsh w0, [x0, x1]
    236 ; CHECK-NOT:   sxth
    237   %1 = add i64 %a, %b
    238   %2 = inttoptr i64 %1 to i16*
    239   %3 = load i16, i16* %2
    240   br label %bb2
    241 
    242 bb2:
    243   %4 = sext i16 %3 to i32
    244   ret i32 %4
    245 }
    246 
    247 define i64 @load_register_sext_i8_to_i64(i64 %a, i64 %b) {
    248 ; CHECK-LABEL: load_register_sext_i8_to_i64
    249 ; CHECK:       ldrsb x0, [x0, x1]
    250 ; CHECK-NOT:   sxtb
    251   %1 = add i64 %a, %b
    252   %2 = inttoptr i64 %1 to i8*
    253   %3 = load i8, i8* %2
    254   br label %bb2
    255 
    256 bb2:
    257   %4 = sext i8 %3 to i64
    258   ret i64 %4
    259 }
    260 
    261 define i64 @load_register_sext_i16_to_i64(i64 %a, i64 %b) {
    262 ; CHECK-LABEL: load_register_sext_i16_to_i64
    263 ; CHECK:       ldrsh x0, [x0, x1]
    264 ; CHECK-NOT:   sxth
    265   %1 = add i64 %a, %b
    266   %2 = inttoptr i64 %1 to i16*
    267   %3 = load i16, i16* %2
    268   br label %bb2
    269 
    270 bb2:
    271   %4 = sext i16 %3 to i64
    272   ret i64 %4
    273 }
    274 
    275 define i64 @load_register_sext_i32_to_i64(i64 %a, i64 %b) {
    276 ; CHECK-LABEL: load_register_sext_i32_to_i64
    277 ; CHECK:       ldrsw x0, [x0, x1]
    278 ; CHECK-NOT:   sxtw
    279   %1 = add i64 %a, %b
    280   %2 = inttoptr i64 %1 to i32*
    281   %3 = load i32, i32* %2
    282   br label %bb2
    283 
    284 bb2:
    285   %4 = sext i32 %3 to i64
    286   ret i64 %4
    287 }
    288 
    289 ; Extend
    290 define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
    291 ; CHECK-LABEL: load_extend_zext_i8_to_i32
    292 ; CHECK:       ldrb w0, [x0, w1, sxtw]
    293 ; CHECK-NOT:   uxtb
    294   %1 = sext i32 %b to i64
    295   %2 = add i64 %a, %1
    296   %3 = inttoptr i64 %2 to i8*
    297   %4 = load i8, i8* %3
    298   br label %bb2
    299 
    300 bb2:
    301   %5 = zext i8 %4 to i32
    302   ret i32 %5
    303 }
    304 
    305 define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
    306 ; CHECK-LABEL: load_extend_zext_i16_to_i32
    307 ; CHECK:       ldrh w0, [x0, w1, sxtw]
    308 ; CHECK-NOT:   uxth
    309   %1 = sext i32 %b to i64
    310   %2 = add i64 %a, %1
    311   %3 = inttoptr i64 %2 to i16*
    312   %4 = load i16, i16* %3
    313   br label %bb2
    314 
    315 bb2:
    316   %5 = zext i16 %4 to i32
    317   ret i32 %5
    318 }
    319 
    320 define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
    321 ; CHECK-LABEL: load_extend_zext_i8_to_i64
    322 ; CHECK:       ldrb w0, [x0, w1, sxtw]
    323 ; CHECK-NOT:   uxtb
    324   %1 = sext i32 %b to i64
    325   %2 = add i64 %a, %1
    326   %3 = inttoptr i64 %2 to i8*
    327   %4 = load i8, i8* %3
    328   br label %bb2
    329 
    330 bb2:
    331   %5 = zext i8 %4 to i64
    332   ret i64 %5
    333 }
    334 
    335 define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
    336 ; CHECK-LABEL: load_extend_zext_i16_to_i64
    337 ; CHECK:       ldrh w0, [x0, w1, sxtw]
    338 ; CHECK-NOT:   uxth
    339   %1 = sext i32 %b to i64
    340   %2 = add i64 %a, %1
    341   %3 = inttoptr i64 %2 to i16*
    342   %4 = load i16, i16* %3
    343   br label %bb2
    344 
    345 bb2:
    346   %5 = zext i16 %4 to i64
    347   ret i64 %5
    348 }
    349 
    350 define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
    351 ; CHECK-LABEL: load_extend_zext_i32_to_i64
    352 ; CHECK:       ldr w0, [x0, w1, sxtw]
    353 ; CHECK-NOT:   uxtw
    354   %1 = sext i32 %b to i64
    355   %2 = add i64 %a, %1
    356   %3 = inttoptr i64 %2 to i32*
    357   %4 = load i32, i32* %3
    358   br label %bb2
    359 
    360 bb2:
    361   %5 = zext i32 %4 to i64
    362   ret i64 %5
    363 }
    364 
    365 define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
    366 ; CHECK-LABEL: load_extend_sext_i8_to_i32
    367 ; CHECK:       ldrsb w0, [x0, w1, sxtw]
    368 ; CHECK-NOT:   sxtb
    369   %1 = sext i32 %b to i64
    370   %2 = add i64 %a, %1
    371   %3 = inttoptr i64 %2 to i8*
    372   %4 = load i8, i8* %3
    373   br label %bb2
    374 
    375 bb2:
    376   %5 = sext i8 %4 to i32
    377   ret i32 %5
    378 }
    379 
    380 define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
    381 ; CHECK-LABEL: load_extend_sext_i16_to_i32
    382 ; CHECK:       ldrsh w0, [x0, w1, sxtw]
    383 ; CHECK-NOT:   sxth
    384   %1 = sext i32 %b to i64
    385   %2 = add i64 %a, %1
    386   %3 = inttoptr i64 %2 to i16*
    387   %4 = load i16, i16* %3
    388   br label %bb2
    389 
    390 bb2:
    391   %5 = sext i16 %4 to i32
    392   ret i32 %5
    393 }
    394 
    395 define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
    396 ; CHECK-LABEL: load_extend_sext_i8_to_i64
    397 ; CHECK:       ldrsb x0, [x0, w1, sxtw]
    398 ; CHECK-NOT:   sxtb
    399   %1 = sext i32 %b to i64
    400   %2 = add i64 %a, %1
    401   %3 = inttoptr i64 %2 to i8*
    402   %4 = load i8, i8* %3
    403   br label %bb2
    404 
    405 bb2:
    406   %5 = sext i8 %4 to i64
    407   ret i64 %5
    408 }
    409 
    410 define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
    411 ; CHECK-LABEL: load_extend_sext_i16_to_i64
    412 ; CHECK:       ldrsh x0, [x0, w1, sxtw]
    413 ; CHECK-NOT:   sxth
    414   %1 = sext i32 %b to i64
    415   %2 = add i64 %a, %1
    416   %3 = inttoptr i64 %2 to i16*
    417   %4 = load i16, i16* %3
    418   br label %bb2
    419 
    420 bb2:
    421   %5 = sext i16 %4 to i64
    422   ret i64 %5
    423 }
    424 
    425 define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
    426 ; CHECK-LABEL: load_extend_sext_i32_to_i64
    427 ; CHECK:       ldrsw x0, [x0, w1, sxtw]
    428 ; CHECK-NOT:   sxtw
    429   %1 = sext i32 %b to i64
    430   %2 = add i64 %a, %1
    431   %3 = inttoptr i64 %2 to i32*
    432   %4 = load i32, i32* %3
    433   br label %bb2
    434 
    435 bb2:
    436   %5 = sext i32 %4 to i64
    437   ret i64 %5
    438 }
    439 
    440