summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-03-27 04:54:00 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-03-27 04:54:00 +0000
commita63d333881e20f3df462263ad6bc557ae3c3e024 (patch)
treee98775e94960286740a8387f2c6b02abb120112b
parent44a23f42837a680b00f88389a4695845016da6ac (diff)
downloadbcm5719-llvm-a63d333881e20f3df462263ad6bc557ae3c3e024.tar.gz
bcm5719-llvm-a63d333881e20f3df462263ad6bc557ae3c3e024.zip
[SCEV] Add one more case in computeConstantDifference
This patch teaches `computeConstantDifference` handle calculation of constant difference between `(X + C1)` and `(X + C2)` which is `(C2 - C1)`. Differential Revision: https://reviews.llvm.org/D43759 Reviewed By: anna llvm-svn: 328609
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp28
-rw-r--r--llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll89
2 files changed, 107 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 004eac7f555..b44107d9a89 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9449,17 +9449,25 @@ Optional<APInt> ScalarEvolution::computeConstantDifference(const SCEV *More,
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();
+ const SCEV *LLess = nullptr, *RLess = nullptr;
+ const SCEV *LMore = nullptr, *RMore = nullptr;
+ const SCEVConstant *C1 = nullptr, *C2 = nullptr;
+ // Compare (X + C1) vs X.
+ if (splitBinaryAdd(Less, LLess, RLess, Flags))
+ if ((C1 = dyn_cast<SCEVConstant>(LLess)))
+ if (RLess == More)
+ return -(C1->getAPInt());
+
+ // Compare X vs (X + C2).
+ if (splitBinaryAdd(More, LMore, RMore, Flags))
+ if ((C2 = dyn_cast<SCEVConstant>(LMore)))
+ if (RMore == Less)
+ return C2->getAPInt();
+
+ // Compare (X + C1) vs (X + C2).
+ if (C1 && C2 && RLess == RMore)
+ return C2->getAPInt() - C1->getAPInt();
return None;
}
diff --git a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
index 956999b7cde..5872e4e03a8 100644
--- a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
+++ b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
@@ -101,3 +101,92 @@ bb: ; preds = %bb, %bb.thread
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
+}
+
+define void @promote_latch_condition_decrementing_loop_02(i32* %p, i32* %a) {
+
+; CHECK-LABEL: @promote_latch_condition_decrementing_loop_02(
+; CHECK-NOT: trunc
+
+entry:
+ %len = load i32, i32* %p, align 4, !range !0
+ %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, %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
+}
+
+define void @promote_latch_condition_decrementing_loop_03(i32* %p, i32* %a) {
+
+; CHECK-LABEL: @promote_latch_condition_decrementing_loop_03(
+; CHECK-NOT: trunc
+
+entry:
+ %len = load i32, i32* %p, align 4, !range !0
+ %len.plus.1 = add 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.plus.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}
OpenPOWER on IntegriCloud