1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; First, a simple example from Clang. The registers could plausibly be 4*9880d681SAndroid Build Coastguard Worker; different, but probably won't be. 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker%struct.foo = type { i8, [2 x i8], i8 } 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine [1 x i64] @from_clang([1 x i64] %f.coerce, i32 %n) nounwind readnone { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: from_clang: 10*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerentry: 13*9880d681SAndroid Build Coastguard Worker %f.coerce.fca.0.extract = extractvalue [1 x i64] %f.coerce, 0 14*9880d681SAndroid Build Coastguard Worker %tmp.sroa.0.0.extract.trunc = trunc i64 %f.coerce.fca.0.extract to i32 15*9880d681SAndroid Build Coastguard Worker %bf.value = shl i32 %n, 3 16*9880d681SAndroid Build Coastguard Worker %0 = and i32 %bf.value, 120 17*9880d681SAndroid Build Coastguard Worker %f.sroa.0.0.insert.ext.masked = and i32 %tmp.sroa.0.0.extract.trunc, 135 18*9880d681SAndroid Build Coastguard Worker %1 = or i32 %f.sroa.0.0.insert.ext.masked, %0 19*9880d681SAndroid Build Coastguard Worker %f.sroa.0.0.extract.trunc = zext i32 %1 to i64 20*9880d681SAndroid Build Coastguard Worker %tmp1.sroa.1.1.insert.insert = and i64 %f.coerce.fca.0.extract, 4294967040 21*9880d681SAndroid Build Coastguard Worker %tmp1.sroa.0.0.insert.insert = or i64 %f.sroa.0.0.extract.trunc, %tmp1.sroa.1.1.insert.insert 22*9880d681SAndroid Build Coastguard Worker %.fca.0.insert = insertvalue [1 x i64] undef, i64 %tmp1.sroa.0.0.insert.insert, 0 23*9880d681SAndroid Build Coastguard Worker ret [1 x i64] %.fca.0.insert 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerdefine void @test_whole32(i32* %existing, i32* %new) { 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_whole32: 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #26, #5 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 32*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 2214592511 ; =0x83ffffff 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker %newval = load volatile i32, i32* %new 35*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 26 36*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 2080374784 ; = 0x7c000000 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 39*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker ret void 42*9880d681SAndroid Build Coastguard Worker} 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Workerdefine void @test_whole64(i64* %existing, i64* %new) { 45*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_whole64: 46*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{x[0-9]+}}, {{x[0-9]+}}, #26, #14 47*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and 48*9880d681SAndroid Build Coastguard Worker; CHECK: ret 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i64, i64* %existing 51*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i64 %oldval, 18446742974265032703 ; = 0xffffff0003ffffffL 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker %newval = load volatile i64, i64* %new 54*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i64 %newval, 26 55*9880d681SAndroid Build Coastguard Worker %newval_masked = and i64 %newval_shifted, 1099444518912 ; = 0xfffc000000 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker %combined = or i64 %oldval_keep, %newval_masked 58*9880d681SAndroid Build Coastguard Worker store volatile i64 %combined, i64* %existing 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker ret void 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Workerdefine void @test_whole32_from64(i64* %existing, i64* %new) { 64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_whole32_from64: 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; CHECK: bfxil {{x[0-9]+}}, {{x[0-9]+}}, #0, #16 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; CHECK: ret 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i64, i64* %existing 72*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i64 %oldval, 4294901760 ; = 0xffff0000 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker %newval = load volatile i64, i64* %new 75*9880d681SAndroid Build Coastguard Worker %newval_masked = and i64 %newval, 65535 ; = 0xffff 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker %combined = or i64 %oldval_keep, %newval_masked 78*9880d681SAndroid Build Coastguard Worker store volatile i64 %combined, i64* %existing 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker ret void 81*9880d681SAndroid Build Coastguard Worker} 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdefine void @test_32bit_masked(i32 *%existing, i32 *%new) { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_32bit_masked: 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker; CHECK: and 87*9880d681SAndroid Build Coastguard Worker; CHECK: bfi [[INSERT:w[0-9]+]], {{w[0-9]+}}, #3, #4 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 90*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 135 ; = 0x87 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker %newval = load volatile i32, i32* %new 93*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 3 94*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 120 ; = 0x78 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 97*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker ret void 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerdefine void @test_64bit_masked(i64 *%existing, i64 *%new) { 103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_64bit_masked: 104*9880d681SAndroid Build Coastguard Worker; CHECK: and 105*9880d681SAndroid Build Coastguard Worker; CHECK: bfi [[INSERT:x[0-9]+]], {{x[0-9]+}}, #40, #8 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i64, i64* %existing 108*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i64 %oldval, 1095216660480 ; = 0xff_0000_0000 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker %newval = load volatile i64, i64* %new 111*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i64 %newval, 40 112*9880d681SAndroid Build Coastguard Worker %newval_masked = and i64 %newval_shifted, 280375465082880 ; = 0xff00_0000_0000 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker %combined = or i64 %newval_masked, %oldval_keep 115*9880d681SAndroid Build Coastguard Worker store volatile i64 %combined, i64* %existing 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker ret void 118*9880d681SAndroid Build Coastguard Worker} 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker; Mask is too complicated for literal ANDwwi, make sure other avenues are tried. 121*9880d681SAndroid Build Coastguard Workerdefine void @test_32bit_complexmask(i32 *%existing, i32 *%new) { 122*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_32bit_complexmask: 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker; CHECK: and 125*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 128*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 647 ; = 0x287 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker %newval = load volatile i32, i32* %new 131*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 3 132*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 120 ; = 0x278 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 135*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker ret void 138*9880d681SAndroid Build Coastguard Worker} 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker; Neither mask is is a contiguous set of 1s. BFI can't be used 141*9880d681SAndroid Build Coastguard Workerdefine void @test_32bit_badmask(i32 *%existing, i32 *%new) { 142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_32bit_badmask: 143*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: bfi 144*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: bfm 145*9880d681SAndroid Build Coastguard Worker; CHECK: ret 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 148*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 135 ; = 0x87 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker %newval = load volatile i32, i32* %new 151*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 3 152*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 632 ; = 0x278 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 155*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker ret void 158*9880d681SAndroid Build Coastguard Worker} 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; Ditto 161*9880d681SAndroid Build Coastguard Workerdefine void @test_64bit_badmask(i64 *%existing, i64 *%new) { 162*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_64bit_badmask: 163*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: bfi 164*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: bfm 165*9880d681SAndroid Build Coastguard Worker; CHECK: ret 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i64, i64* %existing 168*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i64 %oldval, 135 ; = 0x87 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker %newval = load volatile i64, i64* %new 171*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i64 %newval, 3 172*9880d681SAndroid Build Coastguard Worker %newval_masked = and i64 %newval_shifted, 664 ; = 0x278 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker %combined = or i64 %oldval_keep, %newval_masked 175*9880d681SAndroid Build Coastguard Worker store volatile i64 %combined, i64* %existing 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker ret void 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; Bitfield insert where there's a left-over shr needed at the beginning 181*9880d681SAndroid Build Coastguard Worker; (e.g. result of str.bf1 = str.bf2) 182*9880d681SAndroid Build Coastguard Workerdefine void @test_32bit_with_shr(i32* %existing, i32* %new) { 183*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_32bit_with_shr: 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 186*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 2214592511 ; =0x83ffffff 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker %newval = load i32, i32* %new 189*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 12 190*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 2080374784 ; = 0x7c000000 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 193*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 194*9880d681SAndroid Build Coastguard Worker; CHECK: lsr [[BIT:w[0-9]+]], {{w[0-9]+}}, #14 195*9880d681SAndroid Build Coastguard Worker; CHECK: bfi {{w[0-9]+}}, [[BIT]], #26, #5 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker ret void 198*9880d681SAndroid Build Coastguard Worker} 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker; Bitfield insert where the second or operand is a better match to be folded into the BFM 201*9880d681SAndroid Build Coastguard Workerdefine void @test_32bit_opnd1_better(i32* %existing, i32* %new) { 202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_32bit_opnd1_better: 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker %oldval = load volatile i32, i32* %existing 205*9880d681SAndroid Build Coastguard Worker %oldval_keep = and i32 %oldval, 65535 ; 0x0000ffff 206*9880d681SAndroid Build Coastguard Worker 207*9880d681SAndroid Build Coastguard Worker %newval = load i32, i32* %new 208*9880d681SAndroid Build Coastguard Worker %newval_shifted = shl i32 %newval, 16 209*9880d681SAndroid Build Coastguard Worker %newval_masked = and i32 %newval_shifted, 16711680 ; 0x00ff0000 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker %combined = or i32 %oldval_keep, %newval_masked 212*9880d681SAndroid Build Coastguard Worker store volatile i32 %combined, i32* %existing 213*9880d681SAndroid Build Coastguard Worker; CHECK: and [[BIT:w[0-9]+]], {{w[0-9]+}}, #0xffff 214*9880d681SAndroid Build Coastguard Worker; CHECK: bfi [[BIT]], {{w[0-9]+}}, #16, #8 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Worker ret void 217*9880d681SAndroid Build Coastguard Worker} 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker; Tests when all the bits from one operand are not useful 220*9880d681SAndroid Build Coastguard Workerdefine i32 @test_nouseful_bits(i8 %a, i32 %b) { 221*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_nouseful_bits: 222*9880d681SAndroid Build Coastguard Worker; CHECK: bfi 223*9880d681SAndroid Build Coastguard Worker; CHECK: bfi 224*9880d681SAndroid Build Coastguard Worker; CHECK: bfi 225*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: bfi 226*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: or 227*9880d681SAndroid Build Coastguard Worker; CHECK: lsl 228*9880d681SAndroid Build Coastguard Worker %conv = zext i8 %a to i32 ; 0 0 0 A 229*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %b, 8 ; B2 B1 B0 0 230*9880d681SAndroid Build Coastguard Worker %or = or i32 %conv, %shl ; B2 B1 B0 A 231*9880d681SAndroid Build Coastguard Worker %shl.1 = shl i32 %or, 8 ; B1 B0 A 0 232*9880d681SAndroid Build Coastguard Worker %or.1 = or i32 %conv, %shl.1 ; B1 B0 A A 233*9880d681SAndroid Build Coastguard Worker %shl.2 = shl i32 %or.1, 8 ; B0 A A 0 234*9880d681SAndroid Build Coastguard Worker %or.2 = or i32 %conv, %shl.2 ; B0 A A A 235*9880d681SAndroid Build Coastguard Worker %shl.3 = shl i32 %or.2, 8 ; A A A 0 236*9880d681SAndroid Build Coastguard Worker %or.3 = or i32 %conv, %shl.3 ; A A A A 237*9880d681SAndroid Build Coastguard Worker %shl.4 = shl i32 %or.3, 8 ; A A A 0 238*9880d681SAndroid Build Coastguard Worker ret i32 %shl.4 239*9880d681SAndroid Build Coastguard Worker} 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Workerdefine void @test_nouseful_strb(i32* %ptr32, i8* %ptr8, i32 %x) { 242*9880d681SAndroid Build Coastguard Workerentry: 243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_nouseful_strb 244*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 245*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xf8 246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w2, #16, #3 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strb [[REG1]], 248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 249*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %ptr32, align 8 250*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 251*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 252*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 253*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 254*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %or to i8 255*9880d681SAndroid Build Coastguard Worker store i8 %trunc, i8* %ptr8 256*9880d681SAndroid Build Coastguard Worker ret void 257*9880d681SAndroid Build Coastguard Worker} 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerdefine void @test_nouseful_strh(i32* %ptr32, i16* %ptr16, i32 %x) { 260*9880d681SAndroid Build Coastguard Workerentry: 261*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_nouseful_strh 262*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 263*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0 264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w2, #16, #4 265*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strh [[REG1]], 266*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 267*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %ptr32, align 8 268*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -16 269*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 270*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 15 271*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 272*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %or to i16 273*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16* %ptr16 274*9880d681SAndroid Build Coastguard Worker ret void 275*9880d681SAndroid Build Coastguard Worker} 276*9880d681SAndroid Build Coastguard Worker 277*9880d681SAndroid Build Coastguard Workerdefine void @test_nouseful_sturb(i32* %ptr32, i8* %ptr8, i32 %x) { 278*9880d681SAndroid Build Coastguard Workerentry: 279*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_nouseful_sturb 280*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 281*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xf8 282*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w2, #16, #3 283*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sturb [[REG1]], 284*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 285*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %ptr32, align 8 286*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -8 287*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 288*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 7 289*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 290*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %or to i8 291*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i8, i8* %ptr8, i64 -1 292*9880d681SAndroid Build Coastguard Worker store i8 %trunc, i8* %gep 293*9880d681SAndroid Build Coastguard Worker ret void 294*9880d681SAndroid Build Coastguard Worker} 295*9880d681SAndroid Build Coastguard Worker 296*9880d681SAndroid Build Coastguard Workerdefine void @test_nouseful_sturh(i32* %ptr32, i16* %ptr16, i32 %x) { 297*9880d681SAndroid Build Coastguard Workerentry: 298*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_nouseful_sturh 299*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[REG1:w[0-9]+]], 300*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0 301*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bfxil [[REG1]], w2, #16, #4 302*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sturh [[REG1]], 303*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 304*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %ptr32, align 8 305*9880d681SAndroid Build Coastguard Worker %and = and i32 %0, -16 306*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %x, 16 307*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %shr, 15 308*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 309*9880d681SAndroid Build Coastguard Worker %trunc = trunc i32 %or to i16 310*9880d681SAndroid Build Coastguard Worker %gep = getelementptr i16, i16* %ptr16, i64 -1 311*9880d681SAndroid Build Coastguard Worker store i16 %trunc, i16* %gep 312*9880d681SAndroid Build Coastguard Worker ret void 313*9880d681SAndroid Build Coastguard Worker} 314*9880d681SAndroid Build Coastguard Worker 315*9880d681SAndroid Build Coastguard Worker; The next set of tests generate a BFXIL from 'or (and X, Mask0Imm), 316*9880d681SAndroid Build Coastguard Worker; (and Y, Mask1Imm)' iff Mask0Imm and ~Mask1Imm are equivalent and one of the 317*9880d681SAndroid Build Coastguard Worker; MaskImms is a shifted mask (e.g., 0x000ffff0). 318*9880d681SAndroid Build Coastguard Worker 319*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_or_and_and1 320*9880d681SAndroid Build Coastguard Worker; CHECK: lsr w8, w1, #4 321*9880d681SAndroid Build Coastguard Worker; CHECK: bfi w0, w8, #4, #12 322*9880d681SAndroid Build Coastguard Workerdefine i32 @test_or_and_and1(i32 %a, i32 %b) { 323*9880d681SAndroid Build Coastguard Workerentry: 324*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, -65521 ; 0xffff000f 325*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %b, 65520 ; 0x0000fff0 326*9880d681SAndroid Build Coastguard Worker %or = or i32 %and1, %and 327*9880d681SAndroid Build Coastguard Worker ret i32 %or 328*9880d681SAndroid Build Coastguard Worker} 329*9880d681SAndroid Build Coastguard Worker 330*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_or_and_and2 331*9880d681SAndroid Build Coastguard Worker; CHECK: lsr w8, w0, #4 332*9880d681SAndroid Build Coastguard Worker; CHECK: bfi w1, w8, #4, #12 333*9880d681SAndroid Build Coastguard Workerdefine i32 @test_or_and_and2(i32 %a, i32 %b) { 334*9880d681SAndroid Build Coastguard Workerentry: 335*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, 65520 ; 0x0000fff0 336*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %b, -65521 ; 0xffff000f 337*9880d681SAndroid Build Coastguard Worker %or = or i32 %and1, %and 338*9880d681SAndroid Build Coastguard Worker ret i32 %or 339*9880d681SAndroid Build Coastguard Worker} 340*9880d681SAndroid Build Coastguard Worker 341*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_or_and_and3 342*9880d681SAndroid Build Coastguard Worker; CHECK: lsr x8, x1, #16 343*9880d681SAndroid Build Coastguard Worker; CHECK: bfi x0, x8, #16, #32 344*9880d681SAndroid Build Coastguard Workerdefine i64 @test_or_and_and3(i64 %a, i64 %b) { 345*9880d681SAndroid Build Coastguard Workerentry: 346*9880d681SAndroid Build Coastguard Worker %and = and i64 %a, -281474976645121 ; 0xffff00000000ffff 347*9880d681SAndroid Build Coastguard Worker %and1 = and i64 %b, 281474976645120 ; 0x0000ffffffff0000 348*9880d681SAndroid Build Coastguard Worker %or = or i64 %and1, %and 349*9880d681SAndroid Build Coastguard Worker ret i64 %or 350*9880d681SAndroid Build Coastguard Worker} 351*9880d681SAndroid Build Coastguard Worker 352*9880d681SAndroid Build Coastguard Worker; Don't convert 'and' with multiple uses. 353*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_or_and_and4 354*9880d681SAndroid Build Coastguard Worker; CHECK: and w8, w0, #0xffff000f 355*9880d681SAndroid Build Coastguard Worker; CHECK: and w9, w1, #0xfff0 356*9880d681SAndroid Build Coastguard Worker; CHECK: orr w0, w9, w8 357*9880d681SAndroid Build Coastguard Worker; CHECK: str w8, [x2 358*9880d681SAndroid Build Coastguard Workerdefine i32 @test_or_and_and4(i32 %a, i32 %b, i32* %ptr) { 359*9880d681SAndroid Build Coastguard Workerentry: 360*9880d681SAndroid Build Coastguard Worker %and = and i32 %a, -65521 361*9880d681SAndroid Build Coastguard Worker store i32 %and, i32* %ptr, align 4 362*9880d681SAndroid Build Coastguard Worker %and2 = and i32 %b, 65520 363*9880d681SAndroid Build Coastguard Worker %or = or i32 %and2, %and 364*9880d681SAndroid Build Coastguard Worker ret i32 %or 365*9880d681SAndroid Build Coastguard Worker} 366*9880d681SAndroid Build Coastguard Worker 367*9880d681SAndroid Build Coastguard Worker; Don't convert 'and' with multiple uses. 368*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_or_and_and5 369*9880d681SAndroid Build Coastguard Worker; CHECK: and w8, w1, #0xfff0 370*9880d681SAndroid Build Coastguard Worker; CHECK: and w9, w0, #0xffff000f 371*9880d681SAndroid Build Coastguard Worker; CHECK: orr w0, w8, w9 372*9880d681SAndroid Build Coastguard Worker; CHECK: str w8, [x2] 373*9880d681SAndroid Build Coastguard Workerdefine i32 @test_or_and_and5(i32 %a, i32 %b, i32* %ptr) { 374*9880d681SAndroid Build Coastguard Workerentry: 375*9880d681SAndroid Build Coastguard Worker %and = and i32 %b, 65520 376*9880d681SAndroid Build Coastguard Worker store i32 %and, i32* %ptr, align 4 377*9880d681SAndroid Build Coastguard Worker %and1 = and i32 %a, -65521 378*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %and1 379*9880d681SAndroid Build Coastguard Worker ret i32 %or 380*9880d681SAndroid Build Coastguard Worker} 381*9880d681SAndroid Build Coastguard Worker 382*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1 383*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:w[0-9]+]], #5 384*9880d681SAndroid Build Coastguard Worker; CHECK: bfxil w0, [[REG]], #0, #4 385*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32 %a) { 386*9880d681SAndroid Build Coastguard Worker %1 = and i32 %a, -16 ; 0xfffffff0 387*9880d681SAndroid Build Coastguard Worker %2 = or i32 %1, 5 ; 0x00000005 388*9880d681SAndroid Build Coastguard Worker ret i32 %2 389*9880d681SAndroid Build Coastguard Worker} 390*9880d681SAndroid Build Coastguard Worker 391*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2 392*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:w[0-9]+]], #10 393*9880d681SAndroid Build Coastguard Worker; CHECK: bfi w0, [[REG]], #22, #4 394*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32 %a) { 395*9880d681SAndroid Build Coastguard Worker %1 = and i32 %a, -62914561 ; 0xfc3fffff 396*9880d681SAndroid Build Coastguard Worker %2 = or i32 %1, 41943040 ; 0x06400000 397*9880d681SAndroid Build Coastguard Worker ret i32 %2 398*9880d681SAndroid Build Coastguard Worker} 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3 401*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:x[0-9]+]], #5 402*9880d681SAndroid Build Coastguard Worker; CHECK: bfxil x0, [[REG]], #0, #3 403*9880d681SAndroid Build Coastguard Workerdefine i64 @test3(i64 %a) { 404*9880d681SAndroid Build Coastguard Worker %1 = and i64 %a, -8 ; 0xfffffffffffffff8 405*9880d681SAndroid Build Coastguard Worker %2 = or i64 %1, 5 ; 0x0000000000000005 406*9880d681SAndroid Build Coastguard Worker ret i64 %2 407*9880d681SAndroid Build Coastguard Worker} 408*9880d681SAndroid Build Coastguard Worker 409*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4 410*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:x[0-9]+]], #9 411*9880d681SAndroid Build Coastguard Worker; CHECK: bfi x0, [[REG]], #1, #7 412*9880d681SAndroid Build Coastguard Workerdefine i64 @test4(i64 %a) { 413*9880d681SAndroid Build Coastguard Worker %1 = and i64 %a, -255 ; 0xffffffffffffff01 414*9880d681SAndroid Build Coastguard Worker %2 = or i64 %1, 18 ; 0x0000000000000012 415*9880d681SAndroid Build Coastguard Worker ret i64 %2 416*9880d681SAndroid Build Coastguard Worker} 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Worker; Don't generate BFI/BFXIL if the immediate can be encoded in the ORR. 419*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5 420*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG:w[0-9]+]], w0, #0xfffffff0 421*9880d681SAndroid Build Coastguard Worker; CHECK: orr w0, [[REG]], #0x6 422*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32 %a) { 423*9880d681SAndroid Build Coastguard Worker %1 = and i32 %a, 4294967280 ; 0xfffffff0 424*9880d681SAndroid Build Coastguard Worker %2 = or i32 %1, 6 ; 0x00000006 425*9880d681SAndroid Build Coastguard Worker ret i32 %2 426*9880d681SAndroid Build Coastguard Worker} 427*9880d681SAndroid Build Coastguard Worker 428*9880d681SAndroid Build Coastguard Worker; BFXIL will use the same constant as the ORR, so we don't care how the constant 429*9880d681SAndroid Build Coastguard Worker; is materialized (it's an equal cost either way). 430*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6 431*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:w[0-9]+]], #720896 432*9880d681SAndroid Build Coastguard Worker; CHECK: movk [[REG]], #23250 433*9880d681SAndroid Build Coastguard Worker; CHECK: bfxil w0, [[REG]], #0, #20 434*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i32 %a) { 435*9880d681SAndroid Build Coastguard Worker %1 = and i32 %a, 4293918720 ; 0xfff00000 436*9880d681SAndroid Build Coastguard Worker %2 = or i32 %1, 744146 ; 0x000b5ad2 437*9880d681SAndroid Build Coastguard Worker ret i32 %2 438*9880d681SAndroid Build Coastguard Worker} 439*9880d681SAndroid Build Coastguard Worker 440*9880d681SAndroid Build Coastguard Worker; BFIs that require the same number of instruction to materialize the constant 441*9880d681SAndroid Build Coastguard Worker; as the original ORR are okay. 442*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7 443*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG:w[0-9]+]], #327680 444*9880d681SAndroid Build Coastguard Worker; CHECK: movk [[REG]], #44393 445*9880d681SAndroid Build Coastguard Worker; CHECK: bfi w0, [[REG]], #1, #19 446*9880d681SAndroid Build Coastguard Workerdefine i32 @test7(i32 %a) { 447*9880d681SAndroid Build Coastguard Worker %1 = and i32 %a, 4293918721 ; 0xfff00001 448*9880d681SAndroid Build Coastguard Worker %2 = or i32 %1, 744146 ; 0x000b5ad2 449*9880d681SAndroid Build Coastguard Worker ret i32 %2 450*9880d681SAndroid Build Coastguard Worker} 451*9880d681SAndroid Build Coastguard Worker 452*9880d681SAndroid Build Coastguard Worker; BFIs that require more instructions to materialize the constant as compared 453*9880d681SAndroid Build Coastguard Worker; to the original ORR are not okay. In this case we would be replacing the 454*9880d681SAndroid Build Coastguard Worker; 'and' with a 'movk', which would decrease ILP while using the same number of 455*9880d681SAndroid Build Coastguard Worker; instructions. 456*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8 457*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[REG2:x[0-9]+]], #157599529959424 458*9880d681SAndroid Build Coastguard Worker; CHECK: and [[REG1:x[0-9]+]], x0, #0xff000000000000ff 459*9880d681SAndroid Build Coastguard Worker; CHECK: movk [[REG2]], #31059, lsl #16 460*9880d681SAndroid Build Coastguard Worker; CHECK: orr x0, [[REG1]], [[REG2]] 461*9880d681SAndroid Build Coastguard Workerdefine i64 @test8(i64 %a) { 462*9880d681SAndroid Build Coastguard Worker %1 = and i64 %a, -72057594037927681 ; 0xff000000000000ff 463*9880d681SAndroid Build Coastguard Worker %2 = or i64 %1, 157601565442048 ; 0x00008f5679530000 464*9880d681SAndroid Build Coastguard Worker ret i64 %2 465*9880d681SAndroid Build Coastguard Worker} 466*9880d681SAndroid Build Coastguard Worker 467*9880d681SAndroid Build Coastguard Worker; This test exposed an issue with an overly aggressive assert. The bit of code 468*9880d681SAndroid Build Coastguard Worker; that is expected to catch this case is unable to deal with the trunc, which 469*9880d681SAndroid Build Coastguard Worker; results in a failing check due to a mismatch between the BFI opcode and 470*9880d681SAndroid Build Coastguard Worker; the expected value type of the OR. 471*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9 472*9880d681SAndroid Build Coastguard Worker; CHECK: lsr x0, x0, #12 473*9880d681SAndroid Build Coastguard Worker; CHECK: lsr [[REG:w[0-9]+]], w1, #23 474*9880d681SAndroid Build Coastguard Worker; CHECK: bfi w0, [[REG]], #23, #9 475*9880d681SAndroid Build Coastguard Workerdefine i32 @test9(i64 %b, i32 %e) { 476*9880d681SAndroid Build Coastguard Worker %c = lshr i64 %b, 12 477*9880d681SAndroid Build Coastguard Worker %d = trunc i64 %c to i32 478*9880d681SAndroid Build Coastguard Worker %f = and i32 %d, 8388607 479*9880d681SAndroid Build Coastguard Worker %g = and i32 %e, -8388608 480*9880d681SAndroid Build Coastguard Worker %h = or i32 %g, %f 481*9880d681SAndroid Build Coastguard Worker ret i32 %h 482*9880d681SAndroid Build Coastguard Worker} 483