brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.4 KiB · c838c08 Raw
1085 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes="require<profile-summary>,function(codegenprepare)" -mtriple=arm64-apple=ios -S -o - %s | FileCheck --check-prefix=OPT %s3; RUN: llc < %s -mtriple=arm64-eabi | FileCheck --check-prefix=LLC %s4 5%struct.X = type { i8, i8, [2 x i8] }6%struct.Y = type { i32, i8 }7%struct.Z = type { i8, i8, [2 x i8], i16 }8%struct.A = type { i64, i8 }9 10define void @foo(ptr nocapture %x, ptr nocapture %y) nounwind optsize ssp {11; LLC-LABEL: foo:12; LLC:       // %bb.0:13; LLC-NEXT:    ldr w8, [x0]14; LLC-NEXT:    ubfx w8, w8, #3, #115; LLC-NEXT:    strb w8, [x1, #4]16; LLC-NEXT:    ret17; OPT-LABEL: @foo(18; OPT-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X:%.*]], align 419; OPT-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_Y:%.*]], ptr [[Y:%.*]], i64 0, i32 120; OPT-NEXT:    [[BF_CLEAR:%.*]] = lshr i32 [[TMP1]], 321; OPT-NEXT:    [[BF_CLEAR_LOBIT:%.*]] = and i32 [[BF_CLEAR]], 122; OPT-NEXT:    [[FROMBOOL:%.*]] = trunc i32 [[BF_CLEAR_LOBIT]] to i823; OPT-NEXT:    store i8 [[FROMBOOL]], ptr [[B]], align 124; OPT-NEXT:    ret void25;26  %tmp1 = load i32, ptr %x, align 427  %b = getelementptr inbounds %struct.Y, ptr %y, i64 0, i32 128  %bf.clear = lshr i32 %tmp1, 329  %bf.clear.lobit = and i32 %bf.clear, 130  %frombool = trunc i32 %bf.clear.lobit to i831  store i8 %frombool, ptr %b, align 132  ret void33}34 35define i32 @baz(i64 %cav1.coerce) nounwind {36; LLC-LABEL: baz:37; LLC:       // %bb.0:38; LLC-NEXT:    sbfx w0, w0, #0, #439; LLC-NEXT:    ret40; OPT-LABEL: @baz(41; OPT-NEXT:    [[TMP:%.*]] = trunc i64 [[CAV1_COERCE:%.*]] to i3242; OPT-NEXT:    [[TMP1:%.*]] = shl i32 [[TMP]], 2843; OPT-NEXT:    [[BF_VAL_SEXT:%.*]] = ashr exact i32 [[TMP1]], 2844; OPT-NEXT:    ret i32 [[BF_VAL_SEXT]]45;46  %tmp = trunc i64 %cav1.coerce to i3247  %tmp1 = shl i32 %tmp, 2848  %bf.val.sext = ashr exact i32 %tmp1, 2849  ret i32 %bf.val.sext50}51 52define i32 @bar(i64 %cav1.coerce) nounwind {53; LLC-LABEL: bar:54; LLC:       // %bb.0:55; LLC-NEXT:    sbfx w0, w0, #4, #656; LLC-NEXT:    ret57; OPT-LABEL: @bar(58; OPT-NEXT:    [[TMP:%.*]] = trunc i64 [[CAV1_COERCE:%.*]] to i3259; OPT-NEXT:    [[CAV1_SROA_0_1_INSERT:%.*]] = shl i32 [[TMP]], 2260; OPT-NEXT:    [[TMP1:%.*]] = ashr i32 [[CAV1_SROA_0_1_INSERT]], 2661; OPT-NEXT:    ret i32 [[TMP1]]62;63  %tmp = trunc i64 %cav1.coerce to i3264  %cav1.sroa.0.1.insert = shl i32 %tmp, 2265  %tmp1 = ashr i32 %cav1.sroa.0.1.insert, 2666  ret i32 %tmp167}68 69define void @fct1(ptr nocapture %x, ptr nocapture %y) nounwind optsize ssp {70; LLC-LABEL: fct1:71; LLC:       // %bb.0:72; LLC-NEXT:    ldr x8, [x0]73; LLC-NEXT:    ubfx x8, x8, #3, #174; LLC-NEXT:    str x8, [x1]75; LLC-NEXT:    ret76; OPT-LABEL: @fct1(77; OPT-NEXT:    [[TMP1:%.*]] = load i64, ptr [[X:%.*]], align 478; OPT-NEXT:    [[BF_CLEAR:%.*]] = lshr i64 [[TMP1]], 379; OPT-NEXT:    [[BF_CLEAR_LOBIT:%.*]] = and i64 [[BF_CLEAR]], 180; OPT-NEXT:    store i64 [[BF_CLEAR_LOBIT]], ptr [[Y:%.*]], align 881; OPT-NEXT:    ret void82;83  %tmp1 = load i64, ptr %x, align 484  %bf.clear = lshr i64 %tmp1, 385  %bf.clear.lobit = and i64 %bf.clear, 186  store i64 %bf.clear.lobit, ptr %y, align 887  ret void88}89 90define i64 @fct2(i64 %cav1.coerce) nounwind {91; LLC-LABEL: fct2:92; LLC:       // %bb.0:93; LLC-NEXT:    sbfx x0, x0, #0, #3694; LLC-NEXT:    ret95; OPT-LABEL: @fct2(96; OPT-NEXT:    [[TMP:%.*]] = shl i64 [[CAV1_COERCE:%.*]], 2897; OPT-NEXT:    [[BF_VAL_SEXT:%.*]] = ashr exact i64 [[TMP]], 2898; OPT-NEXT:    ret i64 [[BF_VAL_SEXT]]99;100  %tmp = shl i64 %cav1.coerce, 28101  %bf.val.sext = ashr exact i64 %tmp, 28102  ret i64 %bf.val.sext103}104 105define i64 @fct3(i64 %cav1.coerce) nounwind {106; LLC-LABEL: fct3:107; LLC:       // %bb.0:108; LLC-NEXT:    sbfx x0, x0, #4, #38109; LLC-NEXT:    ret110; OPT-LABEL: @fct3(111; OPT-NEXT:    [[CAV1_SROA_0_1_INSERT:%.*]] = shl i64 [[CAV1_COERCE:%.*]], 22112; OPT-NEXT:    [[TMP1:%.*]] = ashr i64 [[CAV1_SROA_0_1_INSERT]], 26113; OPT-NEXT:    ret i64 [[TMP1]]114;115  %cav1.sroa.0.1.insert = shl i64 %cav1.coerce, 22116  %tmp1 = ashr i64 %cav1.sroa.0.1.insert, 26117  ret i64 %tmp1118}119 120define void @fct4(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {121; LLC-LABEL: fct4:122; LLC:       // %bb.0: // %entry123; LLC-NEXT:    ldr x8, [x0]124; LLC-NEXT:    bfxil x8, x1, #16, #24125; LLC-NEXT:    str x8, [x0]126; LLC-NEXT:    ret127; OPT-LABEL: @fct4(128; OPT-NEXT:  entry:129; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8130; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -16777216131; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16132; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 16777215133; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]134; OPT-NEXT:    store i64 [[OR]], ptr [[Y]], align 8135; OPT-NEXT:    ret void136;137entry:138  %0 = load i64, ptr %y, align 8139  %and = and i64 %0, -16777216140  %shr = lshr i64 %x, 16141  %and1 = and i64 %shr, 16777215142  %or = or i64 %and, %and1143  store i64 %or, ptr %y, align 8144  ret void145}146 147define void @fct5(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {148; LLC-LABEL: fct5:149; LLC:       // %bb.0: // %entry150; LLC-NEXT:    ldr w8, [x0]151; LLC-NEXT:    bfxil w8, w1, #16, #3152; LLC-NEXT:    str w8, [x0]153; LLC-NEXT:    ret154; OPT-LABEL: @fct5(155; OPT-NEXT:  entry:156; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8157; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8158; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16159; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7160; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]161; OPT-NEXT:    store i32 [[OR]], ptr [[Y]], align 8162; OPT-NEXT:    ret void163;164entry:165  %0 = load i32, ptr %y, align 8166  %and = and i32 %0, -8167  %shr = lshr i32 %x, 16168  %and1 = and i32 %shr, 7169  %or = or i32 %and, %and1170  store i32 %or, ptr %y, align 8171  ret void172}173 174; Check if we can still catch bfm instruction when we drop some low bits175define void @fct6(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {176; LLC-LABEL: fct6:177; LLC:       // %bb.0: // %entry178; LLC-NEXT:    ldr w8, [x0]179; LLC-NEXT:    bfxil w8, w1, #16, #3180; LLC-NEXT:    lsr w8, w8, #2181; LLC-NEXT:    str w8, [x0]182; LLC-NEXT:    ret183; OPT-LABEL: @fct6(184; OPT-NEXT:  entry:185; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8186; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8187; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16188; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7189; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]190; OPT-NEXT:    [[SHR1:%.*]] = lshr i32 [[OR]], 2191; OPT-NEXT:    store i32 [[SHR1]], ptr [[Y]], align 8192; OPT-NEXT:    ret void193;194entry:195; lsr is an alias of ubfm196  %0 = load i32, ptr %y, align 8197  %and = and i32 %0, -8198  %shr = lshr i32 %x, 16199  %and1 = and i32 %shr, 7200  %or = or i32 %and, %and1201  %shr1 = lshr i32 %or, 2202  store i32 %shr1, ptr %y, align 8203  ret void204}205 206 207; Check if we can still catch bfm instruction when we drop some high bits208define void @fct7(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {209; LLC-LABEL: fct7:210; LLC:       // %bb.0: // %entry211; LLC-NEXT:    ldr w8, [x0]212; LLC-NEXT:    bfxil w8, w1, #16, #3213; LLC-NEXT:    lsl w8, w8, #2214; LLC-NEXT:    str w8, [x0]215; LLC-NEXT:    ret216; OPT-LABEL: @fct7(217; OPT-NEXT:  entry:218; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8219; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8220; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16221; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7222; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]223; OPT-NEXT:    [[SHL:%.*]] = shl i32 [[OR]], 2224; OPT-NEXT:    store i32 [[SHL]], ptr [[Y]], align 8225; OPT-NEXT:    ret void226;227entry:228; lsl is an alias of ubfm229  %0 = load i32, ptr %y, align 8230  %and = and i32 %0, -8231  %shr = lshr i32 %x, 16232  %and1 = and i32 %shr, 7233  %or = or i32 %and, %and1234  %shl = shl i32 %or, 2235  store i32 %shl, ptr %y, align 8236  ret void237}238 239 240; Check if we can still catch bfm instruction when we drop some low bits241; (i64 version)242define void @fct8(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {243; LLC-LABEL: fct8:244; LLC:       // %bb.0: // %entry245; LLC-NEXT:    ldr x8, [x0]246; LLC-NEXT:    bfxil x8, x1, #16, #3247; LLC-NEXT:    lsr x8, x8, #2248; LLC-NEXT:    str x8, [x0]249; LLC-NEXT:    ret250; OPT-LABEL: @fct8(251; OPT-NEXT:  entry:252; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8253; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -8254; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16255; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7256; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]257; OPT-NEXT:    [[SHR1:%.*]] = lshr i64 [[OR]], 2258; OPT-NEXT:    store i64 [[SHR1]], ptr [[Y]], align 8259; OPT-NEXT:    ret void260;261entry:262; lsr is an alias of ubfm263  %0 = load i64, ptr %y, align 8264  %and = and i64 %0, -8265  %shr = lshr i64 %x, 16266  %and1 = and i64 %shr, 7267  %or = or i64 %and, %and1268  %shr1 = lshr i64 %or, 2269  store i64 %shr1, ptr %y, align 8270  ret void271}272 273 274; Check if we can still catch bfm instruction when we drop some high bits275; (i64 version)276define void @fct9(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {277; LLC-LABEL: fct9:278; LLC:       // %bb.0: // %entry279; LLC-NEXT:    ldr x8, [x0]280; LLC-NEXT:    bfxil x8, x1, #16, #3281; LLC-NEXT:    lsl x8, x8, #2282; LLC-NEXT:    str x8, [x0]283; LLC-NEXT:    ret284; OPT-LABEL: @fct9(285; OPT-NEXT:  entry:286; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8287; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -8288; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16289; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7290; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]291; OPT-NEXT:    [[SHL:%.*]] = shl i64 [[OR]], 2292; OPT-NEXT:    store i64 [[SHL]], ptr [[Y]], align 8293; OPT-NEXT:    ret void294;295entry:296; lsr is an alias of ubfm297  %0 = load i64, ptr %y, align 8298  %and = and i64 %0, -8299  %shr = lshr i64 %x, 16300  %and1 = and i64 %shr, 7301  %or = or i64 %and, %and1302  %shl = shl i64 %or, 2303  store i64 %shl, ptr %y, align 8304  ret void305}306 307; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)308; (i32 version)309define void @fct10(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {310; LLC-LABEL: fct10:311; LLC:       // %bb.0: // %entry312; LLC-NEXT:    ldr w8, [x0]313; LLC-NEXT:    bfxil w8, w1, #0, #3314; LLC-NEXT:    lsl w8, w8, #2315; LLC-NEXT:    str w8, [x0]316; LLC-NEXT:    ret317; OPT-LABEL: @fct10(318; OPT-NEXT:  entry:319; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8320; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8321; OPT-NEXT:    [[AND1:%.*]] = and i32 [[X:%.*]], 7322; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]323; OPT-NEXT:    [[SHL:%.*]] = shl i32 [[OR]], 2324; OPT-NEXT:    store i32 [[SHL]], ptr [[Y]], align 8325; OPT-NEXT:    ret void326;327entry:328; lsl is an alias of ubfm329  %0 = load i32, ptr %y, align 8330  %and = and i32 %0, -8331  %and1 = and i32 %x, 7332  %or = or i32 %and, %and1333  %shl = shl i32 %or, 2334  store i32 %shl, ptr %y, align 8335  ret void336}337 338; Check if we can catch bfm instruction when lsb is 0 (i.e., no lshr)339; (i64 version)340define void @fct11(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {341; LLC-LABEL: fct11:342; LLC:       // %bb.0: // %entry343; LLC-NEXT:    ldr x8, [x0]344; LLC-NEXT:    bfxil x8, x1, #0, #3345; LLC-NEXT:    lsl x8, x8, #2346; LLC-NEXT:    str x8, [x0]347; LLC-NEXT:    ret348; OPT-LABEL: @fct11(349; OPT-NEXT:  entry:350; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8351; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -8352; OPT-NEXT:    [[AND1:%.*]] = and i64 [[X:%.*]], 7353; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]354; OPT-NEXT:    [[SHL:%.*]] = shl i64 [[OR]], 2355; OPT-NEXT:    store i64 [[SHL]], ptr [[Y]], align 8356; OPT-NEXT:    ret void357;358entry:359; lsl is an alias of ubfm360  %0 = load i64, ptr %y, align 8361  %and = and i64 %0, -8362  %and1 = and i64 %x, 7363  %or = or i64 %and, %and1364  %shl = shl i64 %or, 2365  store i64 %shl, ptr %y, align 8366  ret void367}368 369define zeroext i1 @fct12bis(i32 %tmp2) unnamed_addr nounwind ssp align 2 {370; LLC-LABEL: fct12bis:371; LLC:       // %bb.0:372; LLC-NEXT:    ubfx w0, w0, #11, #1373; LLC-NEXT:    ret374; OPT-LABEL: @fct12bis(375; OPT-NEXT:    [[AND_I_I:%.*]] = and i32 [[TMP2:%.*]], 2048376; OPT-NEXT:    [[TOBOOL_I_I:%.*]] = icmp ne i32 [[AND_I_I]], 0377; OPT-NEXT:    ret i1 [[TOBOOL_I_I]]378;379  %and.i.i = and i32 %tmp2, 2048380  %tobool.i.i = icmp ne i32 %and.i.i, 0381  ret i1 %tobool.i.i382}383 384; Check if we can still catch bfm instruction when we drop some high bits385; and some low bits386define void @fct12(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {387; LLC-LABEL: fct12:388; LLC:       // %bb.0: // %entry389; LLC-NEXT:    ldr w8, [x0]390; LLC-NEXT:    bfxil w8, w1, #16, #3391; LLC-NEXT:    ubfx w8, w8, #2, #28392; LLC-NEXT:    str w8, [x0]393; LLC-NEXT:    ret394; OPT-LABEL: @fct12(395; OPT-NEXT:  entry:396; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8397; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8398; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16399; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7400; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]401; OPT-NEXT:    [[SHL:%.*]] = shl i32 [[OR]], 2402; OPT-NEXT:    [[SHR2:%.*]] = lshr i32 [[SHL]], 4403; OPT-NEXT:    store i32 [[SHR2]], ptr [[Y]], align 8404; OPT-NEXT:    ret void405;406entry:407; lsr is an alias of ubfm408  %0 = load i32, ptr %y, align 8409  %and = and i32 %0, -8410  %shr = lshr i32 %x, 16411  %and1 = and i32 %shr, 7412  %or = or i32 %and, %and1413  %shl = shl i32 %or, 2414  %shr2 = lshr i32 %shl, 4415  store i32 %shr2, ptr %y, align 8416  ret void417}418define void @fct12_mask(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {419; LLC-LABEL: fct12_mask:420; LLC:       // %bb.0: // %entry421; LLC-NEXT:    ldr w8, [x0]422; LLC-NEXT:    and w8, w8, #0x3ffffff8423; LLC-NEXT:    bfxil w8, w1, #16, #3424; LLC-NEXT:    lsr w8, w8, #2425; LLC-NEXT:    str w8, [x0]426; LLC-NEXT:    ret427; OPT-LABEL: @fct12_mask(428; OPT-NEXT:  entry:429; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8430; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -8431; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16432; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7433; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]434; OPT-NEXT:    [[LSHR:%.*]] = lshr i32 [[OR]], 2435; OPT-NEXT:    [[MASK:%.*]] = and i32 [[LSHR]], 268435455436; OPT-NEXT:    store i32 [[MASK]], ptr [[Y]], align 8437; OPT-NEXT:    ret void438;439entry:440; lsr is an alias of ubfm441  %0 = load i32, ptr %y, align 8442  %and = and i32 %0, -8443  %shr = lshr i32 %x, 16444  %and1 = and i32 %shr, 7445  %or = or i32 %and, %and1446  %lshr = lshr i32 %or, 2447  %mask = and i32 %lshr, 268435455448  store i32 %mask, ptr %y, align 8449  ret void450}451 452; Check if we can still catch bfm instruction when we drop some high bits453; and some low bits454; (i64 version)455define void @fct13(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {456; LLC-LABEL: fct13:457; LLC:       // %bb.0: // %entry458; LLC-NEXT:    ldr x8, [x0]459; LLC-NEXT:    bfxil x8, x1, #16, #3460; LLC-NEXT:    ubfx x8, x8, #2, #60461; LLC-NEXT:    str x8, [x0]462; LLC-NEXT:    ret463; OPT-LABEL: @fct13(464; OPT-NEXT:  entry:465; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8466; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -8467; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16468; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7469; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]470; OPT-NEXT:    [[SHL:%.*]] = shl i64 [[OR]], 2471; OPT-NEXT:    [[SHR2:%.*]] = lshr i64 [[SHL]], 4472; OPT-NEXT:    store i64 [[SHR2]], ptr [[Y]], align 8473; OPT-NEXT:    ret void474;475entry:476; lsr is an alias of ubfm477  %0 = load i64, ptr %y, align 8478  %and = and i64 %0, -8479  %shr = lshr i64 %x, 16480  %and1 = and i64 %shr, 7481  %or = or i64 %and, %and1482  %shl = shl i64 %or, 2483  %shr2 = lshr i64 %shl, 4484  store i64 %shr2, ptr %y, align 8485  ret void486}487define void @fct13_mask(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {488; LLC-LABEL: fct13_mask:489; LLC:       // %bb.0: // %entry490; LLC-NEXT:    ldr x8, [x0]491; LLC-NEXT:    and x8, x8, #0x3ffffffffffffff8492; LLC-NEXT:    bfxil x8, x1, #16, #3493; LLC-NEXT:    lsr x8, x8, #2494; LLC-NEXT:    str x8, [x0]495; LLC-NEXT:    ret496; OPT-LABEL: @fct13_mask(497; OPT-NEXT:  entry:498; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8499; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -8500; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16501; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7502; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]503; OPT-NEXT:    [[LSHR:%.*]] = lshr i64 [[OR]], 2504; OPT-NEXT:    [[MASK:%.*]] = and i64 [[LSHR]], 1152921504606846975505; OPT-NEXT:    store i64 [[MASK]], ptr [[Y]], align 8506; OPT-NEXT:    ret void507;508entry:509; lsr is an alias of ubfm510  %0 = load i64, ptr %y, align 8511  %and = and i64 %0, -8512  %shr = lshr i64 %x, 16513  %and1 = and i64 %shr, 7514  %or = or i64 %and, %and1515  %lshr = lshr i64 %or, 2516  %mask = and i64 %lshr, 1152921504606846975517  store i64 %mask, ptr %y, align 8518  ret void519}520 521 522; Check if we can still catch bfm instruction when we drop some high bits523; and some low bits524define void @fct14(ptr nocapture %y, i32 %x, i32 %x1) nounwind optsize inlinehint ssp {525; LLC-LABEL: fct14:526; LLC:       // %bb.0: // %entry527; LLC-NEXT:    ldr w8, [x0]528; LLC-NEXT:    bfxil w8, w1, #16, #8529; LLC-NEXT:    lsr w8, w8, #4530; LLC-NEXT:    bfxil w8, w2, #5, #3531; LLC-NEXT:    lsl w8, w8, #2532; LLC-NEXT:    str w8, [x0]533; LLC-NEXT:    ret534; OPT-LABEL: @fct14(535; OPT-NEXT:  entry:536; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8537; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], -256538; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16539; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 255540; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]541; OPT-NEXT:    [[SHL:%.*]] = lshr i32 [[OR]], 4542; OPT-NEXT:    [[AND2:%.*]] = and i32 [[SHL]], -8543; OPT-NEXT:    [[SHR1:%.*]] = lshr i32 [[X1:%.*]], 5544; OPT-NEXT:    [[AND3:%.*]] = and i32 [[SHR1]], 7545; OPT-NEXT:    [[OR1:%.*]] = or i32 [[AND2]], [[AND3]]546; OPT-NEXT:    [[SHL1:%.*]] = shl i32 [[OR1]], 2547; OPT-NEXT:    store i32 [[SHL1]], ptr [[Y]], align 8548; OPT-NEXT:    ret void549;550entry:551; lsr is an alias of ubfm552; lsl is an alias of ubfm553  %0 = load i32, ptr %y, align 8554  %and = and i32 %0, -256555  %shr = lshr i32 %x, 16556  %and1 = and i32 %shr, 255557  %or = or i32 %and, %and1558  %shl = lshr i32 %or, 4559  %and2 = and i32 %shl, -8560  %shr1 = lshr i32 %x1, 5561  %and3 = and i32 %shr1, 7562  %or1 = or i32 %and2, %and3563  %shl1 = shl i32 %or1, 2564  store i32 %shl1, ptr %y, align 8565  ret void566}567 568; Check if we can still catch bfm instruction when we drop some high bits569; and some low bits570; (i64 version)571define void @fct15(ptr nocapture %y, i64 %x, i64 %x1) nounwind optsize inlinehint ssp {572; LLC-LABEL: fct15:573; LLC:       // %bb.0: // %entry574; LLC-NEXT:    ldr x8, [x0]575; LLC-NEXT:    bfxil x8, x1, #16, #8576; LLC-NEXT:    lsr x8, x8, #4577; LLC-NEXT:    bfxil x8, x2, #5, #3578; LLC-NEXT:    lsl x8, x8, #2579; LLC-NEXT:    str x8, [x0]580; LLC-NEXT:    ret581; OPT-LABEL: @fct15(582; OPT-NEXT:  entry:583; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8584; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], -256585; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16586; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 255587; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]588; OPT-NEXT:    [[SHL:%.*]] = lshr i64 [[OR]], 4589; OPT-NEXT:    [[AND2:%.*]] = and i64 [[SHL]], -8590; OPT-NEXT:    [[SHR1:%.*]] = lshr i64 [[X1:%.*]], 5591; OPT-NEXT:    [[AND3:%.*]] = and i64 [[SHR1]], 7592; OPT-NEXT:    [[OR1:%.*]] = or i64 [[AND2]], [[AND3]]593; OPT-NEXT:    [[SHL1:%.*]] = shl i64 [[OR1]], 2594; OPT-NEXT:    store i64 [[SHL1]], ptr [[Y]], align 8595; OPT-NEXT:    ret void596;597entry:598; lsr is an alias of ubfm599; lsl is an alias of ubfm600  %0 = load i64, ptr %y, align 8601  %and = and i64 %0, -256602  %shr = lshr i64 %x, 16603  %and1 = and i64 %shr, 255604  %or = or i64 %and, %and1605  %shl = lshr i64 %or, 4606  %and2 = and i64 %shl, -8607  %shr1 = lshr i64 %x1, 5608  %and3 = and i64 %shr1, 7609  %or1 = or i64 %and2, %and3610  %shl1 = shl i64 %or1, 2611  store i64 %shl1, ptr %y, align 8612  ret void613}614 615; Check if we can still catch bfm instruction when we drop some high bits616; and some low bits and a masking operation has to be kept617define void @fct16(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {618; LLC-LABEL: fct16:619; LLC:       // %bb.0: // %entry620; LLC-NEXT:    ldr w8, [x0]621; LLC-NEXT:    mov w9, #33120 // =0x8160622; LLC-NEXT:    movk w9, #26, lsl #16623; LLC-NEXT:    and w8, w8, w9624; LLC-NEXT:    bfxil w8, w1, #16, #3625; LLC-NEXT:    ubfx w8, w8, #2, #28626; LLC-NEXT:    str w8, [x0]627; LLC-NEXT:    ret628; OPT-LABEL: @fct16(629; OPT-NEXT:  entry:630; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8631; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], 1737056632; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16633; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7634; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]635; OPT-NEXT:    [[SHL:%.*]] = shl i32 [[OR]], 2636; OPT-NEXT:    [[SHR2:%.*]] = lshr i32 [[SHL]], 4637; OPT-NEXT:    store i32 [[SHR2]], ptr [[Y]], align 8638; OPT-NEXT:    ret void639;640entry:641; Create the constant642; Do the masking643; lsr is an alias of ubfm644  %0 = load i32, ptr %y, align 8645  %and = and i32 %0, 1737056646  %shr = lshr i32 %x, 16647  %and1 = and i32 %shr, 7648  %or = or i32 %and, %and1649  %shl = shl i32 %or, 2650  %shr2 = lshr i32 %shl, 4651  store i32 %shr2, ptr %y, align 8652  ret void653}654define void @fct16_mask(ptr nocapture %y, i32 %x) nounwind optsize inlinehint ssp {655; LLC-LABEL: fct16_mask:656; LLC:       // %bb.0: // %entry657; LLC-NEXT:    ldr w8, [x0]658; LLC-NEXT:    mov w9, #33120 // =0x8160659; LLC-NEXT:    movk w9, #26, lsl #16660; LLC-NEXT:    and w8, w8, w9661; LLC-NEXT:    bfxil w8, w1, #16, #3662; LLC-NEXT:    lsr w8, w8, #2663; LLC-NEXT:    str w8, [x0]664; LLC-NEXT:    ret665; OPT-LABEL: @fct16_mask(666; OPT-NEXT:  entry:667; OPT-NEXT:    [[TMP0:%.*]] = load i32, ptr [[Y:%.*]], align 8668; OPT-NEXT:    [[AND:%.*]] = and i32 [[TMP0]], 1737056669; OPT-NEXT:    [[SHR:%.*]] = lshr i32 [[X:%.*]], 16670; OPT-NEXT:    [[AND1:%.*]] = and i32 [[SHR]], 7671; OPT-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[AND1]]672; OPT-NEXT:    [[LSHR:%.*]] = lshr i32 [[OR]], 2673; OPT-NEXT:    [[MASK:%.*]] = and i32 [[LSHR]], 268435455674; OPT-NEXT:    store i32 [[MASK]], ptr [[Y]], align 8675; OPT-NEXT:    ret void676;677entry:678; Create the constant679; Do the masking680; lsr is an alias of ubfm681  %0 = load i32, ptr %y, align 8682  %and = and i32 %0, 1737056683  %shr = lshr i32 %x, 16684  %and1 = and i32 %shr, 7685  %or = or i32 %and, %and1686  %lshr = lshr i32 %or, 2687  %mask = and i32 %lshr, 268435455688  store i32 %mask, ptr %y, align 8689  ret void690}691 692 693; Check if we can still catch bfm instruction when we drop some high bits694; and some low bits and a masking operation has to be kept695; (i64 version)696define void @fct17(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {697; LLC-LABEL: fct17:698; LLC:       // %bb.0: // %entry699; LLC-NEXT:    ldr x8, [x0]700; LLC-NEXT:    mov w9, #33120 // =0x8160701; LLC-NEXT:    movk w9, #26, lsl #16702; LLC-NEXT:    and x8, x8, x9703; LLC-NEXT:    bfxil x8, x1, #16, #3704; LLC-NEXT:    ubfx x8, x8, #2, #60705; LLC-NEXT:    str x8, [x0]706; LLC-NEXT:    ret707; OPT-LABEL: @fct17(708; OPT-NEXT:  entry:709; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8710; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], 1737056711; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16712; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7713; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]714; OPT-NEXT:    [[SHL:%.*]] = shl i64 [[OR]], 2715; OPT-NEXT:    [[SHR2:%.*]] = lshr i64 [[SHL]], 4716; OPT-NEXT:    store i64 [[SHR2]], ptr [[Y]], align 8717; OPT-NEXT:    ret void718;719entry:720; Create the constant721; Do the masking722; lsr is an alias of ubfm723  %0 = load i64, ptr %y, align 8724  %and = and i64 %0, 1737056725  %shr = lshr i64 %x, 16726  %and1 = and i64 %shr, 7727  %or = or i64 %and, %and1728  %shl = shl i64 %or, 2729  %shr2 = lshr i64 %shl, 4730  store i64 %shr2, ptr %y, align 8731  ret void732}733define void @fct17_mask(ptr nocapture %y, i64 %x) nounwind optsize inlinehint ssp {734; LLC-LABEL: fct17_mask:735; LLC:       // %bb.0: // %entry736; LLC-NEXT:    ldr x8, [x0]737; LLC-NEXT:    mov w9, #33120 // =0x8160738; LLC-NEXT:    movk w9, #26, lsl #16739; LLC-NEXT:    and x8, x8, x9740; LLC-NEXT:    bfxil x8, x1, #16, #3741; LLC-NEXT:    lsr x8, x8, #2742; LLC-NEXT:    str x8, [x0]743; LLC-NEXT:    ret744; OPT-LABEL: @fct17_mask(745; OPT-NEXT:  entry:746; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[Y:%.*]], align 8747; OPT-NEXT:    [[AND:%.*]] = and i64 [[TMP0]], 1737056748; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 16749; OPT-NEXT:    [[AND1:%.*]] = and i64 [[SHR]], 7750; OPT-NEXT:    [[OR:%.*]] = or i64 [[AND]], [[AND1]]751; OPT-NEXT:    [[LSHR:%.*]] = lshr i64 [[OR]], 2752; OPT-NEXT:    [[MASK:%.*]] = and i64 [[LSHR]], 1152921504606846975753; OPT-NEXT:    store i64 [[MASK]], ptr [[Y]], align 8754; OPT-NEXT:    ret void755;756entry:757; Create the constant758; Do the masking759; lsr is an alias of ubfm760  %0 = load i64, ptr %y, align 8761  %and = and i64 %0, 1737056762  %shr = lshr i64 %x, 16763  %and1 = and i64 %shr, 7764  %or = or i64 %and, %and1765  %lshr = lshr i64 %or, 2766  %mask = and i64 %lshr, 1152921504606846975767  store i64 %mask, ptr %y, align 8768  ret void769}770 771define i64 @fct18(i32 %xor72) nounwind ssp {772; LLC-LABEL: fct18:773; LLC:       // %bb.0:774; LLC-NEXT:    // kill: def $w0 killed $w0 def $x0775; LLC-NEXT:    ubfx x0, x0, #9, #8776; LLC-NEXT:    ret777; OPT-LABEL: @fct18(778; OPT-NEXT:    [[SHR81:%.*]] = lshr i32 [[XOR72:%.*]], 9779; OPT-NEXT:    [[CONV82:%.*]] = zext i32 [[SHR81]] to i64780; OPT-NEXT:    [[RESULT:%.*]] = and i64 [[CONV82]], 255781; OPT-NEXT:    ret i64 [[RESULT]]782;783  %shr81 = lshr i32 %xor72, 9784  %conv82 = zext i32 %shr81 to i64785  %result = and i64 %conv82, 255786  ret i64 %result787}788 789; Using the access to the global array to keep the instruction and control flow.790@first_ones = external dso_local global [65536 x i8]791 792; Function Attrs: nounwind readonly ssp793define i32 @fct19(i64 %arg1) nounwind readonly ssp  {794; LLC-LABEL: fct19:795; LLC:       // %bb.0: // %entry796; LLC-NEXT:    lsr x8, x0, #48797; LLC-NEXT:    cbz x8, .LBB26_2798; LLC-NEXT:  // %bb.1: // %if.then799; LLC-NEXT:    adrp x9, first_ones800; LLC-NEXT:    add x9, x9, :lo12:first_ones801; LLC-NEXT:    ldrb w0, [x9, x8]802; LLC-NEXT:    ret803; LLC-NEXT:  .LBB26_2: // %if.end804; LLC-NEXT:    ubfx x8, x0, #32, #16805; LLC-NEXT:    cbz w8, .LBB26_4806; LLC-NEXT:  // %bb.3: // %if.then7807; LLC-NEXT:    adrp x9, first_ones808; LLC-NEXT:    add x9, x9, :lo12:first_ones809; LLC-NEXT:    ldrb w8, [x9, x8]810; LLC-NEXT:    add w0, w8, #16811; LLC-NEXT:    ret812; LLC-NEXT:  .LBB26_4: // %if.end13813; LLC-NEXT:    lsr w8, w0, #16814; LLC-NEXT:    cbz w8, .LBB26_6815; LLC-NEXT:  // %bb.5: // %if.then17816; LLC-NEXT:    adrp x9, first_ones817; LLC-NEXT:    add x9, x9, :lo12:first_ones818; LLC-NEXT:    ldrb w8, [x9, x8]819; LLC-NEXT:    add w0, w8, #32820; LLC-NEXT:    ret821; LLC-NEXT:  .LBB26_6:822; LLC-NEXT:    mov w0, #64 // =0x40823; LLC-NEXT:    ret824; OPT-LABEL: @fct19(825; OPT-NEXT:  entry:826; OPT-NEXT:    [[X_SROA_1_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[ARG1:%.*]], 16827; OPT-NEXT:    [[X_SROA_1_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[X_SROA_1_0_EXTRACT_SHIFT]] to i16828; OPT-NEXT:    [[X_SROA_5_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[ARG1]], 48829; OPT-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[X_SROA_5_0_EXTRACT_SHIFT]], 0830; OPT-NEXT:    br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]831; OPT:       if.then:832; OPT-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 [[X_SROA_5_0_EXTRACT_SHIFT]]833; OPT-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX3]], align 1834; OPT-NEXT:    [[CONV:%.*]] = zext i8 [[TMP0]] to i32835; OPT-NEXT:    br label [[RETURN:%.*]]836; OPT:       if.end:837; OPT-NEXT:    [[TMP1:%.*]] = lshr i64 [[ARG1]], 32838; OPT-NEXT:    [[X_SROA_3_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[TMP1]] to i16839; OPT-NEXT:    [[TOBOOL6:%.*]] = icmp eq i16 [[X_SROA_3_0_EXTRACT_TRUNC]], 0840; OPT-NEXT:    br i1 [[TOBOOL6]], label [[IF_END13:%.*]], label [[IF_THEN7:%.*]]841; OPT:       if.then7:842; OPT-NEXT:    [[TMP2:%.*]] = lshr i64 [[ARG1]], 32843; OPT-NEXT:    [[IDXPROM10:%.*]] = and i64 [[TMP2]], 65535844; OPT-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 [[IDXPROM10]]845; OPT-NEXT:    [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX11]], align 1846; OPT-NEXT:    [[CONV12:%.*]] = zext i8 [[TMP3]] to i32847; OPT-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV12]], 16848; OPT-NEXT:    br label [[RETURN]]849; OPT:       if.end13:850; OPT-NEXT:    [[TMP4:%.*]] = lshr i64 [[ARG1]], 16851; OPT-NEXT:    [[TMP5:%.*]] = trunc i64 [[TMP4]] to i16852; OPT-NEXT:    [[TOBOOL16:%.*]] = icmp eq i16 [[TMP5]], 0853; OPT-NEXT:    br i1 [[TOBOOL16]], label [[RETURN]], label [[IF_THEN17:%.*]]854; OPT:       if.then17:855; OPT-NEXT:    [[TMP6:%.*]] = lshr i64 [[ARG1]], 16856; OPT-NEXT:    [[IDXPROM20:%.*]] = and i64 [[TMP6]], 65535857; OPT-NEXT:    [[ARRAYIDX21:%.*]] = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 [[IDXPROM20]]858; OPT-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ARRAYIDX21]], align 1859; OPT-NEXT:    [[CONV22:%.*]] = zext i8 [[TMP7]] to i32860; OPT-NEXT:    [[ADD23:%.*]] = add nsw i32 [[CONV22]], 32861; OPT-NEXT:    br label [[RETURN]]862; OPT:       return:863; OPT-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], [[IF_THEN]] ], [ [[ADD]], [[IF_THEN7]] ], [ [[ADD23]], [[IF_THEN17]] ], [ 64, [[IF_END13]] ]864; OPT-NEXT:    ret i32 [[RETVAL_0]]865;866entry:867  %x.sroa.1.0.extract.shift = lshr i64 %arg1, 16868  %x.sroa.1.0.extract.trunc = trunc i64 %x.sroa.1.0.extract.shift to i16869  %x.sroa.3.0.extract.shift = lshr i64 %arg1, 32870  %x.sroa.5.0.extract.shift = lshr i64 %arg1, 48871  %tobool = icmp eq i64 %x.sroa.5.0.extract.shift, 0872  br i1 %tobool, label %if.end, label %if.then873 874if.then:                                          ; preds = %entry875  %arrayidx3 = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 %x.sroa.5.0.extract.shift876  %0 = load i8, ptr %arrayidx3, align 1877  %conv = zext i8 %0 to i32878  br label %return879 880if.end:                                           ; preds = %entry881  %x.sroa.3.0.extract.trunc = trunc i64 %x.sroa.3.0.extract.shift to i16882  %tobool6 = icmp eq i16 %x.sroa.3.0.extract.trunc, 0883  br i1 %tobool6, label %if.end13, label %if.then7884 885if.then7:                                         ; preds = %if.end886; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.887; So neither of them should be in the assemble code.888  %idxprom10 = and i64 %x.sroa.3.0.extract.shift, 65535889  %arrayidx11 = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 %idxprom10890  %1 = load i8, ptr %arrayidx11, align 1891  %conv12 = zext i8 %1 to i32892  %add = add nsw i32 %conv12, 16893  br label %return894 895if.end13:                                         ; preds = %if.end896  %tobool16 = icmp eq i16 %x.sroa.1.0.extract.trunc, 0897  br i1 %tobool16, label %return, label %if.then17898 899if.then17:                                        ; preds = %if.end13900; "and" should be combined to "ubfm" while "ubfm" should be removed by cse.901; So neither of them should be in the assemble code.902  %idxprom20 = and i64 %x.sroa.1.0.extract.shift, 65535903  %arrayidx21 = getelementptr inbounds [65536 x i8], ptr @first_ones, i64 0, i64 %idxprom20904  %2 = load i8, ptr %arrayidx21, align 1905  %conv22 = zext i8 %2 to i32906  %add23 = add nsw i32 %conv22, 32907  br label %return908 909return:                                           ; preds = %if.end13, %if.then17, %if.then7, %if.then910  %retval.0 = phi i32 [ %conv, %if.then ], [ %add, %if.then7 ], [ %add23, %if.then17 ], [ 64, %if.end13 ]911  ret i32 %retval.0912}913 914; Make sure we do not assert if the immediate in and is bigger than i64.915; PR19503.916define i80 @fct20(i128 %a, i128 %b) {917; LLC-LABEL: fct20:918; LLC:       // %bb.0: // %entry919; LLC-NEXT:    mov x12, #11776 // =0x2e00920; LLC-NEXT:    lsr x8, x1, #18921; LLC-NEXT:    extr x9, x1, x0, #18922; LLC-NEXT:    movk x12, #25856, lsl #16923; LLC-NEXT:    orr x10, x2, x3924; LLC-NEXT:    mov w11, #26220 // =0x666c925; LLC-NEXT:    movk x12, #11077, lsl #32926; LLC-NEXT:    and x11, x8, x11927; LLC-NEXT:    cmp x10, #0928; LLC-NEXT:    movk x12, #45, lsl #48929; LLC-NEXT:    csel x1, x11, x8, eq930; LLC-NEXT:    and x12, x9, x12931; LLC-NEXT:    csel x0, x12, x9, eq932; LLC-NEXT:    ret933; OPT-LABEL: @fct20(934; OPT-NEXT:  entry:935; OPT-NEXT:    [[SHR:%.*]] = lshr i128 [[A:%.*]], 18936; OPT-NEXT:    [[CONV:%.*]] = trunc i128 [[SHR]] to i80937; OPT-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[B:%.*]], 0938; OPT-NEXT:    br i1 [[TOBOOL]], label [[THEN:%.*]], label [[END:%.*]]939; OPT:       then:940; OPT-NEXT:    [[AND:%.*]] = and i128 [[SHR]], 483673642326615442599424941; OPT-NEXT:    [[CONV2:%.*]] = trunc i128 [[AND]] to i80942; OPT-NEXT:    br label [[END]]943; OPT:       end:944; OPT-NEXT:    [[CONV3:%.*]] = phi i80 [ [[CONV]], [[ENTRY:%.*]] ], [ [[CONV2]], [[THEN]] ]945; OPT-NEXT:    ret i80 [[CONV3]]946;947entry:948  %shr = lshr i128 %a, 18949  %conv = trunc i128 %shr to i80950  %tobool = icmp eq i128 %b, 0951  br i1 %tobool, label %then, label %end952then:953  %and = and i128 %shr, 483673642326615442599424954  %conv2 = trunc i128 %and to i80955  br label %end956end:957  %conv3 = phi i80 [%conv, %entry], [%conv2, %then]958  ret i80 %conv3959}960 961; Check if we can still catch UBFX when "AND" is used by SHL.962@arr = external dso_local global [8 x [64 x i64]]963define i64 @fct21(i64 %x) {964; LLC-LABEL: fct21:965; LLC:       // %bb.0: // %entry966; LLC-NEXT:    ubfx x8, x0, #4, #4967; LLC-NEXT:    adrp x9, arr968; LLC-NEXT:    add x9, x9, :lo12:arr969; LLC-NEXT:    ldr x0, [x9, x8, lsl #3]970; LLC-NEXT:    ret971; OPT-LABEL: @fct21(972; OPT-NEXT:  entry:973; OPT-NEXT:    [[SHR:%.*]] = lshr i64 [[X:%.*]], 4974; OPT-NEXT:    [[AND:%.*]] = and i64 [[SHR]], 15975; OPT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x [64 x i64]], ptr @arr, i64 0, i64 0, i64 [[AND]]976; OPT-NEXT:    [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8977; OPT-NEXT:    ret i64 [[TMP0]]978;979entry:980  %shr = lshr i64 %x, 4981  %and = and i64 %shr, 15982  %arrayidx = getelementptr inbounds [8 x [64 x i64]], ptr @arr, i64 0, i64 0, i64 %and983  %0 = load i64, ptr %arrayidx, align 8984  ret i64 %0985}986 987define i16 @test_ignored_rightbits(i32 %dst, i32 %in) {988; LLC-LABEL: test_ignored_rightbits:989; LLC:       // %bb.0:990; LLC-NEXT:    and w8, w0, #0x7991; LLC-NEXT:    bfi w8, w1, #3, #4992; LLC-NEXT:    orr w0, w8, w8, lsl #8993; LLC-NEXT:    ret994; OPT-LABEL: @test_ignored_rightbits(995; OPT-NEXT:    [[POSITIONED_FIELD:%.*]] = shl i32 [[IN:%.*]], 3996; OPT-NEXT:    [[POSITIONED_MASKED_FIELD:%.*]] = and i32 [[POSITIONED_FIELD]], 120997; OPT-NEXT:    [[MASKED_DST:%.*]] = and i32 [[DST:%.*]], 7998; OPT-NEXT:    [[INSERTION:%.*]] = or i32 [[MASKED_DST]], [[POSITIONED_MASKED_FIELD]]999; OPT-NEXT:    [[SHL16:%.*]] = shl i32 [[INSERTION]], 81000; OPT-NEXT:    [[OR18:%.*]] = or i32 [[SHL16]], [[INSERTION]]1001; OPT-NEXT:    [[CONV19:%.*]] = trunc i32 [[OR18]] to i161002; OPT-NEXT:    ret i16 [[CONV19]]1003;1004  %positioned_field = shl i32 %in, 31005  %positioned_masked_field = and i32 %positioned_field, 1201006  %masked_dst = and i32 %dst, 71007  %insertion = or i32 %masked_dst, %positioned_masked_field1008 1009  %shl16 = shl i32 %insertion, 81010  %or18 = or i32 %shl16, %insertion1011  %conv19 = trunc i32 %or18 to i161012 1013  ret i16 %conv191014}1015 1016; The following test excercises the case where we have a BFI1017; instruction with the same input in both operands. We need to1018; track the useful bits through both operands.1019define void @sameOperandBFI(i64 %src, i64 %src2, ptr %ptr) {1020; LLC-LABEL: sameOperandBFI:1021; LLC:       // %bb.0: // %entry1022; LLC-NEXT:    cbnz w8, .LBB30_21023; LLC-NEXT:  // %bb.1: // %if.else1024; LLC-NEXT:    lsr x8, x0, #471025; LLC-NEXT:    and w9, w1, #0x31026; LLC-NEXT:    bfi w9, w8, #2, #21027; LLC-NEXT:    orr w8, w9, w9, lsl #41028; LLC-NEXT:    strh w8, [x2]1029; LLC-NEXT:  .LBB30_2: // %end1030; LLC-NEXT:    ret1031; OPT-LABEL: @sameOperandBFI(1032; OPT-NEXT:  entry:1033; OPT-NEXT:    [[SHR47:%.*]] = lshr i64 [[SRC:%.*]], 471034; OPT-NEXT:    [[SRC2_TRUNC:%.*]] = trunc i64 [[SRC2:%.*]] to i321035; OPT-NEXT:    br i1 poison, label [[END:%.*]], label [[IF_ELSE:%.*]]1036; OPT:       if.else:1037; OPT-NEXT:    [[AND3:%.*]] = and i32 [[SRC2_TRUNC]], 31038; OPT-NEXT:    [[SHL2:%.*]] = shl nuw nsw i64 [[SHR47]], 21039; OPT-NEXT:    [[SHL2_TRUNC:%.*]] = trunc i64 [[SHL2]] to i321040; OPT-NEXT:    [[AND12:%.*]] = and i32 [[SHL2_TRUNC]], 121041; OPT-NEXT:    [[BFISOURCE:%.*]] = or i32 [[AND3]], [[AND12]]1042; OPT-NEXT:    [[BFIRHS:%.*]] = shl nuw nsw i32 [[BFISOURCE]], 41043; OPT-NEXT:    [[BFI:%.*]] = or i32 [[BFIRHS]], [[BFISOURCE]]1044; OPT-NEXT:    [[BFITRUNC:%.*]] = trunc i32 [[BFI]] to i161045; OPT-NEXT:    store i16 [[BFITRUNC]], ptr [[PTR:%.*]], align 41046; OPT-NEXT:    br label [[END]]1047; OPT:       end:1048; OPT-NEXT:    ret void1049;1050entry:1051  %shr47 = lshr i64 %src, 471052  %src2.trunc = trunc i64 %src2 to i321053  br i1 poison, label %end, label %if.else1054 1055if.else:1056  %and3 = and i32 %src2.trunc, 31057  %shl2 = shl nuw nsw i64 %shr47, 21058  %shl2.trunc = trunc i64 %shl2 to i321059  %and12 = and i32 %shl2.trunc, 121060  %BFISource = or i32 %and3, %and12         ; ...00000ABCD1061  %BFIRHS = shl nuw nsw i32 %BFISource, 4   ; ...0ABCD00001062  %BFI = or i32 %BFIRHS, %BFISource         ; ...0ABCDABCD1063  %BFItrunc = trunc i32 %BFI to i161064  store i16 %BFItrunc, ptr %ptr, align 41065  br label %end1066 1067end:1068  ret void1069}1070 1071define i64 @sign_extend_lsb(i64 %arg) nounwind {1072; LLC-LABEL: sign_extend_lsb:1073; LLC:       // %bb.0:1074; LLC-NEXT:    sbfx x0, x0, #0, #11075; LLC-NEXT:    ret1076; OPT-LABEL: @sign_extend_lsb(1077; OPT-NEXT:    [[AND:%.*]] = and i64 [[ARG:%.*]], 11078; OPT-NEXT:    [[NEG:%.*]] = sub i64 0, [[AND]]1079; OPT-NEXT:    ret i64 [[NEG]]1080;1081  %and = and i64 %arg, 11082  %neg = sub i64 0, %and1083  ret i64 %neg1084}1085