llvm.org GIT mirror llvm / a2389c7
Re-commit r357452: SimplifyCFG SinkCommonCodeFromPredecessors: Also sink function calls without used results (PR41259) The original commit caused false positives from AddressSanitizer's use-after-scope checks, which have now been fixed in r358478. > The code was previously checking that candidates for sinking had exactly > one use or were a store instruction (which can't have uses). This meant > we could sink call instructions only if they had a use. > > That limitation seemed a bit arbitrary, so this patch changes it to > "instruction has zero or one use" which seems more natural and removes > the need to special-case stores. > > Differential revision: https://reviews.llvm.org/D59936 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358483 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 9 months ago
6 changed file(s) with 125 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
14371437 static bool canSinkInstructions(
14381438 ArrayRef Insts,
14391439 DenseMap> &PHIOperands) {
1440 // Prune out obviously bad instructions to move. Any non-store instruction
1441 // must have exactly one use, and we check later that use is by a single,
1442 // common PHI instruction in the successor.
1440 // Prune out obviously bad instructions to move. Each instruction must have
1441 // exactly zero or one use, and we check later that use is by a single, common
1442 // PHI instruction in the successor.
1443 bool HasUse = !Insts.front()->user_empty();
14431444 for (auto *I : Insts) {
14441445 // These instructions may change or break semantics if moved.
14451446 if (isa(I) || I->isEHPad() || isa(I) ||
14531454 if (C->isInlineAsm())
14541455 return false;
14551456
1456 // Everything must have only one use too, apart from stores which
1457 // have no uses.
1458 if (!isa(I) && !I->hasOneUse())
1457 // Each instruction must have zero or one use.
1458 if (HasUse && !I->hasOneUse())
1459 return false;
1460 if (!HasUse && !I->user_empty())
14591461 return false;
14601462 }
14611463
14641466 if (!I->isSameOperationAs(I0))
14651467 return false;
14661468
1467 // All instructions in Insts are known to be the same opcode. If they aren't
1468 // stores, check the only user of each is a PHI or in the same block as the
1469 // instruction, because if a user is in the same block as an instruction
1470 // we're contemplating sinking, it must already be determined to be sinkable.
1471 if (!isa(I0)) {
1469 // All instructions in Insts are known to be the same opcode. If they have a
1470 // use, check that the only user is a PHI or in the same block as the
1471 // instruction, because if a user is in the same block as an instruction we're
1472 // contemplating sinking, it must already be determined to be sinkable.
1473 if (HasUse) {
14721474 auto *PNUse = dyn_cast(*I0->user_begin());
14731475 auto *Succ = I0->getParent()->getTerminator()->getSuccessor(0);
14741476 if (!all_of(Insts, [&PNUse,&Succ](const Instruction *I) -> bool {
15461548 // it is slightly over-aggressive - it gets confused by commutative instructions
15471549 // so double-check it here.
15481550 Instruction *I0 = Insts.front();
1549 if (!isa(I0)) {
1551 if (!I0->user_empty()) {
15501552 auto *PNUse = dyn_cast(*I0->user_begin());
15511553 if (!all_of(Insts, [&PNUse](const Instruction *I) -> bool {
15521554 auto *U = cast(*I->user_begin());
16041606 I0->andIRFlags(I);
16051607 }
16061608
1607 if (!isa(I0)) {
1609 if (!I0->user_empty()) {
16081610 // canSinkLastInstruction checked that all instructions were used by
16091611 // one and only one PHI node. Find that now, RAUW it to our common
16101612 // instruction and nuke it.
1611 assert(I0->hasOneUse());
16121613 auto *PN = cast(*I0->user_begin());
16131614 PN->replaceAllUsesWith(I0);
16141615 PN->eraseFromParent();
33 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t
44 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m3 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM3 < %t
55
6 declare void @ext(i32)
6 declare void @ext(i32, i32)
77
88 define i32 @jt1(i32 %a, i32 %b) {
99 entry:
4444 ; CHECKM3-NEXT: %jump-table.0:
4545 ; CHECKM3-NOT: %jump-table.1:
4646
47 bb1: tail call void @ext(i32 0) br label %return
48 bb2: tail call void @ext(i32 2) br label %return
49 bb3: tail call void @ext(i32 4) br label %return
50 bb4: tail call void @ext(i32 6) br label %return
51 bb5: tail call void @ext(i32 8) br label %return
52 bb6: tail call void @ext(i32 10) br label %return
53 bb7: tail call void @ext(i32 12) br label %return
54 bb8: tail call void @ext(i32 14) br label %return
55 bb9: tail call void @ext(i32 16) br label %return
56 bb10: tail call void @ext(i32 18) br label %return
57 bb11: tail call void @ext(i32 20) br label %return
58 bb12: tail call void @ext(i32 22) br label %return
59 bb13: tail call void @ext(i32 24) br label %return
60 bb14: tail call void @ext(i32 26) br label %return
61 bb15: tail call void @ext(i32 28) br label %return
62 bb16: tail call void @ext(i32 30) br label %return
63 bb17: tail call void @ext(i32 32) br label %return
47 bb1: tail call void @ext(i32 1, i32 0) br label %return
48 bb2: tail call void @ext(i32 2, i32 2) br label %return
49 bb3: tail call void @ext(i32 3, i32 4) br label %return
50 bb4: tail call void @ext(i32 4, i32 6) br label %return
51 bb5: tail call void @ext(i32 5, i32 8) br label %return
52 bb6: tail call void @ext(i32 6, i32 10) br label %return
53 bb7: tail call void @ext(i32 7, i32 12) br label %return
54 bb8: tail call void @ext(i32 8, i32 14) br label %return
55 bb9: tail call void @ext(i32 9, i32 16) br label %return
56 bb10: tail call void @ext(i32 1, i32 18) br label %return
57 bb11: tail call void @ext(i32 2, i32 20) br label %return
58 bb12: tail call void @ext(i32 3, i32 22) br label %return
59 bb13: tail call void @ext(i32 4, i32 24) br label %return
60 bb14: tail call void @ext(i32 5, i32 26) br label %return
61 bb15: tail call void @ext(i32 6, i32 28) br label %return
62 bb16: tail call void @ext(i32 7, i32 30) br label %return
63 bb17: tail call void @ext(i32 8, i32 32) br label %return
6464
6565 return: ret i32 %b
6666 }
9090 ; CHECKM3-NOT: %jump-table.1
9191 ; CHECK-DAG: End machine code for function jt2.
9292
93 bb1: tail call void @ext(i32 1) br label %return
94 bb2: tail call void @ext(i32 2) br label %return
95 bb3: tail call void @ext(i32 3) br label %return
96 bb4: tail call void @ext(i32 4) br label %return
97 bb5: tail call void @ext(i32 5) br label %return
98 bb6: tail call void @ext(i32 6) br label %return
93 bb1: tail call void @ext(i32 6, i32 1) br label %return
94 bb2: tail call void @ext(i32 5, i32 2) br label %return
95 bb3: tail call void @ext(i32 4, i32 3) br label %return
96 bb4: tail call void @ext(i32 3, i32 4) br label %return
97 bb5: tail call void @ext(i32 2, i32 5) br label %return
98 bb6: tail call void @ext(i32 1, i32 6) br label %return
9999 return: ret void
100100 }
11 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -min-jump-table-entries=4 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4 < %t
22 ; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -min-jump-table-entries=8 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8 < %t
33
4 declare void @ext(i32)
4 declare void @ext(i32, i32)
55
66 define i32 @jt2(i32 %a, i32 %b) {
77 entry:
1616 ; CHECK4-NOT: {{^}}Jump Tables:
1717 ; CHECK8-NOT: {{^}}Jump Tables:
1818
19 bb1: tail call void @ext(i32 0) br label %return
20 bb2: tail call void @ext(i32 2) br label %return
19 bb1: tail call void @ext(i32 1, i32 0) br label %return
20 bb2: tail call void @ext(i32 2, i32 2) br label %return
2121
2222 return: ret i32 %b
2323 }
3939 ; CHECK4-NOT: %jump-table.1:
4040 ; CHECK8-NOT: {{^}}Jump Tables:
4141
42 bb1: tail call void @ext(i32 0) br label %return
43 bb2: tail call void @ext(i32 2) br label %return
44 bb3: tail call void @ext(i32 4) br label %return
45 bb4: tail call void @ext(i32 6) br label %return
42 bb1: tail call void @ext(i32 1, i32 0) br label %return
43 bb2: tail call void @ext(i32 3, i32 2) br label %return
44 bb3: tail call void @ext(i32 4, i32 4) br label %return
45 bb4: tail call void @ext(i32 5, i32 6) br label %return
4646
4747 return: ret i32 %b
4848 }
6464 ; CHECK-NEXT: %jump-table.0:
6565 ; CHECK-NOT: %jump-table.1:
6666
67 bb1: tail call void @ext(i32 0) br label %return
68 bb2: tail call void @ext(i32 2) br label %return
69 bb3: tail call void @ext(i32 4) br label %return
70 bb4: tail call void @ext(i32 6) br label %return
71 bb5: tail call void @ext(i32 8) br label %return
72 bb6: tail call void @ext(i32 10) br label %return
73 bb7: tail call void @ext(i32 12) br label %return
74 bb8: tail call void @ext(i32 14) br label %return
67 bb1: tail call void @ext(i32 1, i32 0) br label %return
68 bb2: tail call void @ext(i32 2, i32 2) br label %return
69 bb3: tail call void @ext(i32 3, i32 4) br label %return
70 bb4: tail call void @ext(i32 4, i32 6) br label %return
71 bb5: tail call void @ext(i32 5, i32 8) br label %return
72 bb6: tail call void @ext(i32 6, i32 10) br label %return
73 bb7: tail call void @ext(i32 7, i32 12) br label %return
74 bb8: tail call void @ext(i32 8, i32 14) br label %return
7575
7676 return: ret i32 %b
7777 }
88 i32 3, label %sw.bb3
99 ]
1010
11 sw.bb: ; preds = %entry
12 tail call void @g(i32 0) #2
11 sw.bb:
12 tail call void @g(i32 0, i32 4)
1313 br label %sw.epilog
1414
15 sw.bb1: ; preds = %entry
16 tail call void @g(i32 1) #2
15 sw.bb1:
16 tail call void @g(i32 1, i32 5)
1717 br label %sw.epilog
1818
19 sw.bb2: ; preds = %entry
20 tail call void @g(i32 2) #2
19 sw.bb2:
20 tail call void @g(i32 2, i32 6)
2121 br label %sw.epilog
2222
23 sw.bb3: ; preds = %entry
24 tail call void @g(i32 3) #2
23 sw.bb3:
24 tail call void @g(i32 3, i32 7)
2525 br label %sw.epilog
2626
27 sw.epilog: ; preds = %entry, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
28 tail call void @g(i32 10) #2
27 sw.epilog:
28 tail call void @g(i32 10, i32 8)
2929 ret void
3030 }
3131
32 declare void @g(i32)
32 declare void @g(i32, i32)
3333
34 ; CHECK: .text
35 ; CHECK: f:
36 ; CHECK: .seh_proc f
37 ; CHECK: b g
38 ; CHECK-NEXT: .p2align 2
39 ; CHECK-NEXT: .LJTI0_0:
40 ; CHECK: .word .LBB0_2-.LJTI0_0
41 ; CHECK: .word .LBB0_3-.LJTI0_0
42 ; CHECK: .word .LBB0_4-.LJTI0_0
43 ; CHECK: .word .LBB0_5-.LJTI0_0
44 ; CHECK: .section .xdata,"dr"
45 ; CHECK: .seh_handlerdata
46 ; CHECK: .text
47 ; CHECK: .seh_endproc
34 ; CHECK: .text
35 ; CHECK: f:
36 ; CHECK: .seh_proc f
37 ; CHECK: b g
38 ; CHECK-NEXT: .p2align 2
39 ; CHECK-NEXT: .LJTI0_0:
40 ; CHECK: .word .LBB0_2-.LJTI0_0
41 ; CHECK: .word .LBB0_3-.LJTI0_0
42 ; CHECK: .word .LBB0_4-.LJTI0_0
43 ; CHECK: .word .LBB0_5-.LJTI0_0
44 ; CHECK: .section .xdata,"dr"
45 ; CHECK: .seh_handlerdata
46 ; CHECK: .text
47 ; CHECK: .seh_endproc
1919 ; CHECK: [[FAILED]]:
2020 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
2121 ; CHECK: clrex
22 ; CHECK: movs r0, #0
2223 ; CHECK: dmb ish
23 ; CHECK: movs r0, #0
2424 ; CHECK: bx lr
2525
2626 ; CHECK: [[SUCCESS]]:
2727 ; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
28 ; CHECK: movs r0, #1
2829 ; CHECK: dmb ish
29 ; CHECK: movs r0, #1
3030 ; CHECK: bx lr
3131
3232 %pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
842842 ; CHECK: insertvalue
843843 ; CHECK-NOT: insertvalue
844844
845
846 declare void @baz(i32)
847
848 define void @test_sink_void_calls(i32 %x) {
849 entry:
850 switch i32 %x, label %default [
851 i32 0, label %bb0
852 i32 1, label %bb1
853 i32 2, label %bb2
854 i32 3, label %bb3
855 i32 4, label %bb4
856 ]
857 bb0:
858 call void @baz(i32 12)
859 br label %return
860 bb1:
861 call void @baz(i32 34)
862 br label %return
863 bb2:
864 call void @baz(i32 56)
865 br label %return
866 bb3:
867 call void @baz(i32 78)
868 br label %return
869 bb4:
870 call void @baz(i32 90)
871 br label %return
872 default:
873 unreachable
874 return:
875 ret void
876
877 ; Check that the calls get sunk to the return block.
878 ; We would previously not sink calls without uses, see PR41259.
879 ; CHECK-LABEL: @test_sink_void_calls
880 ; CHECK-NOT: call
881 ; CHECK-LABEL: return:
882 ; CHECK: phi
883 ; CHECK: call
884 ; CHECK-NOT: call
885 ; CHECK: ret
886 }
887
888
845889 ; CHECK: ![[$TBAA]] = !{![[TYPE:[0-9]]], ![[TYPE]], i64 0}
846890 ; CHECK: ![[TYPE]] = !{!"float", ![[TEXT:[0-9]]]}
847891 ; CHECK: ![[TEXT]] = !{!"an example type tree"}