//===-- DependenceAnalysis.cpp - DA Implementation --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// DependenceAnalysis is an LLVM pass that analyses dependences between memory
// accesses. Currently, it is an (incomplete) implementation of the approach
// described in
//
//            Practical Dependence Testing
//            Goff, Kennedy, Tseng
//            PLDI 1991
//
// There's a single entry point that analyzes the dependence between a pair
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// Currently, the implementation cannot propagate constraints between
// coupled RDIV subscripts and lacks a multi-subscript MIV test.
// Both of these are conservative weaknesses;
// that is, not a source of correctness problems.
//
// Since Clang linearizes some array subscripts, the dependence
// analysis is using SCEV->delinearize to recover the representation of multiple
// subscripts, and thus avoid the more expensive and less precise MIV tests. The
// delinearization is controlled by the flag -da-delinearize.
//
// We should pay some careful attention to the possibility of integer overflow
// in the implementation of the various tests. This could happen with Add,
// Subtract, or Multiply, with both APInt's and SCEV's.
//
// Some non-linear subscript pairs can be handled by the GCD test
// (and perhaps other tests).
// Should explore how often these things occur.
//
// Finally, it seems like certain test cases expose weaknesses in the SCEV
// simplification, especially in the handling of sign and zero extensions.
// It could be useful to spend time exploring these.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
//===----------------------------------------------------------------------===//
//                                                                            //
//                   In memory of Ken Kennedy, 1945 - 2007                    //
//                                                                            //
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/Delinearization.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "da"

//===----------------------------------------------------------------------===//
// statistics

STATISTIC(TotalArrayPairs, "Array pairs tested");
STATISTIC(SeparableSubscriptPairs, "Separable subscript pairs");
STATISTIC(CoupledSubscriptPairs, "Coupled subscript pairs");
STATISTIC(NonlinearSubscriptPairs, "Nonlinear subscript pairs");
STATISTIC(ZIVapplications, "ZIV applications");
STATISTIC(ZIVindependence, "ZIV independence");
STATISTIC(StrongSIVapplications, "Strong SIV applications");
STATISTIC(StrongSIVsuccesses, "Strong SIV successes");
STATISTIC(StrongSIVindependence, "Strong SIV independence");
STATISTIC(WeakCrossingSIVapplications, "Weak-Crossing SIV applications");
STATISTIC(WeakCrossingSIVsuccesses, "Weak-Crossing SIV successes");
STATISTIC(WeakCrossingSIVindependence, "Weak-Crossing SIV independence");
STATISTIC(ExactSIVapplications, "Exact SIV applications");
STATISTIC(ExactSIVsuccesses, "Exact SIV successes");
STATISTIC(ExactSIVindependence, "Exact SIV independence");
STATISTIC(WeakZeroSIVapplications, "Weak-Zero SIV applications");
STATISTIC(WeakZeroSIVsuccesses, "Weak-Zero SIV successes");
STATISTIC(WeakZeroSIVindependence, "Weak-Zero SIV independence");
STATISTIC(ExactRDIVapplications, "Exact RDIV applications");
STATISTIC(ExactRDIVindependence, "Exact RDIV independence");
STATISTIC(SymbolicRDIVapplications, "Symbolic RDIV applications");
STATISTIC(SymbolicRDIVindependence, "Symbolic RDIV independence");
STATISTIC(DeltaApplications, "Delta applications");
STATISTIC(DeltaSuccesses, "Delta successes");
STATISTIC(DeltaIndependence, "Delta independence");
STATISTIC(DeltaPropagations, "Delta propagations");
STATISTIC(GCDapplications, "GCD applications");
STATISTIC(GCDsuccesses, "GCD successes");
STATISTIC(GCDindependence, "GCD independence");
STATISTIC(BanerjeeApplications, "Banerjee applications");
STATISTIC(BanerjeeIndependence, "Banerjee independence");
STATISTIC(BanerjeeSuccesses, "Banerjee successes");

static cl::opt<bool>
    Delinearize("da-delinearize", cl::init(true), cl::Hidden,
                cl::desc("Try to delinearize array references."));
static cl::opt<bool> DisableDelinearizationChecks(
    "da-disable-delinearization-checks", cl::Hidden,
    cl::desc(
        "Disable checks that try to statically verify validity of "
        "delinearized subscripts. Enabling this option may result in incorrect "
        "dependence vectors for languages that allow the subscript of one "
        "dimension to underflow or overflow into another dimension."));

static cl::opt<unsigned> MIVMaxLevelThreshold(
    "da-miv-max-level-threshold", cl::init(7), cl::Hidden,
    cl::desc("Maximum depth allowed for the recursive algorithm used to "
             "explore MIV direction vectors."));

//===----------------------------------------------------------------------===//
// basics

DependenceAnalysis::Result
DependenceAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
  auto &AA = FAM.getResult<AAManager>(F);
  auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F);
  auto &LI = FAM.getResult<LoopAnalysis>(F);
  return DependenceInfo(&F, &AA, &SE, &LI);
}

AnalysisKey DependenceAnalysis::Key;

INITIALIZE_PASS_BEGIN(DependenceAnalysisWrapperPass, "da",
                      "Dependence Analysis", true, true)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(DependenceAnalysisWrapperPass, "da", "Dependence Analysis",
                    true, true)

char DependenceAnalysisWrapperPass::ID = 0;

DependenceAnalysisWrapperPass::DependenceAnalysisWrapperPass()
    : FunctionPass(ID) {}

FunctionPass *llvm::createDependenceAnalysisWrapperPass() {
  return new DependenceAnalysisWrapperPass();
}

bool DependenceAnalysisWrapperPass::runOnFunction(Function &F) {
  auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
  auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
  info.reset(new DependenceInfo(&F, &AA, &SE, &LI));
  return false;
}

DependenceInfo &DependenceAnalysisWrapperPass::getDI() const { return *info; }

void DependenceAnalysisWrapperPass::releaseMemory() { info.reset(); }

void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequiredTransitive<AAResultsWrapperPass>();
  AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
  AU.addRequiredTransitive<LoopInfoWrapperPass>();
}

// Used to test the dependence analyzer.
// Looks through the function, noting instructions that may access memory.
// Calls depends() on every possible pair and prints out the result.
// Ignores all other instructions.
static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
                                  ScalarEvolution &SE, bool NormalizeResults) {
  auto *F = DA->getFunction();
  for (inst_iterator SrcI = inst_begin(F), SrcE = inst_end(F); SrcI != SrcE;
       ++SrcI) {
    if (SrcI->mayReadOrWriteMemory()) {
      for (inst_iterator DstI = SrcI, DstE = inst_end(F); DstI != DstE;
           ++DstI) {
        if (DstI->mayReadOrWriteMemory()) {
          OS << "Src:" << *SrcI << " --> Dst:" << *DstI << "\n";
          OS << "  da analyze - ";
          if (auto D = DA->depends(&*SrcI, &*DstI,
                                   /*UnderRuntimeAssumptions=*/true)) {

#ifndef NDEBUG
            // Verify that the distance being zero is equivalent to the
            // direction being EQ.
            for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
              const SCEV *Distance = D->getDistance(Level);
              bool IsDistanceZero = Distance && Distance->isZero();
              bool IsDirectionEQ =
                  D->getDirection(Level) == Dependence::DVEntry::EQ;
              assert(IsDistanceZero == IsDirectionEQ &&
                     "Inconsistent distance and direction.");
            }
#endif

            // Normalize negative direction vectors if required by clients.
            if (NormalizeResults && D->normalize(&SE))
              OS << "normalized - ";
            D->dump(OS);
            for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
              if (D->isSplitable(Level)) {
                OS << "  da analyze - split level = " << Level;
                OS << ", iteration = " << *DA->getSplitIteration(*D, Level);
                OS << "!\n";
              }
            }
          } else
            OS << "none!\n";
        }
      }
    }
  }
  SCEVUnionPredicate Assumptions = DA->getRuntimeAssumptions();
  if (!Assumptions.isAlwaysTrue()) {
    OS << "Runtime Assumptions:\n";
    Assumptions.print(OS, 0);
  }
}

void DependenceAnalysisWrapperPass::print(raw_ostream &OS,
                                          const Module *) const {
  dumpExampleDependence(
      OS, info.get(), getAnalysis<ScalarEvolutionWrapperPass>().getSE(), false);
}

PreservedAnalyses
DependenceAnalysisPrinterPass::run(Function &F, FunctionAnalysisManager &FAM) {
  OS << "Printing analysis 'Dependence Analysis' for function '" << F.getName()
     << "':\n";
  dumpExampleDependence(OS, &FAM.getResult<DependenceAnalysis>(F),
                        FAM.getResult<ScalarEvolutionAnalysis>(F),
                        NormalizeResults);
  return PreservedAnalyses::all();
}

//===----------------------------------------------------------------------===//
// Dependence methods

// Returns true if this is an input dependence.
bool Dependence::isInput() const {
  return Src->mayReadFromMemory() && Dst->mayReadFromMemory();
}

// Returns true if this is an output dependence.
bool Dependence::isOutput() const {
  return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
}

// Returns true if this is an flow (aka true)  dependence.
bool Dependence::isFlow() const {
  return Src->mayWriteToMemory() && Dst->mayReadFromMemory();
}

// Returns true if this is an anti dependence.
bool Dependence::isAnti() const {
  return Src->mayReadFromMemory() && Dst->mayWriteToMemory();
}

// Returns true if a particular level is scalar; that is,
// if no subscript in the source or destination mention the induction
// variable associated with the loop at this level.
// Leave this out of line, so it will serve as a virtual method anchor
bool Dependence::isScalar(unsigned level) const { return false; }

//===----------------------------------------------------------------------===//
// FullDependence methods

FullDependence::FullDependence(Instruction *Source, Instruction *Destination,
                               const SCEVUnionPredicate &Assumes,
                               bool PossiblyLoopIndependent,
                               unsigned CommonLevels)
    : Dependence(Source, Destination, Assumes), Levels(CommonLevels),
      LoopIndependent(PossiblyLoopIndependent) {
  Consistent = true;
  if (CommonLevels)
    DV = std::make_unique<DVEntry[]>(CommonLevels);
}

// FIXME: in some cases the meaning of a negative direction vector
// may not be straightforward, e.g.,
// for (int i = 0; i < 32; ++i) {
//   Src:    A[i] = ...;
//   Dst:    use(A[31 - i]);
// }
// The dependency is
//   flow { Src[i] -> Dst[31 - i] : when i >= 16 } and
//   anti { Dst[i] -> Src[31 - i] : when i < 16 },
// -- hence a [<>].
// As long as a dependence result contains '>' ('<>', '<=>', "*"), it
// means that a reversed/normalized dependence needs to be considered
// as well. Nevertheless, current isDirectionNegative() only returns
// true with a '>' or '>=' dependency for ease of canonicalizing the
// dependency vector, since the reverse of '<>', '<=>' and "*" is itself.
bool FullDependence::isDirectionNegative() const {
  for (unsigned Level = 1; Level <= Levels; ++Level) {
    unsigned char Direction = DV[Level - 1].Direction;
    if (Direction == Dependence::DVEntry::EQ)
      continue;
    if (Direction == Dependence::DVEntry::GT ||
        Direction == Dependence::DVEntry::GE)
      return true;
    return false;
  }
  return false;
}

bool FullDependence::normalize(ScalarEvolution *SE) {
  if (!isDirectionNegative())
    return false;

  LLVM_DEBUG(dbgs() << "Before normalizing negative direction vectors:\n";
             dump(dbgs()););
  std::swap(Src, Dst);
  for (unsigned Level = 1; Level <= Levels; ++Level) {
    unsigned char Direction = DV[Level - 1].Direction;
    // Reverse the direction vector, this means LT becomes GT
    // and GT becomes LT.
    unsigned char RevDirection = Direction & Dependence::DVEntry::EQ;
    if (Direction & Dependence::DVEntry::LT)
      RevDirection |= Dependence::DVEntry::GT;
    if (Direction & Dependence::DVEntry::GT)
      RevDirection |= Dependence::DVEntry::LT;
    DV[Level - 1].Direction = RevDirection;
    // Reverse the dependence distance as well.
    if (DV[Level - 1].Distance != nullptr)
      DV[Level - 1].Distance = SE->getNegativeSCEV(DV[Level - 1].Distance);
  }

  LLVM_DEBUG(dbgs() << "After normalizing negative direction vectors:\n";
             dump(dbgs()););
  return true;
}

// The rest are simple getters that hide the implementation.

// getDirection - Returns the direction associated with a particular level.
unsigned FullDependence::getDirection(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].Direction;
}

// Returns the distance (or NULL) associated with a particular level.
const SCEV *FullDependence::getDistance(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].Distance;
}

// Returns true if a particular level is scalar; that is,
// if no subscript in the source or destination mention the induction
// variable associated with the loop at this level.
bool FullDependence::isScalar(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].Scalar;
}

// Returns true if peeling the first iteration from this loop
// will break this dependence.
bool FullDependence::isPeelFirst(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].PeelFirst;
}

// Returns true if peeling the last iteration from this loop
// will break this dependence.
bool FullDependence::isPeelLast(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].PeelLast;
}

// Returns true if splitting this loop will break the dependence.
bool FullDependence::isSplitable(unsigned Level) const {
  assert(0 < Level && Level <= Levels && "Level out of range");
  return DV[Level - 1].Splitable;
}

//===----------------------------------------------------------------------===//
// DependenceInfo::Constraint methods

// If constraint is a point <X, Y>, returns X.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getX() const {
  assert(Kind == Point && "Kind should be Point");
  return A;
}

// If constraint is a point <X, Y>, returns Y.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getY() const {
  assert(Kind == Point && "Kind should be Point");
  return B;
}

// If constraint is a line AX + BY = C, returns A.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getA() const {
  assert((Kind == Line || Kind == Distance) &&
         "Kind should be Line (or Distance)");
  return A;
}

// If constraint is a line AX + BY = C, returns B.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getB() const {
  assert((Kind == Line || Kind == Distance) &&
         "Kind should be Line (or Distance)");
  return B;
}

// If constraint is a line AX + BY = C, returns C.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getC() const {
  assert((Kind == Line || Kind == Distance) &&
         "Kind should be Line (or Distance)");
  return C;
}

// If constraint is a distance, returns D.
// Otherwise assert.
const SCEV *DependenceInfo::Constraint::getD() const {
  assert(Kind == Distance && "Kind should be Distance");
  return SE->getNegativeSCEV(C);
}

// Returns the loop associated with this constraint.
const Loop *DependenceInfo::Constraint::getAssociatedLoop() const {
  assert((Kind == Distance || Kind == Line || Kind == Point) &&
         "Kind should be Distance, Line, or Point");
  return AssociatedLoop;
}

void DependenceInfo::Constraint::setPoint(const SCEV *X, const SCEV *Y,
                                          const Loop *CurLoop) {
  Kind = Point;
  A = X;
  B = Y;
  AssociatedLoop = CurLoop;
}

void DependenceInfo::Constraint::setLine(const SCEV *AA, const SCEV *BB,
                                         const SCEV *CC, const Loop *CurLoop) {
  Kind = Line;
  A = AA;
  B = BB;
  C = CC;
  AssociatedLoop = CurLoop;
}

void DependenceInfo::Constraint::setDistance(const SCEV *D,
                                             const Loop *CurLoop) {
  Kind = Distance;
  A = SE->getOne(D->getType());
  B = SE->getNegativeSCEV(A);
  C = SE->getNegativeSCEV(D);
  AssociatedLoop = CurLoop;
}

void DependenceInfo::Constraint::setEmpty() { Kind = Empty; }

void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
  SE = NewSE;
  Kind = Any;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
// For debugging purposes. Dumps the constraint out to OS.
LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS) const {
  if (isEmpty())
    OS << " Empty\n";
  else if (isAny())
    OS << " Any\n";
  else if (isPoint())
    OS << " Point is <" << *getX() << ", " << *getY() << ">\n";
  else if (isDistance())
    OS << " Distance is " << *getD() << " (" << *getA() << "*X + " << *getB()
       << "*Y = " << *getC() << ")\n";
  else if (isLine())
    OS << " Line is " << *getA() << "*X + " << *getB() << "*Y = " << *getC()
       << "\n";
  else
    llvm_unreachable("unknown constraint type in Constraint::dump");
}
#endif

// Updates X with the intersection
// of the Constraints X and Y. Returns true if X has changed.
// Corresponds to Figure 4 from the paper
//
//            Practical Dependence Testing
//            Goff, Kennedy, Tseng
//            PLDI 1991
bool DependenceInfo::intersectConstraints(Constraint *X, const Constraint *Y) {
  ++DeltaApplications;
  LLVM_DEBUG(dbgs() << "\tintersect constraints\n");
  LLVM_DEBUG(dbgs() << "\t    X ="; X->dump(dbgs()));
  LLVM_DEBUG(dbgs() << "\t    Y ="; Y->dump(dbgs()));
  assert(!Y->isPoint() && "Y must not be a Point");
  if (X->isAny()) {
    if (Y->isAny())
      return false;
    *X = *Y;
    return true;
  }
  if (X->isEmpty())
    return false;
  if (Y->isEmpty()) {
    X->setEmpty();
    return true;
  }

  if (X->isDistance() && Y->isDistance()) {
    LLVM_DEBUG(dbgs() << "\t    intersect 2 distances\n");
    if (isKnownPredicate(CmpInst::ICMP_EQ, X->getD(), Y->getD()))
      return false;
    if (isKnownPredicate(CmpInst::ICMP_NE, X->getD(), Y->getD())) {
      X->setEmpty();
      ++DeltaSuccesses;
      return true;
    }
    // Hmmm, interesting situation.
    // I guess if either is constant, keep it and ignore the other.
    if (isa<SCEVConstant>(Y->getD())) {
      *X = *Y;
      return true;
    }
    return false;
  }

  // At this point, the pseudo-code in Figure 4 of the paper
  // checks if (X->isPoint() && Y->isPoint()).
  // This case can't occur in our implementation,
  // since a Point can only arise as the result of intersecting
  // two Line constraints, and the right-hand value, Y, is never
  // the result of an intersection.
  assert(!(X->isPoint() && Y->isPoint()) &&
         "We shouldn't ever see X->isPoint() && Y->isPoint()");

  if (X->isLine() && Y->isLine()) {
    LLVM_DEBUG(dbgs() << "\t    intersect 2 lines\n");
    const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
    const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
    if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2)) {
      // slopes are equal, so lines are parallel
      LLVM_DEBUG(dbgs() << "\t\tsame slope\n");
      Prod1 = SE->getMulExpr(X->getC(), Y->getB());
      Prod2 = SE->getMulExpr(X->getB(), Y->getC());
      if (isKnownPredicate(CmpInst::ICMP_EQ, Prod1, Prod2))
        return false;
      if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
        X->setEmpty();
        ++DeltaSuccesses;
        return true;
      }
      return false;
    }
    if (isKnownPredicate(CmpInst::ICMP_NE, Prod1, Prod2)) {
      // slopes differ, so lines intersect
      LLVM_DEBUG(dbgs() << "\t\tdifferent slopes\n");
      const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
      const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
      const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
      const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->getA());
      const SCEV *A1B2 = SE->getMulExpr(X->getA(), Y->getB());
      const SCEV *A2B1 = SE->getMulExpr(Y->getA(), X->getB());
      const SCEVConstant *C1A2_C2A1 =
          dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1A2, C2A1));
      const SCEVConstant *C1B2_C2B1 =
          dyn_cast<SCEVConstant>(SE->getMinusSCEV(C1B2, C2B1));
      const SCEVConstant *A1B2_A2B1 =
          dyn_cast<SCEVConstant>(SE->getMinusSCEV(A1B2, A2B1));
      const SCEVConstant *A2B1_A1B2 =
          dyn_cast<SCEVConstant>(SE->getMinusSCEV(A2B1, A1B2));
      if (!C1B2_C2B1 || !C1A2_C2A1 || !A1B2_A2B1 || !A2B1_A1B2)
        return false;
      APInt Xtop = C1B2_C2B1->getAPInt();
      APInt Xbot = A1B2_A2B1->getAPInt();
      APInt Ytop = C1A2_C2A1->getAPInt();
      APInt Ybot = A2B1_A1B2->getAPInt();
      LLVM_DEBUG(dbgs() << "\t\tXtop = " << Xtop << "\n");
      LLVM_DEBUG(dbgs() << "\t\tXbot = " << Xbot << "\n");
      LLVM_DEBUG(dbgs() << "\t\tYtop = " << Ytop << "\n");
      LLVM_DEBUG(dbgs() << "\t\tYbot = " << Ybot << "\n");
      APInt Xq = Xtop; // these need to be initialized, even
      APInt Xr = Xtop; // though they're just going to be overwritten
      APInt::sdivrem(Xtop, Xbot, Xq, Xr);
      APInt Yq = Ytop;
      APInt Yr = Ytop;
      APInt::sdivrem(Ytop, Ybot, Yq, Yr);
      if (Xr != 0 || Yr != 0) {
        X->setEmpty();
        ++DeltaSuccesses;
        return true;
      }
      LLVM_DEBUG(dbgs() << "\t\tX = " << Xq << ", Y = " << Yq << "\n");
      if (Xq.slt(0) || Yq.slt(0)) {
        X->setEmpty();
        ++DeltaSuccesses;
        return true;
      }
      if (const SCEVConstant *CUB = collectConstantUpperBound(
              X->getAssociatedLoop(), Prod1->getType())) {
        const APInt &UpperBound = CUB->getAPInt();
        LLVM_DEBUG(dbgs() << "\t\tupper bound = " << UpperBound << "\n");
        if (Xq.sgt(UpperBound) || Yq.sgt(UpperBound)) {
          X->setEmpty();
          ++DeltaSuccesses;
          return true;
        }
      }
      X->setPoint(SE->getConstant(Xq), SE->getConstant(Yq),
                  X->getAssociatedLoop());
      ++DeltaSuccesses;
      return true;
    }
    return false;
  }

  // if (X->isLine() && Y->isPoint()) This case can't occur.
  assert(!(X->isLine() && Y->isPoint()) && "This case should never occur");

  if (X->isPoint() && Y->isLine()) {
    LLVM_DEBUG(dbgs() << "\t    intersect Point and Line\n");
    const SCEV *A1X1 = SE->getMulExpr(Y->getA(), X->getX());
    const SCEV *B1Y1 = SE->getMulExpr(Y->getB(), X->getY());
    const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
    if (isKnownPredicate(CmpInst::ICMP_EQ, Sum, Y->getC()))
      return false;
    if (isKnownPredicate(CmpInst::ICMP_NE, Sum, Y->getC())) {
      X->setEmpty();
      ++DeltaSuccesses;
      return true;
    }
    return false;
  }

  llvm_unreachable("shouldn't reach the end of Constraint intersection");
  return false;
}

