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