[llvm] r335292 - [SCEV] Re-apply r335197 (with Polly fixes).

Tim Shen via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 21 14:29:54 PDT 2018


Author: timshen
Date: Thu Jun 21 14:29:54 2018
New Revision: 335292

URL: http://llvm.org/viewvc/llvm-project?rev=335292&view=rev
Log:
[SCEV] Re-apply r335197 (with Polly fixes).

Summary:
This initiates a discussion on changing Polly accordingly while re-applying r335197 (D48338).

I have never worked on Polly. The proposed change to param_div_div_div_2.ll is not educated, but just patterns that match the output.

All LLVM files are already reviewed in D48338.

Reviewers: jdoerfert, bollu, efriedma

Subscribers: jlebar, sanjoy, hiraditya, llvm-commits, bixia

Differential Revision: https://reviews.llvm.org/D48453

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/zext-divrem.ll
Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=335292&r1=335291&r2=335292&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Thu Jun 21 14:29:54 2018
@@ -1845,6 +1845,10 @@ private:
   /// accordingly.
   void addToLoopUseLists(const SCEV *S);
 
+  /// Try to match the pattern generated by getURemExpr(A, B). If successful,
+  /// Assign A and B to LHS and RHS, respectively.
+  bool matchURem(const SCEV *Expr, const SCEV *&LHS, const SCEV *&RHS);
+
   FoldingSet<SCEV> UniqueSCEVs;
   FoldingSet<SCEVPredicate> UniquePreds;
   BumpPtrAllocator SCEVAllocator;

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=335292&r1=335291&r2=335292&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Jun 21 14:29:54 2018
@@ -1756,6 +1756,20 @@ ScalarEvolution::getZeroExtendExpr(const
       }
     }
 
+  // zext(A % B) --> zext(A) % zext(B)
+  {
+    const SCEV *LHS;
+    const SCEV *RHS;
+    if (matchURem(Op, LHS, RHS))
+      return getURemExpr(getZeroExtendExpr(LHS, Ty, Depth + 1),
+                         getZeroExtendExpr(RHS, Ty, Depth + 1));
+  }
+
+  // zext(A / B) --> zext(A) / zext(B).
+  if (auto *Div = dyn_cast<SCEVUDivExpr>(Op))
+    return getUDivExpr(getZeroExtendExpr(Div->getLHS(), Ty, Depth + 1),
+                       getZeroExtendExpr(Div->getRHS(), Ty, Depth + 1));
+
   if (auto *SA = dyn_cast<SCEVAddExpr>(Op)) {
     // zext((A + B + ...)<nuw>) --> (zext(A) + zext(B) + ...)<nuw>
     if (SA->hasNoUnsignedWrap()) {
@@ -12153,3 +12167,43 @@ void PredicatedScalarEvolution::print(ra
       OS.indent(Depth + 2) << "--> " << *II->second.second << "\n";
     }
 }
+
+// Match the mathematical pattern A - (A / B) * B, where A and B can be
+// arbitrary expressions.
+// It's not always easy, as A and B can be folded (imagine A is X / 2, and B is
+// 4, A / B becomes X / 8).
+bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
+                                const SCEV *&RHS) {
+  const auto *Add = dyn_cast<SCEVAddExpr>(Expr);
+  if (Add == nullptr || Add->getNumOperands() != 2)
+    return false;
+
+  const SCEV *A = Add->getOperand(1);
+  const auto *Mul = dyn_cast<SCEVMulExpr>(Add->getOperand(0));
+
+  if (Mul == nullptr)
+    return false;
+
+  const auto MatchURemWithDivisor = [&](const SCEV *B) {
+    // (SomeExpr + (-(SomeExpr / B) * B)).
+    if (Expr == getURemExpr(A, B)) {
+      LHS = A;
+      RHS = B;
+      return true;
+    }
+    return false;
+  };
+
+  // (SomeExpr + (-1 * (SomeExpr / B) * B)).
+  if (Mul->getNumOperands() == 3 && isa<SCEVConstant>(Mul->getOperand(0)))
+    return MatchURemWithDivisor(Mul->getOperand(1)) ||
+           MatchURemWithDivisor(Mul->getOperand(2));
+
+  // (SomeExpr + ((-SomeExpr / B) * B)) or (SomeExpr + ((SomeExpr / B) * -B)).
+  if (Mul->getNumOperands() == 2)
+    return MatchURemWithDivisor(Mul->getOperand(1)) ||
+           MatchURemWithDivisor(Mul->getOperand(0)) ||
+           MatchURemWithDivisor(getNegativeSCEV(Mul->getOperand(1))) ||
+           MatchURemWithDivisor(getNegativeSCEV(Mul->getOperand(0)));
+  return false;
+}

Added: llvm/trunk/test/Analysis/ScalarEvolution/zext-divrem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/zext-divrem.ll?rev=335292&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/zext-divrem.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/zext-divrem.ll Thu Jun 21 14:29:54 2018
@@ -0,0 +1,42 @@
+; RUN: opt -analyze -scalar-evolution -S < %s | FileCheck %s
+
+define i64 @test1(i32 %a, i32 %b) {
+; CHECK-LABEL: @test1
+  %div = udiv i32 %a, %b
+  %zext = zext i32 %div to i64
+; CHECK: %zext
+; CHECK-NEXT: -->  ((zext i32 %a to i64) /u (zext i32 %b to i64))
+  ret i64 %zext
+}
+
+define i64 @test2(i32 %a, i32 %b) {
+; CHECK-LABEL: @test2
+  %rem = urem i32 %a, %b
+  %zext = zext i32 %rem to i64
+; CHECK: %zext
+; CHECK-NEXT: -->  ((zext i32 %a to i64) + (-1 * (zext i32 %b to i64) * ((zext i32 %a to i64) /u (zext i32 %b to i64))))
+  ret i64 %zext
+}
+
+define i64 @test3(i32 %a, i32 %b) {
+; CHECK-LABEL: @test3
+  %div = udiv i32 %a, %b
+  %mul = mul i32 %div, %b
+  %sub = sub i32 %a, %mul
+  %zext = zext i32 %sub to i64
+; CHECK: %zext
+; CHECK-NEXT: -->  ((zext i32 %a to i64) + (-1 * (zext i32 %b to i64) * ((zext i32 %a to i64) /u (zext i32 %b to i64))))
+  ret i64 %zext
+}
+
+define i64 @test4(i32 %t) {
+; CHECK-LABEL: @test4
+  %a = udiv i32 %t, 2
+  %div = udiv i32 %t, 112
+  %mul = mul i32 %div, 56
+  %sub = sub i32 %a, %mul
+  %zext = zext i32 %sub to i64
+; CHECK: %zext
+; CHECK-NEXT: -->  ((-56 * ((zext i32 %t to i64) /u 112)) + ((zext i32 %t to i64) /u 2))
+  ret i64 %zext
+}




More information about the llvm-commits mailing list