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:
parent
a2be1b6bef
commit
8105587214
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user