//===----------------------------------------------------------------------===//
// DependenceInfo methods

// For debugging purposes. Dumps a dependence to OS.
void Dependence::dump(raw_ostream &OS) const {
  bool Splitable = false;
  if (isConfused())
    OS << "confused";
  else {
    if (isConsistent())
      OS << "consistent ";
    if (isFlow())
      OS << "flow";
    else if (isOutput())
      OS << "output";
    else if (isAnti())
      OS << "anti";
    else if (isInput())
      OS << "input";
    unsigned Levels = getLevels();
    OS << " [";
    for (unsigned II = 1; II <= Levels; ++II) {
      if (isSplitable(II))
        Splitable = true;
      if (isPeelFirst(II))
        OS << 'p';
      const SCEV *Distance = getDistance(II);
      if (Distance)
        OS << *Distance;
      else if (isScalar(II))
        OS << "S";
      else {
        unsigned Direction = getDirection(II);
        if (Direction == DVEntry::ALL)
          OS << "*";
        else {
          if (Direction & DVEntry::LT)
            OS << "<";
          if (Direction & DVEntry::EQ)
            OS << "=";
          if (Direction & DVEntry::GT)
            OS << ">";
        }
      }
      if (isPeelLast(II))
        OS << 'p';
      if (II < Levels)
        OS << " ";
    }
    if (isLoopIndependent())
      OS << "|<";
    OS << "]";
    if (Splitable)
      OS << " splitable";
  }
  OS << "!\n";

  SCEVUnionPredicate Assumptions = getRuntimeAssumptions();
  if (!Assumptions.isAlwaysTrue()) {
    OS << "  Runtime Assumptions:\n";
    Assumptions.print(OS, 2);
  }
}

// Returns NoAlias/MayAliass/MustAlias for two memory locations based upon their
// underlaying objects. If LocA and LocB are known to not alias (for any reason:
// tbaa, non-overlapping regions etc), then it is known there is no dependecy.
// Otherwise the underlying objects are checked to see if they point to
// different identifiable objects.
static AliasResult underlyingObjectsAlias(AAResults *AA, const DataLayout &DL,
                                          const MemoryLocation &LocA,
                                          const MemoryLocation &LocB) {
  // Check the original locations (minus size) for noalias, which can happen for
  // tbaa, incompatible underlying object locations, etc.
  MemoryLocation LocAS =
      MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
  MemoryLocation LocBS =
      MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
  BatchAAResults BAA(*AA);
  BAA.enableCrossIterationMode();

  if (BAA.isNoAlias(LocAS, LocBS))
    return AliasResult::NoAlias;

  // Check the underlying objects are the same
  const Value *AObj = getUnderlyingObject(LocA.Ptr);
  const Value *BObj = getUnderlyingObject(LocB.Ptr);

  // If the underlying objects are the same, they must alias
  if (AObj == BObj)
    return AliasResult::MustAlias;

  // We may have hit the recursion limit for underlying objects, or have
  // underlying objects where we don't know they will alias.
  if (!isIdentifiedObject(AObj) || !isIdentifiedObject(BObj))
    return AliasResult::MayAlias;

  // Otherwise we know the objects are different and both identified objects so
  // must not alias.
  return AliasResult::NoAlias;
}

// Returns true if the load or store can be analyzed. Atomic and volatile
// operations have properties which this analysis does not understand.
static bool isLoadOrStore(const Instruction *I) {
  if (const LoadInst *LI = dyn_cast<LoadInst>(I))
    return LI->isUnordered();
  else if (const StoreInst *SI = dyn_cast<StoreInst>(I))
    return SI->isUnordered();
  return false;
}

// Examines the loop nesting of the Src and Dst
// instructions and establishes their shared loops. Sets the variables
// CommonLevels, SrcLevels, and MaxLevels.
// The source and destination instructions needn't be contained in the same
// loop. The routine establishNestingLevels finds the level of most deeply
// nested loop that contains them both, CommonLevels. An instruction that's
// not contained in a loop is at level = 0. MaxLevels is equal to the level
// of the source plus the level of the destination, minus CommonLevels.
// This lets us allocate vectors MaxLevels in length, with room for every
// distinct loop referenced in both the source and destination subscripts.
// The variable SrcLevels is the nesting depth of the source instruction.
// It's used to help calculate distinct loops referenced by the destination.
// Here's the map from loops to levels:
//            0 - unused
//            1 - outermost common loop
//          ... - other common loops
// CommonLevels - innermost common loop
//          ... - loops containing Src but not Dst
//    SrcLevels - innermost loop containing Src but not Dst
//          ... - loops containing Dst but not Src
//    MaxLevels - innermost loops containing Dst but not Src
// Consider the follow code fragment:
//   for (a = ...) {
//     for (b = ...) {
//       for (c = ...) {
//         for (d = ...) {
//           A[] = ...;
//         }
//       }
//       for (e = ...) {
//         for (f = ...) {
//           for (g = ...) {
//             ... = A[];
//           }
//         }
//       }
//     }
//   }
// If we're looking at the possibility of a dependence between the store
// to A (the Src) and the load from A (the Dst), we'll note that they
// have 2 loops in common, so CommonLevels will equal 2 and the direction
// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
// A map from loop names to loop numbers would look like
//     a - 1
//     b - 2 = CommonLevels
//     c - 3
//     d - 4 = SrcLevels
//     e - 5
//     f - 6
//     g - 7 = MaxLevels
void DependenceInfo::establishNestingLevels(const Instruction *Src,
                                            const Instruction *Dst) {
  const BasicBlock *SrcBlock = Src->getParent();
  const BasicBlock *DstBlock = Dst->getParent();
  unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
  unsigned DstLevel = LI->getLoopDepth(DstBlock);
  const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
  const Loop *DstLoop = LI->getLoopFor(DstBlock);
  SrcLevels = SrcLevel;
  MaxLevels = SrcLevel + DstLevel;
  while (SrcLevel > DstLevel) {
    SrcLoop = SrcLoop->getParentLoop();
    SrcLevel--;
  }
  while (DstLevel > SrcLevel) {
    DstLoop = DstLoop->getParentLoop();
    DstLevel--;
  }
  while (SrcLoop != DstLoop) {
    SrcLoop = SrcLoop->getParentLoop();
    DstLoop = DstLoop->getParentLoop();
    SrcLevel--;
  }
  CommonLevels = SrcLevel;
  MaxLevels -= CommonLevels;
}

// Given one of the loops containing the source, return
// its level index in our numbering scheme.
unsigned DependenceInfo::mapSrcLoop(const Loop *SrcLoop) const {
  return SrcLoop->getLoopDepth();
}

// Given one of the loops containing the destination,
// return its level index in our numbering scheme.
unsigned DependenceInfo::mapDstLoop(const Loop *DstLoop) const {
  unsigned D = DstLoop->getLoopDepth();
  if (D > CommonLevels)
    // This tries to make sure that we assign unique numbers to src and dst when
    // the memory accesses reside in different loops that have the same depth.
    return D - CommonLevels + SrcLevels;
  else
    return D;
}

// Returns true if Expression is loop invariant in LoopNest.
bool DependenceInfo::isLoopInvariant(const SCEV *Expression,
                                     const Loop *LoopNest) const {
  // Unlike ScalarEvolution::isLoopInvariant() we consider an access outside of
  // any loop as invariant, because we only consier expression evaluation at a
  // specific position (where the array access takes place), and not across the
  // entire function.
  if (!LoopNest)
    return true;

  // If the expression is invariant in the outermost loop of the loop nest, it
  // is invariant anywhere in the loop nest.
  return SE->isLoopInvariant(Expression, LoopNest->getOutermostLoop());
}

// Finds the set of loops from the LoopNest that
// have a level <= CommonLevels and are referred to by the SCEV Expression.
void DependenceInfo::collectCommonLoops(const SCEV *Expression,
                                        const Loop *LoopNest,
                                        SmallBitVector &Loops) const {
  while (LoopNest) {
    unsigned Level = LoopNest->getLoopDepth();
    if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
      Loops.set(Level);
    LoopNest = LoopNest->getParentLoop();
  }
}

void DependenceInfo::unifySubscriptType(ArrayRef<Subscript *> Pairs) {

  unsigned widestWidthSeen = 0;
  Type *widestType;

  // Go through each pair and find the widest bit to which we need
  // to extend all of them.
  for (Subscript *Pair : Pairs) {
    const SCEV *Src = Pair->Src;
    const SCEV *Dst = Pair->Dst;
    IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
    IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
    if (SrcTy == nullptr || DstTy == nullptr) {
      assert(SrcTy == DstTy &&
             "This function only unify integer types and "
             "expect Src and Dst share the same type otherwise.");
      continue;
    }
    if (SrcTy->getBitWidth() > widestWidthSeen) {
      widestWidthSeen = SrcTy->getBitWidth();
      widestType = SrcTy;
    }
    if (DstTy->getBitWidth() > widestWidthSeen) {
      widestWidthSeen = DstTy->getBitWidth();
      widestType = DstTy;
    }
  }

  assert(widestWidthSeen > 0);

  // Now extend each pair to the widest seen.
  for (Subscript *Pair : Pairs) {
    const SCEV *Src = Pair->Src;
    const SCEV *Dst = Pair->Dst;
    IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
    IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
    if (SrcTy == nullptr || DstTy == nullptr) {
      assert(SrcTy == DstTy &&
             "This function only unify integer types and "
             "expect Src and Dst share the same type otherwise.");
      continue;
    }
    if (SrcTy->getBitWidth() < widestWidthSeen)
      // Sign-extend Src to widestType
      Pair->Src = SE->getSignExtendExpr(Src, widestType);
    if (DstTy->getBitWidth() < widestWidthSeen) {
      // Sign-extend Dst to widestType
      Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
    }
  }
}

// removeMatchingExtensions - Examines a subscript pair.
// If the source and destination are identically sign (or zero)
// extended, it strips off the extension in an effect to simplify
// the actual analysis.
void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
  const SCEV *Src = Pair->Src;
  const SCEV *Dst = Pair->Dst;
  if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
      (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
    const SCEVIntegralCastExpr *SrcCast = cast<SCEVIntegralCastExpr>(Src);
    const SCEVIntegralCastExpr *DstCast = cast<SCEVIntegralCastExpr>(Dst);
    const SCEV *SrcCastOp = SrcCast->getOperand();
    const SCEV *DstCastOp = DstCast->getOperand();
    if (SrcCastOp->getType() == DstCastOp->getType()) {
      Pair->Src = SrcCastOp;
      Pair->Dst = DstCastOp;
    }
  }
}

// Examine the scev and return true iff it's affine.
// Collect any loops mentioned in the set of "Loops".
bool DependenceInfo::checkSubscript(const SCEV *Expr, const Loop *LoopNest,
                                    SmallBitVector &Loops, bool IsSrc) {
  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
  if (!AddRec)
    return isLoopInvariant(Expr, LoopNest);

  // The AddRec must depend on one of the containing loops. Otherwise,
  // mapSrcLoop and mapDstLoop return indices outside the intended range. This
  // can happen when a subscript in one loop references an IV from a sibling
  // loop that could not be replaced with a concrete exit value by
  // getSCEVAtScope.
  const Loop *L = LoopNest;
  while (L && AddRec->getLoop() != L)
    L = L->getParentLoop();
  if (!L)
    return false;

  const SCEV *Start = AddRec->getStart();
  const SCEV *Step = AddRec->getStepRecurrence(*SE);
  if (!isLoopInvariant(Step, LoopNest))
    return false;
  if (IsSrc)
    Loops.set(mapSrcLoop(AddRec->getLoop()));
  else
    Loops.set(mapDstLoop(AddRec->getLoop()));
  return checkSubscript(Start, LoopNest, Loops, IsSrc);
}

// Examine the scev and return true iff it's linear.
// Collect any loops mentioned in the set of "Loops".
bool DependenceInfo::checkSrcSubscript(const SCEV *Src, const Loop *LoopNest,
                                       SmallBitVector &Loops) {
  return checkSubscript(Src, LoopNest, Loops, true);
}

// Examine the scev and return true iff it's linear.
// Collect any loops mentioned in the set of "Loops".
bool DependenceInfo::checkDstSubscript(const SCEV *Dst, const Loop *LoopNest,
                                       SmallBitVector &Loops) {
  return checkSubscript(Dst, LoopNest, Loops, false);
}

// Examines the subscript pair (the Src and Dst SCEVs)
// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
// Collects the associated loops in a set.
DependenceInfo::Subscript::ClassificationKind
DependenceInfo::classifyPair(const SCEV *Src, const Loop *SrcLoopNest,
                             const SCEV *Dst, const Loop *DstLoopNest,
                             SmallBitVector &Loops) {
  SmallBitVector SrcLoops(MaxLevels + 1);
  SmallBitVector DstLoops(MaxLevels + 1);
  if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
    return Subscript::NonLinear;
  if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
    return Subscript::NonLinear;
  Loops = SrcLoops;
  Loops |= DstLoops;
  unsigned N = Loops.count();
  if (N == 0)
    return Subscript::ZIV;
  if (N == 1)
    return Subscript::SIV;
  if (N == 2 && (SrcLoops.count() == 0 || DstLoops.count() == 0 ||
                 (SrcLoops.count() == 1 && DstLoops.count() == 1)))
    return Subscript::RDIV;
  return Subscript::MIV;
}

// A wrapper around SCEV::isKnownPredicate.
// Looks for cases where we're interested in comparing for equality.
// If both X and Y have been identically sign or zero extended,
// it strips off the (confusing) extensions before invoking
// SCEV::isKnownPredicate. Perhaps, someday, the ScalarEvolution package
// will be similarly updated.
//
// If SCEV::isKnownPredicate can't prove the predicate,
// we try simple subtraction, which seems to help in some cases
// involving symbolics.
bool DependenceInfo::isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *X,
                                      const SCEV *Y) const {
  if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) {
    if ((isa<SCEVSignExtendExpr>(X) && isa<SCEVSignExtendExpr>(Y)) ||
        (isa<SCEVZeroExtendExpr>(X) && isa<SCEVZeroExtendExpr>(Y))) {
      const SCEVIntegralCastExpr *CX = cast<SCEVIntegralCastExpr>(X);
      const SCEVIntegralCastExpr *CY = cast<SCEVIntegralCastExpr>(Y);
      const SCEV *Xop = CX->getOperand();
      const SCEV *Yop = CY->getOperand();
      if (Xop->getType() == Yop->getType()) {
        X = Xop;
        Y = Yop;
      }
    }
  }
  if (SE->isKnownPredicate(Pred, X, Y))
    return true;
  // If SE->isKnownPredicate can't prove the condition,
  // we try the brute-force approach of subtracting
  // and testing the difference.
  // By testing with SE->isKnownPredicate first, we avoid
  // the possibility of overflow when the arguments are constants.
  const SCEV *Delta = SE->getMinusSCEV(X, Y);
  switch (Pred) {
  case CmpInst::ICMP_EQ:
    return Delta->isZero();
  case CmpInst::ICMP_NE:
    return SE->isKnownNonZero(Delta);
  case CmpInst::ICMP_SGE:
    return SE->isKnownNonNegative(Delta);
  case CmpInst::ICMP_SLE:
    return SE->isKnownNonPositive(Delta);
  case CmpInst::ICMP_SGT:
    return SE->isKnownPositive(Delta);
  case CmpInst::ICMP_SLT:
    return SE->isKnownNegative(Delta);
  default:
    llvm_unreachable("unexpected predicate in isKnownPredicate");
  }
}

/// Compare to see if S is less than Size, using
///
///    isKnownNegative(S - Size)
///
/// with some extra checking if S is an AddRec and we can prove less-than using
/// the loop bounds.
bool DependenceInfo::isKnownLessThan(const SCEV *S, const SCEV *Size) const {
  // First unify to the same type
  auto *SType = dyn_cast<IntegerType>(S->getType());
  auto *SizeType = dyn_cast<IntegerType>(Size->getType());
  if (!SType || !SizeType)
    return false;
  Type *MaxType =
      (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
  S = SE->getTruncateOrZeroExtend(S, MaxType);
  Size = SE->getTruncateOrZeroExtend(Size, MaxType);

  // Special check for addrecs using BE taken count
  if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S))
    if (AddRec->isAffine() && AddRec->hasNoSignedWrap()) {
      const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->getLoop());
      const SCEV *Start = AddRec->getStart();
      const SCEV *Step = AddRec->getStepRecurrence(*SE);
      const SCEV *End = AddRec->evaluateAtIteration(BECount, *SE);
      const SCEV *Diff0 = SE->getMinusSCEV(Start, Size);
      const SCEV *Diff1 = SE->getMinusSCEV(End, Size);

      // If the value of Step is non-negative and the AddRec is non-wrap, it
      // reaches its maximum at the last iteration. So it's enouth to check
      // whether End - Size is negative.
      if (SE->isKnownNonNegative(Step) && SE->isKnownNegative(Diff1))
        return true;

      // If the value of Step is non-positive and the AddRec is non-wrap, the
      // initial value is its maximum.
      if (SE->isKnownNonPositive(Step) && SE->isKnownNegative(Diff0))
        return true;

      // Even if we don't know the sign of Step, either Start or End must be
      // the maximum value of the AddRec since it is non-wrap.
      if (SE->isKnownNegative(Diff0) && SE->isKnownNegative(Diff1))
        return true;
    }

  // Check using normal isKnownNegative
  const SCEV *LimitedBound = SE->getMinusSCEV(S, Size);
  return SE->isKnownNegative(LimitedBound);
}

