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