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