bool DependenceInfo::isKnownNonNegative(const SCEV *S, const Value *Ptr) const {
  bool Inbounds = false;
  if (auto *SrcGEP = dyn_cast<GetElementPtrInst>(Ptr))
    Inbounds = SrcGEP->isInBounds();
  if (Inbounds) {
    if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
      if (AddRec->isAffine()) {
        // We know S is for Ptr, the operand on a load/store, so doesn't wrap.
        // If both parts are NonNegative, the end result will be NonNegative
        if (SE->isKnownNonNegative(AddRec->getStart()) &&
            SE->isKnownNonNegative(AddRec->getOperand(1)))
          return true;
      }
    }
  }

  return SE->isKnownNonNegative(S);
}

// All subscripts are all the same type.
// Loop bound may be smaller (e.g., a char).
// Should zero extend loop bound, since it's always >= 0.
// This routine collects upper bound and extends or truncates if needed.
// Truncating is safe when subscripts are known not to wrap. Cases without
// nowrap flags should have been rejected earlier.
// Return null if no bound available.
const SCEV *DependenceInfo::collectUpperBound(const Loop *L, Type *T) const {
  if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
    const SCEV *UB = SE->getBackedgeTakenCount(L);
    return SE->getTruncateOrZeroExtend(UB, T);
  }
  return nullptr;
}

// Calls collectUpperBound(), then attempts to cast it to SCEVConstant.
// If the cast fails, returns NULL.
const SCEVConstant *DependenceInfo::collectConstantUpperBound(const Loop *L,
                                                              Type *T) const {
  if (const SCEV *UB = collectUpperBound(L, T))
    return dyn_cast<SCEVConstant>(UB);
  return nullptr;
}

// testZIV -
// When we have a pair of subscripts of the form [c1] and [c2],
// where c1 and c2 are both loop invariant, we attack it using
// the ZIV test. Basically, we test by comparing the two values,
// but there are actually three possible results:
// 1) the values are equal, so there's a dependence
// 2) the values are different, so there's no dependence
// 3) the values might be equal, so we have to assume a dependence.
//
// Return true if dependence disproved.
bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
                             FullDependence &Result) const {
  LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
  ++ZIVapplications;
  if (isKnownPredicate(CmpInst::ICMP_EQ, Src, Dst)) {
    LLVM_DEBUG(dbgs() << "    provably dependent\n");
    return false; // provably dependent
  }
  if (isKnownPredicate(CmpInst::ICMP_NE, Src, Dst)) {
    LLVM_DEBUG(dbgs() << "    provably independent\n");
    ++ZIVindependence;
    return true; // provably independent
  }
  LLVM_DEBUG(dbgs() << "    possibly dependent\n");
  Result.Consistent = false;
  return false; // possibly dependent
}

// strongSIVtest -
// From the paper, Practical Dependence Testing, Section 4.2.1
//
// When we have a pair of subscripts of the form [c1 + a*i] and [c2 + a*i],
// where i is an induction variable, c1 and c2 are loop invariant,
//  and a is a constant, we can solve it exactly using the Strong SIV test.
//
// Can prove independence. Failing that, can compute distance (and direction).
// In the presence of symbolic terms, we can sometimes make progress.
//
// If there's a dependence,
//
//    c1 + a*i = c2 + a*i'
//
// The dependence distance is
//
//    d = i' - i = (c1 - c2)/a
//
// A dependence only exists if d is an integer and abs(d) <= U, where U is the
// loop's upper bound. If a dependence exists, the dependence direction is
// defined as
//
//                { < if d > 0
//    direction = { = if d = 0
//                { > if d < 0
//
// Return true if dependence disproved.
bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
                                   const SCEV *DstConst, const Loop *CurLoop,
                                   unsigned Level, FullDependence &Result,
                                   Constraint &NewConstraint) const {
  LLVM_DEBUG(dbgs() << "\tStrong SIV test\n");
  LLVM_DEBUG(dbgs() << "\t    Coeff = " << *Coeff);
  LLVM_DEBUG(dbgs() << ", " << *Coeff->getType() << "\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst);
  LLVM_DEBUG(dbgs() << ", " << *SrcConst->getType() << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst);
  LLVM_DEBUG(dbgs() << ", " << *DstConst->getType() << "\n");
  ++StrongSIVapplications;
  assert(0 < Level && Level <= CommonLevels && "level out of range");
  Level--;

  const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta);
  LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n");

  // check that |Delta| < iteration count
  if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
    LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound);
    LLVM_DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
    const SCEV *AbsDelta =
        SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
    const SCEV *AbsCoeff =
        SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
    const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
    if (isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product)) {
      // Distance greater than trip count - no dependence
      ++StrongSIVindependence;
      ++StrongSIVsuccesses;
      return true;
    }
  }

  // Can we compute distance?
  if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
    APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
    APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getAPInt();
    APInt Distance = ConstDelta; // these need to be initialized
    APInt Remainder = ConstDelta;
    APInt::sdivrem(ConstDelta, ConstCoeff, Distance, Remainder);
    LLVM_DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");
    LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
    // Make sure Coeff divides Delta exactly
    if (Remainder != 0) {
      // Coeff doesn't divide Distance, no dependence
      ++StrongSIVindependence;
      ++StrongSIVsuccesses;
      return true;
    }
    Result.DV[Level].Distance = SE->getConstant(Distance);
    NewConstraint.setDistance(SE->getConstant(Distance), CurLoop);
    if (Distance.sgt(0))
      Result.DV[Level].Direction &= Dependence::DVEntry::LT;
    else if (Distance.slt(0))
      Result.DV[Level].Direction &= Dependence::DVEntry::GT;
    else
      Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
    ++StrongSIVsuccesses;
  } else if (Delta->isZero()) {
    // since 0/X == 0
    Result.DV[Level].Distance = Delta;
    NewConstraint.setDistance(Delta, CurLoop);
    Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
    ++StrongSIVsuccesses;
  } else {
    if (Coeff->isOne()) {
      LLVM_DEBUG(dbgs() << "\t    Distance = " << *Delta << "\n");
      Result.DV[Level].Distance = Delta; // since X/1 == X
      NewConstraint.setDistance(Delta, CurLoop);
    } else {
      Result.Consistent = false;
      NewConstraint.setLine(Coeff, SE->getNegativeSCEV(Coeff),
                            SE->getNegativeSCEV(Delta), CurLoop);
    }

    // maybe we can get a useful direction
    bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
    bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
    bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
    bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
    bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
    // The double negatives above are confusing.
    // It helps to read !SE->isKnownNonZero(Delta)
    // as "Delta might be Zero"
    unsigned NewDirection = Dependence::DVEntry::NONE;
    if ((DeltaMaybePositive && CoeffMaybePositive) ||
        (DeltaMaybeNegative && CoeffMaybeNegative))
      NewDirection = Dependence::DVEntry::LT;
    if (DeltaMaybeZero)
      NewDirection |= Dependence::DVEntry::EQ;
    if ((DeltaMaybeNegative && CoeffMaybePositive) ||
        (DeltaMaybePositive && CoeffMaybeNegative))
      NewDirection |= Dependence::DVEntry::GT;
    if (NewDirection < Result.DV[Level].Direction)
      ++StrongSIVsuccesses;
    Result.DV[Level].Direction &= NewDirection;
  }
  return false;
}

// weakCrossingSIVtest -
// From the paper, Practical Dependence Testing, Section 4.2.2
//
// When we have a pair of subscripts of the form [c1 + a*i] and [c2 - a*i],
// where i is an induction variable, c1 and c2 are loop invariant,
// and a is a constant, we can solve it exactly using the
// Weak-Crossing SIV test.
//
// Given c1 + a*i = c2 - a*i', we can look for the intersection of
// the two lines, where i = i', yielding
//
//    c1 + a*i = c2 - a*i
//    2a*i = c2 - c1
//    i = (c2 - c1)/2a
//
// If i < 0, there is no dependence.
// If i > upperbound, there is no dependence.
// If i = 0 (i.e., if c1 = c2), there's a dependence with distance = 0.
// If i = upperbound, there's a dependence with distance = 0.
// If i is integral, there's a dependence (all directions).
// If the non-integer part = 1/2, there's a dependence (<> directions).
// Otherwise, there's no dependence.
//
// Can prove independence. Failing that,
// can sometimes refine the directions.
// Can determine iteration for splitting.
//
// Return true if dependence disproved.
bool DependenceInfo::weakCrossingSIVtest(
    const SCEV *Coeff, const SCEV *SrcConst, const SCEV *DstConst,
    const Loop *CurLoop, unsigned Level, FullDependence &Result,
    Constraint &NewConstraint, const SCEV *&SplitIter) const {
  LLVM_DEBUG(dbgs() << "\tWeak-Crossing SIV test\n");
  LLVM_DEBUG(dbgs() << "\t    Coeff = " << *Coeff << "\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
  ++WeakCrossingSIVapplications;
  assert(0 < Level && Level <= CommonLevels && "Level out of range");
  Level--;
  Result.Consistent = false;
  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
  if (Delta->isZero()) {
    Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
    Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
    ++WeakCrossingSIVsuccesses;
    if (!Result.DV[Level].Direction) {
      ++WeakCrossingSIVindependence;
      return true;
    }
    Result.DV[Level].Distance = Delta; // = 0
    return false;
  }
  const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(Coeff);
  if (!ConstCoeff)
    return false;

  Result.DV[Level].Splitable = true;
  if (SE->isKnownNegative(ConstCoeff)) {
    ConstCoeff = dyn_cast<SCEVConstant>(SE->getNegativeSCEV(ConstCoeff));
    assert(ConstCoeff &&
           "dynamic cast of negative of ConstCoeff should yield constant");
    Delta = SE->getNegativeSCEV(Delta);
  }
  assert(SE->isKnownPositive(ConstCoeff) && "ConstCoeff should be positive");

  // compute SplitIter for use by DependenceInfo::getSplitIteration()
  SplitIter = SE->getUDivExpr(
      SE->getSMaxExpr(SE->getZero(Delta->getType()), Delta),
      SE->getMulExpr(SE->getConstant(Delta->getType(), 2), ConstCoeff));
  LLVM_DEBUG(dbgs() << "\t    Split iter = " << *SplitIter << "\n");

  const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
  if (!ConstDelta)
    return false;

  // We're certain that ConstCoeff > 0; therefore,
  // if Delta < 0, then no dependence.
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  LLVM_DEBUG(dbgs() << "\t    ConstCoeff = " << *ConstCoeff << "\n");
  if (SE->isKnownNegative(Delta)) {
    // No dependence, Delta < 0
    ++WeakCrossingSIVindependence;
    ++WeakCrossingSIVsuccesses;
    return true;
  }

  // We're certain that Delta > 0 and ConstCoeff > 0.
  // Check Delta/(2*ConstCoeff) against upper loop bound
  if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
    LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
    const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
    const SCEV *ML =
        SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound), ConstantTwo);
    LLVM_DEBUG(dbgs() << "\t    ML = " << *ML << "\n");
    if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, ML)) {
      // Delta too big, no dependence
      ++WeakCrossingSIVindependence;
      ++WeakCrossingSIVsuccesses;
      return true;
    }
    if (isKnownPredicate(CmpInst::ICMP_EQ, Delta, ML)) {
      // i = i' = UB
      Result.DV[Level].Direction &= ~Dependence::DVEntry::LT;
      Result.DV[Level].Direction &= ~Dependence::DVEntry::GT;
      ++WeakCrossingSIVsuccesses;
      if (!Result.DV[Level].Direction) {
        ++WeakCrossingSIVindependence;
        return true;
      }
      Result.DV[Level].Splitable = false;
      Result.DV[Level].Distance = SE->getZero(Delta->getType());
      return false;
    }
  }

  // check that Coeff divides Delta
  APInt APDelta = ConstDelta->getAPInt();
  APInt APCoeff = ConstCoeff->getAPInt();
  APInt Distance = APDelta; // these need to be initialzed
  APInt Remainder = APDelta;
  APInt::sdivrem(APDelta, APCoeff, Distance, Remainder);
  LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
  if (Remainder != 0) {
    // Coeff doesn't divide Delta, no dependence
    ++WeakCrossingSIVindependence;
    ++WeakCrossingSIVsuccesses;
    return true;
  }
  LLVM_DEBUG(dbgs() << "\t    Distance = " << Distance << "\n");

  // if 2*Coeff doesn't divide Delta, then the equal direction isn't possible
  APInt Two = APInt(Distance.getBitWidth(), 2, true);
  Remainder = Distance.srem(Two);
  LLVM_DEBUG(dbgs() << "\t    Remainder = " << Remainder << "\n");
  if (Remainder != 0) {
    // Equal direction isn't possible
    Result.DV[Level].Direction &= ~Dependence::DVEntry::EQ;
    ++WeakCrossingSIVsuccesses;
  }
  return false;
}

// Kirch's algorithm, from
//
//        Optimizing Supercompilers for Supercomputers
//        Michael Wolfe
//        MIT Press, 1989
//
// Program 2.1, page 29.
// Computes the GCD of AM and BM.
// Also finds a solution to the equation ax - by = gcd(a, b).
// Returns true if dependence disproved; i.e., gcd does not divide Delta.
static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM,
                    const APInt &Delta, APInt &G, APInt &X, APInt &Y) {
  APInt A0(Bits, 1, true), A1(Bits, 0, true);
  APInt B0(Bits, 0, true), B1(Bits, 1, true);
  APInt G0 = AM.abs();
  APInt G1 = BM.abs();
  APInt Q = G0; // these need to be initialized
  APInt R = G0;
  APInt::sdivrem(G0, G1, Q, R);
  while (R != 0) {
    // clang-format off
    APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
    APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
    G0 = G1; G1 = R;
    // clang-format on
    APInt::sdivrem(G0, G1, Q, R);
  }
  G = G1;
  LLVM_DEBUG(dbgs() << "\t    GCD = " << G << "\n");
  X = AM.slt(0) ? -A1 : A1;
  Y = BM.slt(0) ? B1 : -B1;

  // make sure gcd divides Delta
  R = Delta.srem(G);
  if (R != 0)
    return true; // gcd doesn't divide Delta, no dependence
  Q = Delta.sdiv(G);
  return false;
}

static APInt floorOfQuotient(const APInt &A, const APInt &B) {
  APInt Q = A; // these need to be initialized
  APInt R = A;
  APInt::sdivrem(A, B, Q, R);
  if (R == 0)
    return Q;
  if ((A.sgt(0) && B.sgt(0)) || (A.slt(0) && B.slt(0)))
    return Q;
  else
    return Q - 1;
}

static APInt ceilingOfQuotient(const APInt &A, const APInt &B) {
  APInt Q = A; // these need to be initialized
  APInt R = A;
  APInt::sdivrem(A, B, Q, R);
  if (R == 0)
    return Q;
  if ((A.sgt(0) && B.sgt(0)) || (A.slt(0) && B.slt(0)))
    return Q + 1;
  else
    return Q;
}

/// Given an affine expression of the form A*k + B, where k is an arbitrary
/// integer, infer the possible range of k based on the known range of the
/// affine expression. If we know A*k + B is non-negative, i.e.,
///
///   A*k + B >= 0
///
/// we can derive the following inequalities for k when A is positive:
///
///   k >= -B / A
///
/// Since k is an integer, it means k is greater than or equal to the
/// ceil(-B / A).
///
/// If the upper bound of the affine expression \p UB is passed, the following
/// inequality can be derived as well:
///
///   A*k + B <= UB
///
/// which leads to:
///
///   k <= (UB - B) / A
///
/// Again, as k is an integer, it means k is less than or equal to the
/// floor((UB - B) / A).
///
/// The similar logic applies when A is negative, but the inequalities sign flip
/// while working with them.
///
/// Preconditions: \p A is non-zero, and we know A*k + B is non-negative.
static std::pair<std::optional<APInt>, std::optional<APInt>>
inferDomainOfAffine(const APInt &A, const APInt &B,
                    const std::optional<APInt> &UB) {
  assert(A != 0 && "A must be non-zero");
  std::optional<APInt> TL, TU;
  if (A.sgt(0)) {
    TL = ceilingOfQuotient(-B, A);
    LLVM_DEBUG(dbgs() << "\t    Possible TL = " << *TL << "\n");
    // New bound check - modification to Banerjee's e3 check
    if (UB) {
      // TODO?: Overflow check for UB - B
      TU = floorOfQuotient(*UB - B, A);
      LLVM_DEBUG(dbgs() << "\t    Possible TU = " << *TU << "\n");
    }
  } else {
    TU = floorOfQuotient(-B, A);
    LLVM_DEBUG(dbgs() << "\t    Possible TU = " << *TU << "\n");
    // New bound check - modification to Banerjee's e3 check
    if (UB) {
      // TODO?: Overflow check for UB - B
      TL = ceilingOfQuotient(*UB - B, A);
      LLVM_DEBUG(dbgs() << "\t    Possible TL = " << *TL << "\n");
    }
  }
  return std::make_pair(TL, TU);
}

// exactSIVtest -
// When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*i],
// where i is an induction variable, c1 and c2 are loop invariant, and a1
// and a2 are constant, we can solve it exactly using an algorithm developed
// by Banerjee and Wolfe. See Algorithm 6.2.1 (case 2.5) in:
//
//        Dependence Analysis for Supercomputing
//        Utpal Banerjee
//        Kluwer Academic Publishers, 1988
//
// It's slower than the specialized tests (strong SIV, weak-zero SIV, etc),
// so use them if possible. They're also a bit better with symbolics and,
// in the case of the strong SIV test, can compute Distances.
//
// Return true if dependence disproved.
//
// This is a modified version of the original Banerjee algorithm. The original
// only tested whether Dst depends on Src. This algorithm extends that and
// returns all the dependencies that exist between Dst and Src.
bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
                                  const SCEV *SrcConst, const SCEV *DstConst,
                                  const Loop *CurLoop, unsigned Level,
                                  FullDependence &Result,
                                  Constraint &NewConstraint) const {
  LLVM_DEBUG(dbgs() << "\tExact SIV test\n");
  LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
  LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
  ++ExactSIVapplications;
  assert(0 < Level && Level <= CommonLevels && "Level out of range");
  Level--;
  Result.Consistent = false;
  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
                        CurLoop);
  const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
  const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
  const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
  if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
    return false;

  // find gcd
  APInt G, X, Y;
  APInt AM = ConstSrcCoeff->getAPInt();
  APInt BM = ConstDstCoeff->getAPInt();
  APInt CM = ConstDelta->getAPInt();
  unsigned Bits = AM.getBitWidth();
  if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
    // gcd doesn't divide Delta, no dependence
    ++ExactSIVindependence;
    ++ExactSIVsuccesses;
    return true;
  }

  LLVM_DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");

  // since SCEV construction normalizes, LM = 0
  std::optional<APInt> UM;
  // UM is perhaps unavailable, let's check
  if (const SCEVConstant *CUB =
          collectConstantUpperBound(CurLoop, Delta->getType())) {
    UM = CUB->getAPInt();
    LLVM_DEBUG(dbgs() << "\t    UM = " << *UM << "\n");
  }

  APInt TU(APInt::getSignedMaxValue(Bits));
  APInt TL(APInt::getSignedMinValue(Bits));
  APInt TC = CM.sdiv(G);
  APInt TX = X * TC;
  APInt TY = Y * TC;
  LLVM_DEBUG(dbgs() << "\t    TC = " << TC << "\n");
  LLVM_DEBUG(dbgs() << "\t    TX = " << TX << "\n");
  LLVM_DEBUG(dbgs() << "\t    TY = " << TY << "\n");

  APInt TB = BM.sdiv(G);
  APInt TA = AM.sdiv(G);

  // At this point, we have the following equations:
  //
  //   TA*i0 - TB*i1 = TC
  //
  // Also, we know that the all pairs of (i0, i1) can be expressed as:
  //
  //   (TX + k*TB, TY + k*TA)
  //
  // where k is an arbitrary integer.
  auto [TL0, TU0] = inferDomainOfAffine(TB, TX, UM);
  auto [TL1, TU1] = inferDomainOfAffine(TA, TY, UM);

  auto CreateVec = [](const std::optional<APInt> &V0,
                      const std::optional<APInt> &V1) {
    SmallVector<APInt, 2> Vec;
    if (V0)
      Vec.push_back(*V0);
    if (V1)
      Vec.push_back(*V1);
    return Vec;
  };

  SmallVector<APInt, 2> TLVec = CreateVec(TL0, TL1);
  SmallVector<APInt, 2> TUVec = CreateVec(TU0, TU1);

  LLVM_DEBUG(dbgs() << "\t    TA = " << TA << "\n");
  LLVM_DEBUG(dbgs() << "\t    TB = " << TB << "\n");

  if (TLVec.empty() || TUVec.empty())
    return false;
  TL = APIntOps::smax(TLVec.front(), TLVec.back());
  TU = APIntOps::smin(TUVec.front(), TUVec.back());
  LLVM_DEBUG(dbgs() << "\t    TL = " << TL << "\n");
  LLVM_DEBUG(dbgs() << "\t    TU = " << TU << "\n");

  if (TL.sgt(TU)) {
    ++ExactSIVindependence;
    ++ExactSIVsuccesses;
    return true;
  }

  // explore directions
  unsigned NewDirection = Dependence::DVEntry::NONE;
  APInt LowerDistance, UpperDistance;
  if (TA.sgt(TB)) {
    LowerDistance = (TY - TX) + (TA - TB) * TL;
    UpperDistance = (TY - TX) + (TA - TB) * TU;
  } else {
    LowerDistance = (TY - TX) + (TA - TB) * TU;
    UpperDistance = (TY - TX) + (TA - TB) * TL;
  }

  LLVM_DEBUG(dbgs() << "\t    LowerDistance = " << LowerDistance << "\n");
  LLVM_DEBUG(dbgs() << "\t    UpperDistance = " << UpperDistance << "\n");

  APInt Zero(Bits, 0, true);
  if (LowerDistance.sle(Zero) && UpperDistance.sge(Zero)) {
    NewDirection |= Dependence::DVEntry::EQ;
    ++ExactSIVsuccesses;
  }
  if (LowerDistance.slt(0)) {
    NewDirection |= Dependence::DVEntry::GT;
    ++ExactSIVsuccesses;
  }
  if (UpperDistance.sgt(0)) {
    NewDirection |= Dependence::DVEntry::LT;
    ++ExactSIVsuccesses;
  }

  // finished
  Result.DV[Level].Direction &= NewDirection;
  if (Result.DV[Level].Direction == Dependence::DVEntry::NONE)
    ++ExactSIVindependence;
  LLVM_DEBUG(dbgs() << "\t    Result = ");
  LLVM_DEBUG(Result.dump(dbgs()));
  return Result.DV[Level].Direction == Dependence::DVEntry::NONE;
}

