545 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s3 4define i8 @test1(i32 %a) {5; CHECK-LABEL: test1:6; CHECK: // %bb.0: // %entry7; CHECK-NEXT: and w8, w0, #0x3ffc008; CHECK-NEXT: and w8, w8, #0xffe007ff9; CHECK-NEXT: cmp w8, #102410; CHECK-NEXT: cset w0, eq11; CHECK-NEXT: ret12entry:13 %and = and i32 %a, 209817614 %cmp = icmp eq i32 %and, 102415 %conv = zext i1 %cmp to i816 ret i8 %conv17}18 19; This constant should not be split because it can be handled by one mov.20define i8 @test2(i32 %a) {21; CHECK-LABEL: test2:22; CHECK: // %bb.0: // %entry23; CHECK-NEXT: mov w8, #135 // =0x8724; CHECK-NEXT: and w8, w0, w825; CHECK-NEXT: cmp w8, #102426; CHECK-NEXT: cset w0, eq27; CHECK-NEXT: ret28entry:29 %and = and i32 %a, 13530 %cmp = icmp eq i32 %and, 102431 %conv = zext i1 %cmp to i832 ret i8 %conv33}34 35; This constant should not be split because the split immediate is not valid36; bitmask immediate.37define i8 @test3(i32 %a) {38; CHECK-LABEL: test3:39; CHECK: // %bb.0: // %entry40; CHECK-NEXT: mov w8, #1024 // =0x40041; CHECK-NEXT: movk w8, #33, lsl #1642; CHECK-NEXT: and w8, w0, w843; CHECK-NEXT: cmp w8, #102444; CHECK-NEXT: cset w0, eq45; CHECK-NEXT: ret46entry:47 %and = and i32 %a, 216371248 %cmp = icmp eq i32 %and, 102449 %conv = zext i1 %cmp to i850 ret i8 %conv51}52 53define i8 @test4(i64 %a) {54; CHECK-LABEL: test4:55; CHECK: // %bb.0: // %entry56; CHECK-NEXT: and x8, x0, #0x3ffc0057; CHECK-NEXT: and x8, x8, #0xffffffffffe007ff58; CHECK-NEXT: cmp x8, #102459; CHECK-NEXT: cset w0, eq60; CHECK-NEXT: ret61entry:62 %and = and i64 %a, 209817663 %cmp = icmp eq i64 %and, 102464 %conv = zext i1 %cmp to i865 ret i8 %conv66}67 68define i8 @test5(i64 %a) {69; CHECK-LABEL: test5:70; CHECK: // %bb.0: // %entry71; CHECK-NEXT: and x8, x0, #0x3ffffc00072; CHECK-NEXT: and x8, x8, #0xfffffffe00007fff73; CHECK-NEXT: cmp x8, #102474; CHECK-NEXT: cset w0, eq75; CHECK-NEXT: ret76entry:77 %and = and i64 %a, 858995097678 %cmp = icmp eq i64 %and, 102479 %conv = zext i1 %cmp to i880 ret i8 %conv81}82 83; This constant should not be split because it can be handled by one mov.84define i8 @test6(i64 %a) {85; CHECK-LABEL: test6:86; CHECK: // %bb.0: // %entry87; CHECK-NEXT: mov w8, #135 // =0x8788; CHECK-NEXT: and x8, x0, x889; CHECK-NEXT: cmp x8, #102490; CHECK-NEXT: cset w0, eq91; CHECK-NEXT: ret92entry:93 %and = and i64 %a, 13594 %cmp = icmp eq i64 %and, 102495 %conv = zext i1 %cmp to i896 ret i8 %conv97}98 99; This constant should not be split because the split immediate is not valid100; bitmask immediate.101define i8 @test7(i64 %a) {102; CHECK-LABEL: test7:103; CHECK: // %bb.0: // %entry104; CHECK-NEXT: mov w8, #1024 // =0x400105; CHECK-NEXT: movk w8, #33, lsl #16106; CHECK-NEXT: and x8, x0, x8107; CHECK-NEXT: cmp x8, #1024108; CHECK-NEXT: cset w0, eq109; CHECK-NEXT: ret110entry:111 %and = and i64 %a, 2163712112 %cmp = icmp eq i64 %and, 1024113 %conv = zext i1 %cmp to i8114 ret i8 %conv115}116 117; The split bitmask immediates should be hoisted outside loop because they are118; loop invariant.119define void @test8(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {120; CHECK-LABEL: test8:121; CHECK: // %bb.0: // %loop.ph122; CHECK-NEXT: and x9, x0, #0x3ffc00123; CHECK-NEXT: mov x8, xzr124; CHECK-NEXT: and x9, x9, #0xffffffffffe007ff125; CHECK-NEXT: b .LBB7_2126; CHECK-NEXT: .LBB7_1: // %for.inc127; CHECK-NEXT: // in Loop: Header=BB7_2 Depth=1128; CHECK-NEXT: add x8, x8, #1129; CHECK-NEXT: cmp x8, x3130; CHECK-NEXT: b.gt .LBB7_4131; CHECK-NEXT: .LBB7_2: // %loop132; CHECK-NEXT: // =>This Inner Loop Header: Depth=1133; CHECK-NEXT: cmp x8, x9134; CHECK-NEXT: b.hs .LBB7_1135; CHECK-NEXT: // %bb.3: // %if.then136; CHECK-NEXT: // in Loop: Header=BB7_2 Depth=1137; CHECK-NEXT: ldr x10, [x1, x8, lsl #3]138; CHECK-NEXT: str x10, [x2, x8, lsl #3]139; CHECK-NEXT: b .LBB7_1140; CHECK-NEXT: .LBB7_4: // %exit141; CHECK-NEXT: ret142loop.ph:143 br label %loop144 145loop:146 %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]147 %and = and i64 %a, 2098176148 %cmp = icmp ult i64 %iv, %and149 br i1 %cmp, label %if.then, label %if.else150 151if.then:152 %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv153 %val = load i64, ptr %src.arrayidx154 %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv155 store i64 %val, ptr %dst.arrayidx156 br label %for.inc157 158if.else:159 br label %for.inc160 161for.inc:162 %inc = add nuw nsw i64 %iv, 1163 %cond = icmp sgt i64 %inc, %n164 br i1 %cond, label %exit, label %loop165 166exit:167 ret void168}169 170; This constant should not be split because the `and` is not loop invariant.171define i32 @test9(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {172; CHECK-LABEL: test9:173; CHECK: // %bb.0: // %entry174; CHECK-NEXT: cmp w2, #1175; CHECK-NEXT: b.lt .LBB8_3176; CHECK-NEXT: // %bb.1: // %for.body.preheader177; CHECK-NEXT: mov w9, #1024 // =0x400178; CHECK-NEXT: mov w8, w2179; CHECK-NEXT: movk w9, #32, lsl #16180; CHECK-NEXT: .LBB8_2: // %for.body181; CHECK-NEXT: // =>This Inner Loop Header: Depth=1182; CHECK-NEXT: ldr w10, [x1], #4183; CHECK-NEXT: subs x8, x8, #1184; CHECK-NEXT: and w10, w10, w9185; CHECK-NEXT: str w10, [x0], #4186; CHECK-NEXT: b.ne .LBB8_2187; CHECK-NEXT: .LBB8_3: // %for.cond.cleanup188; CHECK-NEXT: mov w0, wzr189; CHECK-NEXT: ret190entry:191 %cmp8 = icmp sgt i32 %n, 0192 br i1 %cmp8, label %for.body.preheader, label %for.cond.cleanup193 194for.body.preheader: ; preds = %entry195 %wide.trip.count = zext i32 %n to i64196 br label %for.body197 198for.cond.cleanup: ; preds = %for.body, %entry199 ret i32 0200 201for.body: ; preds = %for.body.preheader, %for.body202 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]203 %arrayidx = getelementptr inbounds i32, ptr %y, i64 %indvars.iv204 %0 = load i32, ptr %arrayidx, align 4205 %and = and i32 %0, 2098176206 %arrayidx2 = getelementptr inbounds i32, ptr %x, i64 %indvars.iv207 store i32 %and, ptr %arrayidx2, align 4208 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1209 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count210 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body211}212 213; After instruction selection end, we can see the `and` and `or` share the214; constant as below.215;216; %4:gpr32 = MOVi32imm 2098176217; %5:gpr32 = ANDWrr killed %3:gpr32, %4:gpr32218; STRWui killed %5:gpr32, %0:gpr64common, 0 :: (store (s32) into %ir.x, !tbaa !8)219; %6:gpr32 = LDRWui %1:gpr64common, 0 :: (load (s32) from %ir.y, !tbaa !8)220; %7:gpr32 = ORRWrr killed %6:gpr32, %4:gpr32221;222; In this case, the constant should not be split because it causes more223; instructions.224define void @test10(ptr nocapture %x, ptr nocapture readonly %y, ptr nocapture %z) {225; CHECK-LABEL: test10:226; CHECK: // %bb.0: // %entry227; CHECK-NEXT: ldr w8, [x1]228; CHECK-NEXT: mov w9, #1024 // =0x400229; CHECK-NEXT: movk w9, #32, lsl #16230; CHECK-NEXT: and w8, w8, w9231; CHECK-NEXT: str w8, [x0]232; CHECK-NEXT: ldr w8, [x1]233; CHECK-NEXT: orr w8, w8, w9234; CHECK-NEXT: str w8, [x2]235; CHECK-NEXT: ret236entry:237 %0 = load i32, ptr %y, align 4238 %and = and i32 %0, 2098176239 store i32 %and, ptr %x, align 4240 %1 = load i32, ptr %y, align 4241 %or = or i32 %1, 2098176242 store i32 %or, ptr %z, align 4243 ret void244}245 246; This test genereates below MIs.247;248; MOVi32imm -1610612736249; SUBREG_TO_REG250;251; The constant should be zero-extended to 64 bit and it should not be split.252define i8 @test11(i64 %a) {253; CHECK-LABEL: test11:254; CHECK: // %bb.0: // %entry255; CHECK-NEXT: mov w8, #-1610612736 // =0xa0000000256; CHECK-NEXT: and x8, x0, x8257; CHECK-NEXT: cmp x8, #1024258; CHECK-NEXT: cset w0, eq259; CHECK-NEXT: ret260entry:261 %and = and i64 %a, 2684354560262 %cmp = icmp eq i64 %and, 1024263 %conv = zext i1 %cmp to i8264 ret i8 %conv265}266 267; Test ANDS.268define i32 @test1_ands(i32 %a) {269; CHECK-LABEL: test1_ands:270; CHECK: // %bb.0: // %entry271; CHECK-NEXT: and w8, w0, #0x3ffc00272; CHECK-NEXT: ands w8, w8, #0xffe007ff273; CHECK-NEXT: csel w0, w0, w8, eq274; CHECK-NEXT: ret275entry:276 %ands = and i32 %a, 2098176277 %c = icmp eq i32 %ands, 0278 %r = select i1 %c, i32 %a, i32 %ands279 ret i32 %r280}281 282; This constant should not be split because it can be handled by one mov.283define i32 @test2_ands(i32 %a) {284; CHECK-LABEL: test2_ands:285; CHECK: // %bb.0: // %entry286; CHECK-NEXT: mov w8, #135 // =0x87287; CHECK-NEXT: ands w8, w0, w8288; CHECK-NEXT: csel w0, w0, w8, eq289; CHECK-NEXT: ret290entry:291 %ands = and i32 %a, 135292 %c = icmp eq i32 %ands, 0293 %r = select i1 %c, i32 %a, i32 %ands294 ret i32 %r295}296 297; This constant should not be split because the split immediate is not valid298; bitmask immediate.299define i32 @test3_ands(i32 %a) {300; CHECK-LABEL: test3_ands:301; CHECK: // %bb.0: // %entry302; CHECK-NEXT: mov w8, #1024 // =0x400303; CHECK-NEXT: movk w8, #33, lsl #16304; CHECK-NEXT: ands w8, w0, w8305; CHECK-NEXT: csel w0, w0, w8, eq306; CHECK-NEXT: ret307entry:308 %ands = and i32 %a, 2163712309 %c = icmp eq i32 %ands, 0310 %r = select i1 %c, i32 %a, i32 %ands311 ret i32 %r312}313 314define i64 @test4_ands(i64 %a) {315; CHECK-LABEL: test4_ands:316; CHECK: // %bb.0: // %entry317; CHECK-NEXT: and x8, x0, #0x3ffc00318; CHECK-NEXT: ands x8, x8, #0xffffffffffe007ff319; CHECK-NEXT: csel x0, x0, x8, eq320; CHECK-NEXT: ret321entry:322 %ands = and i64 %a, 2098176323 %c = icmp eq i64 %ands, 0324 %r = select i1 %c, i64 %a, i64 %ands325 ret i64 %r326}327 328define i64 @test5_ands(i64 %a) {329; CHECK-LABEL: test5_ands:330; CHECK: // %bb.0: // %entry331; CHECK-NEXT: and x8, x0, #0x3ffffc000332; CHECK-NEXT: ands x8, x8, #0xfffffffe00007fff333; CHECK-NEXT: csel x0, x0, x8, eq334; CHECK-NEXT: ret335entry:336 %ands = and i64 %a, 8589950976337 %c = icmp eq i64 %ands, 0338 %r = select i1 %c, i64 %a, i64 %ands339 ret i64 %r340}341 342; This constant should not be split because it can be handled by one mov.343define i64 @test6_ands(i64 %a) {344; CHECK-LABEL: test6_ands:345; CHECK: // %bb.0: // %entry346; CHECK-NEXT: mov w8, #135 // =0x87347; CHECK-NEXT: ands x8, x0, x8348; CHECK-NEXT: csel x0, x0, x8, eq349; CHECK-NEXT: ret350entry:351 %ands = and i64 %a, 135352 %c = icmp eq i64 %ands, 0353 %r = select i1 %c, i64 %a, i64 %ands354 ret i64 %r355}356 357; This constant should not be split because the split immediate is not valid358; bitmask immediate.359define i64 @test7_ands(i64 %a) {360; CHECK-LABEL: test7_ands:361; CHECK: // %bb.0: // %entry362; CHECK-NEXT: mov w8, #1024 // =0x400363; CHECK-NEXT: movk w8, #33, lsl #16364; CHECK-NEXT: ands x8, x0, x8365; CHECK-NEXT: csel x0, x0, x8, eq366; CHECK-NEXT: ret367entry:368 %ands = and i64 %a, 2163712369 %c = icmp eq i64 %ands, 0370 %r = select i1 %c, i64 %a, i64 %ands371 ret i64 %r372}373 374; Test EOR.375define i32 @test1_eor(i32 %a) {376; CHECK-LABEL: test1_eor:377; CHECK: // %bb.0: // %entry378; CHECK-NEXT: eor w8, w0, #0x400379; CHECK-NEXT: eor w0, w8, #0x200000380; CHECK-NEXT: ret381entry:382 %eor = xor i32 %a, 2098176383 ret i32 %eor384}385 386; This constant should not be split because it can be handled by one mov.387define i32 @test2_eor(i32 %a) {388; CHECK-LABEL: test2_eor:389; CHECK: // %bb.0: // %entry390; CHECK-NEXT: mov w8, #135 // =0x87391; CHECK-NEXT: eor w0, w0, w8392; CHECK-NEXT: ret393entry:394 %eor = xor i32 %a, 135395 ret i32 %eor396}397 398; This constant should not be split because the split immediate is not valid399; bitmask immediate.400define i32 @test3_eor(i32 %a) {401; CHECK-LABEL: test3_eor:402; CHECK: // %bb.0: // %entry403; CHECK-NEXT: mov w8, #1024 // =0x400404; CHECK-NEXT: movk w8, #33, lsl #16405; CHECK-NEXT: eor w0, w0, w8406; CHECK-NEXT: ret407entry:408 %eor = xor i32 %a, 2163712409 ret i32 %eor410}411 412define i64 @test4_eor(i64 %a) {413; CHECK-LABEL: test4_eor:414; CHECK: // %bb.0: // %entry415; CHECK-NEXT: eor x8, x0, #0x400416; CHECK-NEXT: eor x0, x8, #0x200000417; CHECK-NEXT: ret418entry:419 %eor = xor i64 %a, 2098176420 ret i64 %eor421}422 423define i64 @test5_eor(i64 %a) {424; CHECK-LABEL: test5_eor:425; CHECK: // %bb.0: // %entry426; CHECK-NEXT: eor x8, x0, #0x4000427; CHECK-NEXT: eor x0, x8, #0x200000000428; CHECK-NEXT: ret429entry:430 %eor = xor i64 %a, 8589950976431 ret i64 %eor432}433 434; This constant should not be split because it can be handled by one mov.435define i64 @test6_eor(i64 %a) {436; CHECK-LABEL: test6_eor:437; CHECK: // %bb.0: // %entry438; CHECK-NEXT: mov w8, #135 // =0x87439; CHECK-NEXT: eor x0, x0, x8440; CHECK-NEXT: ret441entry:442 %eor = xor i64 %a, 135443 ret i64 %eor444}445 446; This constant should not be split because the split immediate is not valid447; bitmask immediate.448define i64 @test7_eor(i64 %a) {449; CHECK-LABEL: test7_eor:450; CHECK: // %bb.0: // %entry451; CHECK-NEXT: mov w8, #1024 // =0x400452; CHECK-NEXT: movk w8, #33, lsl #16453; CHECK-NEXT: eor x0, x0, x8454; CHECK-NEXT: ret455entry:456 %eor = xor i64 %a, 2163712457 ret i64 %eor458}459 460; Test ORR.461define i32 @test1_orr(i32 %a) {462; CHECK-LABEL: test1_orr:463; CHECK: // %bb.0: // %entry464; CHECK-NEXT: orr w8, w0, #0x400465; CHECK-NEXT: orr w0, w8, #0x200000466; CHECK-NEXT: ret467entry:468 %orr = or i32 %a, 2098176469 ret i32 %orr470}471 472; This constant should not be split because it can be handled by one mov.473define i32 @test2_orr(i32 %a) {474; CHECK-LABEL: test2_orr:475; CHECK: // %bb.0: // %entry476; CHECK-NEXT: mov w8, #135 // =0x87477; CHECK-NEXT: orr w0, w0, w8478; CHECK-NEXT: ret479entry:480 %orr = or i32 %a, 135481 ret i32 %orr482}483 484; This constant should not be split because the split immediate is not valid485; bitmask immediate.486define i32 @test3_orr(i32 %a) {487; CHECK-LABEL: test3_orr:488; CHECK: // %bb.0: // %entry489; CHECK-NEXT: mov w8, #1024 // =0x400490; CHECK-NEXT: movk w8, #33, lsl #16491; CHECK-NEXT: orr w0, w0, w8492; CHECK-NEXT: ret493entry:494 %orr = or i32 %a, 2163712495 ret i32 %orr496}497 498define i64 @test4_orr(i64 %a) {499; CHECK-LABEL: test4_orr:500; CHECK: // %bb.0: // %entry501; CHECK-NEXT: orr x8, x0, #0x400502; CHECK-NEXT: orr x0, x8, #0x200000503; CHECK-NEXT: ret504entry:505 %orr = or i64 %a, 2098176506 ret i64 %orr507}508 509define i64 @test5_orr(i64 %a) {510; CHECK-LABEL: test5_orr:511; CHECK: // %bb.0: // %entry512; CHECK-NEXT: orr x8, x0, #0x4000513; CHECK-NEXT: orr x0, x8, #0x200000000514; CHECK-NEXT: ret515entry:516 %orr = or i64 %a, 8589950976517 ret i64 %orr518}519 520; This constant should not be split because it can be handled by one mov.521define i64 @test6_orr(i64 %a) {522; CHECK-LABEL: test6_orr:523; CHECK: // %bb.0: // %entry524; CHECK-NEXT: mov w8, #135 // =0x87525; CHECK-NEXT: orr x0, x0, x8526; CHECK-NEXT: ret527entry:528 %orr = or i64 %a, 135529 ret i64 %orr530}531 532; This constant should not be split because the split immediate is not valid533; bitmask immediate.534define i64 @test7_orr(i64 %a) {535; CHECK-LABEL: test7_orr:536; CHECK: // %bb.0: // %entry537; CHECK-NEXT: mov w8, #1024 // =0x400538; CHECK-NEXT: movk w8, #33, lsl #16539; CHECK-NEXT: orr x0, x0, x8540; CHECK-NEXT: ret541entry:542 %orr = or i64 %a, 2163712543 ret i64 %orr544}545