1*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare -mtriple=arm64-apple=ios -S -o - %s | FileCheck --check-prefix=OPT %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=arm64 | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker%struct.X = type { i8, i8, [2 x i8] } 4*9880d681SAndroid Build Coastguard Worker%struct.Y = type { i32, i8 } 5*9880d681SAndroid Build Coastguard Worker%struct.Z = type { i8, i8, [2 x i8], i16 } 6*9880d681SAndroid Build Coastguard Worker%struct.A = type { i64, i8 } 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine void @foo(%struct.X* nocapture %x, %struct.Y* nocapture %y) nounwind optsize ssp { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo: 10*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx 11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 12*9880d681SAndroid Build Coastguard Worker; CHECK: ret 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker %tmp = bitcast %struct.X* %x to i32* 15*9880d681SAndroid Build Coastguard Worker %tmp1 = load i32, i32* %tmp, align 4 16*9880d681SAndroid Build Coastguard Worker %b = getelementptr inbounds %struct.Y, %struct.Y* %y, i64 0, i32 1 17*9880d681SAndroid Build Coastguard Worker %bf.clear = lshr i32 %tmp1, 3 18*9880d681SAndroid Build Coastguard Worker %bf.clear.lobit = and i32 %bf.clear, 1 19*9880d681SAndroid Build Coastguard Worker %frombool = trunc i32 %bf.clear.lobit to i8 20*9880d681SAndroid Build Coastguard Worker store i8 %frombool, i8* %b, align 1 21*9880d681SAndroid Build Coastguard Worker ret void 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine i32 @baz(i64 %cav1.coerce) nounwind { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: baz: 26*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx w0, w0, #0, #4 27*9880d681SAndroid Build Coastguard Worker %tmp = trunc i64 %cav1.coerce to i32 28*9880d681SAndroid Build Coastguard Worker %tmp1 = shl i32 %tmp, 28 29*9880d681SAndroid Build Coastguard Worker %bf.val.sext = ashr exact i32 %tmp1, 28 30*9880d681SAndroid Build Coastguard Worker ret i32 %bf.val.sext 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerdefine i32 @bar(i64 %cav1.coerce) nounwind { 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bar: 35*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx w0, w0, #4, #6 36*9880d681SAndroid Build Coastguard Worker %tmp = trunc i64 %cav1.coerce to i32 37*9880d681SAndroid Build Coastguard Worker %cav1.sroa.0.1.insert = shl i32 %tmp, 22 38*9880d681SAndroid Build Coastguard Worker %tmp1 = ashr i32 %cav1.sroa.0.1.insert, 26 39*9880d681SAndroid Build Coastguard Worker ret i32 %tmp1 40*9880d681SAndroid Build Coastguard Worker} 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerdefine void @fct1(%struct.Z* nocapture %x, %struct.A* nocapture %y) nounwind optsize ssp { 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct1: 44*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx x{{[0-9]+}}, x{{[0-9]+}} 45*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 46*9880d681SAndroid Build Coastguard Worker; CHECK: ret 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker %tmp = bitcast %struct.Z* %x to i64* 49*9880d681SAndroid Build Coastguard Worker %tmp1 = load i64, i64* %tmp, align 4 50*9880d681SAndroid Build Coastguard Worker %b = getelementptr inbounds %struct.A, %struct.A* %y, i64 0, i32 0 51*9880d681SAndroid Build Coastguard Worker %bf.clear = lshr i64 %tmp1, 3 52*9880d681SAndroid Build Coastguard Worker %bf.clear.lobit = and i64 %bf.clear, 1 53*9880d681SAndroid Build Coastguard Worker store i64 %bf.clear.lobit, i64* %b, align 8 54*9880d681SAndroid Build Coastguard Worker ret void 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workerdefine i64 @fct2(i64 %cav1.coerce) nounwind { 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct2: 59*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx x0, x0, #0, #36 60*9880d681SAndroid Build Coastguard Worker %tmp = shl i64 %cav1.coerce, 28 61*9880d681SAndroid Build Coastguard Worker %bf.val.sext = ashr exact i64 %tmp, 28 62*9880d681SAndroid Build Coastguard Worker ret i64 %bf.val.sext 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdefine i64 @fct3(i64 %cav1.coerce) nounwind { 66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct3: 67*9880d681SAndroid Build Coastguard Worker; CHECK: sbfx x0, x0, #4, #38 68*9880d681SAndroid Build Coastguard Worker %cav1.sroa.0.1.insert = shl i64 %cav1.coerce, 22 69*9880d681SAndroid Build Coastguard Worker %tmp1 = ashr i64 %cav1.sroa.0.1.insert, 26 70*9880d681SAndroid Build Coastguard Worker ret i64 %tmp1 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Workerdefine void @fct4(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 74*9880d681SAndroid Build Coastguard Workerentry: 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct4: 76*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #24 78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG1]], 79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 80*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 81*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -16777216 82*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 83*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 16777215 84*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 85*9880d681SAndroid Build Coastguard Worker store i64 %or, i64* %y, align 8 86*9880d681SAndroid Build Coastguard Worker ret void 87*9880d681SAndroid Build Coastguard Worker} 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerdefine void @fct5(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 90*9880d681SAndroid Build Coastguard Workerentry: 91*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct5: 92*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3 94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG1]], 95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 96*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 97*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 98*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 99*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 100*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 101*9880d681SAndroid Build Coastguard Worker store i32 %or, i32* %y, align 8 102*9880d681SAndroid Build Coastguard Worker ret void 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some low bits 106*9880d681SAndroid Build Coastguard Workerdefine void @fct6(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct6: 109*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3 111*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #2 113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 115*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 116*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 117*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 118*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 119*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 120*9880d681SAndroid Build Coastguard Worker %shr1 = lshr i32 %or, 2 121*9880d681SAndroid Build Coastguard Worker store i32 %shr1, i32* %y, align 8 122*9880d681SAndroid Build Coastguard Worker ret void 123*9880d681SAndroid Build Coastguard Worker} 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 127*9880d681SAndroid Build Coastguard Workerdefine void @fct7(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 128*9880d681SAndroid Build Coastguard Workerentry: 129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct7: 130*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3 132*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm 133*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2 134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 136*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 137*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 138*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 139*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 140*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 141*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %or, 2 142*9880d681SAndroid Build Coastguard Worker store i32 %shl, i32* %y, align 8 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some low bits 148*9880d681SAndroid Build Coastguard Worker; (i64 version) 149*9880d681SAndroid Build Coastguard Workerdefine void @fct8(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 150*9880d681SAndroid Build Coastguard Workerentry: 151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct8: 152*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3 154*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #2 156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 158*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 159*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -8 160*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 161*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 7 162*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 163*9880d681SAndroid Build Coastguard Worker %shr1 = lshr i64 %or, 2 164*9880d681SAndroid Build Coastguard Worker store i64 %shr1, i64* %y, align 8 165*9880d681SAndroid Build Coastguard Worker ret void 166*9880d681SAndroid Build Coastguard Worker} 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 170*9880d681SAndroid Build Coastguard Worker; (i64 version) 171*9880d681SAndroid Build Coastguard Workerdefine void @fct9(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 172*9880d681SAndroid Build Coastguard Workerentry: 173*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct9: 174*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3 176*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2 178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 180*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 181*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -8 182*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 183*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 7 184*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 185*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %or, 2 186*9880d681SAndroid Build Coastguard Worker store i64 %shl, i64* %y, align 8 187*9880d681SAndroid Build Coastguard Worker ret void 188*9880d681SAndroid Build Coastguard Worker} 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Worker; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr) 191*9880d681SAndroid Build Coastguard Worker; (i32 version) 192*9880d681SAndroid Build Coastguard Workerdefine void @fct10(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 193*9880d681SAndroid Build Coastguard Workerentry: 194*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct10: 195*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 196*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #0, #3 197*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm 198*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2 199*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 200*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 201*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 202*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 203*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %x, 7 204*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 205*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %or, 2 206*9880d681SAndroid Build Coastguard Worker store i32 %shl, i32* %y, align 8 207*9880d681SAndroid Build Coastguard Worker ret void 208*9880d681SAndroid Build Coastguard Worker} 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr) 211*9880d681SAndroid Build Coastguard Worker; (i64 version) 212*9880d681SAndroid Build Coastguard Workerdefine void @fct11(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 213*9880d681SAndroid Build Coastguard Workerentry: 214*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct11: 215*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 216*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #0, #3 217*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm 218*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2 219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 221*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 222*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -8 223*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %x, 7 224*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 225*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %or, 2 226*9880d681SAndroid Build Coastguard Worker store i64 %shl, i64* %y, align 8 227*9880d681SAndroid Build Coastguard Worker ret void 228*9880d681SAndroid Build Coastguard Worker} 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Workerdefine zeroext i1 @fct12bis(i32 %tmp2) unnamed_addr nounwind ssp align 2 { 231*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct12bis: 232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 233*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx w0, w0, #11, #1 234*9880d681SAndroid Build Coastguard Worker %and.i.i = and i32 %tmp2, 2048 235*9880d681SAndroid Build Coastguard Worker %tobool.i.i = icmp ne i32 %and.i.i, 0 236*9880d681SAndroid Build Coastguard Worker ret i1 %tobool.i.i 237*9880d681SAndroid Build Coastguard Worker} 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 240*9880d681SAndroid Build Coastguard Worker; and some low bits 241*9880d681SAndroid Build Coastguard Workerdefine void @fct12(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 242*9880d681SAndroid Build Coastguard Workerentry: 243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct12: 244*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 245*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3 246*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG2:w[0-9]+]], [[REG1]], #2, #28 248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 250*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 251*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 252*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 253*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 254*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 255*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %or, 2 256*9880d681SAndroid Build Coastguard Worker %shr2 = lshr i32 %shl, 4 257*9880d681SAndroid Build Coastguard Worker store i32 %shr2, i32* %y, align 8 258*9880d681SAndroid Build Coastguard Worker ret void 259*9880d681SAndroid Build Coastguard Worker} 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 262*9880d681SAndroid Build Coastguard Worker; and some low bits 263*9880d681SAndroid Build Coastguard Worker; (i64 version) 264*9880d681SAndroid Build Coastguard Workerdefine void @fct13(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 265*9880d681SAndroid Build Coastguard Workerentry: 266*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct13: 267*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 268*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3 269*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 270*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG2:x[0-9]+]], [[REG1]], #2, #60 271*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG2]], 272*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 273*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 274*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -8 275*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 276*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 7 277*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 278*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %or, 2 279*9880d681SAndroid Build Coastguard Worker %shr2 = lshr i64 %shl, 4 280*9880d681SAndroid Build Coastguard Worker store i64 %shr2, i64* %y, align 8 281*9880d681SAndroid Build Coastguard Worker ret void 282*9880d681SAndroid Build Coastguard Worker} 283*9880d681SAndroid Build Coastguard Worker 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 286*9880d681SAndroid Build Coastguard Worker; and some low bits 287*9880d681SAndroid Build Coastguard Workerdefine void @fct14(i32* nocapture %y, i32 %x, i32 %x1) nounwind optsize inlinehint ssp { 288*9880d681SAndroid Build Coastguard Workerentry: 289*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct14: 290*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 291*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w1, #16, #8 292*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 293*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #4 294*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], w2, #5, #3 295*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm 296*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG3:w[0-9]+]], [[REG2]], #2 297*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], 298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 299*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 300*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -256 301*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 302*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 255 303*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 304*9880d681SAndroid Build Coastguard Worker %shl = lshr i32 %or, 4 305*9880d681SAndroid Build Coastguard Worker %and2 = and i32 %shl, -8 306*9880d681SAndroid Build Coastguard Worker %shr1 = lshr i32 %x1, 5 307*9880d681SAndroid Build Coastguard Worker %and3 = and i32 %shr1, 7 308*9880d681SAndroid Build Coastguard Worker %or1 = or i32 %and2, %and3 309*9880d681SAndroid Build Coastguard Worker %shl1 = shl i32 %or1, 2 310*9880d681SAndroid Build Coastguard Worker store i32 %shl1, i32* %y, align 8 311*9880d681SAndroid Build Coastguard Worker ret void 312*9880d681SAndroid Build Coastguard Worker} 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 315*9880d681SAndroid Build Coastguard Worker; and some low bits 316*9880d681SAndroid Build Coastguard Worker; (i64 version) 317*9880d681SAndroid Build Coastguard Workerdefine void @fct15(i64* nocapture %y, i64 %x, i64 %x1) nounwind optsize inlinehint ssp { 318*9880d681SAndroid Build Coastguard Workerentry: 319*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct15: 320*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 321*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], x1, #16, #8 322*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 323*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #4 324*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], x2, #5, #3 325*9880d681SAndroid Build Coastguard Worker; lsl is an alias of ubfm 326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl [[REG3:x[0-9]+]], [[REG2]], #2 327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], 328*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 329*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 330*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, -256 331*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 332*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 255 333*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 334*9880d681SAndroid Build Coastguard Worker %shl = lshr i64 %or, 4 335*9880d681SAndroid Build Coastguard Worker %and2 = and i64 %shl, -8 336*9880d681SAndroid Build Coastguard Worker %shr1 = lshr i64 %x1, 5 337*9880d681SAndroid Build Coastguard Worker %and3 = and i64 %shr1, 7 338*9880d681SAndroid Build Coastguard Worker %or1 = or i64 %and2, %and3 339*9880d681SAndroid Build Coastguard Worker %shl1 = shl i64 %or1, 2 340*9880d681SAndroid Build Coastguard Worker store i64 %shl1, i64* %y, align 8 341*9880d681SAndroid Build Coastguard Worker ret void 342*9880d681SAndroid Build Coastguard Worker} 343*9880d681SAndroid Build Coastguard Worker 344*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 345*9880d681SAndroid Build Coastguard Worker; and some low bits and a masking operation has to be kept 346*9880d681SAndroid Build Coastguard Workerdefine void @fct16(i32* nocapture %y, i32 %x) nounwind optsize inlinehint ssp { 347*9880d681SAndroid Build Coastguard Workerentry: 348*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct16: 349*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 350*9880d681SAndroid Build Coastguard Worker; Create the constant 351*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REGCST:w[0-9]+]], #1703936 352*9880d681SAndroid Build Coastguard Worker; CHECK: movk [[REGCST]], #33120 353*9880d681SAndroid Build Coastguard Worker; Do the masking 354*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG2:w[0-9]+]], [[REG1]], [[REGCST]] 355*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], w1, #16, #3 356*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 357*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG3:w[0-9]+]], [[REG2]], #2, #28 358*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], 359*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 360*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %y, align 8 361*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, 1737056 362*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 363*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 364*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 365*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %or, 2 366*9880d681SAndroid Build Coastguard Worker %shr2 = lshr i32 %shl, 4 367*9880d681SAndroid Build Coastguard Worker store i32 %shr2, i32* %y, align 8 368*9880d681SAndroid Build Coastguard Worker ret void 369*9880d681SAndroid Build Coastguard Worker} 370*9880d681SAndroid Build Coastguard Worker 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Worker; Check if we can still catch bfm instruction when we drop some high bits 373*9880d681SAndroid Build Coastguard Worker; and some low bits and a masking operation has to be kept 374*9880d681SAndroid Build Coastguard Worker; (i64 version) 375*9880d681SAndroid Build Coastguard Workerdefine void @fct17(i64* nocapture %y, i64 %x) nounwind optsize inlinehint ssp { 376*9880d681SAndroid Build Coastguard Workerentry: 377*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct17: 378*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:x[0-9]+]], 379*9880d681SAndroid Build Coastguard Worker; Create the constant 380*9880d681SAndroid Build Coastguard Worker; CHECK: mov w[[REGCST:[0-9]+]], #1703936 381*9880d681SAndroid Build Coastguard Worker; CHECK: movk w[[REGCST]], #33120 382*9880d681SAndroid Build Coastguard Worker; Do the masking 383*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG2:x[0-9]+]], [[REG1]], x[[REGCST]] 384*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG2]], x1, #16, #3 385*9880d681SAndroid Build Coastguard Worker; lsr is an alias of ubfm 386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ubfx [[REG3:x[0-9]+]], [[REG2]], #2, #60 387*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], 388*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 389*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %y, align 8 390*9880d681SAndroid Build Coastguard Worker %and = and i64 %0, 1737056 391*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 16 392*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %shr, 7 393*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %and1 394*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %or, 2 395*9880d681SAndroid Build Coastguard Worker %shr2 = lshr i64 %shl, 4 396*9880d681SAndroid Build Coastguard Worker store i64 %shr2, i64* %y, align 8 397*9880d681SAndroid Build Coastguard Worker ret void 398*9880d681SAndroid Build Coastguard Worker} 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Workerdefine i64 @fct18(i32 %xor72) nounwind ssp { 401*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct18: 402*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx x0, x0, #9, #8 403*9880d681SAndroid Build Coastguard Worker %shr81 = lshr i32 %xor72, 9 404*9880d681SAndroid Build Coastguard Worker %conv82 = zext i32 %shr81 to i64 405*9880d681SAndroid Build Coastguard Worker %result = and i64 %conv82, 255 406*9880d681SAndroid Build Coastguard Worker ret i64 %result 407*9880d681SAndroid Build Coastguard Worker} 408*9880d681SAndroid Build Coastguard Worker 409*9880d681SAndroid Build Coastguard Worker; Using the access to the global array to keep the instruction and control flow. 410*9880d681SAndroid Build Coastguard Worker@first_ones = external global [65536 x i8] 411*9880d681SAndroid Build Coastguard Worker 412*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readonly ssp 413*9880d681SAndroid Build Coastguard Workerdefine i32 @fct19(i64 %arg1) nounwind readonly ssp { 414*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct19: 415*9880d681SAndroid Build Coastguard Workerentry: 416*9880d681SAndroid Build Coastguard Worker %x.sroa.1.0.extract.shift = lshr i64 %arg1, 16 417*9880d681SAndroid Build Coastguard Worker %x.sroa.1.0.extract.trunc = trunc i64 %x.sroa.1.0.extract.shift to i16 418*9880d681SAndroid Build Coastguard Worker %x.sroa.3.0.extract.shift = lshr i64 %arg1, 32 419*9880d681SAndroid Build Coastguard Worker %x.sroa.5.0.extract.shift = lshr i64 %arg1, 48 420*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i64 %x.sroa.5.0.extract.shift, 0 421*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.end, label %if.then 422*9880d681SAndroid Build Coastguard Worker 423*9880d681SAndroid Build Coastguard Workerif.then: ; preds = %entry 424*9880d681SAndroid Build Coastguard Worker %arrayidx3 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %x.sroa.5.0.extract.shift 425*9880d681SAndroid Build Coastguard Worker %0 = load i8, i8* %arrayidx3, align 1 426*9880d681SAndroid Build Coastguard Worker %conv = zext i8 %0 to i32 427*9880d681SAndroid Build Coastguard Worker br label %return 428*9880d681SAndroid Build Coastguard Worker 429*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.end 430*9880d681SAndroid Build Coastguard Workerif.end: ; preds = %entry 431*9880d681SAndroid Build Coastguard Worker; OPT: lshr 432*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx [[REG1:x[0-9]+]], [[REG2:x[0-9]+]], #32, #16 433*9880d681SAndroid Build Coastguard Worker %x.sroa.3.0.extract.trunc = trunc i64 %x.sroa.3.0.extract.shift to i16 434*9880d681SAndroid Build Coastguard Worker %tobool6 = icmp eq i16 %x.sroa.3.0.extract.trunc, 0 435*9880d681SAndroid Build Coastguard Worker; CHECK: cbz 436*9880d681SAndroid Build Coastguard Worker br i1 %tobool6, label %if.end13, label %if.then7 437*9880d681SAndroid Build Coastguard Worker 438*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.then7 439*9880d681SAndroid Build Coastguard Workerif.then7: ; preds = %if.end 440*9880d681SAndroid Build Coastguard Worker; OPT: lshr 441*9880d681SAndroid Build Coastguard Worker; "and" should be combined to "ubfm" while "ubfm" should be removed by cse. 442*9880d681SAndroid Build Coastguard Worker; So neither of them should be in the assemble code. 443*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 444*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ubfm 445*9880d681SAndroid Build Coastguard Worker %idxprom10 = and i64 %x.sroa.3.0.extract.shift, 65535 446*9880d681SAndroid Build Coastguard Worker %arrayidx11 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom10 447*9880d681SAndroid Build Coastguard Worker %1 = load i8, i8* %arrayidx11, align 1 448*9880d681SAndroid Build Coastguard Worker %conv12 = zext i8 %1 to i32 449*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %conv12, 16 450*9880d681SAndroid Build Coastguard Worker br label %return 451*9880d681SAndroid Build Coastguard Worker 452*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.end13 453*9880d681SAndroid Build Coastguard Workerif.end13: ; preds = %if.end 454*9880d681SAndroid Build Coastguard Worker; OPT: lshr 455*9880d681SAndroid Build Coastguard Worker; OPT: trunc 456*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx [[REG3:x[0-9]+]], [[REG4:x[0-9]+]], #16, #16 457*9880d681SAndroid Build Coastguard Worker %tobool16 = icmp eq i16 %x.sroa.1.0.extract.trunc, 0 458*9880d681SAndroid Build Coastguard Worker; CHECK: cbz 459*9880d681SAndroid Build Coastguard Worker br i1 %tobool16, label %return, label %if.then17 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: if.then17 462*9880d681SAndroid Build Coastguard Workerif.then17: ; preds = %if.end13 463*9880d681SAndroid Build Coastguard Worker; OPT: lshr 464*9880d681SAndroid Build Coastguard Worker; "and" should be combined to "ubfm" while "ubfm" should be removed by cse. 465*9880d681SAndroid Build Coastguard Worker; So neither of them should be in the assemble code. 466*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 467*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ubfm 468*9880d681SAndroid Build Coastguard Worker %idxprom20 = and i64 %x.sroa.1.0.extract.shift, 65535 469*9880d681SAndroid Build Coastguard Worker %arrayidx21 = getelementptr inbounds [65536 x i8], [65536 x i8]* @first_ones, i64 0, i64 %idxprom20 470*9880d681SAndroid Build Coastguard Worker %2 = load i8, i8* %arrayidx21, align 1 471*9880d681SAndroid Build Coastguard Worker %conv22 = zext i8 %2 to i32 472*9880d681SAndroid Build Coastguard Worker %add23 = add nsw i32 %conv22, 32 473*9880d681SAndroid Build Coastguard Worker br label %return 474*9880d681SAndroid Build Coastguard Worker 475*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %if.end13, %if.then17, %if.then7, %if.then 476*9880d681SAndroid Build Coastguard Worker; CHECK: ret 477*9880d681SAndroid Build Coastguard Worker %retval.0 = phi i32 [ %conv, %if.then ], [ %add, %if.then7 ], [ %add23, %if.then17 ], [ 64, %if.end13 ] 478*9880d681SAndroid Build Coastguard Worker ret i32 %retval.0 479*9880d681SAndroid Build Coastguard Worker} 480*9880d681SAndroid Build Coastguard Worker 481*9880d681SAndroid Build Coastguard Worker; Make sure we do not assert if the immediate in and is bigger than i64. 482*9880d681SAndroid Build Coastguard Worker; PR19503. 483*9880d681SAndroid Build Coastguard Worker; OPT-LABEL: @fct20 484*9880d681SAndroid Build Coastguard Worker; OPT: lshr 485*9880d681SAndroid Build Coastguard Worker; OPT-NOT: lshr 486*9880d681SAndroid Build Coastguard Worker; OPT: ret 487*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct20: 488*9880d681SAndroid Build Coastguard Worker; CHECK: ret 489*9880d681SAndroid Build Coastguard Workerdefine i80 @fct20(i128 %a, i128 %b) { 490*9880d681SAndroid Build Coastguard Workerentry: 491*9880d681SAndroid Build Coastguard Worker %shr = lshr i128 %a, 18 492*9880d681SAndroid Build Coastguard Worker %conv = trunc i128 %shr to i80 493*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i128 %b, 0 494*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %then, label %end 495*9880d681SAndroid Build Coastguard Workerthen: 496*9880d681SAndroid Build Coastguard Worker %and = and i128 %shr, 483673642326615442599424 497*9880d681SAndroid Build Coastguard Worker %conv2 = trunc i128 %and to i80 498*9880d681SAndroid Build Coastguard Worker br label %end 499*9880d681SAndroid Build Coastguard Workerend: 500*9880d681SAndroid Build Coastguard Worker %conv3 = phi i80 [%conv, %entry], [%conv2, %then] 501*9880d681SAndroid Build Coastguard Worker ret i80 %conv3 502*9880d681SAndroid Build Coastguard Worker} 503*9880d681SAndroid Build Coastguard Worker 504*9880d681SAndroid Build Coastguard Worker; Check if we can still catch UBFX when "AND" is used by SHL. 505*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fct21: 506*9880d681SAndroid Build Coastguard Worker; CHECK: ubfx 507*9880d681SAndroid Build Coastguard Worker@arr = external global [8 x [64 x i64]] 508*9880d681SAndroid Build Coastguard Workerdefine i64 @fct21(i64 %x) { 509*9880d681SAndroid Build Coastguard Workerentry: 510*9880d681SAndroid Build Coastguard Worker %shr = lshr i64 %x, 4 511*9880d681SAndroid Build Coastguard Worker %and = and i64 %shr, 15 512*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds [8 x [64 x i64]], [8 x [64 x i64]]* @arr, i64 0, i64 0, i64 %and 513*9880d681SAndroid Build Coastguard Worker %0 = load i64, i64* %arrayidx, align 8 514*9880d681SAndroid Build Coastguard Worker ret i64 %0 515*9880d681SAndroid Build Coastguard Worker} 516*9880d681SAndroid Build Coastguard Worker 517*9880d681SAndroid Build Coastguard Workerdefine i16 @test_ignored_rightbits(i32 %dst, i32 %in) { 518*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_ignored_rightbits: 519*9880d681SAndroid Build Coastguard Worker 520*9880d681SAndroid Build Coastguard Worker %positioned_field = shl i32 %in, 3 521*9880d681SAndroid Build Coastguard Worker %positioned_masked_field = and i32 %positioned_field, 120 522*9880d681SAndroid Build Coastguard Worker %masked_dst = and i32 %dst, 7 523*9880d681SAndroid Build Coastguard Worker %insertion = or i32 %masked_dst, %positioned_masked_field 524*9880d681SAndroid Build Coastguard Worker; CHECK: {{bfm|bfi|bfxil}} 525*9880d681SAndroid Build Coastguard Worker 526*9880d681SAndroid Build Coastguard Worker %shl16 = shl i32 %insertion, 8 527*9880d681SAndroid Build Coastguard Worker %or18 = or i32 %shl16, %insertion 528*9880d681SAndroid Build Coastguard Worker %conv19 = trunc i32 %or18 to i16 529*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #8, #7 530*9880d681SAndroid Build Coastguard Worker 531*9880d681SAndroid Build Coastguard Worker ret i16 %conv19 532*9880d681SAndroid Build Coastguard Worker} 533