@@ -3632,7 +3632,9 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
3632
3632
const SCEV *DstSCEV = SE->getSCEV (DstPtr);
3633
3633
LLVM_DEBUG (dbgs () << " SrcSCEV = " << *SrcSCEV << " \n " );
3634
3634
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) {
3636
3638
// If two pointers have different bases, trying to analyze indexes won't
3637
3639
// work; we can't compare them to each other. This can happen, for example,
3638
3640
// if one is produced by an LCSSA PHI node.
@@ -3643,6 +3645,57 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
3643
3645
return std::make_unique<Dependence>(Src, Dst);
3644
3646
}
3645
3647
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
+
3646
3699
// establish loop nesting levels
3647
3700
establishNestingLevels (Src, Dst);
3648
3701
LLVM_DEBUG (dbgs () << " common nesting levels = " << CommonLevels << " \n " );
0 commit comments