926 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -post-RA-scheduler=true -disable-cgp-delete-phis | FileCheck %s3 4declare dso_local void @bar(i32)5declare dso_local void @car(i32)6declare dso_local void @dar(i32)7declare dso_local void @ear(i32)8declare dso_local void @far(i32)9declare i1 @qux()10 11@GHJK = dso_local global i32 012@HABC = dso_local global i32 013 14; BranchFolding should tail-merge the stores since they all precede15; direct branches to the same place.16 17define dso_local void @tail_merge_me() nounwind {18; CHECK-LABEL: tail_merge_me:19; CHECK: # %bb.0: # %entry20; CHECK-NEXT: pushq %rax21; CHECK-NEXT: callq qux@PLT22; CHECK-NEXT: testb $1, %al23; CHECK-NEXT: je .LBB0_124; CHECK-NEXT: # %bb.6: # %A25; CHECK-NEXT: xorl %edi, %edi26; CHECK-NEXT: callq bar27; CHECK-NEXT: jmp .LBB0_428; CHECK-NEXT: .LBB0_1: # %next29; CHECK-NEXT: callq qux@PLT30; CHECK-NEXT: testb $1, %al31; CHECK-NEXT: je .LBB0_332; CHECK-NEXT: # %bb.2: # %B33; CHECK-NEXT: movl $1, %edi34; CHECK-NEXT: callq car35; CHECK-NEXT: jmp .LBB0_436; CHECK-NEXT: .LBB0_3: # %C37; CHECK-NEXT: movl $2, %edi38; CHECK-NEXT: callq dar39; CHECK-NEXT: .LBB0_4: # %M40; CHECK-NEXT: movl $0, GHJK(%rip)41; CHECK-NEXT: movl $1, HABC(%rip)42; CHECK-NEXT: callq qux@PLT43; CHECK-NEXT: testb $1, %al44; CHECK-NEXT: je .LBB0_545; CHECK-NEXT: # %bb.7: # %return46; CHECK-NEXT: movl $1000, %edi # imm = 0x3E847; CHECK-NEXT: callq ear48; CHECK-NEXT: popq %rax49; CHECK-NEXT: retq50; CHECK-NEXT: .LBB0_5: # %altret51; CHECK-NEXT: movl $1001, %edi # imm = 0x3E952; CHECK-NEXT: callq far53; CHECK-NEXT: popq %rax54; CHECK-NEXT: retq55entry:56 %a = call i1 @qux()57 br i1 %a, label %A, label %next58next:59 %b = call i1 @qux()60 br i1 %b, label %B, label %C61 62A:63 call void @bar(i32 0)64 store i32 0, ptr @GHJK65 br label %M66 67B:68 call void @car(i32 1)69 store i32 0, ptr @GHJK70 br label %M71 72C:73 call void @dar(i32 2)74 store i32 0, ptr @GHJK75 br label %M76 77M:78 store i32 1, ptr @HABC79 %c = call i1 @qux()80 br i1 %c, label %return, label %altret81 82return:83 call void @ear(i32 1000)84 ret void85altret:86 call void @far(i32 1001)87 ret void88}89 90declare ptr @choose(ptr, ptr)91 92; BranchFolding should tail-duplicate the indirect jump to avoid93; redundant branching.94 95define dso_local void @tail_duplicate_me() nounwind {96; CHECK-LABEL: tail_duplicate_me:97; CHECK: # %bb.0: # %entry98; CHECK-NEXT: pushq %rbp99; CHECK-NEXT: pushq %rbx100; CHECK-NEXT: pushq %rax101; CHECK-NEXT: callq qux@PLT102; CHECK-NEXT: movl $.Ltmp0, %edi103; CHECK-NEXT: movl $.Ltmp1, %esi104; CHECK-NEXT: movl %eax, %ebp105; CHECK-NEXT: callq choose@PLT106; CHECK-NEXT: movq %rax, %rbx107; CHECK-NEXT: testb $1, %bpl108; CHECK-NEXT: je .LBB1_1109; CHECK-NEXT: # %bb.7: # %A110; CHECK-NEXT: xorl %edi, %edi111; CHECK-NEXT: callq bar112; CHECK-NEXT: movl $0, GHJK(%rip)113; CHECK-NEXT: jmpq *%rbx114; CHECK-NEXT: .Ltmp0: # Block address taken115; CHECK-NEXT: .LBB1_4: # %return116; CHECK-NEXT: movl $1000, %edi # imm = 0x3E8117; CHECK-NEXT: callq ear118; CHECK-NEXT: jmp .LBB1_5119; CHECK-NEXT: .LBB1_1: # %next120; CHECK-NEXT: callq qux@PLT121; CHECK-NEXT: testb $1, %al122; CHECK-NEXT: je .LBB1_3123; CHECK-NEXT: # %bb.2: # %B124; CHECK-NEXT: movl $1, %edi125; CHECK-NEXT: callq car126; CHECK-NEXT: movl $0, GHJK(%rip)127; CHECK-NEXT: jmpq *%rbx128; CHECK-NEXT: .Ltmp1: # Block address taken129; CHECK-NEXT: .LBB1_6: # %altret130; CHECK-NEXT: movl $1001, %edi # imm = 0x3E9131; CHECK-NEXT: callq far132; CHECK-NEXT: .LBB1_5: # %return133; CHECK-NEXT: addq $8, %rsp134; CHECK-NEXT: popq %rbx135; CHECK-NEXT: popq %rbp136; CHECK-NEXT: retq137; CHECK-NEXT: .LBB1_3: # %C138; CHECK-NEXT: movl $2, %edi139; CHECK-NEXT: callq dar140; CHECK-NEXT: movl $0, GHJK(%rip)141; CHECK-NEXT: jmpq *%rbx142entry:143 %a = call i1 @qux()144 %c = call ptr @choose(ptr blockaddress(@tail_duplicate_me, %return),145 ptr blockaddress(@tail_duplicate_me, %altret))146 br i1 %a, label %A, label %next147next:148 %b = call i1 @qux()149 br i1 %b, label %B, label %C150 151A:152 call void @bar(i32 0)153 store i32 0, ptr @GHJK154 br label %M155 156B:157 call void @car(i32 1)158 store i32 0, ptr @GHJK159 br label %M160 161C:162 call void @dar(i32 2)163 store i32 0, ptr @GHJK164 br label %M165 166M:167 indirectbr ptr %c, [label %return, label %altret]168 169return:170 call void @ear(i32 1000)171 ret void172altret:173 call void @far(i32 1001)174 ret void175}176 177; BranchFolding shouldn't try to merge the tails of two blocks178; with only a branch in common, regardless of the fallthrough situation.179 180define i1 @dont_merge_oddly(ptr %result) nounwind {181; CHECK-LABEL: dont_merge_oddly:182; CHECK: # %bb.0: # %entry183; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero184; CHECK-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero185; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero186; CHECK-NEXT: ucomiss %xmm1, %xmm2187; CHECK-NEXT: jbe .LBB2_3188; CHECK-NEXT: # %bb.1: # %bb189; CHECK-NEXT: ucomiss %xmm0, %xmm1190; CHECK-NEXT: ja .LBB2_4191; CHECK-NEXT: .LBB2_2: # %bb30192; CHECK-NEXT: movb $1, %al193; CHECK-NEXT: retq194; CHECK-NEXT: .LBB2_3: # %bb21195; CHECK-NEXT: ucomiss %xmm0, %xmm2196; CHECK-NEXT: jbe .LBB2_2197; CHECK-NEXT: .LBB2_4: # %bb26198; CHECK-NEXT: xorl %eax, %eax199; CHECK-NEXT: retq200entry:201 %tmp4 = getelementptr float, ptr %result, i32 2202 %tmp5 = load float, ptr %tmp4, align 4203 %tmp7 = getelementptr float, ptr %result, i32 4204 %tmp8 = load float, ptr %tmp7, align 4205 %tmp10 = getelementptr float, ptr %result, i32 6206 %tmp11 = load float, ptr %tmp10, align 4207 %tmp12 = fcmp olt float %tmp8, %tmp11208 br i1 %tmp12, label %bb, label %bb21209 210bb:211 %tmp23469 = fcmp olt float %tmp5, %tmp8212 br i1 %tmp23469, label %bb26, label %bb30213 214bb21:215 %tmp23 = fcmp olt float %tmp5, %tmp11216 br i1 %tmp23, label %bb26, label %bb30217 218bb26:219 ret i1 0220 221bb30:222 ret i1 1223}224 225; Do any-size tail-merging when two candidate blocks will both require226; an unconditional jump to complete a two-way conditional branch.227;228; This test only works when register allocation happens to use %rax for both229; load addresses.230 231%0 = type { ptr }232%struct.lang_decl = type opaque233%struct.rtx_def = type { i16, i8, i8, [1 x %union.rtunion] }234%struct.tree_decl = type { [24 x i8], ptr, i32, ptr, i32, i8, i8, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, %union..2anon, %0, ptr, ptr }235%union..2anon = type { i32 }236%union.rtunion = type { ptr }237%union.tree_node = type { %struct.tree_decl }238 239define fastcc void @c_expand_expr_stmt(ptr %expr) nounwind {240; CHECK-LABEL: c_expand_expr_stmt:241; CHECK: # %bb.0: # %entry242; CHECK-NEXT: pushq %rbx243; CHECK-NEXT: xorl %eax, %eax244; CHECK-NEXT: testb %al, %al245; CHECK-NEXT: jne .LBB3_9246; CHECK-NEXT: # %bb.1: # %entry247; CHECK-NEXT: movzbl 0, %ebx248; CHECK-NEXT: xorl %eax, %eax249; CHECK-NEXT: testb %al, %al250; CHECK-NEXT: jne .LBB3_8251; CHECK-NEXT: # %bb.2: # %bb.i252; CHECK-NEXT: xorl %eax, %eax253; CHECK-NEXT: testb %al, %al254; CHECK-NEXT: je .LBB3_8255; CHECK-NEXT: # %bb.3: # %lvalue_p.exit256; CHECK-NEXT: movq 0, %rax257; CHECK-NEXT: movzbl (%rax), %ecx258; CHECK-NEXT: testl %ecx, %ecx259; CHECK-NEXT: je .LBB3_10260; CHECK-NEXT: # %bb.4: # %lvalue_p.exit261; CHECK-NEXT: cmpl $2, %ecx262; CHECK-NEXT: jne .LBB3_15263; CHECK-NEXT: # %bb.5: # %bb.i1264; CHECK-NEXT: movq 32(%rax), %rax265; CHECK-NEXT: movzbl 16(%rax), %ecx266; CHECK-NEXT: testl %ecx, %ecx267; CHECK-NEXT: je .LBB3_13268; CHECK-NEXT: # %bb.6: # %bb.i1269; CHECK-NEXT: cmpl $2, %ecx270; CHECK-NEXT: jne .LBB3_15271; CHECK-NEXT: # %bb.7: # %bb.i.i272; CHECK-NEXT: xorl %edi, %edi273; CHECK-NEXT: callq lvalue_p@PLT274; CHECK-NEXT: testl %eax, %eax275; CHECK-NEXT: setne %al276; CHECK-NEXT: jmp .LBB3_16277; CHECK-NEXT: .LBB3_8: # %bb1278; CHECK-NEXT: cmpb $23, %bl279; CHECK-NEXT: .LBB3_9: # %bb3280; CHECK-NEXT: .LBB3_15:281; CHECK-NEXT: xorl %eax, %eax282; CHECK-NEXT: jmp .LBB3_16283; CHECK-NEXT: .LBB3_10: # %bb2.i3284; CHECK-NEXT: movq 8(%rax), %rax285; CHECK-NEXT: movzbl 16(%rax), %ecx286; CHECK-NEXT: xorl %eax, %eax287; CHECK-NEXT: cmpl $23, %ecx288; CHECK-NEXT: je .LBB3_16289; CHECK-NEXT: # %bb.11: # %bb2.i3290; CHECK-NEXT: cmpl $16, %ecx291; CHECK-NEXT: je .LBB3_16292; CHECK-NEXT: jmp .LBB3_9293; CHECK-NEXT: .LBB3_13: # %bb2.i.i2294; CHECK-NEXT: movq 8(%rax), %rax295; CHECK-NEXT: movzbl 16(%rax), %ecx296; CHECK-NEXT: xorl %eax, %eax297; CHECK-NEXT: cmpl $16, %ecx298; CHECK-NEXT: je .LBB3_16299; CHECK-NEXT: # %bb.14: # %bb2.i.i2300; CHECK-NEXT: cmpl $23, %ecx301; CHECK-NEXT: jne .LBB3_9302; CHECK-NEXT: .LBB3_16: # %lvalue_p.exit4303; CHECK-NEXT: testb %bl, %bl304; CHECK-NEXT: sete %cl305; CHECK-NEXT: orb %al, %cl306entry:307 %tmp4 = load i8, ptr null, align 8 ; <i8> [#uses=3]308 switch i8 %tmp4, label %bb3 [309 i8 18, label %bb310 ]311 312bb: ; preds = %entry313 switch i32 undef, label %bb1 [314 i32 0, label %bb2.i315 i32 37, label %bb.i316 ]317 318bb.i: ; preds = %bb319 switch i32 undef, label %bb1 [320 i32 0, label %lvalue_p.exit321 ]322 323bb2.i: ; preds = %bb324 br label %bb3325 326lvalue_p.exit: ; preds = %bb.i327 %tmp21 = load ptr, ptr null, align 8 ; <ptr> [#uses=3]328 %tmp22 = getelementptr inbounds %union.tree_node, ptr %tmp21, i64 0, i32 0, i32 0, i64 0 ; <ptr> [#uses=1]329 %tmp23 = load i8, ptr %tmp22, align 8 ; <i8> [#uses=1]330 %tmp24 = zext i8 %tmp23 to i32 ; <i32> [#uses=1]331 switch i32 %tmp24, label %lvalue_p.exit4 [332 i32 0, label %bb2.i3333 i32 2, label %bb.i1334 ]335 336bb.i1: ; preds = %lvalue_p.exit337 %tmp25 = getelementptr inbounds %union.tree_node, ptr %tmp21, i64 0, i32 0, i32 2 ; <ptr> [#uses=1]338 %tmp27 = load ptr, ptr %tmp25, align 8 ; <ptr> [#uses=2]339 %tmp28 = getelementptr inbounds %union.tree_node, ptr %tmp27, i64 0, i32 0, i32 0, i64 16 ; <ptr> [#uses=1]340 %tmp29 = load i8, ptr %tmp28, align 8 ; <i8> [#uses=1]341 %tmp30 = zext i8 %tmp29 to i32 ; <i32> [#uses=1]342 switch i32 %tmp30, label %lvalue_p.exit4 [343 i32 0, label %bb2.i.i2344 i32 2, label %bb.i.i345 ]346 347bb.i.i: ; preds = %bb.i1348 %tmp34 = tail call fastcc i32 @lvalue_p(ptr null) nounwind ; <i32> [#uses=1]349 %phitmp = icmp ne i32 %tmp34, 0 ; <i1> [#uses=1]350 br label %lvalue_p.exit4351 352bb2.i.i2: ; preds = %bb.i1353 %tmp35 = getelementptr inbounds %union.tree_node, ptr %tmp27, i64 0, i32 0, i32 0, i64 8 ; <ptr> [#uses=1]354 %tmp37 = load ptr, ptr %tmp35, align 8 ; <ptr> [#uses=1]355 %tmp38 = getelementptr inbounds %union.tree_node, ptr %tmp37, i64 0, i32 0, i32 0, i64 16 ; <ptr> [#uses=1]356 %tmp39 = load i8, ptr %tmp38, align 8 ; <i8> [#uses=1]357 switch i8 %tmp39, label %bb2 [358 i8 16, label %lvalue_p.exit4359 i8 23, label %lvalue_p.exit4360 ]361 362bb2.i3: ; preds = %lvalue_p.exit363 %tmp40 = getelementptr inbounds %union.tree_node, ptr %tmp21, i64 0, i32 0, i32 0, i64 8 ; <ptr> [#uses=1]364 %tmp42 = load ptr, ptr %tmp40, align 8 ; <ptr> [#uses=1]365 %tmp43 = getelementptr inbounds %union.tree_node, ptr %tmp42, i64 0, i32 0, i32 0, i64 16 ; <ptr> [#uses=1]366 %tmp44 = load i8, ptr %tmp43, align 8 ; <i8> [#uses=1]367 switch i8 %tmp44, label %bb2 [368 i8 16, label %lvalue_p.exit4369 i8 23, label %lvalue_p.exit4370 ]371 372lvalue_p.exit4: ; preds = %bb2.i3, %bb2.i3, %bb2.i.i2, %bb2.i.i2, %bb.i.i, %bb.i1, %lvalue_p.exit373 %tmp45 = phi i1 [ %phitmp, %bb.i.i ], [ false, %bb2.i.i2 ], [ false, %bb2.i.i2 ], [ false, %bb.i1 ], [ false, %bb2.i3 ], [ false, %bb2.i3 ], [ false, %lvalue_p.exit ] ; <i1> [#uses=1]374 %tmp46 = icmp eq i8 %tmp4, 0 ; <i1> [#uses=1]375 %or.cond = or i1 %tmp45, %tmp46 ; <i1> [#uses=1]376 br i1 %or.cond, label %bb2, label %bb3377 378bb1: ; preds = %bb2.i.i, %bb.i, %bb379 %.old = icmp eq i8 %tmp4, 23 ; <i1> [#uses=1]380 br i1 %.old, label %bb2, label %bb3381 382bb2: ; preds = %bb1, %lvalue_p.exit4, %bb2.i3, %bb2.i.i2383 br label %bb3384 385bb3: ; preds = %bb2, %bb1, %lvalue_p.exit4, %bb2.i, %entry386 %expr_addr.0 = phi ptr [ null, %bb2 ], [ %expr, %bb2.i ], [ %expr, %entry ], [ %expr, %bb1 ], [ %expr, %lvalue_p.exit4 ] ; <ptr> [#uses=0]387 unreachable388}389 390declare fastcc i32 @lvalue_p(ptr nocapture) nounwind readonly391 392declare fastcc ptr @default_conversion(ptr) nounwind393 394 395; If one tail merging candidate falls through into the other,396; tail merging is likely profitable regardless of how few397; instructions are involved. This function should have only398; one ret instruction.399 400define dso_local void @foo(ptr %V) nounwind {401; CHECK-LABEL: foo:402; CHECK: # %bb.0: # %entry403; CHECK-NEXT: testq %rdi, %rdi404; CHECK-NEXT: je .LBB4_2405; CHECK-NEXT: # %bb.1: # %bb406; CHECK-NEXT: pushq %rax407; CHECK-NEXT: callq func408; CHECK-NEXT: popq %rax409; CHECK-NEXT: .LBB4_2: # %return410; CHECK-NEXT: retq411entry:412 %t0 = icmp eq ptr %V, null413 br i1 %t0, label %return, label %bb414 415bb:416 call void @func()417 ret void418 419return:420 ret void421}422 423declare dso_local void @func()424 425; one - One instruction may be tail-duplicated even with optsize.426 427@XYZ = external dso_local global i32428 429declare dso_local void @tail_call_me()430 431define dso_local void @one(i32 %v) nounwind optsize {432; CHECK-LABEL: one:433; CHECK: # %bb.0: # %entry434; CHECK-NEXT: testl %edi, %edi435; CHECK-NEXT: je .LBB5_3436; CHECK-NEXT: # %bb.1: # %bby437; CHECK-NEXT: cmpl $16, %edi438; CHECK-NEXT: je .LBB5_4439; CHECK-NEXT: # %bb.2: # %bb7440; CHECK-NEXT: jmp tail_call_me # TAILCALL441; CHECK-NEXT: .LBB5_3: # %bbx442; CHECK-NEXT: cmpl $128, %edi443; CHECK-NEXT: jne tail_call_me # TAILCALL444; CHECK-NEXT: .LBB5_4: # %return445; CHECK-NEXT: retq446entry:447 %0 = icmp eq i32 %v, 0448 br i1 %0, label %bbx, label %bby449 450bby:451 switch i32 %v, label %bb7 [452 i32 16, label %return453 ]454 455bb7:456 tail call void @tail_call_me()457 ret void458 459bbx:460 switch i32 %v, label %bb12 [461 i32 128, label %return462 ]463 464bb12:465 tail call void @tail_call_me()466 ret void467 468return:469 ret void470}471 472define dso_local void @one_pgso(i32 %v) nounwind !prof !14 {473; CHECK-LABEL: one_pgso:474; CHECK: # %bb.0: # %entry475; CHECK-NEXT: testl %edi, %edi476; CHECK-NEXT: je .LBB6_3477; CHECK-NEXT: # %bb.1: # %bby478; CHECK-NEXT: cmpl $16, %edi479; CHECK-NEXT: je .LBB6_4480; CHECK-NEXT: # %bb.2: # %bb7481; CHECK-NEXT: jmp tail_call_me # TAILCALL482; CHECK-NEXT: .LBB6_3: # %bbx483; CHECK-NEXT: cmpl $128, %edi484; CHECK-NEXT: jne tail_call_me # TAILCALL485; CHECK-NEXT: .LBB6_4: # %return486; CHECK-NEXT: retq487entry:488 %0 = icmp eq i32 %v, 0489 br i1 %0, label %bbx, label %bby490 491bby:492 switch i32 %v, label %bb7 [493 i32 16, label %return494 ]495 496bb7:497 tail call void @tail_call_me()498 ret void499 500bbx:501 switch i32 %v, label %bb12 [502 i32 128, label %return503 ]504 505bb12:506 tail call void @tail_call_me()507 ret void508 509return:510 ret void511}512 513; two - Same as one, but with two instructions in the common514; tail instead of one. This is too much to be merged, given515; the optsize attribute.516 517define dso_local void @two() nounwind optsize {518; CHECK-LABEL: two:519; CHECK: # %bb.0: # %entry520; CHECK-NEXT: xorl %eax, %eax521; CHECK-NEXT: testb %al, %al522; CHECK-NEXT: xorl %eax, %eax523; CHECK-NEXT: testb %al, %al524; CHECK-NEXT: je .LBB7_1525; CHECK-NEXT: # %bb.2: # %return526; CHECK-NEXT: retq527; CHECK-NEXT: .LBB7_1: # %bb7528; CHECK-NEXT: movl $0, XYZ(%rip)529; CHECK-NEXT: movl $1, XYZ(%rip)530entry:531 %0 = icmp eq i32 undef, 0532 br i1 %0, label %bbx, label %bby533 534bby:535 switch i32 undef, label %bb7 [536 i32 16, label %return537 ]538 539bb7:540 store volatile i32 0, ptr @XYZ541 store volatile i32 1, ptr @XYZ542 unreachable543 544bbx:545 switch i32 undef, label %bb12 [546 i32 128, label %return547 ]548 549bb12:550 store volatile i32 0, ptr @XYZ551 store volatile i32 1, ptr @XYZ552 unreachable553 554return:555 ret void556}557 558define dso_local void @two_pgso() nounwind !prof !14 {559; CHECK-LABEL: two_pgso:560; CHECK: # %bb.0: # %entry561; CHECK-NEXT: xorl %eax, %eax562; CHECK-NEXT: testb %al, %al563; CHECK-NEXT: xorl %eax, %eax564; CHECK-NEXT: testb %al, %al565; CHECK-NEXT: je .LBB8_1566; CHECK-NEXT: # %bb.2: # %return567; CHECK-NEXT: retq568; CHECK-NEXT: .LBB8_1: # %bb7569; CHECK-NEXT: movl $0, XYZ(%rip)570; CHECK-NEXT: movl $1, XYZ(%rip)571entry:572 %0 = icmp eq i32 undef, 0573 br i1 %0, label %bbx, label %bby574 575bby:576 switch i32 undef, label %bb7 [577 i32 16, label %return578 ]579 580bb7:581 store volatile i32 0, ptr @XYZ582 store volatile i32 1, ptr @XYZ583 unreachable584 585bbx:586 switch i32 undef, label %bb12 [587 i32 128, label %return588 ]589 590bb12:591 store volatile i32 0, ptr @XYZ592 store volatile i32 1, ptr @XYZ593 unreachable594 595return:596 ret void597}598 599; two_minsize - Same as two, but with minsize instead of optsize.600 601define dso_local void @two_minsize() nounwind minsize {602; CHECK-LABEL: two_minsize:603; CHECK: # %bb.0: # %entry604; CHECK-NEXT: xorl %eax, %eax605; CHECK-NEXT: testb %al, %al606; CHECK-NEXT: xorl %eax, %eax607; CHECK-NEXT: testb %al, %al608; CHECK-NEXT: je .LBB9_1609; CHECK-NEXT: # %bb.2: # %return610; CHECK-NEXT: retq611; CHECK-NEXT: .LBB9_1: # %bb7612; CHECK-NEXT: movl $0, XYZ(%rip)613; CHECK-NEXT: movl $1, XYZ(%rip)614entry:615 %0 = icmp eq i32 undef, 0616 br i1 %0, label %bbx, label %bby617 618bby:619 switch i32 undef, label %bb7 [620 i32 16, label %return621 ]622 623bb7:624 store volatile i32 0, ptr @XYZ625 store volatile i32 1, ptr @XYZ626 unreachable627 628bbx:629 switch i32 undef, label %bb12 [630 i32 128, label %return631 ]632 633bb12:634 store volatile i32 0, ptr @XYZ635 store volatile i32 1, ptr @XYZ636 unreachable637 638return:639 ret void640}641 642; two_nosize - Same as two, but without the optsize attribute.643; Now two instructions are enough to be tail-duplicated.644 645define dso_local void @two_nosize(i32 %x, i32 %y, i32 %z) nounwind {646; CHECK-LABEL: two_nosize:647; CHECK: # %bb.0: # %entry648; CHECK-NEXT: testl %edi, %edi649; CHECK-NEXT: je .LBB10_3650; CHECK-NEXT: # %bb.1: # %bby651; CHECK-NEXT: testl %esi, %esi652; CHECK-NEXT: je .LBB10_4653; CHECK-NEXT: # %bb.2: # %bb7654; CHECK-NEXT: movl $0, XYZ(%rip)655; CHECK-NEXT: jmp tail_call_me # TAILCALL656; CHECK-NEXT: .LBB10_3: # %bbx657; CHECK-NEXT: cmpl $-1, %edx658; CHECK-NEXT: je .LBB10_4659; CHECK-NEXT: # %bb.5: # %bb12660; CHECK-NEXT: movl $0, XYZ(%rip)661; CHECK-NEXT: jmp tail_call_me # TAILCALL662; CHECK-NEXT: .LBB10_4: # %return663; CHECK-NEXT: retq664entry:665 %0 = icmp eq i32 %x, 0666 br i1 %0, label %bbx, label %bby667 668bby:669 switch i32 %y, label %bb7 [670 i32 0, label %return671 ]672 673bb7:674 store volatile i32 0, ptr @XYZ675 tail call void @tail_call_me()676 ret void677 678bbx:679 switch i32 %z, label %bb12 [680 i32 -1, label %return681 ]682 683bb12:684 store volatile i32 0, ptr @XYZ685 tail call void @tail_call_me()686 ret void687 688return:689 ret void690}691 692; Tail-merging should merge the two ret instructions since one side693; can fall-through into the ret and the other side has to branch anyway.694 695define i64 @TESTE(i64 %parami, i64 %paraml) nounwind readnone {696; CHECK-LABEL: TESTE:697; CHECK: # %bb.0: # %entry698; CHECK-NEXT: testq %rdi, %rdi699; CHECK-NEXT: movl $1, %eax700; CHECK-NEXT: cmovgq %rdi, %rax701; CHECK-NEXT: testq %rsi, %rsi702; CHECK-NEXT: jle .LBB11_2703; CHECK-NEXT: # %bb.1: # %bb.nph704; CHECK-NEXT: imulq %rdi, %rsi705; CHECK-NEXT: movq %rsi, %rax706; CHECK-NEXT: .LBB11_2: # %for.end707; CHECK-NEXT: retq708entry:709 %cmp = icmp slt i64 %parami, 1 ; <i1> [#uses=1]710 %varx.0 = select i1 %cmp, i64 1, i64 %parami ; <i64> [#uses=1]711 %cmp410 = icmp slt i64 %paraml, 1 ; <i1> [#uses=1]712 br i1 %cmp410, label %for.end, label %bb.nph713 714bb.nph: ; preds = %entry715 %tmp15 = mul i64 %paraml, %parami ; <i64> [#uses=1]716 ret i64 %tmp15717 718for.end: ; preds = %entry719 ret i64 %varx.0720}721 722; We should tail merge small blocks that don't end in a tail call or return723; instruction. Those blocks are typically unreachable and will be placed724; out-of-line after the main return, so we should try to eliminate as many of725; them as possible.726 727declare dso_local void @abort()728define dso_local void @merge_aborts() {729; CHECK-LABEL: merge_aborts:730; CHECK: # %bb.0: # %entry731; CHECK-NEXT: pushq %rax732; CHECK-NEXT: .cfi_def_cfa_offset 16733; CHECK-NEXT: callq qux@PLT734; CHECK-NEXT: testb $1, %al735; CHECK-NEXT: je .LBB12_5736; CHECK-NEXT: # %bb.1: # %cont1737; CHECK-NEXT: callq qux@PLT738; CHECK-NEXT: testb $1, %al739; CHECK-NEXT: je .LBB12_5740; CHECK-NEXT: # %bb.2: # %cont2741; CHECK-NEXT: callq qux@PLT742; CHECK-NEXT: testb $1, %al743; CHECK-NEXT: je .LBB12_5744; CHECK-NEXT: # %bb.3: # %cont3745; CHECK-NEXT: callq qux@PLT746; CHECK-NEXT: testb $1, %al747; CHECK-NEXT: je .LBB12_5748; CHECK-NEXT: # %bb.4: # %cont4749; CHECK-NEXT: popq %rax750; CHECK-NEXT: .cfi_def_cfa_offset 8751; CHECK-NEXT: retq752; CHECK-NEXT: .LBB12_5: # %abort1753; CHECK-NEXT: .cfi_def_cfa_offset 16754; CHECK-NEXT: callq abort755entry:756 %c1 = call i1 @qux()757 br i1 %c1, label %cont1, label %abort1758abort1:759 call void @abort()760 unreachable761cont1:762 %c2 = call i1 @qux()763 br i1 %c2, label %cont2, label %abort2764abort2:765 call void @abort()766 unreachable767cont2:768 %c3 = call i1 @qux()769 br i1 %c3, label %cont3, label %abort3770abort3:771 call void @abort()772 unreachable773cont3:774 %c4 = call i1 @qux()775 br i1 %c4, label %cont4, label %abort4776abort4:777 call void @abort()778 unreachable779cont4:780 ret void781}782 783; Use alternating abort functions so that the blocks we wish to merge are not784; layout successors during branch folding.785 786declare dso_local void @alt_abort()787 788define dso_local void @merge_alternating_aborts() {789; CHECK-LABEL: merge_alternating_aborts:790; CHECK: # %bb.0: # %entry791; CHECK-NEXT: pushq %rax792; CHECK-NEXT: .cfi_def_cfa_offset 16793; CHECK-NEXT: callq qux@PLT794; CHECK-NEXT: testb $1, %al795; CHECK-NEXT: je .LBB13_5796; CHECK-NEXT: # %bb.1: # %cont1797; CHECK-NEXT: callq qux@PLT798; CHECK-NEXT: testb $1, %al799; CHECK-NEXT: je .LBB13_6800; CHECK-NEXT: # %bb.2: # %cont2801; CHECK-NEXT: callq qux@PLT802; CHECK-NEXT: testb $1, %al803; CHECK-NEXT: je .LBB13_5804; CHECK-NEXT: # %bb.3: # %cont3805; CHECK-NEXT: callq qux@PLT806; CHECK-NEXT: testb $1, %al807; CHECK-NEXT: je .LBB13_6808; CHECK-NEXT: # %bb.4: # %cont4809; CHECK-NEXT: popq %rax810; CHECK-NEXT: .cfi_def_cfa_offset 8811; CHECK-NEXT: retq812; CHECK-NEXT: .LBB13_5: # %abort1813; CHECK-NEXT: .cfi_def_cfa_offset 16814; CHECK-NEXT: callq abort815; CHECK-NEXT: .LBB13_6: # %abort2816; CHECK-NEXT: callq alt_abort817entry:818 %c1 = call i1 @qux()819 br i1 %c1, label %cont1, label %abort1820abort1:821 call void @abort()822 unreachable823cont1:824 %c2 = call i1 @qux()825 br i1 %c2, label %cont2, label %abort2826abort2:827 call void @alt_abort()828 unreachable829cont2:830 %c3 = call i1 @qux()831 br i1 %c3, label %cont3, label %abort3832abort3:833 call void @abort()834 unreachable835cont3:836 %c4 = call i1 @qux()837 br i1 %c4, label %cont4, label %abort4838abort4:839 call void @alt_abort()840 unreachable841cont4:842 ret void843}844 845; This triggers a situation where a new block (bb4 is split) is created and then846; would be passed to the PGSO interface llvm::shouldOptimizeForSize().847@GV = dso_local global i32 0848define dso_local void @bfi_new_block_pgso(i32 %c) nounwind {849; CHECK-LABEL: bfi_new_block_pgso:850; CHECK: # %bb.0: # %entry851; CHECK-NEXT: testl %edi, %edi852; CHECK-NEXT: je .LBB14_6853; CHECK-NEXT: # %bb.1: # %bb1854; CHECK-NEXT: pushq %rax855; CHECK-NEXT: cmpl $16, %edi856; CHECK-NEXT: je .LBB14_3857; CHECK-NEXT: # %bb.2: # %bb1858; CHECK-NEXT: cmpl $17, %edi859; CHECK-NEXT: je .LBB14_4860; CHECK-NEXT: # %bb.5: # %bb4861; CHECK-NEXT: popq %rax862; CHECK-NEXT: jmp tail_call_me # TAILCALL863; CHECK-NEXT: .LBB14_6: # %bb5864; CHECK-NEXT: cmpl $128, %edi865; CHECK-NEXT: jne tail_call_me # TAILCALL866; CHECK-NEXT: # %bb.7: # %return867; CHECK-NEXT: retq868; CHECK-NEXT: .LBB14_3: # %bb3869; CHECK-NEXT: movl $0, GV(%rip)870; CHECK-NEXT: .LBB14_4: # %bb4871; CHECK-NEXT: callq func872; CHECK-NEXT: popq %rax873; CHECK-NEXT: jmp tail_call_me # TAILCALL874entry:875 %0 = icmp eq i32 %c, 0876 br i1 %0, label %bb5, label %bb1877 878bb1:879 switch i32 %c, label %bb4 [880 i32 16, label %bb3881 i32 17, label %bb2882 ]883 884bb2:885 call void @func()886 br label %bb4887 888bb3:889 store i32 0, ptr @GV890 call void @func()891 br label %bb4892 893bb4:894 tail call void @tail_call_me()895 br label %return896 897bb5:898 switch i32 %c, label %bb6 [899 i32 128, label %return900 ]901 902bb6:903 tail call void @tail_call_me()904 br label %return905 906return:907 ret void908}909 910!llvm.module.flags = !{!0}911!0 = !{i32 1, !"ProfileSummary", !1}912!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}913!2 = !{!"ProfileFormat", !"InstrProf"}914!3 = !{!"TotalCount", i64 10000}915!4 = !{!"MaxCount", i64 10}916!5 = !{!"MaxInternalCount", i64 1}917!6 = !{!"MaxFunctionCount", i64 1000}918!7 = !{!"NumCounts", i64 3}919!8 = !{!"NumFunctions", i64 3}920!9 = !{!"DetailedSummary", !10}921!10 = !{!11, !12, !13}922!11 = !{i32 10000, i64 100, i32 1}923!12 = !{i32 999000, i64 100, i32 1}924!13 = !{i32 999999, i64 1, i32 2}925!14 = !{!"function_entry_count", i64 0}926