summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-10-31 10:30:50 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-10-31 10:30:50 +0000
commit541f824d32e8caee27f8fbd993a7dc8b63040b65 (patch)
tree3896001523dcaef3523721a53c3d8cab52c88d37
parent3d2ab50d33f84acb06e997522838a6a05fc77786 (diff)
downloadbcm5719-llvm-541f824d32e8caee27f8fbd993a7dc8b63040b65.tar.gz
bcm5719-llvm-541f824d32e8caee27f8fbd993a7dc8b63040b65.zip
[IndVars] Strengthen restricton in rewriteLoopExitValues
For some unclear reason rewriteLoopExitValues considers recalculation after the loop profitable if it has some "soft uses" outside the loop (i.e. any use other than call and return), even if we have proved that it has a user inside the loop which we think will not be optimized away. There is no existing unit test that would explain this. This patch provides an example when rematerialisation of exit value is not profitable but it passes this check due to presence of a "soft use" outside the loop. It makes no sense to recalculate value on exit if we are going to compute it due to some irremovable within the loop. This patch disallows applying this transform in the described situation. Differential Revision: https://reviews.llvm.org/D51581 Reviewed By: etherzhhb llvm-svn: 345708
-rw-r--r--llvm/lib/Transforms/Scalar/IndVarSimplify.cpp35
-rw-r--r--llvm/test/Transforms/IndVarSimplify/dont-recompute.ll26
2 files changed, 33 insertions, 28 deletions
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index c35478e220b..ec51ad71abc 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -595,41 +595,20 @@ bool IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
!isSafeToExpand(ExitValue, *SE))
continue;
- // Computing the value outside of the loop brings no benefit if :
- // - it is definitely used inside the loop in a way which can not be
- // optimized away.
- // - no use outside of the loop can take advantage of hoisting the
- // computation out of the loop
+ // Computing the value outside of the loop brings no benefit if it is
+ // definitely used inside the loop in a way which can not be optimized
+ // away.
if (ExitValue->getSCEVType()>=scMulExpr) {
bool HasHardInternalUses = false;
- bool HasSoftExternalUses = false;
for (auto *IB : Inst->users()) {
Instruction *UseInstr = cast<Instruction>(IB);
unsigned Opc = UseInstr->getOpcode();
- if (L->contains(UseInstr)) {
- if (Opc == Instruction::Call)
- HasHardInternalUses = true;
- } else {
- if (Opc == Instruction::PHI) {
- // Do not count the Phi as a use. LCSSA may have inserted
- // plenty of trivial ones.
- for (auto *PB : UseInstr->users()) {
- unsigned PhiOpc = cast<Instruction>(PB)->getOpcode();
- if (PhiOpc != Instruction::Call &&
- PhiOpc != Instruction::Ret) {
- HasSoftExternalUses = true;
- break;
- }
- }
- continue;
- }
- if (Opc != Instruction::Call && Opc != Instruction::Ret) {
- HasSoftExternalUses = true;
- break;
- }
+ if (L->contains(UseInstr) && Opc == Instruction::Call) {
+ HasHardInternalUses = true;
+ break;
}
}
- if (HasHardInternalUses && !HasSoftExternalUses)
+ if (HasHardInternalUses)
continue;
}
diff --git a/llvm/test/Transforms/IndVarSimplify/dont-recompute.ll b/llvm/test/Transforms/IndVarSimplify/dont-recompute.ll
index 713a55154ba..c87cd6596c6 100644
--- a/llvm/test/Transforms/IndVarSimplify/dont-recompute.ll
+++ b/llvm/test/Transforms/IndVarSimplify/dont-recompute.ll
@@ -97,3 +97,29 @@ for.end: ; preds = %for.body
tail call void @func(i32 %add)
ret void
}
+
+; CHECK-LABEL: @test4(
+define void @test4(i32 %m) nounwind uwtable {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
+ %add = add i32 %a.05, %m
+; CHECK: tail call void @func(i32 %add)
+ tail call void @func(i32 %add)
+ %inc = add nsw i32 %i.06, 1
+ %exitcond = icmp eq i32 %inc, 186
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+; CHECK: for.end:
+; CHECK-NOT: mul i32 %m, 186
+; CHECK:%add.lcssa = phi i32 [ %add, %for.body ]
+; CHECK-NEXT: %soft_use = add i32 %add.lcssa, 123
+; CHECK-NEXT: tail call void @func(i32 %soft_use)
+ %soft_use = add i32 %add, 123
+ tail call void @func(i32 %soft_use)
+ ret void
+}
OpenPOWER on IntegriCloud