1*9880d681SAndroid Build Coastguard Worker; Test sequences that can use RISBG with a zeroed first operand. 2*9880d681SAndroid Build Coastguard Worker; The tests here assume that RISBLG isn't available. 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; Test an extraction of bit 0 from a right-shifted value. 7*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i32 %foo) { 8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 9*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 63, 191, 54 10*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 11*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %foo, 10 12*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, 1 13*9880d681SAndroid Build Coastguard Worker ret i32 %and 14*9880d681SAndroid Build Coastguard Worker} 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 17*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %foo) { 18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 19*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 63, 191, 54 20*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 21*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %foo, 10 22*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 1 23*9880d681SAndroid Build Coastguard Worker ret i64 %and 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker; Test an extraction of other bits from a right-shifted value. 27*9880d681SAndroid Build Coastguard Workerdefine i32 @f3(i32 %foo) { 28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 29*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 189, 42 30*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 31*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %foo, 22 32*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, 12 33*9880d681SAndroid Build Coastguard Worker ret i32 %and 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 37*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %foo) { 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 39*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 189, 42 40*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 41*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %foo, 22 42*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 12 43*9880d681SAndroid Build Coastguard Worker ret i64 %and 44*9880d681SAndroid Build Coastguard Worker} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; Test an extraction of most bits from a right-shifted value. 47*9880d681SAndroid Build Coastguard Worker; The range should be reduced to exclude the zeroed high bits. 48*9880d681SAndroid Build Coastguard Workerdefine i32 @f5(i32 %foo) { 49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 50*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 34, 188, 62 51*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 52*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %foo, 2 53*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, -8 54*9880d681SAndroid Build Coastguard Worker ret i32 %and 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 58*9880d681SAndroid Build Coastguard Workerdefine i64 @f6(i64 %foo) { 59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 60*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 2, 188, 62 61*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 62*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %foo, 2 63*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, -8 64*9880d681SAndroid Build Coastguard Worker ret i64 %and 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; Try the next value up (mask ....1111001). This needs a separate shift 68*9880d681SAndroid Build Coastguard Worker; and mask. 69*9880d681SAndroid Build Coastguard Workerdefine i32 @f7(i32 %foo) { 70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 71*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r2, 2 72*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65529 73*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 74*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %foo, 2 75*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, -7 76*9880d681SAndroid Build Coastguard Worker ret i32 %and 77*9880d681SAndroid Build Coastguard Worker} 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 80*9880d681SAndroid Build Coastguard Workerdefine i64 @f8(i64 %foo) { 81*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 82*9880d681SAndroid Build Coastguard Worker; CHECK: srlg %r2, %r2, 2 83*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65529 84*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 85*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %foo, 2 86*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, -7 87*9880d681SAndroid Build Coastguard Worker ret i64 %and 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; Test an extraction of bits from a left-shifted value. The range should 91*9880d681SAndroid Build Coastguard Worker; be reduced to exclude the zeroed low bits. 92*9880d681SAndroid Build Coastguard Workerdefine i32 @f9(i32 %foo) { 93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 94*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 189, 2 95*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 96*9880d681SAndroid Build Coastguard Worker %shr = shl i32 %foo, 2 97*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, 255 98*9880d681SAndroid Build Coastguard Worker ret i32 %and 99*9880d681SAndroid Build Coastguard Worker} 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 102*9880d681SAndroid Build Coastguard Workerdefine i64 @f10(i64 %foo) { 103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 104*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 189, 2 105*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 106*9880d681SAndroid Build Coastguard Worker %shr = shl i64 %foo, 2 107*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 255 108*9880d681SAndroid Build Coastguard Worker ret i64 %and 109*9880d681SAndroid Build Coastguard Worker} 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker; Try a wrap-around mask (mask ....111100001111). This needs a separate shift 112*9880d681SAndroid Build Coastguard Worker; and mask. 113*9880d681SAndroid Build Coastguard Workerdefine i32 @f11(i32 %foo) { 114*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 115*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 2 116*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65295 117*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 118*9880d681SAndroid Build Coastguard Worker %shr = shl i32 %foo, 2 119*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, -241 120*9880d681SAndroid Build Coastguard Worker ret i32 %and 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 124*9880d681SAndroid Build Coastguard Workerdefine i64 @f12(i64 %foo) { 125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 126*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2, %r2, 2 127*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65295 128*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 129*9880d681SAndroid Build Coastguard Worker %shr = shl i64 %foo, 2 130*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, -241 131*9880d681SAndroid Build Coastguard Worker ret i64 %and 132*9880d681SAndroid Build Coastguard Worker} 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker; Test an extraction from a rotated value, no mask wraparound. 135*9880d681SAndroid Build Coastguard Worker; This is equivalent to the lshr case, because the bits from the 136*9880d681SAndroid Build Coastguard Worker; shl are not used. 137*9880d681SAndroid Build Coastguard Workerdefine i32 @f13(i32 %foo) { 138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 139*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 188, 46 140*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 141*9880d681SAndroid Build Coastguard Worker %parta = shl i32 %foo, 14 142*9880d681SAndroid Build Coastguard Worker %partb = lshr i32 %foo, 18 143*9880d681SAndroid Build Coastguard Worker %rotl = or i32 %parta, %partb 144*9880d681SAndroid Build Coastguard Worker %and = and i32 %rotl, 248 145*9880d681SAndroid Build Coastguard Worker ret i32 %and 146*9880d681SAndroid Build Coastguard Worker} 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 149*9880d681SAndroid Build Coastguard Workerdefine i64 @f14(i64 %foo) { 150*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14: 151*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 188, 14 152*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 153*9880d681SAndroid Build Coastguard Worker %parta = shl i64 %foo, 14 154*9880d681SAndroid Build Coastguard Worker %partb = lshr i64 %foo, 50 155*9880d681SAndroid Build Coastguard Worker %rotl = or i64 %parta, %partb 156*9880d681SAndroid Build Coastguard Worker %and = and i64 %rotl, 248 157*9880d681SAndroid Build Coastguard Worker ret i64 %and 158*9880d681SAndroid Build Coastguard Worker} 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; Try a case in which only the bits from the shl are used. 161*9880d681SAndroid Build Coastguard Workerdefine i32 @f15(i32 %foo) { 162*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15: 163*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 47, 177, 14 164*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 165*9880d681SAndroid Build Coastguard Worker %parta = shl i32 %foo, 14 166*9880d681SAndroid Build Coastguard Worker %partb = lshr i32 %foo, 18 167*9880d681SAndroid Build Coastguard Worker %rotl = or i32 %parta, %partb 168*9880d681SAndroid Build Coastguard Worker %and = and i32 %rotl, 114688 169*9880d681SAndroid Build Coastguard Worker ret i32 %and 170*9880d681SAndroid Build Coastguard Worker} 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 173*9880d681SAndroid Build Coastguard Workerdefine i64 @f16(i64 %foo) { 174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16: 175*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 47, 177, 14 176*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 177*9880d681SAndroid Build Coastguard Worker %parta = shl i64 %foo, 14 178*9880d681SAndroid Build Coastguard Worker %partb = lshr i64 %foo, 50 179*9880d681SAndroid Build Coastguard Worker %rotl = or i64 %parta, %partb 180*9880d681SAndroid Build Coastguard Worker %and = and i64 %rotl, 114688 181*9880d681SAndroid Build Coastguard Worker ret i64 %and 182*9880d681SAndroid Build Coastguard Worker} 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker; Test a 32-bit rotate in which both parts of the OR are needed. 185*9880d681SAndroid Build Coastguard Worker; This needs a separate shift and mask. 186*9880d681SAndroid Build Coastguard Workerdefine i32 @f17(i32 %foo) { 187*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17: 188*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 4 189*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 126 190*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 191*9880d681SAndroid Build Coastguard Worker %parta = shl i32 %foo, 4 192*9880d681SAndroid Build Coastguard Worker %partb = lshr i32 %foo, 28 193*9880d681SAndroid Build Coastguard Worker %rotl = or i32 %parta, %partb 194*9880d681SAndroid Build Coastguard Worker %and = and i32 %rotl, 126 195*9880d681SAndroid Build Coastguard Worker ret i32 %and 196*9880d681SAndroid Build Coastguard Worker} 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Worker; ...and for i64, where RISBG should do the rotate too. 199*9880d681SAndroid Build Coastguard Workerdefine i64 @f18(i64 %foo) { 200*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18: 201*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 190, 4 202*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 203*9880d681SAndroid Build Coastguard Worker %parta = shl i64 %foo, 4 204*9880d681SAndroid Build Coastguard Worker %partb = lshr i64 %foo, 60 205*9880d681SAndroid Build Coastguard Worker %rotl = or i64 %parta, %partb 206*9880d681SAndroid Build Coastguard Worker %and = and i64 %rotl, 126 207*9880d681SAndroid Build Coastguard Worker ret i64 %and 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker; Test an arithmetic shift right in which some of the sign bits are kept. 211*9880d681SAndroid Build Coastguard Worker; This needs a separate shift and mask. 212*9880d681SAndroid Build Coastguard Workerdefine i32 @f19(i32 %foo) { 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19: 214*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r2, 28 215*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 30 216*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 217*9880d681SAndroid Build Coastguard Worker %shr = ashr i32 %foo, 28 218*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, 30 219*9880d681SAndroid Build Coastguard Worker ret i32 %and 220*9880d681SAndroid Build Coastguard Worker} 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker; ...and again with i64. In this case RISBG is the best way of doing the AND. 223*9880d681SAndroid Build Coastguard Workerdefine i64 @f20(i64 %foo) { 224*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20: 225*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[0-5]]], %r2, 60 226*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, [[REG]], 59, 190, 0 227*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 228*9880d681SAndroid Build Coastguard Worker %shr = ashr i64 %foo, 60 229*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 30 230*9880d681SAndroid Build Coastguard Worker ret i64 %and 231*9880d681SAndroid Build Coastguard Worker} 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker; Now try an arithmetic right shift in which the sign bits aren't needed. 234*9880d681SAndroid Build Coastguard Worker; Introduce a second use of %shr so that the ashr doesn't decompose to 235*9880d681SAndroid Build Coastguard Worker; an lshr. 236*9880d681SAndroid Build Coastguard Workerdefine i32 @f21(i32 %foo, i32 *%dest) { 237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21: 238*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 190, 36 239*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 240*9880d681SAndroid Build Coastguard Worker %shr = ashr i32 %foo, 28 241*9880d681SAndroid Build Coastguard Worker store i32 %shr, i32 *%dest 242*9880d681SAndroid Build Coastguard Worker %and = and i32 %shr, 14 243*9880d681SAndroid Build Coastguard Worker ret i32 %and 244*9880d681SAndroid Build Coastguard Worker} 245*9880d681SAndroid Build Coastguard Worker 246*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 247*9880d681SAndroid Build Coastguard Workerdefine i64 @f22(i64 %foo, i64 *%dest) { 248*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22: 249*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 190, 4 250*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 251*9880d681SAndroid Build Coastguard Worker %shr = ashr i64 %foo, 60 252*9880d681SAndroid Build Coastguard Worker store i64 %shr, i64 *%dest 253*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 14 254*9880d681SAndroid Build Coastguard Worker ret i64 %and 255*9880d681SAndroid Build Coastguard Worker} 256*9880d681SAndroid Build Coastguard Worker 257*9880d681SAndroid Build Coastguard Worker; Check that we use RISBG for shifted values even if the AND is a 258*9880d681SAndroid Build Coastguard Worker; natural zero extension. 259*9880d681SAndroid Build Coastguard Workerdefine i64 @f23(i64 %foo) { 260*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f23: 261*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 191, 62 262*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 263*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %foo, 2 264*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 255 265*9880d681SAndroid Build Coastguard Worker ret i64 %and 266*9880d681SAndroid Build Coastguard Worker} 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a rotate. This needs a separate 269*9880d681SAndroid Build Coastguard Worker; mask and rotate. 270*9880d681SAndroid Build Coastguard Workerdefine i32 @f24(i32 %foo) { 271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f24: 272*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 254 273*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 29 274*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 275*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, 254 276*9880d681SAndroid Build Coastguard Worker %parta = lshr i32 %and, 3 277*9880d681SAndroid Build Coastguard Worker %partb = shl i32 %and, 29 278*9880d681SAndroid Build Coastguard Worker %rotl = or i32 %parta, %partb 279*9880d681SAndroid Build Coastguard Worker ret i32 %rotl 280*9880d681SAndroid Build Coastguard Worker} 281*9880d681SAndroid Build Coastguard Worker 282*9880d681SAndroid Build Coastguard Worker; ...and again with i64, where a single RISBG is enough. 283*9880d681SAndroid Build Coastguard Workerdefine i64 @f25(i64 %foo) { 284*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f25: 285*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 187, 3 286*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 287*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, 14 288*9880d681SAndroid Build Coastguard Worker %parta = shl i64 %and, 3 289*9880d681SAndroid Build Coastguard Worker %partb = lshr i64 %and, 61 290*9880d681SAndroid Build Coastguard Worker %rotl = or i64 %parta, %partb 291*9880d681SAndroid Build Coastguard Worker ret i64 %rotl 292*9880d681SAndroid Build Coastguard Worker} 293*9880d681SAndroid Build Coastguard Worker 294*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case in which the AND comes before a rotate. 295*9880d681SAndroid Build Coastguard Worker; This again needs a separate mask and rotate. 296*9880d681SAndroid Build Coastguard Workerdefine i32 @f26(i32 %foo) { 297*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f26: 298*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 5 299*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 300*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, -49 301*9880d681SAndroid Build Coastguard Worker %parta = shl i32 %and, 5 302*9880d681SAndroid Build Coastguard Worker %partb = lshr i32 %and, 27 303*9880d681SAndroid Build Coastguard Worker %rotl = or i32 %parta, %partb 304*9880d681SAndroid Build Coastguard Worker ret i32 %rotl 305*9880d681SAndroid Build Coastguard Worker} 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Worker; ...and again with i64, where a single RISBG is OK. 308*9880d681SAndroid Build Coastguard Workerdefine i64 @f27(i64 %foo) { 309*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f27: 310*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 55, 180, 5 311*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 312*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, -49 313*9880d681SAndroid Build Coastguard Worker %parta = shl i64 %and, 5 314*9880d681SAndroid Build Coastguard Worker %partb = lshr i64 %and, 59 315*9880d681SAndroid Build Coastguard Worker %rotl = or i64 %parta, %partb 316*9880d681SAndroid Build Coastguard Worker ret i64 %rotl 317*9880d681SAndroid Build Coastguard Worker} 318*9880d681SAndroid Build Coastguard Worker 319*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a shift left. 320*9880d681SAndroid Build Coastguard Workerdefine i32 @f28(i32 %foo) { 321*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f28: 322*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 32, 173, 17 323*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 324*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, 32766 325*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %and, 17 326*9880d681SAndroid Build Coastguard Worker ret i32 %shl 327*9880d681SAndroid Build Coastguard Worker} 328*9880d681SAndroid Build Coastguard Worker 329*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 330*9880d681SAndroid Build Coastguard Workerdefine i64 @f29(i64 %foo) { 331*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f29: 332*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 0, 141, 49 333*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 334*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, 32766 335*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %and, 49 336*9880d681SAndroid Build Coastguard Worker ret i64 %shl 337*9880d681SAndroid Build Coastguard Worker} 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Worker; Test the next shift up from f28, in which the mask should get shortened. 340*9880d681SAndroid Build Coastguard Workerdefine i32 @f30(i32 %foo) { 341*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f30: 342*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 32, 172, 18 343*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 344*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, 32766 345*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %and, 18 346*9880d681SAndroid Build Coastguard Worker ret i32 %shl 347*9880d681SAndroid Build Coastguard Worker} 348*9880d681SAndroid Build Coastguard Worker 349*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 350*9880d681SAndroid Build Coastguard Workerdefine i64 @f31(i64 %foo) { 351*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f31: 352*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 0, 140, 50 353*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 354*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, 32766 355*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %and, 50 356*9880d681SAndroid Build Coastguard Worker ret i64 %shl 357*9880d681SAndroid Build Coastguard Worker} 358*9880d681SAndroid Build Coastguard Worker 359*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case in which the shift left comes after the AND. 360*9880d681SAndroid Build Coastguard Worker; We can't use RISBG for the shift in that case. 361*9880d681SAndroid Build Coastguard Workerdefine i32 @f32(i32 %foo) { 362*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f32: 363*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2 364*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 365*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, -7 366*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %and, 10 367*9880d681SAndroid Build Coastguard Worker ret i32 %shl 368*9880d681SAndroid Build Coastguard Worker} 369*9880d681SAndroid Build Coastguard Worker 370*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 371*9880d681SAndroid Build Coastguard Workerdefine i64 @f33(i64 %foo) { 372*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f33: 373*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2 374*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 375*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, -7 376*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %and, 10 377*9880d681SAndroid Build Coastguard Worker ret i64 %shl 378*9880d681SAndroid Build Coastguard Worker} 379*9880d681SAndroid Build Coastguard Worker 380*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a shift right. 381*9880d681SAndroid Build Coastguard Workerdefine i32 @f34(i32 %foo) { 382*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f34: 383*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 191, 55 384*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 385*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, 65535 386*9880d681SAndroid Build Coastguard Worker %shl = lshr i32 %and, 9 387*9880d681SAndroid Build Coastguard Worker ret i32 %shl 388*9880d681SAndroid Build Coastguard Worker} 389*9880d681SAndroid Build Coastguard Worker 390*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 391*9880d681SAndroid Build Coastguard Workerdefine i64 @f35(i64 %foo) { 392*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f35: 393*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 191, 55 394*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 395*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, 65535 396*9880d681SAndroid Build Coastguard Worker %shl = lshr i64 %and, 9 397*9880d681SAndroid Build Coastguard Worker ret i64 %shl 398*9880d681SAndroid Build Coastguard Worker} 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case where the AND comes before a shift right. 401*9880d681SAndroid Build Coastguard Worker; We can't use RISBG for the shift in that case. 402*9880d681SAndroid Build Coastguard Workerdefine i32 @f36(i32 %foo) { 403*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f36: 404*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r2 405*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 406*9880d681SAndroid Build Coastguard Worker %and = and i32 %foo, -25 407*9880d681SAndroid Build Coastguard Worker %shl = lshr i32 %and, 1 408*9880d681SAndroid Build Coastguard Worker ret i32 %shl 409*9880d681SAndroid Build Coastguard Worker} 410*9880d681SAndroid Build Coastguard Worker 411*9880d681SAndroid Build Coastguard Worker; ...and again with i64. 412*9880d681SAndroid Build Coastguard Workerdefine i64 @f37(i64 %foo) { 413*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f37: 414*9880d681SAndroid Build Coastguard Worker; CHECK: srlg %r2 415*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 416*9880d681SAndroid Build Coastguard Worker %and = and i64 %foo, -25 417*9880d681SAndroid Build Coastguard Worker %shl = lshr i64 %and, 1 418*9880d681SAndroid Build Coastguard Worker ret i64 %shl 419*9880d681SAndroid Build Coastguard Worker} 420*9880d681SAndroid Build Coastguard Worker 421*9880d681SAndroid Build Coastguard Worker; Test a combination involving a large ASHR and a shift left. We can't 422*9880d681SAndroid Build Coastguard Worker; use RISBG there. 423*9880d681SAndroid Build Coastguard Workerdefine i64 @f38(i64 %foo) { 424*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f38: 425*9880d681SAndroid Build Coastguard Worker; CHECK: srag {{%r[0-5]}} 426*9880d681SAndroid Build Coastguard Worker; CHECK: sllg {{%r[0-5]}} 427*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 428*9880d681SAndroid Build Coastguard Worker %ashr = ashr i64 %foo, 32 429*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ashr, 5 430*9880d681SAndroid Build Coastguard Worker ret i64 %shl 431*9880d681SAndroid Build Coastguard Worker} 432*9880d681SAndroid Build Coastguard Worker 433*9880d681SAndroid Build Coastguard Worker; Try a similar thing in which no shifted sign bits are kept. 434*9880d681SAndroid Build Coastguard Workerdefine i64 @f39(i64 %foo, i64 *%dest) { 435*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f39: 436*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[01345]]], %r2, 35 437*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 33, 189, 31 438*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 439*9880d681SAndroid Build Coastguard Worker %ashr = ashr i64 %foo, 35 440*9880d681SAndroid Build Coastguard Worker store i64 %ashr, i64 *%dest 441*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ashr, 2 442*9880d681SAndroid Build Coastguard Worker %and = and i64 %shl, 2147483647 443*9880d681SAndroid Build Coastguard Worker ret i64 %and 444*9880d681SAndroid Build Coastguard Worker} 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Worker; ...and again with the next highest shift value, where one sign bit is kept. 447*9880d681SAndroid Build Coastguard Workerdefine i64 @f40(i64 %foo, i64 *%dest) { 448*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f40: 449*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[01345]]], %r2, 36 450*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, [[REG]], 33, 189, 2 451*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 452*9880d681SAndroid Build Coastguard Worker %ashr = ashr i64 %foo, 36 453*9880d681SAndroid Build Coastguard Worker store i64 %ashr, i64 *%dest 454*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ashr, 2 455*9880d681SAndroid Build Coastguard Worker %and = and i64 %shl, 2147483647 456*9880d681SAndroid Build Coastguard Worker ret i64 %and 457*9880d681SAndroid Build Coastguard Worker} 458*9880d681SAndroid Build Coastguard Worker 459*9880d681SAndroid Build Coastguard Worker; Check a case where the result is zero-extended. 460*9880d681SAndroid Build Coastguard Workerdefine i64 @f41(i32 %a) { 461*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f41 462*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 36, 191, 62 463*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 464*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %a, 2 465*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %shl, 4 466*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %shr to i64 467*9880d681SAndroid Build Coastguard Worker ret i64 %ext 468*9880d681SAndroid Build Coastguard Worker} 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Worker; In this case the sign extension is converted to a pair of 32-bit shifts, 471*9880d681SAndroid Build Coastguard Worker; which is then extended to 64 bits. We previously used the wrong bit size 472*9880d681SAndroid Build Coastguard Worker; when testing whether the shifted-in bits of the shift right were significant. 473*9880d681SAndroid Build Coastguard Workerdefine i64 @f42(i1 %x) { 474*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f42: 475*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 31 476*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r2, 31 477*9880d681SAndroid Build Coastguard Worker; CHECK: llgcr %r2, %r2 478*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 479*9880d681SAndroid Build Coastguard Worker %ext = sext i1 %x to i8 480*9880d681SAndroid Build Coastguard Worker %ext2 = zext i8 %ext to i64 481*9880d681SAndroid Build Coastguard Worker ret i64 %ext2 482*9880d681SAndroid Build Coastguard Worker} 483*9880d681SAndroid Build Coastguard Worker 484*9880d681SAndroid Build Coastguard Worker; Check that we get the case where a 64-bit shift is used by a 32-bit and. 485*9880d681SAndroid Build Coastguard Workerdefine signext i32 @f43(i64 %x) { 486*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f43: 487*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[REG:%r[0-5]]], %r2, 32, 189, 52 488*9880d681SAndroid Build Coastguard Worker; CHECK: lgfr %r2, [[REG]] 489*9880d681SAndroid Build Coastguard Worker %shr3 = lshr i64 %x, 12 490*9880d681SAndroid Build Coastguard Worker %shr3.tr = trunc i64 %shr3 to i32 491*9880d681SAndroid Build Coastguard Worker %conv = and i32 %shr3.tr, -4 492*9880d681SAndroid Build Coastguard Worker ret i32 %conv 493*9880d681SAndroid Build Coastguard Worker} 494*9880d681SAndroid Build Coastguard Worker 495*9880d681SAndroid Build Coastguard Worker; Check that we don't get the case where the 32-bit and mask is not contiguous 496*9880d681SAndroid Build Coastguard Workerdefine signext i32 @f44(i64 %x) { 497*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f44: 498*9880d681SAndroid Build Coastguard Worker; CHECK: srlg [[REG:%r[0-5]]], %r2, 12 499*9880d681SAndroid Build Coastguard Worker %shr4 = lshr i64 %x, 12 500*9880d681SAndroid Build Coastguard Worker %conv = trunc i64 %shr4 to i32 501*9880d681SAndroid Build Coastguard Worker %and = and i32 %conv, 10 502*9880d681SAndroid Build Coastguard Worker ret i32 %and 503*9880d681SAndroid Build Coastguard Worker} 504