// Return true if the divisor evenly divides the dividend.
static bool isRemainderZero(const SCEVConstant *Dividend,
                            const SCEVConstant *Divisor) {
  const APInt &ConstDividend = Dividend->getAPInt();
  const APInt &ConstDivisor = Divisor->getAPInt();
  return ConstDividend.srem(ConstDivisor) == 0;
}

// weakZeroSrcSIVtest -
// From the paper, Practical Dependence Testing, Section 4.2.2
//
// When we have a pair of subscripts of the form [c1] and [c2 + a*i],
// where i is an induction variable, c1 and c2 are loop invariant,
// and a is a constant, we can solve it exactly using the
// Weak-Zero SIV test.
//
// Given
//
//    c1 = c2 + a*i
//
// we get
//
//    (c1 - c2)/a = i
//
// If i is not an integer, there's no dependence.
// If i < 0 or > UB, there's no dependence.
// If i = 0, the direction is >= and peeling the
// 1st iteration will break the dependence.
// If i = UB, the direction is <= and peeling the
// last iteration will break the dependence.
// Otherwise, the direction is *.
//
// Can prove independence. Failing that, we can sometimes refine
// the directions. Can sometimes show that first or last
// iteration carries all the dependences (so worth peeling).
//
// (see also weakZeroDstSIVtest)
//
// Return true if dependence disproved.
bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
                                        const SCEV *SrcConst,
                                        const SCEV *DstConst,
                                        const Loop *CurLoop, unsigned Level,
                                        FullDependence &Result,
                                        Constraint &NewConstraint) const {
  // For the WeakSIV test, it's possible the loop isn't common to
  // the Src and Dst loops. If it isn't, then there's no need to
  // record a direction.
  LLVM_DEBUG(dbgs() << "\tWeak-Zero (src) SIV test\n");
  LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << "\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
  ++WeakZeroSIVapplications;
  assert(0 < Level && Level <= MaxLevels && "Level out of range");
  Level--;
  Result.Consistent = false;
  const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
  NewConstraint.setLine(SE->getZero(Delta->getType()), DstCoeff, Delta,
                        CurLoop);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  if (isKnownPredicate(CmpInst::ICMP_EQ, SrcConst, DstConst)) {
    if (Level < CommonLevels) {
      Result.DV[Level].Direction &= Dependence::DVEntry::GE;
      Result.DV[Level].PeelFirst = true;
      ++WeakZeroSIVsuccesses;
    }
    return false; // dependences caused by first iteration
  }
  const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
  if (!ConstCoeff)
    return false;
  const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
                             ? SE->getNegativeSCEV(ConstCoeff)
                             : ConstCoeff;
  const SCEV *NewDelta =
      SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;

  // check that Delta/SrcCoeff < iteration count
  // really check NewDelta < count*AbsCoeff
  if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
    LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
    const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
    if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
      ++WeakZeroSIVindependence;
      ++WeakZeroSIVsuccesses;
      return true;
    }
    if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
      // dependences caused by last iteration
      if (Level < CommonLevels) {
        Result.DV[Level].Direction &= Dependence::DVEntry::LE;
        Result.DV[Level].PeelLast = true;
        ++WeakZeroSIVsuccesses;
      }
      return false;
    }
  }

  // check that Delta/SrcCoeff >= 0
  // really check that NewDelta >= 0
  if (SE->isKnownNegative(NewDelta)) {
    // No dependence, newDelta < 0
    ++WeakZeroSIVindependence;
    ++WeakZeroSIVsuccesses;
    return true;
  }

  // if SrcCoeff doesn't divide Delta, then no dependence
  if (isa<SCEVConstant>(Delta) &&
      !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
    ++WeakZeroSIVindependence;
    ++WeakZeroSIVsuccesses;
    return true;
  }
  return false;
}

// weakZeroDstSIVtest -
// From the paper, Practical Dependence Testing, Section 4.2.2
//
// When we have a pair of subscripts of the form [c1 + a*i] and [c2],
// where i is an induction variable, c1 and c2 are loop invariant,
// and a is a constant, we can solve it exactly using the
// Weak-Zero SIV test.
//
// Given
//
//    c1 + a*i = c2
//
// we get
//
//    i = (c2 - c1)/a
//
// If i is not an integer, there's no dependence.
// If i < 0 or > UB, there's no dependence.
// If i = 0, the direction is <= and peeling the
// 1st iteration will break the dependence.
// If i = UB, the direction is >= and peeling the
// last iteration will break the dependence.
// Otherwise, the direction is *.
//
// Can prove independence. Failing that, we can sometimes refine
// the directions. Can sometimes show that first or last
// iteration carries all the dependences (so worth peeling).
//
// (see also weakZeroSrcSIVtest)
//
// Return true if dependence disproved.
bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
                                        const SCEV *SrcConst,
                                        const SCEV *DstConst,
                                        const Loop *CurLoop, unsigned Level,
                                        FullDependence &Result,
                                        Constraint &NewConstraint) const {
  // For the WeakSIV test, it's possible the loop isn't common to the
  // Src and Dst loops. If it isn't, then there's no need to record a direction.
  LLVM_DEBUG(dbgs() << "\tWeak-Zero (dst) SIV test\n");
  LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << "\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
  ++WeakZeroSIVapplications;
  assert(0 < Level && Level <= SrcLevels && "Level out of range");
  Level--;
  Result.Consistent = false;
  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
  NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->getType()), Delta,
                        CurLoop);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  if (isKnownPredicate(CmpInst::ICMP_EQ, DstConst, SrcConst)) {
    if (Level < CommonLevels) {
      Result.DV[Level].Direction &= Dependence::DVEntry::LE;
      Result.DV[Level].PeelFirst = true;
      ++WeakZeroSIVsuccesses;
    }
    return false; // dependences caused by first iteration
  }
  const SCEVConstant *ConstCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
  if (!ConstCoeff)
    return false;
  const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
                             ? SE->getNegativeSCEV(ConstCoeff)
                             : ConstCoeff;
  const SCEV *NewDelta =
      SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;

  // check that Delta/SrcCoeff < iteration count
  // really check NewDelta < count*AbsCoeff
  if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
    LLVM_DEBUG(dbgs() << "\t    UpperBound = " << *UpperBound << "\n");
    const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
    if (isKnownPredicate(CmpInst::ICMP_SGT, NewDelta, Product)) {
      ++WeakZeroSIVindependence;
      ++WeakZeroSIVsuccesses;
      return true;
    }
    if (isKnownPredicate(CmpInst::ICMP_EQ, NewDelta, Product)) {
      // dependences caused by last iteration
      if (Level < CommonLevels) {
        Result.DV[Level].Direction &= Dependence::DVEntry::GE;
        Result.DV[Level].PeelLast = true;
        ++WeakZeroSIVsuccesses;
      }
      return false;
    }
  }

  // check that Delta/SrcCoeff >= 0
  // really check that NewDelta >= 0
  if (SE->isKnownNegative(NewDelta)) {
    // No dependence, newDelta < 0
    ++WeakZeroSIVindependence;
    ++WeakZeroSIVsuccesses;
    return true;
  }

  // if SrcCoeff doesn't divide Delta, then no dependence
  if (isa<SCEVConstant>(Delta) &&
      !isRemainderZero(cast<SCEVConstant>(Delta), ConstCoeff)) {
    ++WeakZeroSIVindependence;
    ++WeakZeroSIVsuccesses;
    return true;
  }
  return false;
}

// exactRDIVtest - Tests the RDIV subscript pair for dependence.
// Things of the form [c1 + a*i] and [c2 + b*j],
// where i and j are induction variable, c1 and c2 are loop invariant,
// and a and b are constants.
// Returns true if any possible dependence is disproved.
// Marks the result as inconsistent.
// Works in some cases that symbolicRDIVtest doesn't, and vice versa.
bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
                                   const SCEV *SrcConst, const SCEV *DstConst,
                                   const Loop *SrcLoop, const Loop *DstLoop,
                                   FullDependence &Result) const {
  LLVM_DEBUG(dbgs() << "\tExact RDIV test\n");
  LLVM_DEBUG(dbgs() << "\t    SrcCoeff = " << *SrcCoeff << " = AM\n");
  LLVM_DEBUG(dbgs() << "\t    DstCoeff = " << *DstCoeff << " = BM\n");
  LLVM_DEBUG(dbgs() << "\t    SrcConst = " << *SrcConst << "\n");
  LLVM_DEBUG(dbgs() << "\t    DstConst = " << *DstConst << "\n");
  ++ExactRDIVapplications;
  Result.Consistent = false;
  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
  LLVM_DEBUG(dbgs() << "\t    Delta = " << *Delta << "\n");
  const SCEVConstant *ConstDelta = dyn_cast<SCEVConstant>(Delta);
  const SCEVConstant *ConstSrcCoeff = dyn_cast<SCEVConstant>(SrcCoeff);
  const SCEVConstant *ConstDstCoeff = dyn_cast<SCEVConstant>(DstCoeff);
  if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
    return false;

  // find gcd
  APInt G, X, Y;
  APInt AM = ConstSrcCoeff->getAPInt();
  APInt BM = ConstDstCoeff->getAPInt();
  APInt CM = ConstDelta->getAPInt();
  unsigned Bits = AM.getBitWidth();
  if (findGCD(Bits, AM, BM, CM, G, X, Y)) {
    // gcd doesn't divide Delta, no dependence
    ++ExactRDIVindependence;
    return true;
  }

  LLVM_DEBUG(dbgs() << "\t    X = " << X << ", Y = " << Y << "\n");

  // since SCEV construction seems to normalize, LM = 0
  std::optional<APInt> SrcUM;
  // SrcUM is perhaps unavailable, let's check
  if (const SCEVConstant *UpperBound =
          collectConstantUpperBound(SrcLoop, Delta->getType())) {
    SrcUM = UpperBound->getAPInt();
    LLVM_DEBUG(dbgs() << "\t    SrcUM = " << *SrcUM << "\n");
  }

  std::optional<APInt> DstUM;
  // UM is perhaps unavailable, let's check
  if (const SCEVConstant *UpperBound =
          collectConstantUpperBound(DstLoop, Delta->getType())) {
    DstUM = UpperBound->getAPInt();
    LLVM_DEBUG(dbgs() << "\t    DstUM = " << *DstUM << "\n");
  }

  APInt TU(APInt::getSignedMaxValue(Bits));
  APInt TL(APInt::getSignedMinValue(Bits));
  APInt TC = CM.sdiv(G);
  APInt TX = X * TC;
  APInt TY = Y * TC;
  LLVM_DEBUG(dbgs() << "\t    TC = " << TC << "\n");
  LLVM_DEBUG(dbgs() << "\t    TX = " << TX << "\n");
  LLVM_DEBUG(dbgs() << "\t    TY = " << TY << "\n");

  APInt TB = BM.sdiv(G);
  APInt TA = AM.sdiv(G);

  // At this point, we have the following equations:
  //
  //   TA*i - TB*j = TC
  //
  // Also, we know that the all pairs of (i, j) can be expressed as:
  //
  //   (TX + k*TB, TY + k*TA)
  //
  // where k is an arbitrary integer.
  auto [TL0, TU0] = inferDomainOfAffine(TB, TX, SrcUM);
  auto [TL1, TU1] = inferDomainOfAffine(TA, TY, DstUM);

  LLVM_DEBUG(dbgs() << "\t    TA = " << TA << "\n");
  LLVM_DEBUG(dbgs() << "\t    TB = " << TB << "\n");

  auto CreateVec = [](const std::optional<APInt> &V0,
                      const std::optional<APInt> &V1) {
    SmallVector<APInt, 2> Vec;
    if (V0)
      Vec.push_back(*V0);
    if (V1)
      Vec.push_back(*V1);
    return Vec;
  };

  SmallVector<APInt, 2> TLVec = CreateVec(TL0, TL1);
  SmallVector<APInt, 2> TUVec = CreateVec(TU0, TU1);
  if (TLVec.empty() || TUVec.empty())
    return false;

  TL = APIntOps::smax(TLVec.front(), TLVec.back());
  TU = APIntOps::smin(TUVec.front(), TUVec.back());
  LLVM_DEBUG(dbgs() << "\t    TL = " << TL << "\n");
  LLVM_DEBUG(dbgs() << "\t    TU = " << TU << "\n");

  if (TL.sgt(TU))
    ++ExactRDIVindependence;
  return TL.sgt(TU);
}

// symbolicRDIVtest -
// In Section 4.5 of the Practical Dependence Testing paper,the authors
// introduce a special case of Banerjee's Inequalities (also called the
// Extreme-Value Test) that can handle some of the SIV and RDIV cases,
// particularly cases with symbolics. Since it's only able to disprove
// dependence (not compute distances or directions), we'll use it as a
// fall back for the other tests.
//
// When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
// where i and j are induction variables and c1 and c2 are loop invariants,
// we can use the symbolic tests to disprove some dependences, serving as a
// backup for the RDIV test. Note that i and j can be the same variable,
// letting this test serve as a backup for the various SIV tests.
//
// For a dependence to exist, c1 + a1*i must equal c2 + a2*j for some
//  0 <= i <= N1 and some 0 <= j <= N2, where N1 and N2 are the (normalized)
// loop bounds for the i and j loops, respectively. So, ...
//
// c1 + a1*i = c2 + a2*j
// a1*i - a2*j = c2 - c1
//
// To test for a dependence, we compute c2 - c1 and make sure it's in the
// range of the maximum and minimum possible values of a1*i - a2*j.
// Considering the signs of a1 and a2, we have 4 possible cases:
//
// 1) If a1 >= 0 and a2 >= 0, then
//        a1*0 - a2*N2 <= c2 - c1 <= a1*N1 - a2*0
//              -a2*N2 <= c2 - c1 <= a1*N1
//
// 2) If a1 >= 0 and a2 <= 0, then
//        a1*0 - a2*0 <= c2 - c1 <= a1*N1 - a2*N2
//                  0 <= c2 - c1 <= a1*N1 - a2*N2
//
// 3) If a1 <= 0 and a2 >= 0, then
//        a1*N1 - a2*N2 <= c2 - c1 <= a1*0 - a2*0
//        a1*N1 - a2*N2 <= c2 - c1 <= 0
//
// 4) If a1 <= 0 and a2 <= 0, then
//        a1*N1 - a2*0  <= c2 - c1 <= a1*0 - a2*N2
//        a1*N1         <= c2 - c1 <=       -a2*N2
//
// return true if dependence disproved
bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
                                      const SCEV *C1, const SCEV *C2,
                                      const Loop *Loop1,
                                      const Loop *Loop2) const {
  ++SymbolicRDIVapplications;
  LLVM_DEBUG(dbgs() << "\ttry symbolic RDIV test\n");
  LLVM_DEBUG(dbgs() << "\t    A1 = " << *A1);
  LLVM_DEBUG(dbgs() << ", type = " << *A1->getType() << "\n");
  LLVM_DEBUG(dbgs() << "\t    A2 = " << *A2 << "\n");
  LLVM_DEBUG(dbgs() << "\t    C1 = " << *C1 << "\n");
  LLVM_DEBUG(dbgs() << "\t    C2 = " << *C2 << "\n");
  const SCEV *N1 = collectUpperBound(Loop1, A1->getType());
  const SCEV *N2 = collectUpperBound(Loop2, A1->getType());
  LLVM_DEBUG(if (N1) dbgs() << "\t    N1 = " << *N1 << "\n");
  LLVM_DEBUG(if (N2) dbgs() << "\t    N2 = " << *N2 << "\n");
  const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
  const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
  LLVM_DEBUG(dbgs() << "\t    C2 - C1 = " << *C2_C1 << "\n");
  LLVM_DEBUG(dbgs() << "\t    C1 - C2 = " << *C1_C2 << "\n");
  if (SE->isKnownNonNegative(A1)) {
    if (SE->isKnownNonNegative(A2)) {
      // A1 >= 0 && A2 >= 0
      if (N1) {
        // make sure that c2 - c1 <= a1*N1
        const SCEV *A1N1 = SE->getMulExpr(A1, N1);
        LLVM_DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
      if (N2) {
        // make sure that -a2*N2 <= c2 - c1, or a2*N2 >= c1 - c2
        const SCEV *A2N2 = SE->getMulExpr(A2, N2);
        LLVM_DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SLT, A2N2, C1_C2)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
    } else if (SE->isKnownNonPositive(A2)) {
      // a1 >= 0 && a2 <= 0
      if (N1 && N2) {
        // make sure that c2 - c1 <= a1*N1 - a2*N2
        const SCEV *A1N1 = SE->getMulExpr(A1, N1);
        const SCEV *A2N2 = SE->getMulExpr(A2, N2);
        const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
        LLVM_DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1_A2N2)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
      // make sure that 0 <= c2 - c1
      if (SE->isKnownNegative(C2_C1)) {
        ++SymbolicRDIVindependence;
        return true;
      }
    }
  } else if (SE->isKnownNonPositive(A1)) {
    if (SE->isKnownNonNegative(A2)) {
      // a1 <= 0 && a2 >= 0
      if (N1 && N2) {
        // make sure that a1*N1 - a2*N2 <= c2 - c1
        const SCEV *A1N1 = SE->getMulExpr(A1, N1);
        const SCEV *A2N2 = SE->getMulExpr(A2, N2);
        const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
        LLVM_DEBUG(dbgs() << "\t    A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1_A2N2, C2_C1)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
      // make sure that c2 - c1 <= 0
      if (SE->isKnownPositive(C2_C1)) {
        ++SymbolicRDIVindependence;
        return true;
      }
    } else if (SE->isKnownNonPositive(A2)) {
      // a1 <= 0 && a2 <= 0
      if (N1) {
        // make sure that a1*N1 <= c2 - c1
        const SCEV *A1N1 = SE->getMulExpr(A1, N1);
        LLVM_DEBUG(dbgs() << "\t    A1*N1 = " << *A1N1 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1, C2_C1)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
      if (N2) {
        // make sure that c2 - c1 <= -a2*N2, or c1 - c2 >= a2*N2
        const SCEV *A2N2 = SE->getMulExpr(A2, N2);
        LLVM_DEBUG(dbgs() << "\t    A2*N2 = " << *A2N2 << "\n");
        if (isKnownPredicate(CmpInst::ICMP_SLT, C1_C2, A2N2)) {
          ++SymbolicRDIVindependence;
          return true;
        }
      }
    }
  }
  return false;
}

// testSIV -
// When we have a pair of subscripts of the form [c1 + a1*i] and [c2 - a2*i]
// where i is an induction variable, c1 and c2 are loop invariant, and a1 and
// a2 are constant, we attack it with an SIV test. While they can all be
// solved with the Exact SIV test, it's worthwhile to use simpler tests when
// they apply; they're cheaper and sometimes more precise.
//
// Return true if dependence disproved.
bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
                             FullDependence &Result, Constraint &NewConstraint,
                             const SCEV *&SplitIter) const {
  LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
  const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
  const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
  if (SrcAddRec && DstAddRec) {
    const SCEV *SrcConst = SrcAddRec->getStart();
    const SCEV *DstConst = DstAddRec->getStart();
    const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
    const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
    const Loop *CurLoop = SrcAddRec->getLoop();
    assert(CurLoop == DstAddRec->getLoop() &&
           "both loops in SIV should be same");
    Level = mapSrcLoop(CurLoop);
    bool disproven;
    if (SrcCoeff == DstCoeff)
      disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop, Level,
                                Result, NewConstraint);
    else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
      disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
                                      Level, Result, NewConstraint, SplitIter);
    else
      disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
                               Level, Result, NewConstraint);
    return disproven || gcdMIVtest(Src, Dst, Result) ||
           symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
                            CurLoop);
  }
  if (SrcAddRec) {
    const SCEV *SrcConst = SrcAddRec->getStart();
    const SCEV *SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
    const SCEV *DstConst = Dst;
    const Loop *CurLoop = SrcAddRec->getLoop();
    Level = mapSrcLoop(CurLoop);
    return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop, Level,
                              Result, NewConstraint) ||
           gcdMIVtest(Src, Dst, Result);
  }
  if (DstAddRec) {
    const SCEV *DstConst = DstAddRec->getStart();
    const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
    const SCEV *SrcConst = Src;
    const Loop *CurLoop = DstAddRec->getLoop();
    Level = mapDstLoop(CurLoop);
    return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst, CurLoop, Level,
                              Result, NewConstraint) ||
           gcdMIVtest(Src, Dst, Result);
  }
  llvm_unreachable("SIV test expected at least one AddRec");
  return false;
}

