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, and then 101; mask the amount. 102define i32 @f8(i32 %a, i32 %amt) { 103; CHECK-LABEL: f8: 104; CHECK: # %bb.0: 105; CHECK-NEXT: rll %r2, %r2, -1(%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, masking the amount removes the addition. 161define i32 @f12(i32 %a, i32 %amt) { 162; CHECK-LABEL: f12: 163; CHECK: # %bb.0: 164; CHECK-NEXT: rll %r2, %r2, -1(%r3) 165; CHECK-NEXT: br %r14 166 %suba = sub i32 %amt, 524289 167 %subb = sub i32 32, %suba 168 %parta = shl i32 %a, %suba 169 %partb = lshr i32 %a, %subb 170 %or = or i32 %parta, %partb 171 ret i32 %or 172} 173 174; Check that we don't try to generate "indexed" shifts. 175define i32 @f13(i32 %a, i32 %b, i32 %c) { 176; CHECK-LABEL: f13: 177; CHECK: # %bb.0: 178; CHECK-NEXT: ar %r3, %r4 179; CHECK-NEXT: rll %r2, %r2, 0(%r3) 180; CHECK-NEXT: br %r14 181 %add = add i32 %b, %c 182 %sub = sub i32 32, %add 183 %parta = shl i32 %a, %add 184 %partb = lshr i32 %a, %sub 185 %or = or i32 %parta, %partb 186 ret i32 %or 187} 188 189; Check that the shift amount uses an address register. It cannot be in %r0. 190define i32 @f14(i32 %a, i32 *%ptr) { 191; CHECK-LABEL: f14: 192; CHECK: # %bb.0: 193; CHECK-NEXT: l %r1, 0(%r3) 194; CHECK-NEXT: rll %r2, %r2, 0(%r1) 195; CHECK-NEXT: br %r14 196 %amt = load i32, i32 *%ptr 197 %amtb = sub i32 32, %amt 198 %parta = shl i32 %a, %amt 199 %partb = lshr i32 %a, %amtb 200 %or = or i32 %parta, %partb 201 ret i32 %or 202} 203 204; Check another form of f5, which is the one produced by running f5 through 205; instcombine. 206define i32 @f15(i32 %a, i32 %amt) { 207; CHECK-LABEL: f15: 208; CHECK: # %bb.0: 209; CHECK-NEXT: rll %r2, %r2, 10(%r3) 210; CHECK-NEXT: br %r14 211 %add = add i32 %amt, 10 212 %sub = sub i32 22, %amt 213 %parta = shl i32 %a, %add 214 %partb = lshr i32 %a, %sub 215 %or = or i32 %parta, %partb 216 ret i32 %or 217} 218 219; Likewise for f7. 220define i32 @f16(i32 %a, i64 %amt) { 221; CHECK-LABEL: f16: 222; CHECK: # %bb.0: 223; CHECK-NEXT: rll %r2, %r2, 10(%r3) 224; CHECK-NEXT: br %r14 225 %add = add i64 %amt, 10 226 %sub = sub i64 22, %amt 227 %addtrunc = trunc i64 %add to i32 228 %subtrunc = trunc i64 %sub to i32 229 %parta = shl i32 %a, %addtrunc 230 %partb = lshr i32 %a, %subtrunc 231 %or = or i32 %parta, %partb 232 ret i32 %or 233} 234 235; Check cases where (-x & 31) is used instead of 32 - x. 236define i32 @f17(i32 %x, i32 %y) { 237; CHECK-LABEL: f17: 238; CHECK: # %bb.0: # %entry 239; CHECK-NEXT: rll %r2, %r2, 0(%r3) 240; CHECK-NEXT: br %r14 241entry: 242 %shl = shl i32 %x, %y 243 %sub = sub i32 0, %y 244 %and = and i32 %sub, 31 245 %shr = lshr i32 %x, %and 246 %or = or i32 %shr, %shl 247 ret i32 %or 248} 249 250; ...and again with ((32 - x) & 31). 251define i32 @f18(i32 %x, i32 %y) { 252; CHECK-LABEL: f18: 253; CHECK: # %bb.0: # %entry 254; CHECK-NEXT: rll %r2, %r2, 0(%r3) 255; CHECK-NEXT: br %r14 256entry: 257 %shl = shl i32 %x, %y 258 %sub = sub i32 32, %y 259 %and = and i32 %sub, 31 260 %shr = lshr i32 %x, %and 261 %or = or i32 %shr, %shl 262 ret i32 %or 263} 264 265; This is not a rotation. 266define i32 @f19(i32 %x, i32 %y) { 267; CHECK-LABEL: f19: 268; CHECK: # %bb.0: # %entry 269; CHECK-NEXT: lr %r0, %r2 270; CHECK-NEXT: sll %r0, 0(%r3) 271; CHECK-NEXT: lhi %r1, 16 272; CHECK-NEXT: sr %r1, %r3 273; CHECK-NEXT: nill %r1, 31 274; CHECK-NEXT: srl %r2, 0(%r1) 275; CHECK-NEXT: or %r2, %r0 276; CHECK-NEXT: br %r14 277entry: 278 %shl = shl i32 %x, %y 279 %sub = sub i32 16, %y 280 %and = and i32 %sub, 31 281 %shr = lshr i32 %x, %and 282 %or = or i32 %shr, %shl 283 ret i32 %or 284} 285 286; Repeat f17 with an addition on the shift count. 287define i32 @f20(i32 %x, i32 %y) { 288; CHECK-LABEL: f20: 289; CHECK: # %bb.0: # %entry 290; CHECK-NEXT: rll %r2, %r2, 199(%r3) 291; CHECK-NEXT: br %r14 292entry: 293 %add = add i32 %y, 199 294 %shl = shl i32 %x, %add 295 %sub = sub i32 0, %add 296 %and = and i32 %sub, 31 297 %shr = lshr i32 %x, %and 298 %or = or i32 %shr, %shl 299 ret i32 %or 300} 301 302; ...and again with the InstCombine version. 303define i32 @f21(i32 %x, i32 %y) { 304; CHECK-LABEL: f21: 305; CHECK: # %bb.0: # %entry 306; CHECK-NEXT: rll %r2, %r2, 199(%r3) 307; CHECK-NEXT: br %r14 308entry: 309 %add = add i32 %y, 199 310 %shl = shl i32 %x, %add 311 %sub = sub i32 -199, %y 312 %and = and i32 %sub, 31 313 %shr = lshr i32 %x, %and 314 %or = or i32 %shr, %shl 315 ret i32 %or 316} 317