@@ -3569,116 +3569,6 @@ bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
35693569 Inv.invalidate <LoopAnalysis>(F, PA);
35703570}
35713571
3572- // / Check that memory access offsets in V are multiples of array element size
3573- // / EltSize. Param records the first parametric expression. If the scalar
3574- // / evolution V contains two or more parameters, we check that the subsequent
3575- // / parametric expressions are multiples of the first parametric expression
3576- // / Param.
3577- static bool checkOffsets (ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
3578- uint64_t EltSize) {
3579- if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
3580- return checkOffsets (SE, AddRec->getStart (), Param, EltSize) &&
3581- checkOffsets (SE, AddRec->getStepRecurrence (*SE), Param, EltSize);
3582- }
3583- if (auto *Cst = dyn_cast<SCEVConstant>(V)) {
3584- APInt C = Cst->getAPInt ();
3585-
3586- // For example, alias_with_different_offsets in
3587- // test/Analysis/DependenceAnalysis/DifferentOffsets.ll accesses "%A + 2":
3588- // %arrayidx = getelementptr inbounds i8, ptr %A, i64 2
3589- // store i32 42, ptr %arrayidx, align 1
3590- // which is writing an i32, i.e., EltSize = 4 bytes, with an offset C = 2.
3591- // checkOffsets returns false, as the offset C=2 is not a multiple of 4.
3592- return C.srem (EltSize) == 0 ;
3593- }
3594-
3595- // Use a lambda helper function to check V for parametric expressions.
3596- // Param records the first parametric expression. If the scalar evolution V
3597- // contains two or more parameters, we check that the subsequent parametric
3598- // expressions are multiples of the first parametric expression Param.
3599- auto checkParamsMultipleOfSize = [&](const SCEV *V,
3600- const SCEV *&Param) -> bool {
3601- if (EltSize == 1 )
3602- return true ;
3603- if (!Param) {
3604- Param = V;
3605- return true ;
3606- }
3607- if (Param == V)
3608- return true ;
3609-
3610- // Check whether "(Param - V) % Size == 0".
3611- const SCEV *Diff = SE->getMinusSCEV (Param, V);
3612- if (auto *Cst = dyn_cast<SCEVConstant>(Diff)) {
3613- APInt Val = Cst->getAPInt ();
3614- if (Val.isZero ())
3615- return true ;
3616- auto Rem = Val.srem (APInt (Val.getBitWidth (), EltSize, /* isSigned=*/ true ));
3617- if (Rem.isZero ())
3618- // For example in test/Analysis/DependenceAnalysis/Preliminary.ll
3619- // SrcSCEV = ((4 * (sext i8 %n to i64))<nsw> + %A)
3620- // DstSCEV = (4 + (4 * (sext i8 %n to i64))<nsw> + %A)
3621- // Param = (4 * (sext i8 %n to i64))<nsw>
3622- // V = 4 + (4 * (sext i8 %n to i64))<nsw>
3623- // Diff = -4, Rem = 0, and so all offsets are multiple of 4.
3624- return true ;
3625- LLVM_DEBUG (dbgs () << " SCEV with different offsets: " << *Param << " - "
3626- << *V << " = " << *Diff << " % " << EltSize << " = "
3627- << Rem << " != 0\n " );
3628- return false ;
3629- }
3630- // Check if the symbolic difference is a multiple of Size.
3631- const SCEV *Val =
3632- SE->getConstant (APInt (Diff->getType ()->getScalarSizeInBits (), EltSize));
3633-
3634- // Check by using the remainder computation.
3635- const SCEV *Remainder = SE->getURemExpr (Diff, Val);
3636- if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Remainder))
3637- if (C->getValue ()->isZero ())
3638- // For example test/Analysis/DependenceAnalysis/DADelin.ll
3639- // SrcSCEV = {{{%A,+,(4 * %m * %o)}<%for.cond1.preheader>,+,(4 * %o)}
3640- // DstSCEV = {{{%A,+,(4 * %m * %o)}<%for.cond1.preheader>,+,(4 * %o)}
3641- // The strides '(4 * %m * %o)' and '(4 * %o)' are multiple of 4.
3642- return true ;
3643-
3644- // Check by using the division computation.
3645- const SCEV *Q = SE->getUDivExpr (Diff, Val);
3646- const SCEV *Product = SE->getMulExpr (Q, Val);
3647- if (Diff == Product)
3648- return true ;
3649- LLVM_DEBUG (dbgs () << " SCEV with different offsets:\n "
3650- << *Param << " - " << *V << " = " << *Diff << " \n "
3651- << " Remainder = " << *Remainder << " \n "
3652- << " Q = " << *Q << " Product = " << *Product << " \n " );
3653- // For example in test/Analysis/DependenceAnalysis/MIVCheckConst.ll
3654- // SrcSCEV = {(80640 + (4 * (1 + %n) * %v1) + %A),+,(8 * %v1)}<%bb13>
3655- // DstSCEV = {(126720 + (128 * %m) + %A),+,256}<%bb13>
3656- // We fail to prove that the offsets 80640 + (4 * (1 + %n) * %v1) and
3657- // (8 * %v1) are multiples of 128.
3658- // Param = 80640 + (4 * (1 + %n) * %v1)
3659- // (80640 + (4 * (1 + %n) * %v1)) - (8 * %v1) =
3660- // (80640 + ((-4 + (4 * %n)) * %v1))
3661- // Remainder = (zext i7 ((trunc i32 %v1 to i7) *
3662- // (-4 + (4 * (trunc i32 %n to i7)))) to i32)
3663- // Q = ((80640 + ((-4 + (4 * %n)) * %v1)) /u 128)
3664- // Product = (128 * ((80640 + ((-4 + (4 * %n)) * %v1)) /u 128))<nuw>
3665- return false ;
3666- };
3667-
3668- // Expressions like "n".
3669- if (isa<SCEVUnknown>(V))
3670- return checkParamsMultipleOfSize (V, Param);
3671-
3672- // Expressions like "n + 1".
3673- if (isa<SCEVAddExpr>(V) || isa<SCEVMulExpr>(V))
3674- return !SCEVExprContains (V, [](const SCEV *S) {
3675- return isa<SCEVUnknown>(S);
3676- }) || checkParamsMultipleOfSize (V, Param);
3677-
3678- LLVM_DEBUG (dbgs () << " SCEV node not handled yet: " << *V << " \n " );
3679- return false ;
3680- }
3681-
36823572// depends -
36833573// Returns NULL if there is no dependence.
36843574// Otherwise, return a Dependence with as many details as possible.
@@ -3758,8 +3648,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst) {
37583648
37593649 if (Src != Dst) {
37603650 // Check that memory access offsets are multiples of element sizes.
3761- if (!checkOffsets (SE, SrcEv, Param, EltSize) ||
3762- !checkOffsets (SE, DstEv, Param, EltSize)) {
3651+ if (!SE-> isKnownMultipleOf ( SrcEv, Param, EltSize) ||
3652+ !SE-> isKnownMultipleOf ( DstEv, Param, EltSize)) {
37633653 LLVM_DEBUG (dbgs () << " can't analyze SCEV with different offsets\n " );
37643654 return std::make_unique<Dependence>(Src, Dst);
37653655 }
0 commit comments