// testRDIV -
// When we have a pair of subscripts of the form [c1 + a1*i] and [c2 + a2*j]
// where i and j are induction variables, c1 and c2 are loop invariant,
// and a1 and a2 are constant, we can solve it exactly with an easy adaptation
// of the Exact SIV test, the Restricted Double Index Variable (RDIV) test.
// It doesn't make sense to talk about distance or direction in this case,
// so there's no point in making special versions of the Strong SIV test or
// the Weak-crossing SIV test.
//
// With minor algebra, this test can also be used for things like
// [c1 + a1*i + a2*j][c2].
//
// Return true if dependence disproved.
bool DependenceInfo::testRDIV(const SCEV *Src, const SCEV *Dst,
                              FullDependence &Result) const {
  // we have 3 possible situations here:
  //   1) [a*i + b] and [c*j + d]
  //   2) [a*i + c*j + b] and [d]
  //   3) [b] and [a*i + c*j + d]
  // We need to find what we've got and get organized

  const SCEV *SrcConst, *DstConst;
  const SCEV *SrcCoeff, *DstCoeff;
  const Loop *SrcLoop, *DstLoop;

  LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
  const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
  const SCEVAddRecExpr *DstAddRec = dyn_cast<SCEVAddRecExpr>(Dst);
  if (SrcAddRec && DstAddRec) {
    SrcConst = SrcAddRec->getStart();
    SrcCoeff = SrcAddRec->getStepRecurrence(*SE);
    SrcLoop = SrcAddRec->getLoop();
    DstConst = DstAddRec->getStart();
    DstCoeff = DstAddRec->getStepRecurrence(*SE);
    DstLoop = DstAddRec->getLoop();
  } else if (SrcAddRec) {
    if (const SCEVAddRecExpr *tmpAddRec =
            dyn_cast<SCEVAddRecExpr>(SrcAddRec->getStart())) {
      SrcConst = tmpAddRec->getStart();
      SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
      SrcLoop = tmpAddRec->getLoop();
      DstConst = Dst;
      DstCoeff = SE->getNegativeSCEV(SrcAddRec->getStepRecurrence(*SE));
      DstLoop = SrcAddRec->getLoop();
    } else
      llvm_unreachable("RDIV reached by surprising SCEVs");
  } else if (DstAddRec) {
    if (const SCEVAddRecExpr *tmpAddRec =
            dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
      DstConst = tmpAddRec->getStart();
      DstCoeff = tmpAddRec->getStepRecurrence(*SE);
      DstLoop = tmpAddRec->getLoop();
      SrcConst = Src;
      SrcCoeff = SE->getNegativeSCEV(DstAddRec->getStepRecurrence(*SE));
      SrcLoop = DstAddRec->getLoop();
    } else
      llvm_unreachable("RDIV reached by surprising SCEVs");
  } else
    llvm_unreachable("RDIV expected at least one AddRec");
  return exactRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop, DstLoop,
                       Result) ||
         gcdMIVtest(Src, Dst, Result) ||
         symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop,
                          DstLoop);
}

// Tests the single-subscript MIV pair (Src and Dst) for dependence.
// Return true if dependence disproved.
// Can sometimes refine direction vectors.
bool DependenceInfo::testMIV(const SCEV *Src, const SCEV *Dst,
                             const SmallBitVector &Loops,
                             FullDependence &Result) const {
  LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
  Result.Consistent = false;
  return gcdMIVtest(Src, Dst, Result) ||
         banerjeeMIVtest(Src, Dst, Loops, Result);
}

// Given a product, e.g., 10*X*Y, returns the first constant operand,
// in this case 10. If there is no constant part, returns std::nullopt.
static std::optional<APInt> getConstantPart(const SCEV *Expr) {
  if (const auto *Constant = dyn_cast<SCEVConstant>(Expr))
    return Constant->getAPInt();
  if (const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
    if (const auto *Constant = dyn_cast<SCEVConstant>(Product->getOperand(0)))
      return Constant->getAPInt();
  return std::nullopt;
}

bool DependenceInfo::accumulateCoefficientsGCD(const SCEV *Expr,
                                               const Loop *CurLoop,
                                               const SCEV *&CurLoopCoeff,
                                               APInt &RunningGCD) const {
  // If RunningGCD is already 1, exit early.
  // TODO: It might be better to continue the recursion to find CurLoopCoeff.
  if (RunningGCD == 1)
    return true;

  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
  if (!AddRec) {
    assert(isLoopInvariant(Expr, CurLoop) &&
           "Expected loop invariant expression");
    return true;
  }

  assert(AddRec->isAffine() && "Unexpected Expr");
  const SCEV *Start = AddRec->getStart();
  const SCEV *Step = AddRec->getStepRecurrence(*SE);
  if (AddRec->getLoop() == CurLoop) {
    CurLoopCoeff = Step;
  } else {
    std::optional<APInt> ConstCoeff = getConstantPart(Step);

    // If the coefficient is the product of a constant and other stuff, we can
    // use the constant in the GCD computation.
    if (!ConstCoeff)
      return false;

    // TODO: What happens if ConstCoeff is the "most negative" signed number
    // (e.g. -128 for 8 bit wide APInt)?
    RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff->abs());
  }

  return accumulateCoefficientsGCD(Start, CurLoop, CurLoopCoeff, RunningGCD);
}

//===----------------------------------------------------------------------===//
// gcdMIVtest -
// Tests an MIV subscript pair for dependence.
// Returns true if any possible dependence is disproved.
// Marks the result as inconsistent.
// Can sometimes disprove the equal direction for 1 or more loops,
// as discussed in Michael Wolfe's book,
// High Performance Compilers for Parallel Computing, page 235.
//
// We spend some effort (code!) to handle cases like
// [10*i + 5*N*j + 15*M + 6], where i and j are induction variables,
// but M and N are just loop-invariant variables.
// This should help us handle linearized subscripts;
// also makes this test a useful backup to the various SIV tests.
//
// It occurs to me that the presence of loop-invariant variables
// changes the nature of the test from "greatest common divisor"
// to "a common divisor".
bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
                                FullDependence &Result) const {
  LLVM_DEBUG(dbgs() << "starting gcd\n");
  ++GCDapplications;
  unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
  APInt RunningGCD = APInt::getZero(BitWidth);

  // Examine Src coefficients.
  // Compute running GCD and record source constant.
  // Because we're looking for the constant at the end of the chain,
  // we can't quit the loop just because the GCD == 1.
  const SCEV *Coefficients = Src;
  while (const SCEVAddRecExpr *AddRec =
             dyn_cast<SCEVAddRecExpr>(Coefficients)) {
    const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
    // If the coefficient is the product of a constant and other stuff,
    // we can use the constant in the GCD computation.
    std::optional<APInt> ConstCoeff = getConstantPart(Coeff);
    if (!ConstCoeff)
      return false;
    RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff->abs());
    Coefficients = AddRec->getStart();
  }
  const SCEV *SrcConst = Coefficients;

  // Examine Dst coefficients.
  // Compute running GCD and record destination constant.
  // Because we're looking for the constant at the end of the chain,
  // we can't quit the loop just because the GCD == 1.
  Coefficients = Dst;
  while (const SCEVAddRecExpr *AddRec =
             dyn_cast<SCEVAddRecExpr>(Coefficients)) {
    const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
    // If the coefficient is the product of a constant and other stuff,
    // we can use the constant in the GCD computation.
    std::optional<APInt> ConstCoeff = getConstantPart(Coeff);
    if (!ConstCoeff)
      return false;
    RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff->abs());
    Coefficients = AddRec->getStart();
  }
  const SCEV *DstConst = Coefficients;

  APInt ExtraGCD = APInt::getZero(BitWidth);
  const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
  LLVM_DEBUG(dbgs() << "    Delta = " << *Delta << "\n");
  const SCEVConstant *Constant = dyn_cast<SCEVConstant>(Delta);
  if (const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
    // If Delta is a sum of products, we may be able to make further progress.
    for (const SCEV *Operand : Sum->operands()) {
      if (isa<SCEVConstant>(Operand)) {
        assert(!Constant && "Surprised to find multiple constants");
        Constant = cast<SCEVConstant>(Operand);
      } else if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
        // Search for constant operand to participate in GCD;
        // If none found; return false.
        std::optional<APInt> ConstOp = getConstantPart(Product);
        if (!ConstOp)
          return false;
        ExtraGCD = APIntOps::GreatestCommonDivisor(ExtraGCD, ConstOp->abs());
      } else
        return false;
    }
  }
  if (!Constant)
    return false;
  APInt ConstDelta = cast<SCEVConstant>(Constant)->getAPInt();
  LLVM_DEBUG(dbgs() << "    ConstDelta = " << ConstDelta << "\n");
  if (ConstDelta == 0)
    return false;
  RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ExtraGCD);
  LLVM_DEBUG(dbgs() << "    RunningGCD = " << RunningGCD << "\n");
  APInt Remainder = ConstDelta.srem(RunningGCD);
  if (Remainder != 0) {
    ++GCDindependence;
    return true;
  }

  // Try to disprove equal directions.
  // For example, given a subscript pair [3*i + 2*j] and [i' + 2*j' - 1],
  // the code above can't disprove the dependence because the GCD = 1.
  // So we consider what happen if i = i' and what happens if j = j'.
  // If i = i', we can simplify the subscript to [2*i + 2*j] and [2*j' - 1],
  // which is infeasible, so we can disallow the = direction for the i level.
  // Setting j = j' doesn't help matters, so we end up with a direction vector
  // of [<>, *]
  //
  // Given A[5*i + 10*j*M + 9*M*N] and A[15*i + 20*j*M - 21*N*M + 5],
  // we need to remember that the constant part is 5 and the RunningGCD should
  // be initialized to ExtraGCD = 30.
  LLVM_DEBUG(dbgs() << "    ExtraGCD = " << ExtraGCD << '\n');

  bool Improved = false;
  Coefficients = Src;
  while (const SCEVAddRecExpr *AddRec =
             dyn_cast<SCEVAddRecExpr>(Coefficients)) {
    Coefficients = AddRec->getStart();
    const Loop *CurLoop = AddRec->getLoop();
    RunningGCD = ExtraGCD;
    const SCEV *SrcCoeff = AddRec->getStepRecurrence(*SE);
    const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);

    if (!accumulateCoefficientsGCD(Src, CurLoop, SrcCoeff, RunningGCD) ||
        !accumulateCoefficientsGCD(Dst, CurLoop, DstCoeff, RunningGCD))
      return false;

    Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
    // If the coefficient is the product of a constant and other stuff,
    // we can use the constant in the GCD computation.
    std::optional<APInt> ConstCoeff = getConstantPart(Delta);
    if (!ConstCoeff)
      // The difference of the two coefficients might not be a product
      // or constant, in which case we give up on this direction.
      continue;
    RunningGCD = APIntOps::GreatestCommonDivisor(RunningGCD, ConstCoeff->abs());
    LLVM_DEBUG(dbgs() << "\tRunningGCD = " << RunningGCD << "\n");
    if (RunningGCD != 0) {
      Remainder = ConstDelta.srem(RunningGCD);
      LLVM_DEBUG(dbgs() << "\tRemainder = " << Remainder << "\n");
      if (Remainder != 0) {
        unsigned Level = mapSrcLoop(CurLoop);
        Result.DV[Level - 1].Direction &= ~Dependence::DVEntry::EQ;
        Improved = true;
      }
    }
  }
  if (Improved)
    ++GCDsuccesses;
  LLVM_DEBUG(dbgs() << "all done\n");
  return false;
}

//===----------------------------------------------------------------------===//
// banerjeeMIVtest -
// Use Banerjee's Inequalities to test an MIV subscript pair.
// (Wolfe, in the race-car book, calls this the Extreme Value Test.)
// Generally follows the discussion in Section 2.5.2 of
//
//    Optimizing Supercompilers for Supercomputers
//    Michael Wolfe
//
// The inequalities given on page 25 are simplified in that loops are
// normalized so that the lower bound is always 0 and the stride is always 1.
// For example, Wolfe gives
//
//     LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
//
// where A_k is the coefficient of the kth index in the source subscript,
// B_k is the coefficient of the kth index in the destination subscript,
// U_k is the upper bound of the kth index, L_k is the lower bound of the Kth
// index, and N_k is the stride of the kth index. Since all loops are normalized
// by the SCEV package, N_k = 1 and L_k = 0, allowing us to simplify the
// equation to
//
//     LB^<_k = (A^-_k - B_k)^- (U_k - 0 - 1) + (A_k - B_k)0 - B_k 1
//            = (A^-_k - B_k)^- (U_k - 1)  - B_k
//
// Similar simplifications are possible for the other equations.
//
// When we can't determine the number of iterations for a loop,
// we use NULL as an indicator for the worst case, infinity.
// When computing the upper bound, NULL denotes +inf;
// for the lower bound, NULL denotes -inf.
//
// Return true if dependence disproved.
bool DependenceInfo::banerjeeMIVtest(const SCEV *Src, const SCEV *Dst,
                                     const SmallBitVector &Loops,
                                     FullDependence &Result) const {
  LLVM_DEBUG(dbgs() << "starting Banerjee\n");
  ++BanerjeeApplications;
  LLVM_DEBUG(dbgs() << "    Src = " << *Src << '\n');
  const SCEV *A0;
  CoefficientInfo *A = collectCoeffInfo(Src, true, A0);
  LLVM_DEBUG(dbgs() << "    Dst = " << *Dst << '\n');
  const SCEV *B0;
  CoefficientInfo *B = collectCoeffInfo(Dst, false, B0);
  BoundInfo *Bound = new BoundInfo[MaxLevels + 1];
  const SCEV *Delta = SE->getMinusSCEV(B0, A0);
  LLVM_DEBUG(dbgs() << "\tDelta = " << *Delta << '\n');

  // Compute bounds for all the * directions.
  LLVM_DEBUG(dbgs() << "\tBounds[*]\n");
  for (unsigned K = 1; K <= MaxLevels; ++K) {
    Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
    Bound[K].Direction = Dependence::DVEntry::ALL;
    Bound[K].DirSet = Dependence::DVEntry::NONE;
    findBoundsALL(A, B, Bound, K);
#ifndef NDEBUG
    LLVM_DEBUG(dbgs() << "\t    " << K << '\t');
    if (Bound[K].Lower[Dependence::DVEntry::ALL])
      LLVM_DEBUG(dbgs() << *Bound[K].Lower[Dependence::DVEntry::ALL] << '\t');
    else
      LLVM_DEBUG(dbgs() << "-inf\t");
    if (Bound[K].Upper[Dependence::DVEntry::ALL])
      LLVM_DEBUG(dbgs() << *Bound[K].Upper[Dependence::DVEntry::ALL] << '\n');
    else
      LLVM_DEBUG(dbgs() << "+inf\n");
#endif
  }

  // Test the *, *, *, ... case.
  bool Disproved = false;
  if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
    // Explore the direction vector hierarchy.
    unsigned DepthExpanded = 0;
    unsigned NewDeps =
        exploreDirections(1, A, B, Bound, Loops, DepthExpanded, Delta);
    if (NewDeps > 0) {
      bool Improved = false;
      for (unsigned K = 1; K <= CommonLevels; ++K) {
        if (Loops[K]) {
          unsigned Old = Result.DV[K - 1].Direction;
          Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
          Improved |= Old != Result.DV[K - 1].Direction;
          if (!Result.DV[K - 1].Direction) {
            Improved = false;
            Disproved = true;
            break;
          }
        }
      }
      if (Improved)
        ++BanerjeeSuccesses;
    } else {
      ++BanerjeeIndependence;
      Disproved = true;
    }
  } else {
    ++BanerjeeIndependence;
    Disproved = true;
  }
  delete[] Bound;
  delete[] A;
  delete[] B;
  return Disproved;
}

