[PATCH] D28536: [SCEV] Make howFarToZero max backedge-taken count check for precondition
Eli Friedman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 10 14:29:15 PST 2017
efriedma created this revision.
efriedma added a reviewer: sanjoy.
efriedma added a subscriber: llvm-commits.
efriedma set the repository for this revision to rL LLVM.
Herald added a subscriber: mzolotukhin.
Refines max backedge-taken count if a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated.
Repository:
rL LLVM
https://reviews.llvm.org/D28536
Files:
lib/Analysis/ScalarEvolution.cpp
test/Analysis/ScalarEvolution/max-trip-count.ll
Index: test/Analysis/ScalarEvolution/max-trip-count.ll
===================================================================
--- test/Analysis/ScalarEvolution/max-trip-count.ll
+++ test/Analysis/ScalarEvolution/max-trip-count.ll
@@ -242,9 +242,8 @@
ret i32 0
}
-; TODO: Improve count based on guard.
; CHECK-LABEL: @ne_max_trip_count_3
-; CHECK: Loop %for.body: max backedge-taken count is -1
+; CHECK: Loop %for.body: max backedge-taken count is 6
define i32 @ne_max_trip_count_3(i32 %n) {
entry:
%masked = and i32 %n, 7
@@ -267,9 +266,8 @@
ret i32 0
}
-; TODO: Improve count based on guard.
; CHECK-LABEL: @ne_max_trip_count_4
-; CHECK: Loop %for.body: max backedge-taken count is -1
+; CHECK: Loop %for.body: max backedge-taken count is -2
define i32 @ne_max_trip_count_4(i32 %n) {
entry:
%guard = icmp eq i32 %n, 0
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -7207,6 +7207,25 @@
// N = Distance (as unsigned)
if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) {
APInt MaxBECount = getUnsignedRange(Distance).getUnsignedMax();
+
+ // When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
+ // we end up with a loop whose backedge-taken count is n - 1. Detect this
+ // case, and see if we can improve the bound.
+ //
+ // Explicitly handling this here is necessary because getUnsignedRange
+ // isn't context-sensitive; it doesn't know that we only care about the
+ // range inside the loop.
+ const SCEV *Zero = getZero(Distance->getType());
+ const SCEV *One = getOne(Distance->getType());
+ const SCEV *DistancePlusOne = getAddExpr(Distance, One);
+ if (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, DistancePlusOne, Zero)) {
+ // If Distance + 1 doesn't overflow, we can compute the maximum distance
+ // as "unsigned_max(Distance + 1) - 1".
+ ConstantRange CR = getUnsignedRange(DistancePlusOne);
+ APInt NewMaxBECount = CR.getUnsignedMax() - 1;
+ if (NewMaxBECount.ult(MaxBECount))
+ MaxBECount = NewMaxBECount;
+ }
return ExitLimit(Distance, getConstant(MaxBECount), false, Predicates);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28536.83874.patch
Type: text/x-patch
Size: 2301 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170110/8a97dbc3/attachment.bin>
More information about the llvm-commits
mailing list