1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; Test 32-bit rotates left. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5 6; Check the low end of the RLL range. 7define i32 @f1(i32 %a) { 8; CHECK-LABEL: f1: 9; CHECK: # %bb.0: 10; CHECK-NEXT: rll %r2, %r2, 1 11; CHECK-NEXT: br %r14 12 %parta = shl i32 %a, 1 13 %partb = lshr i32 %a, 31 14 %or = or i32 %parta, %partb 15 ret i32 %or 16} 17 18; Check the high end of the defined RLL range. 19define i32 @f2(i32 %a) { 20; CHECK-LABEL: f2: 21; CHECK: # %bb.0: 22; CHECK-NEXT: rll %r2, %r2, 31 23; CHECK-NEXT: br %r14 24 %parta = shl i32 %a, 31 25 %partb = lshr i32 %a, 1 26 %or = or i32 %parta, %partb 27 ret i32 %or 28} 29 30; We don't generate shifts by out-of-range values. 31define i32 @f3(i32 %a) { 32; CHECK-LABEL: f3: 33; CHECK: # %bb.0: 34; CHECK-NEXT: lhi %r2, -1 35; CHECK-NEXT: br %r14 36 %parta = shl i32 %a, 32 37 %partb = lshr i32 %a, 0 38 %or = or i32 %parta, %partb 39 ret i32 %or 40} 41 42; Check variable shifts. 43define i32 @f4(i32 %a, i32 %amt) { 44; CHECK-LABEL: f4: 45; CHECK: # %bb.0: 46; CHECK-NEXT: rll %r2, %r2, 0(%r3) 47; CHECK-NEXT: br %r14 48 %amtb = sub i32 32, %amt 49 %parta = shl i32 %a, %amt 50 %partb = lshr i32 %a, %amtb 51 %or = or i32 %parta, %partb 52 ret i32 %or 53} 54 55; Check shift amounts that have a constant term. 56define i32 @f5(i32 %a, i32 %amt) { 57; CHECK-LABEL: f5: 58; CHECK: # %bb.0: 59; CHECK-NEXT: rll %r2, %r2, 10(%r3) 60; CHECK-NEXT: br %r14 61 %add = add i32 %amt, 10 62 %sub = sub i32 32, %add 63 %parta = shl i32 %a, %add 64 %partb = lshr i32 %a, %sub 65 %or = or i32 %parta, %partb 66 ret i32 %or 67} 68 69; ...and again with a truncated 64-bit shift amount. 70define i32 @f6(i32 %a, i64 %amt) { 71; CHECK-LABEL: f6: 72; CHECK: # %bb.0: 73; CHECK-NEXT: rll %r2, %r2, 10(%r3) 74; CHECK-NEXT: br %r14 75 %add = add i64 %amt, 10 76 %addtrunc = trunc i64 %add to i32 77 %sub = sub i32 32, %addtrunc 78 %parta = shl i32 %a, %addtrunc 79 %partb = lshr i32 %a, %sub 80 %or = or i32 %parta, %partb 81 ret i32 %or 82} 83 84; ...and again with a different truncation representation. 85define i32 @f7(i32 %a, i64 %amt) { 86; CHECK-LABEL: f7: 87; CHECK: # %bb.0: 88; CHECK-NEXT: rll %r2, %r2, 10(%r3) 89; CHECK-NEXT: br %r14 90 %add = add i64 %amt, 10 91 %sub = sub i64 32, %add 92 %addtrunc = trunc i64 %add to i32 93 %subtrunc = trunc i64 %sub to i32 94 %parta = shl i32 %a, %addtrunc 95 %partb = lshr i32 %a, %subtrunc 96 %or = or i32 %parta, %partb 97 ret i32 %or 98} 99 100; Check shift amounts that have the largest in-range constant term. We could 101; mask the amount instead. 102define i32 @f8(i32 %a, i32 %amt) { 103; CHECK-LABEL: f8: 104; CHECK: # %bb.0: 105; CHECK-NEXT: rll %r2, %r2, 524287(%r3) 106; CHECK-NEXT: br %r14 107 %add = add i32 %amt, 524287 108 %sub = sub i32 32, %add 109 %parta = shl i32 %a, %add 110 %partb = lshr i32 %a, %sub 111 %or = or i32 %parta, %partb 112 ret i32 %or 113} 114 115; Check the next value up, which without masking must use a separate 116; addition. 117define i32 @f9(i32 %a, i32 %amt) { 118; CHECK-LABEL: f9: 119; CHECK: # %bb.0: 120; CHECK-NEXT: afi %r3, 524288 121; CHECK-NEXT: rll %r2, %r2, 0(%r3) 122; CHECK-NEXT: br %r14 123 %add = add i32 %amt, 524288 124 %sub = sub i32 32, %add 125 %parta = shl i32 %a, %add 126 %partb = lshr i32 %a, %sub 127 %or = or i32 %parta, %partb 128 ret i32 %or 129} 130 131; Check cases where 1 is subtracted from the shift amount. 132define i32 @f10(i32 %a, i32 %amt) { 133; CHECK-LABEL: f10: 134; CHECK: # %bb.0: 135; CHECK-NEXT: rll %r2, %r2, -1(%r3) 136; CHECK-NEXT: br %r14 137 %suba = sub i32 %amt, 1 138 %subb = sub i32 32, %suba 139 %parta = shl i32 %a, %suba 140 %partb = lshr i32 %a, %subb 141 %or = or i32 %parta, %partb 142 ret i32 %or 143} 144 145; Check the lowest value that can be subtracted from the shift amount. 146; Again, we could mask the shift amount instead. 147define i32 @f11(i32 %a, i32 %amt) { 148; CHECK-LABEL: f11: 149; CHECK: # %bb.0: 150; CHECK-NEXT: rll %r2, %r2, -524288(%r3) 151; CHECK-NEXT: br %r14 152 %suba = sub i32 %amt, 524288 153 %subb = sub i32 32, %suba 154 %parta = shl i32 %a, %suba 155 %partb = lshr i32 %a, %subb 156 %or = or i32 %parta, %partb 157 ret i32 %or 158} 159 160; Check the next value down, which without masking must use a separate 161; addition. 162define i32 @f12(i32 %a, i32 %amt) { 163; CHECK-LABEL: f12: 164; CHECK: # %bb.0: 165; CHECK-NEXT: afi %r3, -524289 166; CHECK-NEXT: rll %r2, %r2, 0(%r3) 167; CHECK-NEXT: br %r14 168 %suba = sub i32 %amt, 524289 169 %subb = sub i32 32, %suba 170 %parta = shl i32 %a, %suba 171 %partb = lshr i32 %a, %subb 172 %or = or i32 %parta, %partb 173 ret i32 %or 174} 175 176; Check that we don't try to generate "indexed" shifts. 177define i32 @f13(i32 %a, i32 %b, i32 %c) { 178; CHECK-LABEL: f13: 179; CHECK: # %bb.0: 180; CHECK-NEXT: ar %r3, %r4 181; CHECK-NEXT: rll %r2, %r2, 0(%r3) 182; CHECK-NEXT: br %r14 183 %add = add i32 %b, %c 184 %sub = sub i32 32, %add 185 %parta = shl i32 %a, %add 186 %partb = lshr i32 %a, %sub 187 %or = or i32 %parta, %partb 188 ret i32 %or 189} 190 191; Check that the shift amount uses an address register. It cannot be in %r0. 192define i32 @f14(i32 %a, i32 *%ptr) { 193; CHECK-LABEL: f14: 194; CHECK: # %bb.0: 195; CHECK-NEXT: l %r1, 0(%r3) 196; CHECK-NEXT: rll %r2, %r2, 0(%r1) 197; CHECK-NEXT: br %r14 198 %amt = load i32, i32 *%ptr 199 %amtb = sub i32 32, %amt 200 %parta = shl i32 %a, %amt 201 %partb = lshr i32 %a, %amtb 202 %or = or i32 %parta, %partb 203 ret i32 %or 204} 205 206; Check another form of f5, which is the one produced by running f5 through 207; instcombine. 208define i32 @f15(i32 %a, i32 %amt) { 209; CHECK-LABEL: f15: 210; CHECK: # %bb.0: 211; CHECK-NEXT: rll %r2, %r2, 10(%r3) 212; CHECK-NEXT: br %r14 213 %add = add i32 %amt, 10 214 %sub = sub i32 22, %amt 215 %parta = shl i32 %a, %add 216 %partb = lshr i32 %a, %sub 217 %or = or i32 %parta, %partb 218 ret i32 %or 219} 220 221; Likewise for f7. 222define i32 @f16(i32 %a, i64 %amt) { 223; CHECK-LABEL: f16: 224; CHECK: # %bb.0: 225; CHECK-NEXT: rll %r2, %r2, 10(%r3) 226; CHECK-NEXT: br %r14 227 %add = add i64 %amt, 10 228 %sub = sub i64 22, %amt 229 %addtrunc = trunc i64 %add to i32 230 %subtrunc = trunc i64 %sub to i32 231 %parta = shl i32 %a, %addtrunc 232 %partb = lshr i32 %a, %subtrunc 233 %or = or i32 %parta, %partb 234 ret i32 %or 235} 236 237; Check cases where (-x & 31) is used instead of 32 - x. 238define i32 @f17(i32 %x, i32 %y) { 239; CHECK-LABEL: f17: 240; CHECK: # %bb.0: # %entry 241; CHECK-NEXT: rll %r2, %r2, 0(%r3) 242; CHECK-NEXT: br %r14 243entry: 244 %shl = shl i32 %x, %y 245 %sub = sub i32 0, %y 246 %and = and i32 %sub, 31 247 %shr = lshr i32 %x, %and 248 %or = or i32 %shr, %shl 249 ret i32 %or 250} 251 252; ...and again with ((32 - x) & 31). 253define i32 @f18(i32 %x, i32 %y) { 254; CHECK-LABEL: f18: 255; CHECK: # %bb.0: # %entry 256; CHECK-NEXT: rll %r2, %r2, 0(%r3) 257; CHECK-NEXT: br %r14 258entry: 259 %shl = shl i32 %x, %y 260 %sub = sub i32 32, %y 261 %and = and i32 %sub, 31 262 %shr = lshr i32 %x, %and 263 %or = or i32 %shr, %shl 264 ret i32 %or 265} 266 267; This is not a rotation. 268define i32 @f19(i32 %x, i32 %y) { 269; CHECK-LABEL: f19: 270; CHECK: # %bb.0: # %entry 271; CHECK-NEXT: lr %r0, %r2 272; CHECK-NEXT: sll %r0, 0(%r3) 273; CHECK-NEXT: lhi %r1, 16 274; CHECK-NEXT: sr %r1, %r3 275; CHECK-NEXT: nill %r1, 31 276; CHECK-NEXT: srl %r2, 0(%r1) 277; CHECK-NEXT: or %r2, %r0 278; CHECK-NEXT: br %r14 279entry: 280 %shl = shl i32 %x, %y 281 %sub = sub i32 16, %y 282 %and = and i32 %sub, 31 283 %shr = lshr i32 %x, %and 284 %or = or i32 %shr, %shl 285 ret i32 %or 286} 287 288; Repeat f17 with an addition on the shift count. 289define i32 @f20(i32 %x, i32 %y) { 290; CHECK-LABEL: f20: 291; CHECK: # %bb.0: # %entry 292; CHECK-NEXT: rll %r2, %r2, 199(%r3) 293; CHECK-NEXT: br %r14 294entry: 295 %add = add i32 %y, 199 296 %shl = shl i32 %x, %add 297 %sub = sub i32 0, %add 298 %and = and i32 %sub, 31 299 %shr = lshr i32 %x, %and 300 %or = or i32 %shr, %shl 301 ret i32 %or 302} 303 304; ...and again with the InstCombine version. 305define i32 @f21(i32 %x, i32 %y) { 306; CHECK-LABEL: f21: 307; CHECK: # %bb.0: # %entry 308; CHECK-NEXT: rll %r2, %r2, 199(%r3) 309; CHECK-NEXT: br %r14 310entry: 311 %add = add i32 %y, 199 312 %shl = shl i32 %x, %add 313 %sub = sub i32 -199, %y 314 %and = and i32 %sub, 31 315 %shr = lshr i32 %x, %and 316 %or = or i32 %shr, %shl 317 ret i32 %or 318} 319