@@ -3632,7 +3632,9 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36323632 const SCEV *DstSCEV = SE->getSCEV (DstPtr);
36333633 LLVM_DEBUG (dbgs () << " SrcSCEV = " << *SrcSCEV << " \n " );
36343634 LLVM_DEBUG (dbgs () << " DstSCEV = " << *DstSCEV << " \n " );
3635- if (SE->getPointerBase (SrcSCEV) != SE->getPointerBase (DstSCEV)) {
3635+ const SCEV *SrcBase = SE->getPointerBase (SrcSCEV);
3636+ const SCEV *DstBase = SE->getPointerBase (DstSCEV);
3637+ if (SrcBase != DstBase) {
36363638 // If two pointers have different bases, trying to analyze indexes won't
36373639 // work; we can't compare them to each other. This can happen, for example,
36383640 // if one is produced by an LCSSA PHI node.
@@ -3643,6 +3645,57 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36433645 return std::make_unique<Dependence>(Src, Dst);
36443646 }
36453647
3648+ std::function<bool (ScalarEvolution *, const SCEV *, uint64_t )>
3649+ checkOffsetsAndStrides =
3650+ [&](ScalarEvolution *SE, const SCEV *V, uint64_t Size) -> bool {
3651+ if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
3652+ if (!checkOffsetsAndStrides (SE, AddRec->getStart (), Size))
3653+ return false ;
3654+ return checkOffsetsAndStrides (SE, AddRec->getStepRecurrence (*SE), Size);
3655+ }
3656+ if (auto *Cst = dyn_cast<SCEVConstant>(V)) {
3657+ APInt C = Cst->getAPInt ();
3658+ return C.srem (Size) == 0 ;
3659+ }
3660+ if (auto *Add = dyn_cast<SCEVAddExpr>(V)) {
3661+ // FIXME: DA cannot reason about expressions containing SSA names.
3662+ return true ;
3663+ // If the expression contains variable names, i.e., "n + 1", then we
3664+ // cannot reason about the coefficients of V being multiples of Size.
3665+ if (SCEVExprContains (V, [](const SCEV *S) { return isa<SCEVUnknown>(S); }))
3666+ return false ;
3667+ for (const SCEV *AddOp : Add->operands ()) {
3668+ if (!checkOffsetsAndStrides (SE, AddOp, Size))
3669+ return false ;
3670+ }
3671+ return true ;
3672+ }
3673+ if (auto *Mul = dyn_cast<SCEVMulExpr>(V)) {
3674+ // FIXME: DA cannot reason about expressions containing SSA names.
3675+ return true ;
3676+ // If the expression contains variable names, i.e., "n * 3", then we
3677+ // cannot reason about the coefficients of V being multiples of Size.
3678+ if (SCEVExprContains (V, [](const SCEV *S) { return isa<SCEVUnknown>(S); }))
3679+ return false ;
3680+ for (const SCEV *MulOp : Mul->operands ()) {
3681+ if (!checkOffsetsAndStrides (SE, MulOp, Size))
3682+ return false ;
3683+ }
3684+ return true ;
3685+ }
3686+ // SCEV node not handled yet.
3687+ return false ;
3688+ };
3689+
3690+ // Check that memory access offsets are multiples of element sizes.
3691+ const SCEV *SrcEv = SE->getMinusSCEV (SrcSCEV, SrcBase);
3692+ const SCEV *DstEv = SE->getMinusSCEV (DstSCEV, DstBase);
3693+ if (!checkOffsetsAndStrides (SE, SrcEv, SrcLoc.Size .toRaw ()) ||
3694+ !checkOffsetsAndStrides (SE, DstEv, DstLoc.Size .toRaw ())) {
3695+ LLVM_DEBUG (dbgs () << " can't analyze SCEV with different offsets\n " );
3696+ return std::make_unique<Dependence>(Src, Dst);
3697+ }
3698+
36463699 // establish loop nesting levels
36473700 establishNestingLevels (Src, Dst);
36483701 LLVM_DEBUG (dbgs () << " common nesting levels = " << CommonLevels << " \n " );
0 commit comments