1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[LICM] Adjust how moving the re-hoist point works

In some cases the order that we hoist instructions in means that when rehoisting
(which uses the same order as hoisting) we can rehoist to a block A, then a
block B, then block A again. This currently causes an assertion failure as it
expects that when changing the hoist point it only ever moves to a block that
dominates the hoist point being moved from.

Fix this by moving the re-hoist point when it doesn't dominate the dominator of
hoisted instruction, or in other words when it wouldn't dominate the uses of
the instruction being rehoisted.

Differential Revision: https://reviews.llvm.org/D55266

llvm-svn: 350408
This commit is contained in:
John Brawn 2019-01-04 17:12:09 +00:00
parent a2be1b6bef
commit 8105587214
2 changed files with 168 additions and 3 deletions

View File

@ -809,14 +809,15 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
[&](Use &U) { return DT->dominates(I, U); })) {
BasicBlock *Dominator =
DT->getNode(I->getParent())->getIDom()->getBlock();
LLVM_DEBUG(dbgs() << "LICM rehoisting to " << Dominator->getName()
<< ": " << *I << "\n");
if (!HoistPoint || HoistPoint->getParent() != Dominator) {
if (!HoistPoint || !DT->dominates(HoistPoint->getParent(), Dominator)) {
if (HoistPoint)
assert(DT->dominates(Dominator, HoistPoint->getParent()) &&
"New hoist point expected to dominate old hoist point");
HoistPoint = Dominator->getTerminator();
}
LLVM_DEBUG(dbgs() << "LICM rehoisting to "
<< HoistPoint->getParent()->getName()
<< ": " << *I << "\n");
moveInstructionBefore(*I, *HoistPoint, *SafetyInfo);
HoistPoint = I;
Changed = true;

View File

@ -1349,3 +1349,167 @@ if.then3:
loop.backedge:
br label %loop
}
; The order that we hoist instructions from the loop is different to the textual
; order in the function. Check that we can rehoist this correctly.
; CHECK-LABEL: @rehoist_wrong_order_1
define void @rehoist_wrong_order_1(i32* %ptr) {
; CHECK-LABEL: entry
; CHECK-DAG: %gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
; CHECK-DAG: %gep3 = getelementptr inbounds i32, i32* %ptr, i64 3
; CHECK-DAG: %gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
; CHECK-ENABLED: br i1 undef, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
entry:
br label %loop
; CHECK-ENABLED: [[IF1_LICM]]:
; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]
; CHECK-ENABLED: [[ELSE1_LICM]]:
; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
; CHECK-ENABLED: br i1 undef, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
; CHECK-ENABLED: [[IF3_LICM]]:
; CHECK-ENABLED: br label %[[END_LICM]]
; CHECK-ENABLED: [[END_LICM]]:
; CHECK: br label %loop
loop:
br i1 undef, label %if1, label %else1
if1:
%gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
store i32 0, i32* %gep1, align 4
br label %loop.backedge
else1:
%gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
store i32 0, i32* %gep2, align 4
br i1 undef, label %if2, label %loop.backedge
if2:
br i1 undef, label %if3, label %end
if3:
%gep3 = getelementptr inbounds i32, i32* %ptr, i64 3
store i32 0, i32* %gep3, align 4
br label %end
end:
br label %loop.backedge
loop.backedge:
br label %loop
}
; CHECK-LABEL: @rehoist_wrong_order_2
define void @rehoist_wrong_order_2(i32* %ptr) {
; CHECK-LABEL: entry
; CHECK-DAG: %gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
; CHECK-DAG: %gep3 = getelementptr inbounds i32, i32* %gep2, i64 3
; CHECK-DAG: %gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
; CHECK-ENABLED: br i1 undef, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
entry:
br label %loop
; CHECK-ENABLED: [[IF1_LICM]]:
; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM:.*]]
; CHECK-ENABLED: [[ELSE1_LICM]]:
; CHECK-ENABLED: br label %[[LOOP_BACKEDGE_LICM]]
; CHECK-ENABLED: [[LOOP_BACKEDGE_LICM]]:
; CHECK-ENABLED: br i1 undef, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
; CHECK-ENABLED: [[IF3_LICM]]:
; CHECK-ENABLED: br label %[[END_LICM]]
; CHECK-ENABLED: [[END_LICM]]:
; CHECK: br label %loop
loop:
br i1 undef, label %if1, label %else1
if1:
%gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
store i32 0, i32* %gep1, align 4
br label %loop.backedge
else1:
%gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
store i32 0, i32* %gep2, align 4
br i1 undef, label %if2, label %loop.backedge
if2:
br i1 undef, label %if3, label %end
if3:
%gep3 = getelementptr inbounds i32, i32* %gep2, i64 3
store i32 0, i32* %gep3, align 4
br label %end
end:
br label %loop.backedge
loop.backedge:
br label %loop
}
; CHECK-LABEL: @rehoist_wrong_order_3
define void @rehoist_wrong_order_3(i32* %ptr) {
; CHECK-LABEL: entry
; CHECK-DAG: %gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
; CHECK-DAG: %gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
; CHECK-ENABLED: br i1 undef, label %[[IF1_LICM:.*]], label %[[ELSE1_LICM:.*]]
entry:
br label %loop
; CHECK-ENABLED: [[IF1_LICM]]:
; CHECK-ENABLED: br label %[[IF2_LICM:.*]]
; CHECK-ENABLED: [[ELSE1_LICM]]:
; CHECK-ENABLED: br label %[[IF2_LICM]]
; CHECK-ENABLED: [[IF2_LICM]]:
; CHECK-ENABLED: %phi = phi i32* [ %gep1, %[[IF1_LICM]] ], [ %gep2, %[[ELSE1_LICM]] ]
; CHECK-ENABLED: %gep3 = getelementptr inbounds i32, i32* %phi, i64 3
; CHECK-ENABLED: br i1 undef, label %[[IF3_LICM:.*]], label %[[END_LICM:.*]]
; CHECK-ENABLED: [[IF3_LICM]]:
; CHECK-ENABLED: br label %[[END_LICM]]
; CHECK-ENABLED: [[END_LICM]]:
; CHECK: br label %loop
loop:
br i1 undef, label %if1, label %else1
if1:
%gep1 = getelementptr inbounds i32, i32* %ptr, i64 1
store i32 0, i32* %gep1, align 4
br label %if2
else1:
%gep2 = getelementptr inbounds i32, i32* %ptr, i64 2
store i32 0, i32* %gep2, align 4
br i1 undef, label %if2, label %loop.backedge
if2:
%phi = phi i32* [ %gep1, %if1 ], [ %gep2, %else1 ]
br i1 undef, label %if3, label %end
if3:
%gep3 = getelementptr inbounds i32, i32* %phi, i64 3
store i32 0, i32* %gep3, align 4
br label %end
end:
br label %loop.backedge
loop.backedge:
br label %loop
}