/// Check if the root value for Value that comes
/// along the path from DomBB is equivalent to the
/// DomCondition.
SILValue CheckedCastBrJumpThreading::isArgValueEquivalentToCondition(
    SILValue Value, SILBasicBlock *DomBB, SILValue DomValue,
    DominanceInfo *DT) {
  SmallPtrSet<ValueBase *, 16> SeenValues;
  DomValue = DomValue.stripClassCasts();

  while (true) {
    Value = Value.stripClassCasts();
    if (Value == DomValue)
      return Value;

    // We know how to propagate through BBArgs only.
    auto *V = dyn_cast<SILArgument>(Value);
    if (!V)
      return SILValue();

    // Have we visited this BB already?
    if (!SeenValues.insert(Value.getDef()).second)
      return SILValue();

    if (SeenValues.size() > 10)
      return SILValue();

    SmallVector<SILValue, 4> IncomingValues;
    if (!V->getIncomingValues(IncomingValues) || IncomingValues.empty())
      return SILValue();

    ValueBase *Def = nullptr;
    for (auto IncomingValue : IncomingValues) {
      // Each incoming value should be either from a block
      // dominated by DomBB or it should be the value used in
      // condition in DomBB
      Value = IncomingValue.stripClassCasts();
      if (Value == DomValue)
        continue;

      // Values should be the same
      if (!Def)
        Def = Value.getDef();

      if (Def != Value.getDef())
        return SILValue();

      if (!DT->dominates(DomBB, Value.getDef()->getParentBB()))
        return SILValue();
      // OK, this value is a potential candidate
    }

    Value = IncomingValues[0];
  }
}