std::pair<Intrinsic::ID, bool>
canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL);
+ /// Attempt to match a simple recurrence cycle of the form:
+ /// <Start, Op, Step> (using SCEV's notation)
+ /// In IR, this might look like:
+ /// %iv = phi Ty [%Start, %Entry], [%Inc, %backedge]
+ /// %inc = binop %iv, %step
+ /// NOTE: This is intentional simple. If you want the ability to analyze
+ /// non-trivial loop conditons, see ScalarEvolution instead.
+ bool matchSimpleRecurrence(PHINode *P, BinaryOperator *&BO,
+ Value *&Start, Value *&Step);
+
/// Return true if RHS is known to be implied true by LHS. Return false if
/// RHS is known to be implied false by LHS. Otherwise, return None if no
/// implication can be made.
return {Intrinsic::not_intrinsic, false};
}
+bool llvm::matchSimpleRecurrence(PHINode *P, BinaryOperator *&BO,
+ Value *&Start, Value *&Step) {
+ // Handle the case of a simple two-predecessor recurrence PHI.
+ // There's a lot more that could theoretically be done here, but
+ // this is sufficient to catch some interesting cases.
+ if (P->getNumIncomingValues() != 2)
+ return false;
+
+ for (unsigned i = 0; i != 2; ++i) {
+ Value *L = P->getIncomingValue(i);
+ Value *R = P->getIncomingValue(!i);
+ Operator *LU = dyn_cast<Operator>(L);
+ if (!LU)
+ continue;
+ unsigned Opcode = LU->getOpcode();
+
+ switch (Opcode) {
+ default:
+ continue;
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::Shl: {
+ Value *LL = LU->getOperand(0);
+ Value *LR = LU->getOperand(1);
+ // Find a recurrence.
+ if (LL == P)
+ L = LR;
+ else
+ continue; // Check for recurrence with L and R flipped.
+
+ break; // Match!
+ }
+
+ // TODO: Expand list -- xor, mul, div, gep, uaddo, etc..
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Mul: {
+ Value *LL = LU->getOperand(0);
+ Value *LR = LU->getOperand(1);
+ // Find a recurrence.
+ if (LL == P)
+ L = LR;
+ else if (LR == P)
+ L = LL;
+ else
+ continue; // Check for recurrence with L and R flipped.
+
+ break; // Match!
+ }
+ };
+
+ // We have matched a recurrence of the form:
+ // %iv = [R, %entry], [%iv.next, %backedge]
+ // %iv.next = binop %iv, L
+ BO = cast<BinaryOperator>(LU);
+ Start = R;
+ Step = L;
+ return true;
+ }
+ return false;
+}
+
/// Return true if "icmp Pred LHS RHS" is always true.
static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
const Value *RHS, const DataLayout &DL,