summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp15
-rw-r--r--llvm/test/Analysis/ScalarEvolution/fold.ll28
2 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 840861653be..d6e64012126 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3066,6 +3066,21 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
}
}
}
+
+ // (A/B)/C --> A/(B*C) if safe and B*C can be folded.
+ if (const SCEVUDivExpr *OtherDiv = dyn_cast<SCEVUDivExpr>(LHS)) {
+ if (auto *DivisorConstant =
+ dyn_cast<SCEVConstant>(OtherDiv->getRHS())) {
+ bool Overflow = false;
+ APInt NewRHS =
+ DivisorConstant->getAPInt().umul_ov(RHSC->getAPInt(), Overflow);
+ if (Overflow) {
+ return getConstant(RHSC->getType(), 0, false);
+ }
+ return getUDivExpr(OtherDiv->getLHS(), getConstant(NewRHS));
+ }
+ }
+
// (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded.
if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(LHS)) {
SmallVector<const SCEV *, 4> Operands;
diff --git a/llvm/test/Analysis/ScalarEvolution/fold.ll b/llvm/test/Analysis/ScalarEvolution/fold.ll
index 226a24ff9c8..ba8f2310ba4 100644
--- a/llvm/test/Analysis/ScalarEvolution/fold.ll
+++ b/llvm/test/Analysis/ScalarEvolution/fold.ll
@@ -98,3 +98,31 @@ define void @test7(i32 %A) {
; CHECK-NEXT: --> 0
ret void
}
+
+define i64 @test8(i64 %a) {
+; CHECK-LABEL: @test8
+ %t0 = udiv i64 %a, 56
+ %t1 = udiv i64 %t0, 56
+; CHECK: %t1
+; CHECK-NEXT: --> (%a /u 3136)
+ ret i64 %t1
+}
+
+define i64 @test9(i64 %a) {
+; CHECK-LABEL: @test9
+ %t0 = udiv i64 %a, 100000000000000
+ %t1 = udiv i64 %t0, 100000000000000
+; CHECK: %t1
+; CHECK-NEXT: --> 0
+ ret i64 %t1
+}
+
+define i64 @test10(i64 %a, i64 %b) {
+; CHECK-LABEL: @test9
+ %t0 = udiv i64 %a, 100000000000000
+ %t1 = udiv i64 %t0, 100000000000000
+ %t2 = mul i64 %b, %t1
+; CHECK: %t2
+; CHECK-NEXT: --> 0
+ ret i64 %t2
+}
OpenPOWER on IntegriCloud