[PATCH] D43759: [SCEV] Smarter logic in computeConstantDifference
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 26 03:05:43 PST 2018
mkazantsev created this revision.
mkazantsev added reviewers: sanjoy, apilipenko, anna, reames.
Current implementation of `computeConstantDifference` is limited to handling a bunch
of particular cases in order to prevent SCEV from making too complex transforms and
keep it fast. This code basically duplicates logic of `getAddExpr` in some limited variant.
This patch proposes an alternative way of restraining SCEV from making complex transforms.
Instead of duplication of logic, we can simply call `getMinusSCEV` with `Depth` parameter close
to its limit value. Currently I set it to `MaxArithDepth - 1` because it is sufficient to handle a
typical case `LHS = {X + C1,+,step}, RHS = {X + C2,+,step}` which is not handled by existing
implementation. I intentionally prefer making it via limiting depth and not via making one more
code duplication to handle this case.
As a result of this change, SCEV is now able to prove non-negativity of the indvar in
decrementing loop with signed latch condition and widen this condition.
https://reviews.llvm.org/D43759
Files:
lib/Analysis/ScalarEvolution.cpp
test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
Index: test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
===================================================================
--- test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
+++ test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
@@ -101,3 +101,34 @@
return: ; preds = %bb
ret void
}
+
+define void @promote_latch_condition_decrementing_loop_01(i32* %p, i32* %a) {
+
+; CHECK-LABEL: @promote_latch_condition_decrementing_loop_01(
+; CHECK-NOT: trunc
+
+entry:
+ %len = load i32, i32* %p, align 4, !range !0
+ %len.minus.1 = add nsw i32 %len, -1
+ %zero_check = icmp eq i32 %len, 0
+ br i1 %zero_check, label %loopexit, label %preheader
+
+preheader:
+ br label %loop
+
+loopexit:
+ ret void
+
+loop:
+ %iv = phi i32 [ %iv.next, %loop ], [ %len.minus.1, %preheader ]
+ ; CHECK: %indvars.iv = phi i64
+ %iv.wide = zext i32 %iv to i64
+ %el = getelementptr inbounds i32, i32* %a, i64 %iv.wide
+ store atomic i32 0, i32* %el unordered, align 4
+ %iv.next = add nsw i32 %iv, -1
+ ; CHECK: %loopcond = icmp slt i64 %indvars.iv, 1
+ %loopcond = icmp slt i32 %iv, 1
+ br i1 %loopcond, label %loopexit, label %loop
+}
+
+!0 = !{i32 0, i32 2147483647}
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -9369,10 +9369,7 @@
Optional<APInt> ScalarEvolution::computeConstantDifference(const SCEV *More,
const SCEV *Less) {
- // We avoid subtracting expressions here because this function is usually
- // fairly deep in the call stack (i.e. is called many times).
-
- if (isa<SCEVAddRecExpr>(Less) && isa<SCEVAddRecExpr>(More)) {
+ while (isa<SCEVAddRecExpr>(Less) && isa<SCEVAddRecExpr>(More)) {
const auto *LAR = cast<SCEVAddRecExpr>(Less);
const auto *MAR = cast<SCEVAddRecExpr>(More);
@@ -9393,24 +9390,11 @@
// fall through
}
- if (isa<SCEVConstant>(Less) && isa<SCEVConstant>(More)) {
- const auto &M = cast<SCEVConstant>(More)->getAPInt();
- const auto &L = cast<SCEVConstant>(Less)->getAPInt();
- return M - L;
- }
-
- const SCEV *L, *R;
- SCEV::NoWrapFlags Flags;
- if (splitBinaryAdd(Less, L, R, Flags))
- if (const auto *LC = dyn_cast<SCEVConstant>(L))
- if (R == More)
- return -(LC->getAPInt());
-
- if (splitBinaryAdd(More, L, R, Flags))
- if (const auto *LC = dyn_cast<SCEVConstant>(L))
- if (R == Less)
- return LC->getAPInt();
-
+ // We limit recursion depth here because this function is usually
+ // fairly deep in the call stack (i.e. is called many times).
+ if (auto *Difference = dyn_cast<SCEVConstant>(
+ getMinusSCEV(More, Less, SCEV::FlagAnyWrap, MaxArithDepth - 1)))
+ return Difference->getAPInt();
return None;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43759.135879.patch
Type: text/x-patch
Size: 2894 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180226/4c56e9b0/attachment.bin>
More information about the llvm-commits
mailing list