// Hierarchically expands the direction vector
// search space, combining the directions of discovered dependences
// in the DirSet field of Bound. Returns the number of distinct
// dependences discovered. If the dependence is disproved,
// it will return 0.
unsigned DependenceInfo::exploreDirections(unsigned Level, CoefficientInfo *A,
                                           CoefficientInfo *B, BoundInfo *Bound,
                                           const SmallBitVector &Loops,
                                           unsigned &DepthExpanded,
                                           const SCEV *Delta) const {
  // This algorithm has worst case complexity of O(3^n), where 'n' is the number
  // of common loop levels. To avoid excessive compile-time, pessimize all the
  // results and immediately return when the number of common levels is beyond
  // the given threshold.
  if (CommonLevels > MIVMaxLevelThreshold) {
    LLVM_DEBUG(dbgs() << "Number of common levels exceeded the threshold. MIV "
                         "direction exploration is terminated.\n");
    for (unsigned K = 1; K <= CommonLevels; ++K)
      if (Loops[K])
        Bound[K].DirSet = Dependence::DVEntry::ALL;
    return 1;
  }

  if (Level > CommonLevels) {
    // record result
    LLVM_DEBUG(dbgs() << "\t[");
    for (unsigned K = 1; K <= CommonLevels; ++K) {
      if (Loops[K]) {
        Bound[K].DirSet |= Bound[K].Direction;
#ifndef NDEBUG
        switch (Bound[K].Direction) {
        case Dependence::DVEntry::LT:
          LLVM_DEBUG(dbgs() << " <");
          break;
        case Dependence::DVEntry::EQ:
          LLVM_DEBUG(dbgs() << " =");
          break;
        case Dependence::DVEntry::GT:
          LLVM_DEBUG(dbgs() << " >");
          break;
        case Dependence::DVEntry::ALL:
          LLVM_DEBUG(dbgs() << " *");
          break;
        default:
          llvm_unreachable("unexpected Bound[K].Direction");
        }
#endif
      }
    }
    LLVM_DEBUG(dbgs() << " ]\n");
    return 1;
  }
  if (Loops[Level]) {
    if (Level > DepthExpanded) {
      DepthExpanded = Level;
      // compute bounds for <, =, > at current level
      findBoundsLT(A, B, Bound, Level);
      findBoundsGT(A, B, Bound, Level);
      findBoundsEQ(A, B, Bound, Level);
#ifndef NDEBUG
      LLVM_DEBUG(dbgs() << "\tBound for level = " << Level << '\n');
      LLVM_DEBUG(dbgs() << "\t    <\t");
      if (Bound[Level].Lower[Dependence::DVEntry::LT])
        LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::LT]
                          << '\t');
      else
        LLVM_DEBUG(dbgs() << "-inf\t");
      if (Bound[Level].Upper[Dependence::DVEntry::LT])
        LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::LT]
                          << '\n');
      else
        LLVM_DEBUG(dbgs() << "+inf\n");
      LLVM_DEBUG(dbgs() << "\t    =\t");
      if (Bound[Level].Lower[Dependence::DVEntry::EQ])
        LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::EQ]
                          << '\t');
      else
        LLVM_DEBUG(dbgs() << "-inf\t");
      if (Bound[Level].Upper[Dependence::DVEntry::EQ])
        LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::EQ]
                          << '\n');
      else
        LLVM_DEBUG(dbgs() << "+inf\n");
      LLVM_DEBUG(dbgs() << "\t    >\t");
      if (Bound[Level].Lower[Dependence::DVEntry::GT])
        LLVM_DEBUG(dbgs() << *Bound[Level].Lower[Dependence::DVEntry::GT]
                          << '\t');
      else
        LLVM_DEBUG(dbgs() << "-inf\t");
      if (Bound[Level].Upper[Dependence::DVEntry::GT])
        LLVM_DEBUG(dbgs() << *Bound[Level].Upper[Dependence::DVEntry::GT]
                          << '\n');
      else
        LLVM_DEBUG(dbgs() << "+inf\n");
#endif
    }

    unsigned NewDeps = 0;

    // test bounds for <, *, *, ...
    if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
      NewDeps += exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded,
                                   Delta);

    // Test bounds for =, *, *, ...
    if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
      NewDeps += exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded,
                                   Delta);

    // test bounds for >, *, *, ...
    if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
      NewDeps += exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded,
                                   Delta);

    Bound[Level].Direction = Dependence::DVEntry::ALL;
    return NewDeps;
  } else
    return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded,
                             Delta);
}

// Returns true iff the current bounds are plausible.
bool DependenceInfo::testBounds(unsigned char DirKind, unsigned Level,
                                BoundInfo *Bound, const SCEV *Delta) const {
  Bound[Level].Direction = DirKind;
  if (const SCEV *LowerBound = getLowerBound(Bound))
    if (isKnownPredicate(CmpInst::ICMP_SGT, LowerBound, Delta))
      return false;
  if (const SCEV *UpperBound = getUpperBound(Bound))
    if (isKnownPredicate(CmpInst::ICMP_SGT, Delta, UpperBound))
      return false;
  return true;
}

// Computes the upper and lower bounds for level K
// using the * direction. Records them in Bound.
// Wolfe gives the equations
//
//    LB^*_k = (A^-_k - B^+_k)(U_k - L_k) + (A_k - B_k)L_k
//    UB^*_k = (A^+_k - B^-_k)(U_k - L_k) + (A_k - B_k)L_k
//
// Since we normalize loops, we can simplify these equations to
//
//    LB^*_k = (A^-_k - B^+_k)U_k
//    UB^*_k = (A^+_k - B^-_k)U_k
//
// We must be careful to handle the case where the upper bound is unknown.
// Note that the lower bound is always <= 0
// and the upper bound is always >= 0.
void DependenceInfo::findBoundsALL(CoefficientInfo *A, CoefficientInfo *B,
                                   BoundInfo *Bound, unsigned K) const {
  Bound[K].Lower[Dependence::DVEntry::ALL] =
      nullptr; // Default value = -infinity.
  Bound[K].Upper[Dependence::DVEntry::ALL] =
      nullptr; // Default value = +infinity.
  if (Bound[K].Iterations) {
    Bound[K].Lower[Dependence::DVEntry::ALL] = SE->getMulExpr(
        SE->getMinusSCEV(A[K].NegPart, B[K].PosPart), Bound[K].Iterations);
    Bound[K].Upper[Dependence::DVEntry::ALL] = SE->getMulExpr(
        SE->getMinusSCEV(A[K].PosPart, B[K].NegPart), Bound[K].Iterations);
  } else {
    // If the difference is 0, we won't need to know the number of iterations.
    if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].NegPart, B[K].PosPart))
      Bound[K].Lower[Dependence::DVEntry::ALL] =
          SE->getZero(A[K].Coeff->getType());
    if (isKnownPredicate(CmpInst::ICMP_EQ, A[K].PosPart, B[K].NegPart))
      Bound[K].Upper[Dependence::DVEntry::ALL] =
          SE->getZero(A[K].Coeff->getType());
  }
}

// Computes the upper and lower bounds for level K
// using the = direction. Records them in Bound.
// Wolfe gives the equations
//
//    LB^=_k = (A_k - B_k)^- (U_k - L_k) + (A_k - B_k)L_k
//    UB^=_k = (A_k - B_k)^+ (U_k - L_k) + (A_k - B_k)L_k
//
// Since we normalize loops, we can simplify these equations to
//
//    LB^=_k = (A_k - B_k)^- U_k
//    UB^=_k = (A_k - B_k)^+ U_k
//
// We must be careful to handle the case where the upper bound is unknown.
// Note that the lower bound is always <= 0
// and the upper bound is always >= 0.
void DependenceInfo::findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B,
                                  BoundInfo *Bound, unsigned K) const {
  Bound[K].Lower[Dependence::DVEntry::EQ] =
      nullptr; // Default value = -infinity.
  Bound[K].Upper[Dependence::DVEntry::EQ] =
      nullptr; // Default value = +infinity.
  if (Bound[K].Iterations) {
    const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
    const SCEV *NegativePart = getNegativePart(Delta);
    Bound[K].Lower[Dependence::DVEntry::EQ] =
        SE->getMulExpr(NegativePart, Bound[K].Iterations);
    const SCEV *PositivePart = getPositivePart(Delta);
    Bound[K].Upper[Dependence::DVEntry::EQ] =
        SE->getMulExpr(PositivePart, Bound[K].Iterations);
  } else {
    // If the positive/negative part of the difference is 0,
    // we won't need to know the number of iterations.
    const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
    const SCEV *NegativePart = getNegativePart(Delta);
    if (NegativePart->isZero())
      Bound[K].Lower[Dependence::DVEntry::EQ] = NegativePart; // Zero
    const SCEV *PositivePart = getPositivePart(Delta);
    if (PositivePart->isZero())
      Bound[K].Upper[Dependence::DVEntry::EQ] = PositivePart; // Zero
  }
}

// Computes the upper and lower bounds for level K
// using the < direction. Records them in Bound.
// Wolfe gives the equations
//
//    LB^<_k = (A^-_k - B_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
//    UB^<_k = (A^+_k - B_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k - B_k N_k
//
// Since we normalize loops, we can simplify these equations to
//
//    LB^<_k = (A^-_k - B_k)^- (U_k - 1) - B_k
//    UB^<_k = (A^+_k - B_k)^+ (U_k - 1) - B_k
//
// We must be careful to handle the case where the upper bound is unknown.
void DependenceInfo::findBoundsLT(CoefficientInfo *A, CoefficientInfo *B,
                                  BoundInfo *Bound, unsigned K) const {
  Bound[K].Lower[Dependence::DVEntry::LT] =
      nullptr; // Default value = -infinity.
  Bound[K].Upper[Dependence::DVEntry::LT] =
      nullptr; // Default value = +infinity.
  if (Bound[K].Iterations) {
    const SCEV *Iter_1 = SE->getMinusSCEV(
        Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
    const SCEV *NegPart =
        getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
    Bound[K].Lower[Dependence::DVEntry::LT] =
        SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1), B[K].Coeff);
    const SCEV *PosPart =
        getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
    Bound[K].Upper[Dependence::DVEntry::LT] =
        SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1), B[K].Coeff);
  } else {
    // If the positive/negative part of the difference is 0,
    // we won't need to know the number of iterations.
    const SCEV *NegPart =
        getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
    if (NegPart->isZero())
      Bound[K].Lower[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
    const SCEV *PosPart =
        getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
    if (PosPart->isZero())
      Bound[K].Upper[Dependence::DVEntry::LT] = SE->getNegativeSCEV(B[K].Coeff);
  }
}

// Computes the upper and lower bounds for level K
// using the > direction. Records them in Bound.
// Wolfe gives the equations
//
//    LB^>_k = (A_k - B^+_k)^- (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
//    UB^>_k = (A_k - B^-_k)^+ (U_k - L_k - N_k) + (A_k - B_k)L_k + A_k N_k
//
// Since we normalize loops, we can simplify these equations to
//
//    LB^>_k = (A_k - B^+_k)^- (U_k - 1) + A_k
//    UB^>_k = (A_k - B^-_k)^+ (U_k - 1) + A_k
//
// We must be careful to handle the case where the upper bound is unknown.
void DependenceInfo::findBoundsGT(CoefficientInfo *A, CoefficientInfo *B,
                                  BoundInfo *Bound, unsigned K) const {
  Bound[K].Lower[Dependence::DVEntry::GT] =
      nullptr; // Default value = -infinity.
  Bound[K].Upper[Dependence::DVEntry::GT] =
      nullptr; // Default value = +infinity.
  if (Bound[K].Iterations) {
    const SCEV *Iter_1 = SE->getMinusSCEV(
        Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
    const SCEV *NegPart =
        getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
    Bound[K].Lower[Dependence::DVEntry::GT] =
        SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1), A[K].Coeff);
    const SCEV *PosPart =
        getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
    Bound[K].Upper[Dependence::DVEntry::GT] =
        SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1), A[K].Coeff);
  } else {
    // If the positive/negative part of the difference is 0,
    // we won't need to know the number of iterations.
    const SCEV *NegPart =
        getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
    if (NegPart->isZero())
      Bound[K].Lower[Dependence::DVEntry::GT] = A[K].Coeff;
    const SCEV *PosPart =
        getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
    if (PosPart->isZero())
      Bound[K].Upper[Dependence::DVEntry::GT] = A[K].Coeff;
  }
}

// X^+ = max(X, 0)
const SCEV *DependenceInfo::getPositivePart(const SCEV *X) const {
  return SE->getSMaxExpr(X, SE->getZero(X->getType()));
}

// X^- = min(X, 0)
const SCEV *DependenceInfo::getNegativePart(const SCEV *X) const {
  return SE->getSMinExpr(X, SE->getZero(X->getType()));
}

// Walks through the subscript,
// collecting each coefficient, the associated loop bounds,
// and recording its positive and negative parts for later use.
DependenceInfo::CoefficientInfo *
DependenceInfo::collectCoeffInfo(const SCEV *Subscript, bool SrcFlag,
                                 const SCEV *&Constant) const {
  const SCEV *Zero = SE->getZero(Subscript->getType());
  CoefficientInfo *CI = new CoefficientInfo[MaxLevels + 1];
  for (unsigned K = 1; K <= MaxLevels; ++K) {
    CI[K].Coeff = Zero;
    CI[K].PosPart = Zero;
    CI[K].NegPart = Zero;
    CI[K].Iterations = nullptr;
  }
  while (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
    const Loop *L = AddRec->getLoop();
    unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
    CI[K].Coeff = AddRec->getStepRecurrence(*SE);
    CI[K].PosPart = getPositivePart(CI[K].Coeff);
    CI[K].NegPart = getNegativePart(CI[K].Coeff);
    CI[K].Iterations = collectUpperBound(L, Subscript->getType());
    Subscript = AddRec->getStart();
  }
  Constant = Subscript;
#ifndef NDEBUG
  LLVM_DEBUG(dbgs() << "\tCoefficient Info\n");
  for (unsigned K = 1; K <= MaxLevels; ++K) {
    LLVM_DEBUG(dbgs() << "\t    " << K << "\t" << *CI[K].Coeff);
    LLVM_DEBUG(dbgs() << "\tPos Part = ");
    LLVM_DEBUG(dbgs() << *CI[K].PosPart);
    LLVM_DEBUG(dbgs() << "\tNeg Part = ");
    LLVM_DEBUG(dbgs() << *CI[K].NegPart);
    LLVM_DEBUG(dbgs() << "\tUpper Bound = ");
    if (CI[K].Iterations)
      LLVM_DEBUG(dbgs() << *CI[K].Iterations);
    else
      LLVM_DEBUG(dbgs() << "+inf");
    LLVM_DEBUG(dbgs() << '\n');
  }
  LLVM_DEBUG(dbgs() << "\t    Constant = " << *Subscript << '\n');
#endif
  return CI;
}

// Looks through all the bounds info and
// computes the lower bound given the current direction settings
// at each level. If the lower bound for any level is -inf,
// the result is -inf.
const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound) const {
  const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
  for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
    if (Bound[K].Lower[Bound[K].Direction])
      Sum = SE->getAddExpr(Sum, Bound[K].Lower[Bound[K].Direction]);
    else
      Sum = nullptr;
  }
  return Sum;
}

// Looks through all the bounds info and
// computes the upper bound given the current direction settings
// at each level. If the upper bound at any level is +inf,
// the result is +inf.
const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound) const {
  const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
  for (unsigned K = 2; Sum && K <= MaxLevels; ++K) {
    if (Bound[K].Upper[Bound[K].Direction])
      Sum = SE->getAddExpr(Sum, Bound[K].Upper[Bound[K].Direction]);
    else
      Sum = nullptr;
  }
  return Sum;
}

//===----------------------------------------------------------------------===//
// Constraint manipulation for Delta test.

// Given a linear SCEV,
// return the coefficient (the step)
// corresponding to the specified loop.
// If there isn't one, return 0.
// For example, given a*i + b*j + c*k, finding the coefficient
// corresponding to the j loop would yield b.
const SCEV *DependenceInfo::findCoefficient(const SCEV *Expr,
                                            const Loop *TargetLoop) const {
  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
  if (!AddRec)
    return SE->getZero(Expr->getType());
  if (AddRec->getLoop() == TargetLoop)
    return AddRec->getStepRecurrence(*SE);
  return findCoefficient(AddRec->getStart(), TargetLoop);
}

// Given a linear SCEV,
// return the SCEV given by zeroing out the coefficient
// corresponding to the specified loop.
// For example, given a*i + b*j + c*k, zeroing the coefficient
// corresponding to the j loop would yield a*i + c*k.
const SCEV *DependenceInfo::zeroCoefficient(const SCEV *Expr,
                                            const Loop *TargetLoop) const {
  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
  if (!AddRec)
    return Expr; // ignore
  if (AddRec->getLoop() == TargetLoop)
    return AddRec->getStart();
  return SE->getAddRecExpr(zeroCoefficient(AddRec->getStart(), TargetLoop),
                           AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
                           AddRec->getNoWrapFlags());
}

// Given a linear SCEV Expr,
// return the SCEV given by adding some Value to the
// coefficient corresponding to the specified TargetLoop.
// For example, given a*i + b*j + c*k, adding 1 to the coefficient
// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
                                             const Loop *TargetLoop,
                                             const SCEV *Value) const {
  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
  if (!AddRec) // create a new addRec
    return SE->getAddRecExpr(Expr, Value, TargetLoop,
                             SCEV::FlagAnyWrap); // Worst case, with no info.
  if (AddRec->getLoop() == TargetLoop) {
    const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
    if (Sum->isZero())
      return AddRec->getStart();
    return SE->getAddRecExpr(AddRec->getStart(), Sum, AddRec->getLoop(),
                             AddRec->getNoWrapFlags());
  }
  if (SE->isLoopInvariant(AddRec, TargetLoop))
    return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
  return SE->getAddRecExpr(
      addToCoefficient(AddRec->getStart(), TargetLoop, Value),
      AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
      AddRec->getNoWrapFlags());
}

// Review the constraints, looking for opportunities
// to simplify a subscript pair (Src and Dst).
// Return true if some simplification occurs.
// If the simplification isn't exact (that is, if it is conservative
// in terms of dependence), set consistent to false.
// Corresponds to Figure 5 from the paper
//
//            Practical Dependence Testing
//            Goff, Kennedy, Tseng
//            PLDI 1991
bool DependenceInfo::propagate(const SCEV *&Src, const SCEV *&Dst,
                               SmallBitVector &Loops,
                               SmallVectorImpl<Constraint> &Constraints,
                               bool &Consistent) {
  bool Result = false;
  for (unsigned LI : Loops.set_bits()) {
    LLVM_DEBUG(dbgs() << "\t    Constraint[" << LI << "] is");
    LLVM_DEBUG(Constraints[LI].dump(dbgs()));
    if (Constraints[LI].isDistance())
      Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
    else if (Constraints[LI].isLine())
      Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
    else if (Constraints[LI].isPoint())
      Result |= propagatePoint(Src, Dst, Constraints[LI]);
  }
  return Result;
}

// Attempt to propagate a distance
// constraint into a subscript pair (Src and Dst).
// Return true if some simplification occurs.
// If the simplification isn't exact (that is, if it is conservative
// in terms of dependence), set consistent to false.
bool DependenceInfo::propagateDistance(const SCEV *&Src, const SCEV *&Dst,
                                       Constraint &CurConstraint,
                                       bool &Consistent) {
  const Loop *CurLoop = CurConstraint.getAssociatedLoop();
  LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
  const SCEV *A_K = findCoefficient(Src, CurLoop);
  if (A_K->isZero())
    return false;
  const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
  Src = SE->getMinusSCEV(Src, DA_K);
  Src = zeroCoefficient(Src, CurLoop);
  LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
  Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
  LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
  if (!findCoefficient(Dst, CurLoop)->isZero())
    Consistent = false;
  return true;
}

