Home | History | Annotate | Download | only in SystemZ
      1 ; Test 32-bit rotates left.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; Check the low end of the RLLG range.
      6 define i64 @f1(i64 %a) {
      7 ; CHECK-LABEL: f1:
      8 ; CHECK: rllg %r2, %r2, 1
      9 ; CHECK: br %r14
     10   %parta = shl i64 %a, 1
     11   %partb = lshr i64 %a, 63
     12   %or = or i64 %parta, %partb
     13   ret i64 %or
     14 }
     15 
     16 ; Check the high end of the defined RLLG range.
     17 define i64 @f2(i64 %a) {
     18 ; CHECK-LABEL: f2:
     19 ; CHECK: rllg %r2, %r2, 63
     20 ; CHECK: br %r14
     21   %parta = shl i64 %a, 63
     22   %partb = lshr i64 %a, 1
     23   %or = or i64 %parta, %partb
     24   ret i64 %or
     25 }
     26 
     27 ; We don't generate shifts by out-of-range values.
     28 define i64 @f3(i64 %a) {
     29 ; CHECK-LABEL: f3:
     30 ; CHECK-NOT: rllg
     31 ; CHECK: br %r14
     32   %parta = shl i64 %a, 64
     33   %partb = lshr i64 %a, 0
     34   %or = or i64 %parta, %partb
     35   ret i64 %or
     36 }
     37 
     38 ; Check variable shifts.
     39 define i64 @f4(i64 %a, i64 %amt) {
     40 ; CHECK-LABEL: f4:
     41 ; CHECK: rllg %r2, %r2, 0(%r3)
     42 ; CHECK: br %r14
     43   %amtb = sub i64 64, %amt
     44   %parta = shl i64 %a, %amt
     45   %partb = lshr i64 %a, %amtb
     46   %or = or i64 %parta, %partb
     47   ret i64 %or
     48 }
     49 
     50 ; Check shift amounts that have a constant term.
     51 define i64 @f5(i64 %a, i64 %amt) {
     52 ; CHECK-LABEL: f5:
     53 ; CHECK: rllg %r2, %r2, 10(%r3)
     54 ; CHECK: br %r14
     55   %add = add i64 %amt, 10
     56   %sub = sub i64 64, %add
     57   %parta = shl i64 %a, %add
     58   %partb = lshr i64 %a, %sub
     59   %or = or i64 %parta, %partb
     60   ret i64 %or
     61 }
     62 
     63 ; ...and again with a sign-extended 32-bit shift amount.
     64 define i64 @f6(i64 %a, i32 %amt) {
     65 ; CHECK-LABEL: f6:
     66 ; CHECK: rllg %r2, %r2, 10(%r3)
     67 ; CHECK: br %r14
     68   %add = add i32 %amt, 10
     69   %sub = sub i32 64, %add
     70   %addext = sext i32 %add to i64
     71   %subext = sext i32 %sub to i64
     72   %parta = shl i64 %a, %addext
     73   %partb = lshr i64 %a, %subext
     74   %or = or i64 %parta, %partb
     75   ret i64 %or
     76 }
     77 
     78 ; ...and now with a zero-extended 32-bit shift amount.
     79 define i64 @f7(i64 %a, i32 %amt) {
     80 ; CHECK-LABEL: f7:
     81 ; CHECK: rllg %r2, %r2, 10(%r3)
     82 ; CHECK: br %r14
     83   %add = add i32 %amt, 10
     84   %sub = sub i32 64, %add
     85   %addext = zext i32 %add to i64
     86   %subext = zext i32 %sub to i64
     87   %parta = shl i64 %a, %addext
     88   %partb = lshr i64 %a, %subext
     89   %or = or i64 %parta, %partb
     90   ret i64 %or
     91 }
     92 
     93 ; Check shift amounts that have the largest in-range constant term.  We could
     94 ; mask the amount instead.
     95 define i64 @f8(i64 %a, i64 %amt) {
     96 ; CHECK-LABEL: f8:
     97 ; CHECK: rllg %r2, %r2, 524287(%r3)
     98 ; CHECK: br %r14
     99   %add = add i64 %amt, 524287
    100   %sub = sub i64 64, %add
    101   %parta = shl i64 %a, %add
    102   %partb = lshr i64 %a, %sub
    103   %or = or i64 %parta, %partb
    104   ret i64 %or
    105 }
    106 
    107 ; Check the next value up, which without masking must use a separate
    108 ; addition.
    109 define i64 @f9(i64 %a, i64 %amt) {
    110 ; CHECK-LABEL: f9:
    111 ; CHECK: a{{g?}}fi %r3, 524288
    112 ; CHECK: rllg %r2, %r2, 0(%r3)
    113 ; CHECK: br %r14
    114   %add = add i64 %amt, 524288
    115   %sub = sub i64 64, %add
    116   %parta = shl i64 %a, %add
    117   %partb = lshr i64 %a, %sub
    118   %or = or i64 %parta, %partb
    119   ret i64 %or
    120 }
    121 
    122 ; Check cases where 1 is subtracted from the shift amount.
    123 define i64 @f10(i64 %a, i64 %amt) {
    124 ; CHECK-LABEL: f10:
    125 ; CHECK: rllg %r2, %r2, -1(%r3)
    126 ; CHECK: br %r14
    127   %suba = sub i64 %amt, 1
    128   %subb = sub i64 64, %suba
    129   %parta = shl i64 %a, %suba
    130   %partb = lshr i64 %a, %subb
    131   %or = or i64 %parta, %partb
    132   ret i64 %or
    133 }
    134 
    135 ; Check the lowest value that can be subtracted from the shift amount.
    136 ; Again, we could mask the shift amount instead.
    137 define i64 @f11(i64 %a, i64 %amt) {
    138 ; CHECK-LABEL: f11:
    139 ; CHECK: rllg %r2, %r2, -524288(%r3)
    140 ; CHECK: br %r14
    141   %suba = sub i64 %amt, 524288
    142   %subb = sub i64 64, %suba
    143   %parta = shl i64 %a, %suba
    144   %partb = lshr i64 %a, %subb
    145   %or = or i64 %parta, %partb
    146   ret i64 %or
    147 }
    148 
    149 ; Check the next value down, which without masking must use a separate
    150 ; addition.
    151 define i64 @f12(i64 %a, i64 %amt) {
    152 ; CHECK-LABEL: f12:
    153 ; CHECK: a{{g?}}fi %r3, -524289
    154 ; CHECK: rllg %r2, %r2, 0(%r3)
    155 ; CHECK: br %r14
    156   %suba = sub i64 %amt, 524289
    157   %subb = sub i64 64, %suba
    158   %parta = shl i64 %a, %suba
    159   %partb = lshr i64 %a, %subb
    160   %or = or i64 %parta, %partb
    161   ret i64 %or
    162 }
    163 
    164 ; Check that we don't try to generate "indexed" shifts.
    165 define i64 @f13(i64 %a, i64 %b, i64 %c) {
    166 ; CHECK-LABEL: f13:
    167 ; CHECK: a{{g?}}r {{%r3, %r4|%r4, %r3}}
    168 ; CHECK: rllg %r2, %r2, 0({{%r[34]}})
    169 ; CHECK: br %r14
    170   %add = add i64 %b, %c
    171   %sub = sub i64 64, %add
    172   %parta = shl i64 %a, %add
    173   %partb = lshr i64 %a, %sub
    174   %or = or i64 %parta, %partb
    175   ret i64 %or
    176 }
    177 
    178 ; Check that the shift amount uses an address register.  It cannot be in %r0.
    179 define i64 @f14(i64 %a, i64 *%ptr) {
    180 ; CHECK-LABEL: f14:
    181 ; CHECK: l %r1, 4(%r3)
    182 ; CHECK: rllg %r2, %r2, 0(%r1)
    183 ; CHECK: br %r14
    184   %amt = load i64 *%ptr
    185   %amtb = sub i64 64, %amt
    186   %parta = shl i64 %a, %amt
    187   %partb = lshr i64 %a, %amtb
    188   %or = or i64 %parta, %partb
    189   ret i64 %or
    190 }
    191