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