[llvm] r350408 - [LICM] Adjust how moving the re-hoist point works
John Brawn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 4 09:12:09 PST 2019
Author: john.brawn
Date: Fri Jan 4 09:12:09 2019
New Revision: 350408
URL: http://llvm.org/viewvc/llvm-project?rev=350408&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/Scalar/LICM.cpp
llvm/trunk/test/Transforms/LICM/hoist-phi.ll
Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=350408&r1=350407&r2=350408&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Fri Jan 4 09:12:09 2019
@@ -809,14 +809,15 @@ bool llvm::hoistRegion(DomTreeNode *N, A
[&](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;
Modified: llvm/trunk/test/Transforms/LICM/hoist-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/hoist-phi.ll?rev=350408&r1=350407&r2=350408&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LICM/hoist-phi.ll (original)
+++ llvm/trunk/test/Transforms/LICM/hoist-phi.ll Fri Jan 4 09:12:09 2019
@@ -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
+}
More information about the llvm-commits
mailing list