[PATCH] D88210: [IndVars] Use knowledge about execution on last iteration when removing checks
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 28 00:04:05 PDT 2020
mkazantsev updated this revision to Diff 294611.
mkazantsev added a comment.
Rebased.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D88210/new/
https://reviews.llvm.org/D88210
Files:
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
Index: llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
+++ llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
@@ -21,8 +21,7 @@
; CHECK-NEXT: br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
; CHECK: range_check_block:
; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], 1
-; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[LEN]]
-; CHECK-NEXT: br i1 [[RANGE_CHECK]], label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
; CHECK: backedge:
; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, i32* [[P]], i32 [[IV]]
; CHECK-NEXT: [[EL:%.*]] = load i32, i32* [[EL_PTR]], align 4
Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -2484,6 +2484,8 @@
DeadInsts.emplace_back(OldCond);
};
+ const SCEV *MaxCheckExecutionCount = MaxExitCount;
+
bool Changed = false;
SmallSet<const SCEV*, 8> DominatingExitCounts;
for (BasicBlock *ExitingBB : ExitingBlocks) {
@@ -2503,9 +2505,38 @@
Changed = true;
else if (OptimizeCond(true, MaxExitCount))
Changed = true;
+ else if (MaxCheckExecutionCount != MaxExitCount) {
+ // If we cannot prove it on the last loop iteration, try to benefit
+ // from the fact that this check will not be executed on the last
+ // iteration.
+ // TODO: What we really want is to query with MaxCheckExecutionCount,
+ // and the check should only check the condition on pre-last iteration
+ // if the backedge was taken at least once. Consider loop:
+ //
+ // for (i = len; i != 0; i--) { ... check (i ult X) ... }
+ //
+ // If len = 0 then MaxExitCount = 0, and the pre-last iteration will
+ // not be executed at all. But SCEV does not always recognize this and
+ // may start thinking that i on the iteration (MaxExitCount - 1) is a
+ // huge value. So we just query this separately.
+ //
+ // The checks against MaxExitCount above can be removed once we find a
+ // good way to resolve this problem.
+ if (OptimizeCond(false, MaxCheckExecutionCount))
+ Changed = true;
+ else if (OptimizeCond(true, MaxCheckExecutionCount))
+ Changed = true;
+ }
continue;
}
+ if (MaxCheckExecutionCount == ExitCount)
+ // If the loop has more than 1 iteration, all further checks will be
+ // executed 1 iteration less.
+ MaxCheckExecutionCount = SE->getMinusSCEV(
+ MaxCheckExecutionCount, SE->getOne(MaxCheckExecutionCount->getType()),
+ SCEV::FlagNUW);
+
// If we know we'd exit on the first iteration, rewrite the exit to
// reflect this. This does not imply the loop must exit through this
// exit; there may be an earlier one taken on the first iteration.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88210.294611.patch
Type: text/x-patch
Size: 3169 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200928/6d2a4053/attachment.bin>
More information about the llvm-commits
mailing list