// Attempt to propagate a line
// constraint into a subscript pair (Src and Dst).
// Return true if some simplification occurs.
// If the simplification isn't exact (that is, if it is conservative
// in terms of dependence), set consistent to false.
bool DependenceInfo::propagateLine(const SCEV *&Src, const SCEV *&Dst,
                                   Constraint &CurConstraint,
                                   bool &Consistent) {
  const Loop *CurLoop = CurConstraint.getAssociatedLoop();
  const SCEV *A = CurConstraint.getA();
  const SCEV *B = CurConstraint.getB();
  const SCEV *C = CurConstraint.getC();
  LLVM_DEBUG(dbgs() << "\t\tA = " << *A << ", B = " << *B << ", C = " << *C
                    << "\n");
  LLVM_DEBUG(dbgs() << "\t\tSrc = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "\t\tDst = " << *Dst << "\n");
  if (A->isZero()) {
    const SCEVConstant *Bconst = dyn_cast<SCEVConstant>(B);
    const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
    if (!Bconst || !Cconst)
      return false;
    APInt Beta = Bconst->getAPInt();
    APInt Charlie = Cconst->getAPInt();
    APInt CdivB = Charlie.sdiv(Beta);
    assert(Charlie.srem(Beta) == 0 && "C should be evenly divisible by B");
    const SCEV *AP_K = findCoefficient(Dst, CurLoop);
    Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
    Dst = zeroCoefficient(Dst, CurLoop);
    if (!findCoefficient(Src, CurLoop)->isZero())
      Consistent = false;
  } else if (B->isZero()) {
    const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
    const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
    if (!Aconst || !Cconst)
      return false;
    APInt Alpha = Aconst->getAPInt();
    APInt Charlie = Cconst->getAPInt();
    APInt CdivA = Charlie.sdiv(Alpha);
    assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
    const SCEV *A_K = findCoefficient(Src, CurLoop);
    Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
    Src = zeroCoefficient(Src, CurLoop);
    if (!findCoefficient(Dst, CurLoop)->isZero())
      Consistent = false;
  } else if (isKnownPredicate(CmpInst::ICMP_EQ, A, B)) {
    const SCEVConstant *Aconst = dyn_cast<SCEVConstant>(A);
    const SCEVConstant *Cconst = dyn_cast<SCEVConstant>(C);
    if (!Aconst || !Cconst)
      return false;
    APInt Alpha = Aconst->getAPInt();
    APInt Charlie = Cconst->getAPInt();
    APInt CdivA = Charlie.sdiv(Alpha);
    assert(Charlie.srem(Alpha) == 0 && "C should be evenly divisible by A");
    const SCEV *A_K = findCoefficient(Src, CurLoop);
    Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
    Src = zeroCoefficient(Src, CurLoop);
    Dst = addToCoefficient(Dst, CurLoop, A_K);
    if (!findCoefficient(Dst, CurLoop)->isZero())
      Consistent = false;
  } else {
    // paper is incorrect here, or perhaps just misleading
    const SCEV *A_K = findCoefficient(Src, CurLoop);
    Src = SE->getMulExpr(Src, A);
    Dst = SE->getMulExpr(Dst, A);
    Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
    Src = zeroCoefficient(Src, CurLoop);
    Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
    if (!findCoefficient(Dst, CurLoop)->isZero())
      Consistent = false;
  }
  LLVM_DEBUG(dbgs() << "\t\tnew Src = " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "\t\tnew Dst = " << *Dst << "\n");
  return true;
}

// Attempt to propagate a point
// constraint into a subscript pair (Src and Dst).
// Return true if some simplification occurs.
bool DependenceInfo::propagatePoint(const SCEV *&Src, const SCEV *&Dst,
                                    Constraint &CurConstraint) {
  const Loop *CurLoop = CurConstraint.getAssociatedLoop();
  const SCEV *A_K = findCoefficient(Src, CurLoop);
  const SCEV *AP_K = findCoefficient(Dst, CurLoop);
  const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
  const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
  LLVM_DEBUG(dbgs() << "\t\tSrc is " << *Src << "\n");
  Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
  Src = zeroCoefficient(Src, CurLoop);
  LLVM_DEBUG(dbgs() << "\t\tnew Src is " << *Src << "\n");
  LLVM_DEBUG(dbgs() << "\t\tDst is " << *Dst << "\n");
  Dst = zeroCoefficient(Dst, CurLoop);
  LLVM_DEBUG(dbgs() << "\t\tnew Dst is " << *Dst << "\n");
  return true;
}

// Update direction vector entry based on the current constraint.
void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
                                     const Constraint &CurConstraint) const {
  LLVM_DEBUG(dbgs() << "\tUpdate direction, constraint =");
  LLVM_DEBUG(CurConstraint.dump(dbgs()));
  if (CurConstraint.isAny())
    ; // use defaults
  else if (CurConstraint.isDistance()) {
    // this one is consistent, the others aren't
    Level.Scalar = false;
    Level.Distance = CurConstraint.getD();
    unsigned NewDirection = Dependence::DVEntry::NONE;
    if (!SE->isKnownNonZero(Level.Distance)) // if may be zero
      NewDirection = Dependence::DVEntry::EQ;
    if (!SE->isKnownNonPositive(Level.Distance)) // if may be positive
      NewDirection |= Dependence::DVEntry::LT;
    if (!SE->isKnownNonNegative(Level.Distance)) // if may be negative
      NewDirection |= Dependence::DVEntry::GT;
    Level.Direction &= NewDirection;
  } else if (CurConstraint.isLine()) {
    Level.Scalar = false;
    Level.Distance = nullptr;
    // direction should be accurate
  } else if (CurConstraint.isPoint()) {
    Level.Scalar = false;
    Level.Distance = nullptr;
    unsigned NewDirection = Dependence::DVEntry::NONE;
    if (!isKnownPredicate(CmpInst::ICMP_NE, CurConstraint.getY(),
                          CurConstraint.getX()))
      // if X may be = Y
      NewDirection |= Dependence::DVEntry::EQ;
    if (!isKnownPredicate(CmpInst::ICMP_SLE, CurConstraint.getY(),
                          CurConstraint.getX()))
      // if Y may be > X
      NewDirection |= Dependence::DVEntry::LT;
    if (!isKnownPredicate(CmpInst::ICMP_SGE, CurConstraint.getY(),
                          CurConstraint.getX()))
      // if Y may be < X
      NewDirection |= Dependence::DVEntry::GT;
    Level.Direction &= NewDirection;
  } else
    llvm_unreachable("constraint has unexpected kind");
}

/// Check if we can delinearize the subscripts. If the SCEVs representing the
/// source and destination array references are recurrences on a nested loop,
/// this function flattens the nested recurrences into separate recurrences
/// for each loop level.
bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
                                    SmallVectorImpl<Subscript> &Pair) {
  assert(isLoadOrStore(Src) && "instruction is not load or store");
  assert(isLoadOrStore(Dst) && "instruction is not load or store");
  Value *SrcPtr = getLoadStorePointerOperand(Src);
  Value *DstPtr = getLoadStorePointerOperand(Dst);
  Loop *SrcLoop = LI->getLoopFor(Src->getParent());
  Loop *DstLoop = LI->getLoopFor(Dst->getParent());
  const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
  const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
  const SCEVUnknown *SrcBase =
      dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
  const SCEVUnknown *DstBase =
      dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));

  if (!SrcBase || !DstBase || SrcBase != DstBase)
    return false;

  SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;

  if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
                               SrcSubscripts, DstSubscripts) &&
      !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
                                    SrcSubscripts, DstSubscripts))
    return false;

  assert(isLoopInvariant(SrcBase, SrcLoop) &&
         isLoopInvariant(DstBase, DstLoop) &&
         "Expected SrcBase and DstBase to be loop invariant");

  int Size = SrcSubscripts.size();
  LLVM_DEBUG({
    dbgs() << "\nSrcSubscripts: ";
    for (int I = 0; I < Size; I++)
      dbgs() << *SrcSubscripts[I];
    dbgs() << "\nDstSubscripts: ";
    for (int I = 0; I < Size; I++)
      dbgs() << *DstSubscripts[I];
  });

  // The delinearization transforms a single-subscript MIV dependence test into
  // a multi-subscript SIV dependence test that is easier to compute. So we
  // resize Pair to contain as many pairs of subscripts as the delinearization
  // has found, and then initialize the pairs following the delinearization.
  Pair.resize(Size);
  for (int I = 0; I < Size; ++I) {
    Pair[I].Src = SrcSubscripts[I];
    Pair[I].Dst = DstSubscripts[I];
    unifySubscriptType(&Pair[I]);
  }

  return true;
}

/// Try to delinearize \p SrcAccessFn and \p DstAccessFn if the underlying
/// arrays accessed are fixed-size arrays. Return true if delinearization was
/// successful.
bool DependenceInfo::tryDelinearizeFixedSize(
    Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
    const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
    SmallVectorImpl<const SCEV *> &DstSubscripts) {
  LLVM_DEBUG({
    const SCEVUnknown *SrcBase =
        dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
    const SCEVUnknown *DstBase =
        dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
    assert(SrcBase && DstBase && SrcBase == DstBase &&
           "expected src and dst scev unknowns to be equal");
  });

  SmallVector<int, 4> SrcSizes;
  SmallVector<int, 4> DstSizes;
  if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
                                   SrcSizes) ||
      !tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
                                   DstSizes))
    return false;

  // Check that the two size arrays are non-empty and equal in length and
  // value.
  if (SrcSizes.size() != DstSizes.size() ||
      !std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
    SrcSubscripts.clear();
    DstSubscripts.clear();
    return false;
  }

  assert(SrcSubscripts.size() == DstSubscripts.size() &&
         "Expected equal number of entries in the list of SrcSubscripts and "
         "DstSubscripts.");

  Value *SrcPtr = getLoadStorePointerOperand(Src);
  Value *DstPtr = getLoadStorePointerOperand(Dst);

  // In general we cannot safely assume that the subscripts recovered from GEPs
  // are in the range of values defined for their corresponding array
  // dimensions. For example some C language usage/interpretation make it
  // impossible to verify this at compile-time. As such we can only delinearize
  // iff the subscripts are positive and are less than the range of the
  // dimension.
  if (!DisableDelinearizationChecks) {
    auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
                                 SmallVectorImpl<const SCEV *> &Subscripts,
                                 Value *Ptr) {
      size_t SSize = Subscripts.size();
      for (size_t I = 1; I < SSize; ++I) {
        const SCEV *S = Subscripts[I];
        if (!isKnownNonNegative(S, Ptr)) {
          LLVM_DEBUG({
            dbgs() << "Check failed: !isKnownNonNegative(S, Ptr)\n";
            dbgs() << "  S: " << *S << "\n" << "  Ptr: " << *Ptr << "\n";
          });
          return false;
        }
        if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
          const SCEV *Range = SE->getConstant(
              ConstantInt::get(SType, DimensionSizes[I - 1], false));
          if (!isKnownLessThan(S, Range)) {
            LLVM_DEBUG({
              dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
              dbgs() << "  S: " << *S << "\n"
                     << "  Range: " << *Range << "\n";
            });
            return false;
          }
        }
      }
      return true;
    };

    if (!AllIndicesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
        !AllIndicesInRange(DstSizes, DstSubscripts, DstPtr)) {
      LLVM_DEBUG(dbgs() << "Check failed: AllIndicesInRange.\n");
      SrcSubscripts.clear();
      DstSubscripts.clear();
      return false;
    }
  }
  LLVM_DEBUG({
    dbgs() << "Delinearized subscripts of fixed-size array\n"
           << "SrcGEP:" << *SrcPtr << "\n"
           << "DstGEP:" << *DstPtr << "\n";
  });
  return true;
}

bool DependenceInfo::tryDelinearizeParametricSize(
    Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
    const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
    SmallVectorImpl<const SCEV *> &DstSubscripts) {

  Value *SrcPtr = getLoadStorePointerOperand(Src);
  Value *DstPtr = getLoadStorePointerOperand(Dst);
  const SCEVUnknown *SrcBase =
      dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
  const SCEVUnknown *DstBase =
      dyn_cast<SCEVUnknown>(SE->getPointerBase(DstAccessFn));
  assert(SrcBase && DstBase && SrcBase == DstBase &&
         "expected src and dst scev unknowns to be equal");

  const SCEV *ElementSize = SE->getElementSize(Src);
  if (ElementSize != SE->getElementSize(Dst))
    return false;

  const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
  const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);

  const SCEVAddRecExpr *SrcAR = dyn_cast<SCEVAddRecExpr>(SrcSCEV);
  const SCEVAddRecExpr *DstAR = dyn_cast<SCEVAddRecExpr>(DstSCEV);
  if (!SrcAR || !DstAR || !SrcAR->isAffine() || !DstAR->isAffine())
    return false;

  // First step: collect parametric terms in both array references.
  SmallVector<const SCEV *, 4> Terms;
  collectParametricTerms(*SE, SrcAR, Terms);
  collectParametricTerms(*SE, DstAR, Terms);

  // Second step: find subscript sizes.
  SmallVector<const SCEV *, 4> Sizes;
  findArrayDimensions(*SE, Terms, Sizes, ElementSize);

  // Third step: compute the access functions for each subscript.
  computeAccessFunctions(*SE, SrcAR, SrcSubscripts, Sizes);
  computeAccessFunctions(*SE, DstAR, DstSubscripts, Sizes);

  // Fail when there is only a subscript: that's a linearized access function.
  if (SrcSubscripts.size() < 2 || DstSubscripts.size() < 2 ||
      SrcSubscripts.size() != DstSubscripts.size())
    return false;

  size_t Size = SrcSubscripts.size();

  // Statically check that the array bounds are in-range. The first subscript we
  // don't have a size for and it cannot overflow into another subscript, so is
  // always safe. The others need to be 0 <= subscript[i] < bound, for both src
  // and dst.
  // FIXME: It may be better to record these sizes and add them as constraints
  // to the dependency checks.
  if (!DisableDelinearizationChecks)
    for (size_t I = 1; I < Size; ++I) {
      bool SNN = isKnownNonNegative(SrcSubscripts[I], SrcPtr);
      bool DNN = isKnownNonNegative(DstSubscripts[I], DstPtr);
      bool SLT = isKnownLessThan(SrcSubscripts[I], Sizes[I - 1]);
      bool DLT = isKnownLessThan(DstSubscripts[I], Sizes[I - 1]);
      if (SNN && DNN && SLT && DLT)
        continue;

      LLVM_DEBUG({
        dbgs() << "Delinearization checks failed: can't prove the following\n";
        if (!SNN)
          dbgs() << "  isKnownNonNegative(" << *SrcSubscripts[I] << ")\n";
        if (!DNN)
          dbgs() << "  isKnownNonNegative(" << *DstSubscripts[I] << ")\n";
        if (!SLT)
          dbgs() << "  isKnownLessThan(" << *SrcSubscripts[I] << ", "
                 << *Sizes[I - 1] << ")\n";
        if (!DLT)
          dbgs() << "  isKnownLessThan(" << *DstSubscripts[I] << ", "
                 << *Sizes[I - 1] << ")\n";
      });
      return false;
    }

  return true;
}

//===----------------------------------------------------------------------===//

#ifndef NDEBUG
// For debugging purposes, dump a small bit vector to dbgs().
static void dumpSmallBitVector(SmallBitVector &BV) {
  dbgs() << "{";
  for (unsigned VI : BV.set_bits()) {
    dbgs() << VI;
    if (BV.find_next(VI) >= 0)
      dbgs() << ' ';
  }
  dbgs() << "}\n";
}
#endif

bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
                                FunctionAnalysisManager::Invalidator &Inv) {
  // Check if the analysis itself has been invalidated.
  auto PAC = PA.getChecker<DependenceAnalysis>();
  if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>())
    return true;

  // Check transitive dependencies.
  return Inv.invalidate<AAManager>(F, PA) ||
         Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
         Inv.invalidate<LoopAnalysis>(F, PA);
}

SCEVUnionPredicate DependenceInfo::getRuntimeAssumptions() const {
  return SCEVUnionPredicate(Assumptions, *SE);
}

