[PATCH] D34598: ScalarEvolution: Add URem support

Alexandre Isoard via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 28 11:36:39 PDT 2017


alexandre.isoard updated this revision to Diff 104482.
alexandre.isoard added a comment.

Fixed the short-circuit. (should be 0, not x)


https://reviews.llvm.org/D34598

Files:
  include/llvm/Analysis/ScalarEvolution.h
  lib/Analysis/ScalarEvolution.cpp
  test/Analysis/ScalarEvolution/flattened.ll
  test/Analysis/ScalarEvolution/urem-0.ll


Index: test/Analysis/ScalarEvolution/urem-0.ll
===================================================================
--- /dev/null
+++ test/Analysis/ScalarEvolution/urem-0.ll
@@ -0,0 +1,8 @@
+; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s
+
+; CHECK: -->  ((-27 * (%a /u 27)) + %a)
+
+define i8 @foo(i8 %a) {
+        %t0 = urem i8 %a, 27
+        ret i8 %t0
+}
Index: test/Analysis/ScalarEvolution/flattened.ll
===================================================================
--- /dev/null
+++ test/Analysis/ScalarEvolution/flattened.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s
+
+
+define void @foo([7 x i8]* %a) {
+entry:
+	br label %bb
+
+bb:
+	%idx = phi i64 [ 0, %entry ], [ %idx.incr, %bb ]
+	%i = udiv i64 %idx, 7
+	%j = urem i64 %idx, 7
+	%a.ptr = getelementptr [7 x i8], [7 x i8]* %a, i64 %i, i64 %j
+; CHECK: %a.ptr
+; CHECK-NEXT: -->  {%a,+,1}<nw><%bb>
+	%val = load i8, i8* %a.ptr
+	%idx.incr = add i64 %idx, 1
+	%test = icmp ne i64 %idx.incr, 35
+	br i1 %test, label %bb, label %exit
+
+exit:
+	ret void
+}
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -2935,6 +2935,23 @@
   return getOrCreateMulExpr(Ops, Flags);
 }
 
+/// Represents an unsigned remainder expression based on unsigned division.
+const SCEV *ScalarEvolution::getURemExpr(const SCEV *LHS,
+                                         const SCEV *RHS) {
+  assert(getEffectiveSCEVType(LHS->getType()) ==
+         getEffectiveSCEVType(RHS->getType()) &&
+         "SCEVURemExpr operand types don't match!");
+
+  // Short-circuit easy cases
+  if (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS))
+    if (RHSC->getValue()->equalsInt(1))
+      return getZero(LHS->getType()); // X urem 1 --> 0
+
+  const SCEV *UDiv = getUDivExpr(LHS, RHS);
+  const SCEV *Mult = getMulExpr(UDiv, RHS, SCEV::FlagNUW);
+  return getMinusSCEV(LHS, Mult, SCEV::FlagNUW);
+}
+
 /// Get a canonical unsigned division expression, or something simpler if
 /// possible.
 const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
@@ -4095,6 +4112,7 @@
   case Instruction::Sub:
   case Instruction::Mul:
   case Instruction::UDiv:
+  case Instruction::URem:
   case Instruction::And:
   case Instruction::Or:
   case Instruction::AShr:
@@ -5416,6 +5434,8 @@
     }
     case Instruction::UDiv:
       return getUDivExpr(getSCEV(BO->LHS), getSCEV(BO->RHS));
+    case Instruction::URem:
+      return getURemExpr(getSCEV(BO->LHS), getSCEV(BO->RHS));
     case Instruction::Sub: {
       SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
       if (BO->Op)
Index: include/llvm/Analysis/ScalarEvolution.h
===================================================================
--- include/llvm/Analysis/ScalarEvolution.h
+++ include/llvm/Analysis/ScalarEvolution.h
@@ -1244,6 +1244,7 @@
   }
   const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
   const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS);
+  const SCEV *getURemExpr(const SCEV *LHS, const SCEV *RHS);
   const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L,
                             SCEV::NoWrapFlags Flags);
   const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34598.104482.patch
Type: text/x-patch
Size: 3323 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170628/d17e7ac6/attachment.bin>


More information about the llvm-commits mailing list