}
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,
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!");
-
- // TODO:
- // - short circuit '%a = %x urem %x --> 0' (why is it not done for udiv?)
- // - short circuit '%a = %x urem 0 --> %a' (same as for udiv)
- // - update upper-bound and lower-bound cache for the final result
- // (or improve how subtraction is estimated)
-
- // 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,
case Instruction::Sub:
case Instruction::Mul:
case Instruction::UDiv:
- case Instruction::URem:
case Instruction::And:
case Instruction::Or:
case Instruction::AShr:
}
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)
+++ /dev/null
-; 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
-}