// depends -
// Returns NULL if there is no dependence.
// Otherwise, return a Dependence with as many details as possible.
// Corresponds to Section 3.1 in the paper
//
//            Practical Dependence Testing
//            Goff, Kennedy, Tseng
//            PLDI 1991
//
// Care is required to keep the routine below, getSplitIteration(),
// up to date with respect to this routine.
std::unique_ptr<Dependence>
DependenceInfo::depends(Instruction *Src, Instruction *Dst,
                        bool UnderRuntimeAssumptions) {
  SmallVector<const SCEVPredicate *, 4> Assume;
  bool PossiblyLoopIndependent = true;
  if (Src == Dst)
    PossiblyLoopIndependent = false;

  if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
    // if both instructions don't reference memory, there's no dependence
    return nullptr;

  if (!isLoadOrStore(Src) || !isLoadOrStore(Dst)) {
    // can only analyze simple loads and stores, i.e., no calls, invokes, etc.
    LLVM_DEBUG(dbgs() << "can only handle simple loads and stores\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  }

  const MemoryLocation &DstLoc = MemoryLocation::get(Dst);
  const MemoryLocation &SrcLoc = MemoryLocation::get(Src);

  switch (underlyingObjectsAlias(AA, F->getDataLayout(), DstLoc, SrcLoc)) {
  case AliasResult::MayAlias:
  case AliasResult::PartialAlias:
    // cannot analyse objects if we don't understand their aliasing.
    LLVM_DEBUG(dbgs() << "can't analyze may or partial alias\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  case AliasResult::NoAlias:
    // If the objects noalias, they are distinct, accesses are independent.
    LLVM_DEBUG(dbgs() << "no alias\n");
    return nullptr;
  case AliasResult::MustAlias:
    break; // The underlying objects alias; test accesses for dependence.
  }

  if (DstLoc.Size != SrcLoc.Size || !DstLoc.Size.isPrecise() ||
      !SrcLoc.Size.isPrecise()) {
    // The dependence test gets confused if the size of the memory accesses
    // differ.
    LLVM_DEBUG(dbgs() << "can't analyze must alias with different sizes\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  }

  Value *SrcPtr = getLoadStorePointerOperand(Src);
  Value *DstPtr = getLoadStorePointerOperand(Dst);
  const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
  const SCEV *DstSCEV = SE->getSCEV(DstPtr);
  LLVM_DEBUG(dbgs() << "    SrcSCEV = " << *SrcSCEV << "\n");
  LLVM_DEBUG(dbgs() << "    DstSCEV = " << *DstSCEV << "\n");
  const SCEV *SrcBase = SE->getPointerBase(SrcSCEV);
  const SCEV *DstBase = SE->getPointerBase(DstSCEV);
  if (SrcBase != DstBase) {
    // If two pointers have different bases, trying to analyze indexes won't
    // work; we can't compare them to each other. This can happen, for example,
    // if one is produced by an LCSSA PHI node.
    //
    // We check this upfront so we don't crash in cases where getMinusSCEV()
    // returns a SCEVCouldNotCompute.
    LLVM_DEBUG(dbgs() << "can't analyze SCEV with different pointer base\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  }

  // Even if the base pointers are the same, they may not be loop-invariant. It
  // could lead to incorrect results, as we're analyzing loop-carried
  // dependencies. Src and Dst can be in different loops, so we need to check
  // the base pointer is invariant in both loops.
  Loop *SrcLoop = LI->getLoopFor(Src->getParent());
  Loop *DstLoop = LI->getLoopFor(Dst->getParent());
  if (!isLoopInvariant(SrcBase, SrcLoop) ||
      !isLoopInvariant(DstBase, DstLoop)) {
    LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  }

  uint64_t EltSize = SrcLoc.Size.toRaw();
  const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase);
  const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase);

  // Check that memory access offsets are multiples of element sizes.
  if (!SE->isKnownMultipleOf(SrcEv, EltSize, Assume) ||
      !SE->isKnownMultipleOf(DstEv, EltSize, Assume)) {
    LLVM_DEBUG(dbgs() << "can't analyze SCEV with different offsets\n");
    return std::make_unique<Dependence>(Src, Dst,
                                        SCEVUnionPredicate(Assume, *SE));
  }

  if (!Assume.empty()) {
    if (!UnderRuntimeAssumptions)
      return std::make_unique<Dependence>(Src, Dst,
                                          SCEVUnionPredicate(Assume, *SE));
    // Add non-redundant assumptions.
    unsigned N = Assumptions.size();
    for (const SCEVPredicate *P : Assume) {
      bool Implied = false;
      for (unsigned I = 0; I != N && !Implied; I++)
        if (Assumptions[I]->implies(P, *SE))
          Implied = true;
      if (!Implied)
        Assumptions.push_back(P);
    }
  }

  establishNestingLevels(Src, Dst);
  LLVM_DEBUG(dbgs() << "    common nesting levels = " << CommonLevels << "\n");
  LLVM_DEBUG(dbgs() << "    maximum nesting levels = " << MaxLevels << "\n");

  FullDependence Result(Src, Dst, SCEVUnionPredicate(Assume, *SE),
                        PossiblyLoopIndependent, CommonLevels);
  ++TotalArrayPairs;

  unsigned Pairs = 1;
  SmallVector<Subscript, 2> Pair(Pairs);
  Pair[0].Src = SrcSCEV;
  Pair[0].Dst = DstSCEV;

  if (Delinearize) {
    if (tryDelinearize(Src, Dst, Pair)) {
      LLVM_DEBUG(dbgs() << "    delinearized\n");
      Pairs = Pair.size();
    }
  }

  for (unsigned P = 0; P < Pairs; ++P) {
    Pair[P].Loops.resize(MaxLevels + 1);
    Pair[P].GroupLoops.resize(MaxLevels + 1);
    Pair[P].Group.resize(Pairs);
    removeMatchingExtensions(&Pair[P]);
    Pair[P].Classification =
        classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()), Pair[P].Dst,
                     LI->getLoopFor(Dst->getParent()), Pair[P].Loops);
    Pair[P].GroupLoops = Pair[P].Loops;
    Pair[P].Group.set(P);
    LLVM_DEBUG(dbgs() << "    subscript " << P << "\n");
    LLVM_DEBUG(dbgs() << "\tsrc = " << *Pair[P].Src << "\n");
    LLVM_DEBUG(dbgs() << "\tdst = " << *Pair[P].Dst << "\n");
    LLVM_DEBUG(dbgs() << "\tclass = " << Pair[P].Classification << "\n");
    LLVM_DEBUG(dbgs() << "\tloops = ");
    LLVM_DEBUG(dumpSmallBitVector(Pair[P].Loops));
  }

  SmallBitVector Separable(Pairs);
  SmallBitVector Coupled(Pairs);

  // Partition subscripts into separable and minimally-coupled groups
  // Algorithm in paper is algorithmically better;
  // this may be faster in practice. Check someday.
  //
  // Here's an example of how it works. Consider this code:
  //
  //   for (i = ...) {
  //     for (j = ...) {
  //       for (k = ...) {
  //         for (l = ...) {
  //           for (m = ...) {
  //             A[i][j][k][m] = ...;
  //             ... = A[0][j][l][i + j];
  //           }
  //         }
  //       }
  //     }
  //   }
  //
  // There are 4 subscripts here:
  //    0 [i] and [0]
  //    1 [j] and [j]
  //    2 [k] and [l]
  //    3 [m] and [i + j]
  //
  // We've already classified each subscript pair as ZIV, SIV, etc.,
  // and collected all the loops mentioned by pair P in Pair[P].Loops.
  // In addition, we've initialized Pair[P].GroupLoops to Pair[P].Loops
  // and set Pair[P].Group = {P}.
  //
  //      Src Dst    Classification Loops  GroupLoops Group
  //    0 [i] [0]         SIV       {1}      {1}        {0}
  //    1 [j] [j]         SIV       {2}      {2}        {1}
  //    2 [k] [l]         RDIV      {3,4}    {3,4}      {2}
  //    3 [m] [i + j]     MIV       {1,2,5}  {1,2,5}    {3}
  //
  // For each subscript SI 0 .. 3, we consider each remaining subscript, SJ.
  // So, 0 is compared against 1, 2, and 3; 1 is compared against 2 and 3, etc.
  //
  // We begin by comparing 0 and 1. The intersection of the GroupLoops is empty.
  // Next, 0 and 2. Again, the intersection of their GroupLoops is empty.
  // Next 0 and 3. The intersection of their GroupLoop = {1}, not empty,
  // so Pair[3].Group = {0,3} and Done = false (that is, 0 will not be added
  // to either Separable or Coupled).
  //
  // Next, we consider 1 and 2. The intersection of the GroupLoops is empty.
  // Next, 1 and 3. The intersection of their GroupLoops = {2}, not empty,
  // so Pair[3].Group = {0, 1, 3} and Done = false.
  //
  // Next, we compare 2 against 3. The intersection of the GroupLoops is empty.
  // Since Done remains true, we add 2 to the set of Separable pairs.
  //
  // Finally, we consider 3. There's nothing to compare it with,
  // so Done remains true and we add it to the Coupled set.
  // Pair[3].Group = {0, 1, 3} and GroupLoops = {1, 2, 5}.
  //
  // In the end, we've got 1 separable subscript and 1 coupled group.
  for (unsigned SI = 0; SI < Pairs; ++SI) {
    if (Pair[SI].Classification == Subscript::NonLinear) {
      // ignore these, but collect loops for later
      ++NonlinearSubscriptPairs;
      collectCommonLoops(Pair[SI].Src, LI->getLoopFor(Src->getParent()),
                         Pair[SI].Loops);
      collectCommonLoops(Pair[SI].Dst, LI->getLoopFor(Dst->getParent()),
                         Pair[SI].Loops);
      Result.Consistent = false;
    } else if (Pair[SI].Classification == Subscript::ZIV) {
      // always separable
      Separable.set(SI);
    } else {
      // SIV, RDIV, or MIV, so check for coupled group
      bool Done = true;
      for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
        SmallBitVector Intersection = Pair[SI].GroupLoops;
        Intersection &= Pair[SJ].GroupLoops;
        if (Intersection.any()) {
          // accumulate set of all the loops in group
          Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
          // accumulate set of all subscripts in group
          Pair[SJ].Group |= Pair[SI].Group;
          Done = false;
        }
      }
      if (Done) {
        if (Pair[SI].Group.count() == 1) {
          Separable.set(SI);
          ++SeparableSubscriptPairs;
        } else {
          Coupled.set(SI);
          ++CoupledSubscriptPairs;
        }
      }
    }
  }

  LLVM_DEBUG(dbgs() << "    Separable = ");
  LLVM_DEBUG(dumpSmallBitVector(Separable));
  LLVM_DEBUG(dbgs() << "    Coupled = ");
  LLVM_DEBUG(dumpSmallBitVector(Coupled));

  Constraint NewConstraint;
  NewConstraint.setAny(SE);

  // test separable subscripts
  for (unsigned SI : Separable.set_bits()) {
    LLVM_DEBUG(dbgs() << "testing subscript " << SI);
    switch (Pair[SI].Classification) {
    case Subscript::ZIV:
      LLVM_DEBUG(dbgs() << ", ZIV\n");
      if (testZIV(Pair[SI].Src, Pair[SI].Dst, Result))
        return nullptr;
      break;
    case Subscript::SIV: {
      LLVM_DEBUG(dbgs() << ", SIV\n");
      unsigned Level;
      const SCEV *SplitIter = nullptr;
      if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
                  SplitIter))
        return nullptr;
      break;
    }
    case Subscript::RDIV:
      LLVM_DEBUG(dbgs() << ", RDIV\n");
      if (testRDIV(Pair[SI].Src, Pair[SI].Dst, Result))
        return nullptr;
      break;
    case Subscript::MIV:
      LLVM_DEBUG(dbgs() << ", MIV\n");
      if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, Result))
        return nullptr;
      break;
    default:
      llvm_unreachable("subscript has unexpected classification");
    }
  }

  if (Coupled.count()) {
    // test coupled subscript groups
    LLVM_DEBUG(dbgs() << "starting on coupled subscripts\n");
    LLVM_DEBUG(dbgs() << "MaxLevels + 1 = " << MaxLevels + 1 << "\n");
    SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
    for (unsigned II = 0; II <= MaxLevels; ++II)
      Constraints[II].setAny(SE);
    for (unsigned SI : Coupled.set_bits()) {
      LLVM_DEBUG(dbgs() << "testing subscript group " << SI << " { ");
      SmallBitVector Group(Pair[SI].Group);
      SmallBitVector Sivs(Pairs);
      SmallBitVector Mivs(Pairs);
      SmallBitVector ConstrainedLevels(MaxLevels + 1);
      SmallVector<Subscript *, 4> PairsInGroup;
      for (unsigned SJ : Group.set_bits()) {
        LLVM_DEBUG(dbgs() << SJ << " ");
        if (Pair[SJ].Classification == Subscript::SIV)
          Sivs.set(SJ);
        else
          Mivs.set(SJ);
        PairsInGroup.push_back(&Pair[SJ]);
      }
      unifySubscriptType(PairsInGroup);
      LLVM_DEBUG(dbgs() << "}\n");
      while (Sivs.any()) {
        bool Changed = false;
        for (unsigned SJ : Sivs.set_bits()) {
          LLVM_DEBUG(dbgs() << "testing subscript " << SJ << ", SIV\n");
          // SJ is an SIV subscript that's part of the current coupled group
          unsigned Level;
          const SCEV *SplitIter = nullptr;
          LLVM_DEBUG(dbgs() << "SIV\n");
          if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
                      SplitIter))
            return nullptr;
          ConstrainedLevels.set(Level);
          if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
            if (Constraints[Level].isEmpty()) {
              ++DeltaIndependence;
              return nullptr;
            }
            Changed = true;
          }
          Sivs.reset(SJ);
        }
        if (Changed) {
          // propagate, possibly creating new SIVs and ZIVs
          LLVM_DEBUG(dbgs() << "    propagating\n");
          LLVM_DEBUG(dbgs() << "\tMivs = ");
          LLVM_DEBUG(dumpSmallBitVector(Mivs));
          for (unsigned SJ : Mivs.set_bits()) {
            // SJ is an MIV subscript that's part of the current coupled group
            LLVM_DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
            if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
                          Constraints, Result.Consistent)) {
              LLVM_DEBUG(dbgs() << "\t    Changed\n");
              ++DeltaPropagations;
              Pair[SJ].Classification = classifyPair(
                  Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
                  LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
              switch (Pair[SJ].Classification) {
              case Subscript::ZIV:
                LLVM_DEBUG(dbgs() << "ZIV\n");
                if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
                  return nullptr;
                Mivs.reset(SJ);
                break;
              case Subscript::SIV:
                Sivs.set(SJ);
                Mivs.reset(SJ);
                break;
              case Subscript::RDIV:
              case Subscript::MIV:
                break;
              default:
                llvm_unreachable("bad subscript classification");
              }
            }
          }
        }
      }

      // test & propagate remaining RDIVs
      for (unsigned SJ : Mivs.set_bits()) {
        if (Pair[SJ].Classification == Subscript::RDIV) {
          LLVM_DEBUG(dbgs() << "RDIV test\n");
          if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
            return nullptr;
          // I don't yet understand how to propagate RDIV results
          Mivs.reset(SJ);
        }
      }

      // test remaining MIVs
      // This code is temporary.
      // Better to somehow test all remaining subscripts simultaneously.
      for (unsigned SJ : Mivs.set_bits()) {
        if (Pair[SJ].Classification == Subscript::MIV) {
          LLVM_DEBUG(dbgs() << "MIV test\n");
          if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
            return nullptr;
        } else
          llvm_unreachable("expected only MIV subscripts at this point");
      }

      // update Result.DV from constraint vector
      LLVM_DEBUG(dbgs() << "    updating\n");
      for (unsigned SJ : ConstrainedLevels.set_bits()) {
        if (SJ > CommonLevels)
          break;
        updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
        if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
          return nullptr;
      }
    }
  }

  // Make sure the Scalar flags are set correctly.
  SmallBitVector CompleteLoops(MaxLevels + 1);
  for (unsigned SI = 0; SI < Pairs; ++SI)
    CompleteLoops |= Pair[SI].Loops;
  for (unsigned II = 1; II <= CommonLevels; ++II)
    if (CompleteLoops[II])
      Result.DV[II - 1].Scalar = false;

  // Set the distance to zero if the direction is EQ.
  // TODO: Ideally, the distance should be set to 0 immediately simultaneously
  // with the corresponding direction being set to EQ.
  for (unsigned II = 1; II <= Result.getLevels(); ++II) {
    if (Result.getDirection(II) == Dependence::DVEntry::EQ) {
      if (Result.DV[II - 1].Distance == nullptr)
        Result.DV[II - 1].Distance = SE->getZero(SrcSCEV->getType());
      else
        assert(Result.DV[II - 1].Distance->isZero() &&
               "Inconsistency between distance and direction");
    }

#ifndef NDEBUG
    // Check that the converse (i.e., if the distance is zero, then the
    // direction is EQ) holds.
    const SCEV *Distance = Result.getDistance(II);
    if (Distance && Distance->isZero())
      assert(Result.getDirection(II) == Dependence::DVEntry::EQ &&
             "Distance is zero, but direction is not EQ");
#endif
  }

  if (PossiblyLoopIndependent) {
    // Make sure the LoopIndependent flag is set correctly.
    // All directions must include equal, otherwise no
    // loop-independent dependence is possible.
    for (unsigned II = 1; II <= CommonLevels; ++II) {
      if (!(Result.getDirection(II) & Dependence::DVEntry::EQ)) {
        Result.LoopIndependent = false;
        break;
      }
    }
  } else {
    // On the other hand, if all directions are equal and there's no
    // loop-independent dependence possible, then no dependence exists.
    bool AllEqual = true;
    for (unsigned II = 1; II <= CommonLevels; ++II) {
      if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
        AllEqual = false;
        break;
      }
    }
    if (AllEqual)
      return nullptr;
  }

  return std::make_unique<FullDependence>(std::move(Result));
}

//===----------------------------------------------------------------------===//
// getSplitIteration -
// Rather than spend rarely-used space recording the splitting iteration
// during the Weak-Crossing SIV test, we re-compute it on demand.
// The re-computation is basically a repeat of the entire dependence test,
// though simplified since we know that the dependence exists.
// It's tedious, since we must go through all propagations, etc.
//
// Care is required to keep this code up to date with respect to the routine
// above, depends().
//
// Generally, the dependence analyzer will be used to build
// a dependence graph for a function (basically a map from instructions
// to dependences). Looking for cycles in the graph shows us loops
// that cannot be trivially vectorized/parallelized.
//
// We can try to improve the situation by examining all the dependences
// that make up the cycle, looking for ones we can break.
// Sometimes, peeling the first or last iteration of a loop will break
// dependences, and we've got flags for those possibilities.
// Sometimes, splitting a loop at some other iteration will do the trick,
// and we've got a flag for that case. Rather than waste the space to
// record the exact iteration (since we rarely know), we provide
// a method that calculates the iteration. It's a drag that it must work
// from scratch, but wonderful in that it's possible.
//
// Here's an example:
//
//    for (i = 0; i < 10; i++)
//        A[i] = ...
//        ... = A[11 - i]
//
// There's a loop-carried flow dependence from the store to the load,
// found by the weak-crossing SIV test. The dependence will have a flag,
// indicating that the dependence can be broken by splitting the loop.
// Calling getSplitIteration will return 5.
// Splitting the loop breaks the dependence, like so:
//
//    for (i = 0; i <= 5; i++)
//        A[i] = ...
//        ... = A[11 - i]
//    for (i = 6; i < 10; i++)
//        A[i] = ...
//        ... = A[11 - i]
//
// breaks the dependence and allows us to vectorize/parallelize
// both loops.
const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
                                              unsigned SplitLevel) {
  assert(Dep.isSplitable(SplitLevel) &&
         "Dep should be splitable at SplitLevel");
  Instruction *Src = Dep.getSrc();
  Instruction *Dst = Dep.getDst();
  assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
  assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
  assert(isLoadOrStore(Src));
  assert(isLoadOrStore(Dst));
  Value *SrcPtr = getLoadStorePointerOperand(Src);
  Value *DstPtr = getLoadStorePointerOperand(Dst);
  assert(underlyingObjectsAlias(
             AA, F->getDataLayout(), MemoryLocation::get(Dst),
             MemoryLocation::get(Src)) == AliasResult::MustAlias);

  // establish loop nesting levels
  establishNestingLevels(Src, Dst);

  FullDependence Result(Src, Dst, Dep.Assumptions, false, CommonLevels);

  unsigned Pairs = 1;
  SmallVector<Subscript, 2> Pair(Pairs);
  const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
  const SCEV *DstSCEV = SE->getSCEV(DstPtr);
  Pair[0].Src = SrcSCEV;
  Pair[0].Dst = DstSCEV;

  if (Delinearize) {
    if (tryDelinearize(Src, Dst, Pair)) {
      LLVM_DEBUG(dbgs() << "    delinearized\n");
      Pairs = Pair.size();
    }
  }

  for (unsigned P = 0; P < Pairs; ++P) {
    Pair[P].Loops.resize(MaxLevels + 1);
    Pair[P].GroupLoops.resize(MaxLevels + 1);
    Pair[P].Group.resize(Pairs);
    removeMatchingExtensions(&Pair[P]);
    Pair[P].Classification =
        classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()), Pair[P].Dst,
                     LI->getLoopFor(Dst->getParent()), Pair[P].Loops);
    Pair[P].GroupLoops = Pair[P].Loops;
    Pair[P].Group.set(P);
  }

  SmallBitVector Separable(Pairs);
  SmallBitVector Coupled(Pairs);

  // partition subscripts into separable and minimally-coupled groups
  for (unsigned SI = 0; SI < Pairs; ++SI) {
    if (Pair[SI].Classification == Subscript::NonLinear) {
      // ignore these, but collect loops for later
      collectCommonLoops(Pair[SI].Src, LI->getLoopFor(Src->getParent()),
                         Pair[SI].Loops);
      collectCommonLoops(Pair[SI].Dst, LI->getLoopFor(Dst->getParent()),
                         Pair[SI].Loops);
      Result.Consistent = false;
    } else if (Pair[SI].Classification == Subscript::ZIV)
      Separable.set(SI);
    else {
      // SIV, RDIV, or MIV, so check for coupled group
      bool Done = true;
      for (unsigned SJ = SI + 1; SJ < Pairs; ++SJ) {
        SmallBitVector Intersection = Pair[SI].GroupLoops;
        Intersection &= Pair[SJ].GroupLoops;
        if (Intersection.any()) {
          // accumulate set of all the loops in group
          Pair[SJ].GroupLoops |= Pair[SI].GroupLoops;
          // accumulate set of all subscripts in group
          Pair[SJ].Group |= Pair[SI].Group;
          Done = false;
        }
      }
      if (Done) {
        if (Pair[SI].Group.count() == 1)
          Separable.set(SI);
        else
          Coupled.set(SI);
      }
    }
  }

  Constraint NewConstraint;
  NewConstraint.setAny(SE);

  // test separable subscripts
  for (unsigned SI : Separable.set_bits()) {
    switch (Pair[SI].Classification) {
    case Subscript::SIV: {
      unsigned Level;
      const SCEV *SplitIter = nullptr;
      (void)testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
                    SplitIter);
      if (Level == SplitLevel) {
        assert(SplitIter != nullptr);
        return SplitIter;
      }
      break;
    }
    case Subscript::ZIV:
    case Subscript::RDIV:
    case Subscript::MIV:
      break;
    default:
      llvm_unreachable("subscript has unexpected classification");
    }
  }

  assert(!Coupled.empty() && "coupled expected non-empty");

  // test coupled subscript groups
  SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
  for (unsigned II = 0; II <= MaxLevels; ++II)
    Constraints[II].setAny(SE);
  for (unsigned SI : Coupled.set_bits()) {
    SmallBitVector Group(Pair[SI].Group);
    SmallBitVector Sivs(Pairs);
    SmallBitVector Mivs(Pairs);
    SmallBitVector ConstrainedLevels(MaxLevels + 1);
    for (unsigned SJ : Group.set_bits()) {
      if (Pair[SJ].Classification == Subscript::SIV)
        Sivs.set(SJ);
      else
        Mivs.set(SJ);
    }
    while (Sivs.any()) {
      bool Changed = false;
      for (unsigned SJ : Sivs.set_bits()) {
        // SJ is an SIV subscript that's part of the current coupled group
        unsigned Level;
        const SCEV *SplitIter = nullptr;
        (void)testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
                      SplitIter);
        if (Level == SplitLevel && SplitIter)
          return SplitIter;
        ConstrainedLevels.set(Level);
        if (intersectConstraints(&Constraints[Level], &NewConstraint))
          Changed = true;
        Sivs.reset(SJ);
      }
      if (!Changed)
        continue;
      // propagate, possibly creating new SIVs and ZIVs
      for (unsigned SJ : Mivs.set_bits()) {
        // SJ is an MIV subscript that's part of the current coupled group
        if (!propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Constraints,
                       Result.Consistent))
          continue;
        Pair[SJ].Classification = classifyPair(
            Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
            LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
        switch (Pair[SJ].Classification) {
        case Subscript::ZIV:
          Mivs.reset(SJ);
          break;
        case Subscript::SIV:
          Sivs.set(SJ);
          Mivs.reset(SJ);
          break;
        case Subscript::RDIV:
        case Subscript::MIV:
          break;
        default:
          llvm_unreachable("bad subscript classification");
        }
      }
    }
  }
  llvm_unreachable("somehow reached end of routine");
}
