1*9880d681SAndroid Build Coastguard Worker; Test sequences that can use RNSBG. 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; Test a simple mask, which is a wrap-around case. 6*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i32 %a, i32 %b) { 7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 8*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 59, 56, 0 9*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 10*9880d681SAndroid Build Coastguard Worker %orb = or i32 %b, 96 11*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 12*9880d681SAndroid Build Coastguard Worker ret i32 %and 13*9880d681SAndroid Build Coastguard Worker} 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 16*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %a, i64 %b) { 17*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 18*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 59, 56, 0 19*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 20*9880d681SAndroid Build Coastguard Worker %orb = or i64 %b, 96 21*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 22*9880d681SAndroid Build Coastguard Worker ret i64 %and 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker; Test a case where no wraparound is needed. 26*9880d681SAndroid Build Coastguard Workerdefine i32 @f3(i32 %a, i32 %b) { 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 28*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 58, 61, 0 29*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 30*9880d681SAndroid Build Coastguard Worker %orb = or i32 %b, -61 31*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 32*9880d681SAndroid Build Coastguard Worker ret i32 %and 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 36*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %a, i64 %b) { 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 38*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 58, 61, 0 39*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 40*9880d681SAndroid Build Coastguard Worker %orb = or i64 %b, -61 41*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 42*9880d681SAndroid Build Coastguard Worker ret i64 %and 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; Test a case with just a left shift. This can't use RNSBG. 46*9880d681SAndroid Build Coastguard Workerdefine i32 @f6(i32 %a, i32 %b) { 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 48*9880d681SAndroid Build Coastguard Worker; CHECK: sll {{%r[0-5]}} 49*9880d681SAndroid Build Coastguard Worker; CHECK: nr {{%r[0-5]}} 50*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 51*9880d681SAndroid Build Coastguard Worker %shrb = shl i32 %b, 20 52*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %shrb 53*9880d681SAndroid Build Coastguard Worker ret i32 %and 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 57*9880d681SAndroid Build Coastguard Workerdefine i64 @f7(i64 %a, i64 %b) { 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 59*9880d681SAndroid Build Coastguard Worker; CHECK: sllg {{%r[0-5]}} 60*9880d681SAndroid Build Coastguard Worker; CHECK: ngr {{%r[0-5]}} 61*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 62*9880d681SAndroid Build Coastguard Worker %shrb = shl i64 %b, 20 63*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %shrb 64*9880d681SAndroid Build Coastguard Worker ret i64 %and 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; Test a case with just a rotate. This can't use RNSBG. 68*9880d681SAndroid Build Coastguard Workerdefine i32 @f8(i32 %a, i32 %b) { 69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 70*9880d681SAndroid Build Coastguard Worker; CHECK: rll {{%r[0-5]}} 71*9880d681SAndroid Build Coastguard Worker; CHECK: nr {{%r[0-5]}} 72*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 73*9880d681SAndroid Build Coastguard Worker %shlb = shl i32 %b, 22 74*9880d681SAndroid Build Coastguard Worker %shrb = lshr i32 %b, 10 75*9880d681SAndroid Build Coastguard Worker %rotlb = or i32 %shlb, %shrb 76*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %rotlb 77*9880d681SAndroid Build Coastguard Worker ret i32 %and 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker; ...and again with i64, which can. 81*9880d681SAndroid Build Coastguard Workerdefine i64 @f9(i64 %a, i64 %b) { 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 83*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 0, 63, 44 84*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 85*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %b, 44 86*9880d681SAndroid Build Coastguard Worker %shrb = lshr i64 %b, 20 87*9880d681SAndroid Build Coastguard Worker %rotlb = or i64 %shlb, %shrb 88*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %rotlb 89*9880d681SAndroid Build Coastguard Worker ret i64 %and 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; Test a case with a left shift and OR, where the OR covers all shifted bits. 93*9880d681SAndroid Build Coastguard Worker; We can do the whole thing using RNSBG. 94*9880d681SAndroid Build Coastguard Workerdefine i32 @f10(i32 %a, i32 %b) { 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 96*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 56, 7 97*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 98*9880d681SAndroid Build Coastguard Worker %shlb = shl i32 %b, 7 99*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shlb, 127 100*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 101*9880d681SAndroid Build Coastguard Worker ret i32 %and 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 105*9880d681SAndroid Build Coastguard Workerdefine i64 @f11(i64 %a, i64 %b) { 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 107*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 0, 56, 7 108*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 109*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %b, 7 110*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shlb, 127 111*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 112*9880d681SAndroid Build Coastguard Worker ret i64 %and 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker; Test a case with a left shift and OR, where the OR doesn't cover all 116*9880d681SAndroid Build Coastguard Worker; shifted bits. We can't use RNSBG for the shift, but we can for the OR 117*9880d681SAndroid Build Coastguard Worker; and AND. 118*9880d681SAndroid Build Coastguard Workerdefine i32 @f12(i32 %a, i32 %b) { 119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 120*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r3, 7 121*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 57, 0 122*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 123*9880d681SAndroid Build Coastguard Worker %shlb = shl i32 %b, 7 124*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shlb, 63 125*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 126*9880d681SAndroid Build Coastguard Worker ret i32 %and 127*9880d681SAndroid Build Coastguard Worker} 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 130*9880d681SAndroid Build Coastguard Workerdefine i64 @f13(i64 %a, i64 %b) { 131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 132*9880d681SAndroid Build Coastguard Worker; CHECK: sllg [[REG:%r[01345]]], %r3, 7 133*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 0, 57, 0 134*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 135*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %b, 7 136*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shlb, 63 137*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 138*9880d681SAndroid Build Coastguard Worker ret i64 %and 139*9880d681SAndroid Build Coastguard Worker} 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker; Test a case with a right shift and OR, where the OR covers all the shifted 142*9880d681SAndroid Build Coastguard Worker; bits. The whole thing can be done using RNSBG. 143*9880d681SAndroid Build Coastguard Workerdefine i32 @f14(i32 %a, i32 %b) { 144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14: 145*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 37 146*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 147*9880d681SAndroid Build Coastguard Worker %shrb = lshr i32 %b, 27 148*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shrb, -16 149*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 150*9880d681SAndroid Build Coastguard Worker ret i32 %and 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 154*9880d681SAndroid Build Coastguard Workerdefine i64 @f15(i64 %a, i64 %b) { 155*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15: 156*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 5 157*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 158*9880d681SAndroid Build Coastguard Worker %shrb = lshr i64 %b, 59 159*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shrb, -16 160*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 161*9880d681SAndroid Build Coastguard Worker ret i64 %and 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Worker; Test a case with a right shift and OR, where the OR doesn't cover all the 165*9880d681SAndroid Build Coastguard Worker; shifted bits. The shift needs to be done separately, but the OR and AND 166*9880d681SAndroid Build Coastguard Worker; can use RNSBG. 167*9880d681SAndroid Build Coastguard Workerdefine i32 @f16(i32 %a, i32 %b) { 168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16: 169*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r3, 29 170*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 0 171*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 172*9880d681SAndroid Build Coastguard Worker %shrb = lshr i32 %b, 29 173*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shrb, -16 174*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 175*9880d681SAndroid Build Coastguard Worker ret i32 %and 176*9880d681SAndroid Build Coastguard Worker} 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 179*9880d681SAndroid Build Coastguard Workerdefine i64 @f17(i64 %a, i64 %b) { 180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17: 181*9880d681SAndroid Build Coastguard Worker; CHECK: srlg [[REG:%r[01345]]], %r3, 61 182*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 60, 63, 0 183*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 184*9880d681SAndroid Build Coastguard Worker %shrb = lshr i64 %b, 61 185*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shrb, -16 186*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 187*9880d681SAndroid Build Coastguard Worker ret i64 %and 188*9880d681SAndroid Build Coastguard Worker} 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Worker; Test a combination involving an ASHR in which the sign bits matter. 191*9880d681SAndroid Build Coastguard Worker; We can't use RNSBG for the ASHR in that case, but we can for the rest. 192*9880d681SAndroid Build Coastguard Workerdefine i32 @f18(i32 %a, i32 %b, i32 *%dest) { 193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18: 194*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r3, 4 195*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 62, 1 196*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 197*9880d681SAndroid Build Coastguard Worker %ashrb = ashr i32 %b, 4 198*9880d681SAndroid Build Coastguard Worker store i32 %ashrb, i32 *%dest 199*9880d681SAndroid Build Coastguard Worker %shlb = shl i32 %ashrb, 1 200*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shlb, 1 201*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 202*9880d681SAndroid Build Coastguard Worker ret i32 %and 203*9880d681SAndroid Build Coastguard Worker} 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 206*9880d681SAndroid Build Coastguard Workerdefine i64 @f19(i64 %a, i64 %b, i64 *%dest) { 207*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19: 208*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[0145]]], %r3, 34 209*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 0, 62, 1 210*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 211*9880d681SAndroid Build Coastguard Worker %ashrb = ashr i64 %b, 34 212*9880d681SAndroid Build Coastguard Worker store i64 %ashrb, i64 *%dest 213*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %ashrb, 1 214*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shlb, 1 215*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 216*9880d681SAndroid Build Coastguard Worker ret i64 %and 217*9880d681SAndroid Build Coastguard Worker} 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker; Test a combination involving an ASHR in which the sign bits don't matter. 220*9880d681SAndroid Build Coastguard Workerdefine i32 @f20(i32 %a, i32 %b, i32 *%dest) { 221*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20: 222*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 48, 62, 48 223*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 224*9880d681SAndroid Build Coastguard Worker %ashrb = ashr i32 %b, 17 225*9880d681SAndroid Build Coastguard Worker store i32 %ashrb, i32 *%dest 226*9880d681SAndroid Build Coastguard Worker %shlb = shl i32 %ashrb, 1 227*9880d681SAndroid Build Coastguard Worker %orb = or i32 %shlb, -65535 228*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, %orb 229*9880d681SAndroid Build Coastguard Worker ret i32 %and 230*9880d681SAndroid Build Coastguard Worker} 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 233*9880d681SAndroid Build Coastguard Workerdefine i64 @f21(i64 %a, i64 %b, i64 *%dest) { 234*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21: 235*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 48, 62, 16 236*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 237*9880d681SAndroid Build Coastguard Worker %ashrb = ashr i64 %b, 49 238*9880d681SAndroid Build Coastguard Worker store i64 %ashrb, i64 *%dest 239*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %ashrb, 1 240*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shlb, -65535 241*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %orb 242*9880d681SAndroid Build Coastguard Worker ret i64 %and 243*9880d681SAndroid Build Coastguard Worker} 244*9880d681SAndroid Build Coastguard Worker 245*9880d681SAndroid Build Coastguard Worker; Test a case with a shift, OR, and rotate where the OR covers all shifted bits. 246*9880d681SAndroid Build Coastguard Workerdefine i64 @f22(i64 %a, i64 %b) { 247*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22: 248*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 54, 9 249*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 250*9880d681SAndroid Build Coastguard Worker %shlb = shl i64 %b, 5 251*9880d681SAndroid Build Coastguard Worker %orb = or i64 %shlb, 31 252*9880d681SAndroid Build Coastguard Worker %shlorb = shl i64 %orb, 4 253*9880d681SAndroid Build Coastguard Worker %shrorb = lshr i64 %orb, 60 254*9880d681SAndroid Build Coastguard Worker %rotlorb = or i64 %shlorb, %shrorb 255*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %rotlorb 256*9880d681SAndroid Build Coastguard Worker ret i64 %and 257*9880d681SAndroid Build Coastguard Worker} 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Worker; Check the handling of zext and AND, which isn't suitable for RNSBG. 260*9880d681SAndroid Build Coastguard Workerdefine i64 @f23(i64 %a, i32 %b) { 261*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f23: 262*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: rnsbg 263*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 264*9880d681SAndroid Build Coastguard Worker %add = add i32 %b, 1 265*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %add to i64 266*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, %ext 267*9880d681SAndroid Build Coastguard Worker ret i64 %and 268*9880d681SAndroid Build Coastguard Worker} 269