Home | History | Annotate | Download | only in SystemZ
      1 ; Test sequences that can use RISBG with a zeroed first operand.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; Test an extraction of bit 0 from a right-shifted value.
      6 define i32 @f1(i32 %foo) {
      7 ; CHECK-LABEL: f1:
      8 ; CHECK: risbg %r2, %r2, 63, 191, 54
      9 ; CHECK: br %r14
     10   %shr = lshr i32 %foo, 10
     11   %and = and i32 %shr, 1
     12   ret i32 %and
     13 }
     14 
     15 ; ...and again with i64.
     16 define i64 @f2(i64 %foo) {
     17 ; CHECK-LABEL: f2:
     18 ; CHECK: risbg %r2, %r2, 63, 191, 54
     19 ; CHECK: br %r14
     20   %shr = lshr i64 %foo, 10
     21   %and = and i64 %shr, 1
     22   ret i64 %and
     23 }
     24 
     25 ; Test an extraction of other bits from a right-shifted value.
     26 define i32 @f3(i32 %foo) {
     27 ; CHECK-LABEL: f3:
     28 ; CHECK: risbg %r2, %r2, 60, 189, 42
     29 ; CHECK: br %r14
     30   %shr = lshr i32 %foo, 22
     31   %and = and i32 %shr, 12
     32   ret i32 %and
     33 }
     34 
     35 ; ...and again with i64.
     36 define i64 @f4(i64 %foo) {
     37 ; CHECK-LABEL: f4:
     38 ; CHECK: risbg %r2, %r2, 60, 189, 42
     39 ; CHECK: br %r14
     40   %shr = lshr i64 %foo, 22
     41   %and = and i64 %shr, 12
     42   ret i64 %and
     43 }
     44 
     45 ; Test an extraction of most bits from a right-shifted value.
     46 ; The range should be reduced to exclude the zeroed high bits.
     47 define i32 @f5(i32 %foo) {
     48 ; CHECK-LABEL: f5:
     49 ; CHECK: risbg %r2, %r2, 34, 188, 62
     50 ; CHECK: br %r14
     51   %shr = lshr i32 %foo, 2
     52   %and = and i32 %shr, -8
     53   ret i32 %and
     54 }
     55 
     56 ; ...and again with i64.
     57 define i64 @f6(i64 %foo) {
     58 ; CHECK-LABEL: f6:
     59 ; CHECK: risbg %r2, %r2, 2, 188, 62
     60 ; CHECK: br %r14
     61   %shr = lshr i64 %foo, 2
     62   %and = and i64 %shr, -8
     63   ret i64 %and
     64 }
     65 
     66 ; Try the next value up (mask ....1111001).  This needs a separate shift
     67 ; and mask.
     68 define i32 @f7(i32 %foo) {
     69 ; CHECK-LABEL: f7:
     70 ; CHECK: srl %r2, 2
     71 ; CHECK: nill %r2, 65529
     72 ; CHECK: br %r14
     73   %shr = lshr i32 %foo, 2
     74   %and = and i32 %shr, -7
     75   ret i32 %and
     76 }
     77 
     78 ; ...and again with i64.
     79 define i64 @f8(i64 %foo) {
     80 ; CHECK-LABEL: f8:
     81 ; CHECK: srlg %r2, %r2, 2
     82 ; CHECK: nill %r2, 65529
     83 ; CHECK: br %r14
     84   %shr = lshr i64 %foo, 2
     85   %and = and i64 %shr, -7
     86   ret i64 %and
     87 }
     88 
     89 ; Test an extraction of bits from a left-shifted value.  The range should
     90 ; be reduced to exclude the zeroed low bits.
     91 define i32 @f9(i32 %foo) {
     92 ; CHECK-LABEL: f9:
     93 ; CHECK: risbg %r2, %r2, 56, 189, 2
     94 ; CHECK: br %r14
     95   %shr = shl i32 %foo, 2
     96   %and = and i32 %shr, 255
     97   ret i32 %and
     98 }
     99 
    100 ; ...and again with i64.
    101 define i64 @f10(i64 %foo) {
    102 ; CHECK-LABEL: f10:
    103 ; CHECK: risbg %r2, %r2, 56, 189, 2
    104 ; CHECK: br %r14
    105   %shr = shl i64 %foo, 2
    106   %and = and i64 %shr, 255
    107   ret i64 %and
    108 }
    109 
    110 ; Try a wrap-around mask (mask ....111100001111).  This needs a separate shift
    111 ; and mask.
    112 define i32 @f11(i32 %foo) {
    113 ; CHECK-LABEL: f11:
    114 ; CHECK: sll %r2, 2
    115 ; CHECK: nill %r2, 65295
    116 ; CHECK: br %r14
    117   %shr = shl i32 %foo, 2
    118   %and = and i32 %shr, -241
    119   ret i32 %and
    120 }
    121 
    122 ; ...and again with i64.
    123 define i64 @f12(i64 %foo) {
    124 ; CHECK-LABEL: f12:
    125 ; CHECK: sllg %r2, %r2, 2
    126 ; CHECK: nill %r2, 65295
    127 ; CHECK: br %r14
    128   %shr = shl i64 %foo, 2
    129   %and = and i64 %shr, -241
    130   ret i64 %and
    131 }
    132 
    133 ; Test an extraction from a rotated value, no mask wraparound.
    134 ; This is equivalent to the lshr case, because the bits from the
    135 ; shl are not used.
    136 define i32 @f13(i32 %foo) {
    137 ; CHECK-LABEL: f13:
    138 ; CHECK: risbg %r2, %r2, 56, 188, 46
    139 ; CHECK: br %r14
    140   %parta = shl i32 %foo, 14
    141   %partb = lshr i32 %foo, 18
    142   %rotl = or i32 %parta, %partb
    143   %and = and i32 %rotl, 248
    144   ret i32 %and
    145 }
    146 
    147 ; ...and again with i64.
    148 define i64 @f14(i64 %foo) {
    149 ; CHECK-LABEL: f14:
    150 ; CHECK: risbg %r2, %r2, 56, 188, 14
    151 ; CHECK: br %r14
    152   %parta = shl i64 %foo, 14
    153   %partb = lshr i64 %foo, 50
    154   %rotl = or i64 %parta, %partb
    155   %and = and i64 %rotl, 248
    156   ret i64 %and
    157 }
    158 
    159 ; Try a case in which only the bits from the shl are used.
    160 define i32 @f15(i32 %foo) {
    161 ; CHECK-LABEL: f15:
    162 ; CHECK: risbg %r2, %r2, 47, 177, 14
    163 ; CHECK: br %r14
    164   %parta = shl i32 %foo, 14
    165   %partb = lshr i32 %foo, 18
    166   %rotl = or i32 %parta, %partb
    167   %and = and i32 %rotl, 114688
    168   ret i32 %and
    169 }
    170 
    171 ; ...and again with i64.
    172 define i64 @f16(i64 %foo) {
    173 ; CHECK-LABEL: f16:
    174 ; CHECK: risbg %r2, %r2, 47, 177, 14
    175 ; CHECK: br %r14
    176   %parta = shl i64 %foo, 14
    177   %partb = lshr i64 %foo, 50
    178   %rotl = or i64 %parta, %partb
    179   %and = and i64 %rotl, 114688
    180   ret i64 %and
    181 }
    182 
    183 ; Test a 32-bit rotate in which both parts of the OR are needed.
    184 ; This needs a separate shift and mask.
    185 define i32 @f17(i32 %foo) {
    186 ; CHECK-LABEL: f17:
    187 ; CHECK: rll %r2, %r2, 4
    188 ; CHECK: nilf %r2, 126
    189 ; CHECK: br %r14
    190   %parta = shl i32 %foo, 4
    191   %partb = lshr i32 %foo, 28
    192   %rotl = or i32 %parta, %partb
    193   %and = and i32 %rotl, 126
    194   ret i32 %and
    195 }
    196 
    197 ; ...and for i64, where RISBG should do the rotate too.
    198 define i64 @f18(i64 %foo) {
    199 ; CHECK-LABEL: f18:
    200 ; CHECK: risbg %r2, %r2, 57, 190, 4
    201 ; CHECK: br %r14
    202   %parta = shl i64 %foo, 4
    203   %partb = lshr i64 %foo, 60
    204   %rotl = or i64 %parta, %partb
    205   %and = and i64 %rotl, 126
    206   ret i64 %and
    207 }
    208 
    209 ; Test an arithmetic shift right in which some of the sign bits are kept.
    210 ; This needs a separate shift and mask.
    211 define i32 @f19(i32 %foo) {
    212 ; CHECK-LABEL: f19:
    213 ; CHECK: sra %r2, 28
    214 ; CHECK: nilf %r2, 30
    215 ; CHECK: br %r14
    216   %shr = ashr i32 %foo, 28
    217   %and = and i32 %shr, 30
    218   ret i32 %and
    219 }
    220 
    221 ; ...and again with i64.  In this case RISBG is the best way of doing the AND.
    222 define i64 @f20(i64 %foo) {
    223 ; CHECK-LABEL: f20:
    224 ; CHECK: srag [[REG:%r[0-5]]], %r2, 60
    225 ; CHECK: risbg %r2, [[REG]], 59, 190, 0
    226 ; CHECK: br %r14
    227   %shr = ashr i64 %foo, 60
    228   %and = and i64 %shr, 30
    229   ret i64 %and
    230 }
    231 
    232 ; Now try an arithmetic right shift in which the sign bits aren't needed.
    233 ; Introduce a second use of %shr so that the ashr doesn't decompose to
    234 ; an lshr.
    235 define i32 @f21(i32 %foo, i32 *%dest) {
    236 ; CHECK-LABEL: f21:
    237 ; CHECK: risbg %r2, %r2, 60, 190, 36
    238 ; CHECK: br %r14
    239   %shr = ashr i32 %foo, 28
    240   store i32 %shr, i32 *%dest
    241   %and = and i32 %shr, 14
    242   ret i32 %and
    243 }
    244 
    245 ; ...and again with i64.
    246 define i64 @f22(i64 %foo, i64 *%dest) {
    247 ; CHECK-LABEL: f22:
    248 ; CHECK: risbg %r2, %r2, 60, 190, 4
    249 ; CHECK: br %r14
    250   %shr = ashr i64 %foo, 60
    251   store i64 %shr, i64 *%dest
    252   %and = and i64 %shr, 14
    253   ret i64 %and
    254 }
    255 
    256 ; Check that we use RISBG for shifted values even if the AND is a
    257 ; natural zero extension.
    258 define i64 @f23(i64 %foo) {
    259 ; CHECK-LABEL: f23:
    260 ; CHECK: risbg %r2, %r2, 56, 191, 62
    261 ; CHECK: br %r14
    262   %shr = lshr i64 %foo, 2
    263   %and = and i64 %shr, 255
    264   ret i64 %and
    265 }
    266 
    267 ; Test a case where the AND comes before a rotate.  This needs a separate
    268 ; mask and rotate.
    269 define i32 @f24(i32 %foo) {
    270 ; CHECK-LABEL: f24:
    271 ; CHECK: nilf %r2, 14
    272 ; CHECK: rll %r2, %r2, 3
    273 ; CHECK: br %r14
    274   %and = and i32 %foo, 14
    275   %parta = shl i32 %and, 3
    276   %partb = lshr i32 %and, 29
    277   %rotl = or i32 %parta, %partb
    278   ret i32 %rotl
    279 }
    280 
    281 ; ...and again with i64, where a single RISBG is enough.
    282 define i64 @f25(i64 %foo) {
    283 ; CHECK-LABEL: f25:
    284 ; CHECK: risbg %r2, %r2, 57, 187, 3
    285 ; CHECK: br %r14
    286   %and = and i64 %foo, 14
    287   %parta = shl i64 %and, 3
    288   %partb = lshr i64 %and, 61
    289   %rotl = or i64 %parta, %partb
    290   ret i64 %rotl
    291 }
    292 
    293 ; Test a wrap-around case in which the AND comes before a rotate.
    294 ; This again needs a separate mask and rotate.
    295 define i32 @f26(i32 %foo) {
    296 ; CHECK-LABEL: f26:
    297 ; CHECK: nill %r2, 65487
    298 ; CHECK: rll %r2, %r2, 5
    299 ; CHECK: br %r14
    300   %and = and i32 %foo, -49
    301   %parta = shl i32 %and, 5
    302   %partb = lshr i32 %and, 27
    303   %rotl = or i32 %parta, %partb
    304   ret i32 %rotl
    305 }
    306 
    307 ; ...and again with i64, where a single RISBG is OK.
    308 define i64 @f27(i64 %foo) {
    309 ; CHECK-LABEL: f27:
    310 ; CHECK: risbg %r2, %r2, 55, 180, 5
    311 ; CHECK: br %r14
    312   %and = and i64 %foo, -49
    313   %parta = shl i64 %and, 5
    314   %partb = lshr i64 %and, 59
    315   %rotl = or i64 %parta, %partb
    316   ret i64 %rotl
    317 }
    318 
    319 ; Test a case where the AND comes before a shift left.
    320 define i32 @f28(i32 %foo) {
    321 ; CHECK-LABEL: f28:
    322 ; CHECK: risbg %r2, %r2, 32, 173, 17
    323 ; CHECK: br %r14
    324   %and = and i32 %foo, 32766
    325   %shl = shl i32 %and, 17
    326   ret i32 %shl
    327 }
    328 
    329 ; ...and again with i64.
    330 define i64 @f29(i64 %foo) {
    331 ; CHECK-LABEL: f29:
    332 ; CHECK: risbg %r2, %r2, 0, 141, 49
    333 ; CHECK: br %r14
    334   %and = and i64 %foo, 32766
    335   %shl = shl i64 %and, 49
    336   ret i64 %shl
    337 }
    338 
    339 ; Test the next shift up from f28, in which the mask should get shortened.
    340 define i32 @f30(i32 %foo) {
    341 ; CHECK-LABEL: f30:
    342 ; CHECK: risbg %r2, %r2, 32, 172, 18
    343 ; CHECK: br %r14
    344   %and = and i32 %foo, 32766
    345   %shl = shl i32 %and, 18
    346   ret i32 %shl
    347 }
    348 
    349 ; ...and again with i64.
    350 define i64 @f31(i64 %foo) {
    351 ; CHECK-LABEL: f31:
    352 ; CHECK: risbg %r2, %r2, 0, 140, 50
    353 ; CHECK: br %r14
    354   %and = and i64 %foo, 32766
    355   %shl = shl i64 %and, 50
    356   ret i64 %shl
    357 }
    358 
    359 ; Test a wrap-around case in which the shift left comes after the AND.
    360 ; We can't use RISBG for the shift in that case.
    361 define i32 @f32(i32 %foo) {
    362 ; CHECK-LABEL: f32:
    363 ; CHECK: sll %r2
    364 ; CHECK: br %r14
    365   %and = and i32 %foo, -7
    366   %shl = shl i32 %and, 10
    367   ret i32 %shl
    368 }
    369 
    370 ; ...and again with i64.
    371 define i64 @f33(i64 %foo) {
    372 ; CHECK-LABEL: f33:
    373 ; CHECK: sllg %r2
    374 ; CHECK: br %r14
    375   %and = and i64 %foo, -7
    376   %shl = shl i64 %and, 10
    377   ret i64 %shl
    378 }
    379 
    380 ; Test a case where the AND comes before a shift right.
    381 define i32 @f34(i32 %foo) {
    382 ; CHECK-LABEL: f34:
    383 ; CHECK: risbg %r2, %r2, 57, 191, 55
    384 ; CHECK: br %r14
    385   %and = and i32 %foo, 65535
    386   %shl = lshr i32 %and, 9
    387   ret i32 %shl
    388 }
    389 
    390 ; ...and again with i64.
    391 define i64 @f35(i64 %foo) {
    392 ; CHECK-LABEL: f35:
    393 ; CHECK: risbg %r2, %r2, 57, 191, 55
    394 ; CHECK: br %r14
    395   %and = and i64 %foo, 65535
    396   %shl = lshr i64 %and, 9
    397   ret i64 %shl
    398 }
    399 
    400 ; Test a wrap-around case where the AND comes before a shift right.
    401 ; We can't use RISBG for the shift in that case.
    402 define i32 @f36(i32 %foo) {
    403 ; CHECK-LABEL: f36:
    404 ; CHECK: srl %r2
    405 ; CHECK: br %r14
    406   %and = and i32 %foo, -25
    407   %shl = lshr i32 %and, 1
    408   ret i32 %shl
    409 }
    410 
    411 ; ...and again with i64.
    412 define i64 @f37(i64 %foo) {
    413 ; CHECK-LABEL: f37:
    414 ; CHECK: srlg %r2
    415 ; CHECK: br %r14
    416   %and = and i64 %foo, -25
    417   %shl = lshr i64 %and, 1
    418   ret i64 %shl
    419 }
    420 
    421 ; Test a combination involving a large ASHR and a shift left.  We can't
    422 ; use RISBG there.
    423 define i64 @f38(i64 %foo) {
    424 ; CHECK-LABEL: f38:
    425 ; CHECK: srag {{%r[0-5]}}
    426 ; CHECK: sllg {{%r[0-5]}}
    427 ; CHECK: br %r14
    428   %ashr = ashr i64 %foo, 32
    429   %shl = shl i64 %ashr, 5
    430   ret i64 %shl
    431 }
    432 
    433 ; Try a similar thing in which no shifted sign bits are kept.
    434 define i64 @f39(i64 %foo, i64 *%dest) {
    435 ; CHECK-LABEL: f39:
    436 ; CHECK: srag [[REG:%r[01345]]], %r2, 35
    437 ; CHECK: risbg %r2, %r2, 33, 189, 31
    438 ; CHECK: br %r14
    439   %ashr = ashr i64 %foo, 35
    440   store i64 %ashr, i64 *%dest
    441   %shl = shl i64 %ashr, 2
    442   %and = and i64 %shl, 2147483647
    443   ret i64 %and
    444 }
    445 
    446 ; ...and again with the next highest shift value, where one sign bit is kept.
    447 define i64 @f40(i64 %foo, i64 *%dest) {
    448 ; CHECK-LABEL: f40:
    449 ; CHECK: srag [[REG:%r[01345]]], %r2, 36
    450 ; CHECK: risbg %r2, [[REG]], 33, 189, 2
    451 ; CHECK: br %r14
    452   %ashr = ashr i64 %foo, 36
    453   store i64 %ashr, i64 *%dest
    454   %shl = shl i64 %ashr, 2
    455   %and = and i64 %shl, 2147483647
    456   ret i64 %and
    457 }
    458