Repository: llvm/llvm-project
File: llvm/lib/Analysis/ValueTracking.cpp (C++)

Code before:
    if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
        Operation && Operation->getNumOperands() >= 2) {
      Value *LHS = Operation->getOperand(0);
      Value *RHS = Operation->getOperand(1);
      if (LHS != PN && RHS != PN)
        continue;

      Inst = Operation;
      Init = PN->getIncomingValue(!I);
      OtherOp = (LHS == PN) ? RHS : LHS;
      return true;
    }
  }
  return false;
}

template <typename InstTy>
static bool matchThreeInputRecurrence(const PHINode *PN, InstTy *&Inst,
                                      Value *&Init, Value *&OtherOp0,
                                      Value *&OtherOp1) {
  if (PN->getNumIncomingValues() != 2)
    return false;

  for (unsigned I = 0; I != 2; ++I) {
    if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
        Operation && Operation->arg_size() == 3) {
      Value *Op0 = Operation->getOperand(0);
      Value *Op1 = Operation->getOperand(1);
      Value *Op2 = Operation->getOperand(2);

      if (Op0 != PN && Op1 != PN && Op2 != PN)
        continue;

      Inst = Operation;
      Init = PN->getIncomingValue(!I);
      if (Op0 == PN) {
        OtherOp0 = Op1;
        OtherOp1 = Op2;
      } else if (Op1 == PN) {
        OtherOp0 = Op0;
        OtherOp1 = Op2;
      } else {
        OtherOp0 = Op0;
        OtherOp1 = Op1;
      }
      return true;
    }
  }
  return false;
}
bool llvm::matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO,

Review comment (suggestion):
nit: I think you can use a `continue` here instead of nesting the body, right?

```suggestion
    auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
    if(!Operation || Operation->arg_size() != 3)
       continue;
```

Code after:
      Inst = Operation;
      Init = PN->getIncomingValue(!I);
      OtherOp = (LHS == PN) ? RHS : LHS;
      return true;
    }
  }
  return false;
}

template <typename InstTy>
static bool matchThreeInputRecurrence(const PHINode *PN, InstTy *&Inst,
                                      Value *&Init, Value *&OtherOp0,
                                      Value *&OtherOp1) {
  if (PN->getNumIncomingValues() != 2)
    return false;

  for (unsigned I = 0; I != 2; ++I) {
    if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
        Operation && Operation->getNumOperands() >= 3) {
      Value *Op0 = Operation->getOperand(0);
      Value *Op1 = Operation->getOperand(1);
      Value *Op2 = Operation->getOperand(2);

      if (Op0 != PN && Op1 != PN && Op2 != PN)
        continue;

      Inst = Operation;
      Init = PN->getIncomingValue(!I);
      if (Op0 == PN) {
        OtherOp0 = Op1;
        OtherOp1 = Op2;
      } else if (Op1 == PN) {
        OtherOp0 = Op0;
        OtherOp1 = Op2;
      } else {
        OtherOp0 = Op0;
        OtherOp1 = Op1;
      }
      return true;
    }
  }
  return false;
}
bool llvm::matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO,
                                 Value *&Start, Value *&Step) {
  // We try to match a recurrence of the form:
  //   %iv = [Start, %entry], [%iv.next, %backedge]
  //   %iv.next = binop %iv, Step
  // Or:
  //   %iv = [Start, %entry], [%iv.next, %backedge]
  //   %iv.next = binop Step, %iv