diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -637,6 +637,9 @@ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, unsigned Depth = 0); + /// Return LHS-RHS, casted to an integer. + const SCEV *getPointerDiff(const SCEV *LHS, const SCEV *RHS); + /// Return a SCEV corresponding to a conversion of the input value to the /// specified type. If the type must be extended, it is zero extended. const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty, diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp --- a/llvm/lib/Analysis/Delinearization.cpp +++ b/llvm/lib/Analysis/Delinearization.cpp @@ -76,7 +76,7 @@ // Do not delinearize if we cannot find the base pointer. if (!BasePointer) break; - AccessFn = SE->getMinusSCEV(AccessFn, BasePointer); + AccessFn = SE->getPointerDiff(AccessFn, BasePointer); O << "\n"; O << "Inst:" << Inst << "\n"; diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -988,7 +988,7 @@ // 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); + const SCEV *Delta = SE->getPointerDiff(X, Y); switch (Pred) { case CmpInst::ICMP_EQ: return Delta->isZero(); @@ -1157,7 +1157,7 @@ assert(0 < Level && Level <= CommonLevels && "level out of range"); Level--; - const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst); + const SCEV *Delta = SE->getPointerDiff(SrcConst, DstConst); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta); LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n"); @@ -1290,7 +1290,7 @@ assert(0 < Level && Level <= CommonLevels && "Level out of range"); Level--; Result.Consistent = false; - const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst); + const SCEV *Delta = SE->getPointerDiff(DstConst, SrcConst); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n"); NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop); if (Delta->isZero()) { @@ -1492,7 +1492,7 @@ assert(0 < Level && Level <= CommonLevels && "Level out of range"); Level--; Result.Consistent = false; - const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst); + const SCEV *Delta = SE->getPointerDiff(DstConst, SrcConst); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n"); NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta, CurLoop); @@ -1688,7 +1688,7 @@ assert(0 < Level && Level <= MaxLevels && "Level out of range"); Level--; Result.Consistent = false; - const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst); + const SCEV *Delta = SE->getPointerDiff(SrcConst, DstConst); NewConstraint.setLine(SE->getZero(Delta->getType()), DstCoeff, Delta, CurLoop); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n"); @@ -1797,7 +1797,7 @@ assert(0 < Level && Level <= SrcLevels && "Level out of range"); Level--; Result.Consistent = false; - const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst); + const SCEV *Delta = SE->getPointerDiff(DstConst, SrcConst); NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->getType()), Delta, CurLoop); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n"); @@ -1877,7 +1877,7 @@ LLVM_DEBUG(dbgs() << "\t DstConst = " << *DstConst << "\n"); ++ExactRDIVapplications; Result.Consistent = false; - const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst); + const SCEV *Delta = SE->getPointerDiff(DstConst, SrcConst); LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta << "\n"); const SCEVConstant *ConstDelta = dyn_cast(Delta); const SCEVConstant *ConstSrcCoeff = dyn_cast(SrcCoeff); @@ -2038,8 +2038,8 @@ 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); + const SCEV *C2_C1 = SE->getPointerDiff(C2, C1); + const SCEV *C1_C2 = SE->getPointerDiff(C1, C2); LLVM_DEBUG(dbgs() << "\t C2 - C1 = " << *C2_C1 << "\n"); LLVM_DEBUG(dbgs() << "\t C1 - C2 = " << *C1_C2 << "\n"); if (SE->isKnownNonNegative(A1)) { @@ -2360,7 +2360,7 @@ const SCEV *DstConst = Coefficients; APInt ExtraGCD = APInt::getNullValue(BitWidth); - const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst); + const SCEV *Delta = SE->getPointerDiff(DstConst, SrcConst); LLVM_DEBUG(dbgs() << " Delta = " << *Delta << "\n"); const SCEVConstant *Constant = dyn_cast(Delta); if (const SCEVAddExpr *Sum = dyn_cast(Delta)) { @@ -2529,7 +2529,7 @@ const SCEV *B0; CoefficientInfo *B = collectCoeffInfo(Dst, false, B0); BoundInfo *Bound = new BoundInfo[MaxLevels + 1]; - const SCEV *Delta = SE->getMinusSCEV(B0, A0); + const SCEV *Delta = SE->getPointerDiff(B0, A0); LLVM_DEBUG(dbgs() << "\tDelta = " << *Delta << '\n'); // Compute bounds for all the * directions. @@ -3411,8 +3411,8 @@ if (ElementSize != SE->getElementSize(Dst)) return false; - const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase); - const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase); + const SCEV *SrcSCEV = SE->getPointerDiff(SrcAccessFn, SrcBase); + const SCEV *DstSCEV = SE->getPointerDiff(DstAccessFn, DstBase); const SCEVAddRecExpr *SrcAR = dyn_cast(SrcSCEV); const SCEVAddRecExpr *DstAR = dyn_cast(DstSCEV); diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -269,7 +269,7 @@ /// Return nullptr in case we couldn't find an answer. static const SCEV *getMinFromExprs(const SCEV *I, const SCEV *J, ScalarEvolution *SE) { - const SCEV *Diff = SE->getMinusSCEV(J, I); + const SCEV *Diff = SE->getPointerDiff(J, I); const SCEVConstant *C = dyn_cast(Diff); if (!C) @@ -1169,7 +1169,7 @@ const SCEV *PtrSCEVA = SE.getSCEV(PtrA); const SCEV *PtrSCEVB = SE.getSCEV(PtrB); const auto *Diff = - dyn_cast(SE.getMinusSCEV(PtrSCEVB, PtrSCEVA)); + dyn_cast(SE.getPointerDiff(PtrSCEVB, PtrSCEVA)); if (!Diff) return None; Val = Diff->getAPInt().getSExtValue(); @@ -1485,7 +1485,7 @@ std::swap(StrideAPtr, StrideBPtr); } - const SCEV *Dist = PSE.getSE()->getMinusSCEV(Sink, Src); + const SCEV *Dist = PSE.getSE()->getPointerDiff(Sink, Src); LLVM_DEBUG(dbgs() << "LAA: Src Scev: " << *Src << "Sink Scev: " << *Sink << "(Induction step: " << StrideAPtr << ")\n"); diff --git a/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/llvm/lib/Analysis/LoopCacheAnalysis.cpp --- a/llvm/lib/Analysis/LoopCacheAnalysis.cpp +++ b/llvm/lib/Analysis/LoopCacheAnalysis.cpp @@ -339,7 +339,7 @@ return false; } - AccessFn = SE.getMinusSCEV(AccessFn, BasePointer); + AccessFn = SE.getPointerDiff(AccessFn, BasePointer); LLVM_DEBUG(dbgs().indent(2) << "In Loop '" << L->getName() << "', AccessFn: " << *AccessFn << "\n"); diff --git a/llvm/lib/Analysis/LoopUnrollAnalyzer.cpp b/llvm/lib/Analysis/LoopUnrollAnalyzer.cpp --- a/llvm/lib/Analysis/LoopUnrollAnalyzer.cpp +++ b/llvm/lib/Analysis/LoopUnrollAnalyzer.cpp @@ -56,7 +56,7 @@ if (!Base) return false; auto *Offset = - dyn_cast(SE.getMinusSCEV(ValueAtIteration, Base)); + dyn_cast(SE.getPointerDiff(ValueAtIteration, Base)); if (!Offset) return false; SimplifiedAddress Address; diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1183,6 +1183,7 @@ "This is not a truncating conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't truncate pointer!"); Ty = getEffectiveSCEVType(Ty); FoldingSetNodeID ID; @@ -1572,6 +1573,7 @@ "This is not an extending conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); Ty = getEffectiveSCEVType(Ty); // Fold if the operand is constant. @@ -1874,6 +1876,7 @@ "This is not an extending conversion!"); assert(isSCEVable(Ty) && "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); Ty = getEffectiveSCEVType(Ty); // Fold if the operand is constant. @@ -2401,6 +2404,9 @@ for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVAddExpr operand types don't match!"); + unsigned NumPtrs = count_if( + Ops, [](const SCEV *Op) { return Op->getType()->isPointerTy(); }); + assert(NumPtrs <= 1 && "add has at most one pointer operand"); #endif // Sort by complexity, this groups all similar expression types together. @@ -2594,12 +2600,16 @@ Ops.clear(); if (AccumulatedConstant != 0) Ops.push_back(getConstant(AccumulatedConstant)); - for (auto &MulOp : MulOpLists) - if (MulOp.first != 0) + for (auto &MulOp : MulOpLists) { + if (MulOp.first == 1) { + Ops.push_back(getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1)); + } else if (MulOp.first != 0) { Ops.push_back(getMulExpr( getConstant(MulOp.first), getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1), SCEV::FlagAnyWrap, Depth + 1)); + } + } if (Ops.empty()) return getZero(Ty); if (Ops.size() == 1) @@ -2918,9 +2928,10 @@ assert(!Ops.empty() && "Cannot get empty mul!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = Ops[0]->getType(); + assert(!ETy->isPointerTy()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) - assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && + assert(Ops[i]->getType() == ETy && "SCEVMulExpr operand types don't match!"); #endif @@ -3205,8 +3216,9 @@ /// possible. const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS, const SCEV *RHS) { - assert(getEffectiveSCEVType(LHS->getType()) == - getEffectiveSCEVType(RHS->getType()) && + assert(!LHS->getType()->isPointerTy() && + "SCEVUDivExpr operand can't be pointer!"); + assert(LHS->getType() == RHS->getType() && "SCEVUDivExpr operand types don't match!"); FoldingSetNodeID ID; @@ -3450,9 +3462,11 @@ if (Operands.size() == 1) return Operands[0]; #ifndef NDEBUG Type *ETy = getEffectiveSCEVType(Operands[0]->getType()); - for (unsigned i = 1, e = Operands.size(); i != e; ++i) + for (unsigned i = 1, e = Operands.size(); i != e; ++i) { assert(getEffectiveSCEVType(Operands[i]->getType()) == ETy && "SCEVAddRecExpr operand types don't match!"); + assert(!Operands[i]->getType()->isPointerTy() && "Step must be integer"); + } for (unsigned i = 0, e = Operands.size(); i != e; ++i) assert(isLoopInvariant(Operands[i], L) && "SCEVAddRecExpr operand is not loop-invariant!"); @@ -3606,9 +3620,13 @@ if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); - for (unsigned i = 1, e = Ops.size(); i != e; ++i) + for (unsigned i = 1, e = Ops.size(); i != e; ++i) { assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "Operand types don't match!"); + assert(Ops[0]->getType()->isPointerTy() == + Ops[i]->getType()->isPointerTy() && + "min/max should be consistently pointerish"); + } #endif bool IsSigned = Kind == scSMaxExpr || Kind == scSMinExpr; @@ -4114,6 +4132,20 @@ return getAddExpr(LHS, getNegativeSCEV(RHS, NegFlags), AddFlags, Depth); } +const SCEV *ScalarEvolution::getPointerDiff(const SCEV *LHS, const SCEV *RHS) { + if (LHS->getType()->isPointerTy()) { + LHS = getLosslessPtrToIntExpr(LHS); + if (isa(LHS)) + return LHS; + } + if (RHS->getType()->isPointerTy()) { + RHS = getLosslessPtrToIntExpr(RHS); + if (isa(RHS)) + return RHS; + } + return getMinusSCEV(LHS, RHS); +} + const SCEV *ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth) { Type *SrcTy = V->getType(); @@ -5278,7 +5310,7 @@ Flags = setFlags(Flags, SCEV::FlagNW); const SCEV *Ptr = getSCEV(GEP->getPointerOperand()); - if (isKnownPositive(getMinusSCEV(getSCEV(GEP), Ptr))) + if (isKnownPositive(getPointerDiff(getSCEV(GEP), Ptr))) Flags = setFlags(Flags, SCEV::FlagNUW); } @@ -7956,24 +7988,14 @@ switch (Pred) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) - if (LHS->getType()->isPointerTy()) { - LHS = getLosslessPtrToIntExpr(LHS); - if (isa(LHS)) - return LHS; - } - if (RHS->getType()->isPointerTy()) { - RHS = getLosslessPtrToIntExpr(RHS); - if (isa(RHS)) - return RHS; - } - ExitLimit EL = howFarToZero(getMinusSCEV(LHS, RHS), L, ControlsExit, + ExitLimit EL = howFarToZero(getPointerDiff(LHS, RHS), L, ControlsExit, AllowPredicates); if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_EQ: { // while (X == Y) // Convert to: while (X-Y == 0) - ExitLimit EL = howFarToNonZero(getMinusSCEV(LHS, RHS), L); + ExitLimit EL = howFarToNonZero(getPointerDiff(LHS, RHS), L); if (EL.hasAnyInfo()) return EL; break; } @@ -10013,7 +10035,7 @@ if (Pred == CmpInst::ICMP_NE) return CheckRanges(getSignedRange(LHS), getSignedRange(RHS)) || CheckRanges(getUnsignedRange(LHS), getUnsignedRange(RHS)) || - isKnownNonZero(getMinusSCEV(LHS, RHS)); + isKnownNonZero(getPointerDiff(LHS, RHS)); if (CmpInst::isSigned(Pred)) return CheckRanges(getSignedRange(LHS), getSignedRange(RHS)); @@ -10446,6 +10468,8 @@ } } + if (LHS->getType()->isPointerTy()) + return false; if (CmpInst::isSigned(Pred)) { LHS = getSignExtendExpr(LHS, FoundLHS->getType()); RHS = getSignExtendExpr(RHS, FoundLHS->getType()); @@ -10455,6 +10479,8 @@ } } else if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(FoundLHS->getType())) { + if (FoundLHS->getType()->isPointerTy()) + return false; if (CmpInst::isSigned(FoundPred)) { FoundLHS = getSignExtendExpr(FoundLHS, LHS->getType()); FoundRHS = getSignExtendExpr(FoundRHS, LHS->getType()); @@ -10516,6 +10542,10 @@ if (!isa(FoundRHS) && !isa(FoundLHS)) return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, Context); + // Don't try to getNotSCEV pointers. + if (LHS->getType()->isPointerTy() || FoundLHS->getType()->isPointerTy()) + return false; + // There's no clear preference between forms 3. and 4., try both. return isImpliedCondOperands(FoundPred, getNotSCEV(LHS), getNotSCEV(RHS), FoundLHS, FoundRHS, Context) || diff --git a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp --- a/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -52,7 +52,7 @@ : MemoryLocation::UnknownSize); // Compute the difference between the two pointers. - const SCEV *BA = SE.getMinusSCEV(BS, AS); + const SCEV *BA = SE.getPointerDiff(BS, AS); // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt @@ -66,7 +66,7 @@ // and try again to see if things fold better that way. // Compute the difference between the two pointers. - const SCEV *AB = SE.getMinusSCEV(AS, BS); + const SCEV *AB = SE.getPointerDiff(AS, BS); // Test whether the difference is known to be great enough that memory of // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -262,7 +262,7 @@ auto *PtrTy = IntegerType::getInt8PtrTy(SE.getContext()); const SCEV *AddrExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Addr), PtrTy); const SCEV *BaseExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Base), PtrTy); - const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp); + const SCEV *Diff = SE.getPointerDiff(AddrExp, BaseExp); ConstantRange Offset = SE.getSignedRange(Diff); if (isUnsafe(Offset)) diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -1157,7 +1157,7 @@ // Calculate the distance from A to B. const SCEVConstant *DistToB = dyn_cast( - PSE.getSE()->getMinusSCEV(DesA.Scev, DesB.Scev)); + PSE.getSE()->getPointerDiff(DesA.Scev, DesB.Scev)); if (!DistToB) continue; int64_t DistanceToB = DistToB->getAPInt().getSExtValue(); diff --git a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp --- a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp +++ b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp @@ -314,7 +314,7 @@ assert(LSCEV && "Invalid SCEV for Ptr value."); bool FoundBucket = false; for (auto &B : Buckets) { - const SCEV *Diff = SE->getMinusSCEV(LSCEV, B.BaseSCEV); + const SCEV *Diff = SE->getPointerDiff(LSCEV, B.BaseSCEV); if (const auto *CDiff = dyn_cast(Diff)) { B.Elements.push_back(BucketElement(CDiff, MemI)); FoundBucket = true; @@ -779,8 +779,9 @@ return true; } if (Form == DSForm || Form == DQForm) { - const SCEVConstant *Diff = dyn_cast( - SE->getMinusSCEV(PHIBasePtrSCEV->getStart(), BasePtrStartSCEV)); + const SCEVConstant *Diff = + dyn_cast(SE->getPointerDiff( + PHIBasePtrSCEV->getStart(), BasePtrStartSCEV)); if (Diff && !Diff->getAPInt().urem(Form)) { if (Form == DSForm) ++PHINodeAlreadyExistsDS; diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp --- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -134,7 +134,7 @@ // may disagree. Trunc/extend so they agree. PtrSCEV = SE->getTruncateOrZeroExtend( PtrSCEV, SE->getEffectiveSCEVType(AASCEV->getType())); - const SCEV *DiffSCEV = SE->getMinusSCEV(PtrSCEV, AASCEV); + const SCEV *DiffSCEV = SE->getPointerDiff(PtrSCEV, AASCEV); // On 32-bit platforms, DiffSCEV might now have type i32 -- we've always // sign-extended OffSCEV to i64, so make sure they agree again. diff --git a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp --- a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp @@ -349,7 +349,7 @@ // has already been prefetched, then don't prefetch this one as well. bool DupPref = false; for (auto &Pref : Prefetches) { - const SCEV *PtrDiff = SE->getMinusSCEV(LSCEVAddRec, Pref.LSCEVAddRec); + const SCEV *PtrDiff = SE->getPointerDiff(LSCEVAddRec, Pref.LSCEVAddRec); if (const SCEVConstant *ConstPtrDiff = dyn_cast(PtrDiff)) { int64_t PD = std::abs(ConstPtrDiff->getValue()->getSExtValue()); diff --git a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp --- a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp +++ b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -123,7 +123,7 @@ // We don't need to check non-wrapping here because forward/backward // dependence wouldn't be valid if these weren't monotonic accesses. auto *Dist = cast( - PSE.getSE()->getMinusSCEV(StorePtrSCEV, LoadPtrSCEV)); + PSE.getSE()->getPointerDiff(StorePtrSCEV, LoadPtrSCEV)); const APInt &Val = Dist->getAPInt(); return Val == TypeByteSize; } diff --git a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp --- a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp @@ -910,15 +910,15 @@ // Check that the first root is evenly spaced. unsigned N = DRS.Roots.size() + 1; - const SCEV *StepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[0]), ADR); + const SCEV *StepSCEV = SE->getPointerDiff(SE->getSCEV(DRS.Roots[0]), ADR); const SCEV *ScaleSCEV = SE->getConstant(StepSCEV->getType(), N); if (ADR->getStepRecurrence(*SE) != SE->getMulExpr(StepSCEV, ScaleSCEV)) return false; // Check that the remainling roots are evenly spaced. for (unsigned i = 1; i < N - 1; ++i) { - const SCEV *NewStepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[i]), - SE->getSCEV(DRS.Roots[i-1])); + const SCEV *NewStepSCEV = SE->getPointerDiff(SE->getSCEV(DRS.Roots[i]), + SE->getSCEV(DRS.Roots[i - 1])); if (NewStepSCEV != StepSCEV) return false; } @@ -1450,7 +1450,7 @@ const SCEVAddRecExpr *IVSCEV = cast(SE->getSCEV(DRS.BaseInst)); StartExprs.push_back(IVSCEV->getStart()); - IncrExprs.push_back(SE->getMinusSCEV(SE->getSCEV(DRS.Roots[0]), IVSCEV)); + IncrExprs.push_back(SE->getPointerDiff(SE->getSCEV(DRS.Roots[0]), IVSCEV)); } // Remove instructions associated with non-base iterations. diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -682,7 +682,7 @@ // Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do // some folding. if (RA.isAllOnesValue()) - return SE.getMulExpr(LHS, RC); + return SE.getPointerDiff(SE.getZero(LHS->getType()), LHS); // Handle x /s 1 as x. if (RA == 1) return LHS; @@ -2832,7 +2832,7 @@ // increment. if (!isa(IncExpr)) { const SCEV *HeadExpr = SE.getSCEV(getWideOperand(Incs[0].IVOperand)); - if (isa(SE.getMinusSCEV(OperExpr, HeadExpr))) + if (isa(SE.getPointerDiff(OperExpr, HeadExpr))) return false; } @@ -2961,7 +2961,7 @@ // The increment must be loop-invariant so it can be kept in a register. const SCEV *PrevExpr = SE.getSCEV(PrevIV); - const SCEV *IncExpr = SE.getMinusSCEV(OperExpr, PrevExpr); + const SCEV *IncExpr = SE.getPointerDiff(OperExpr, PrevExpr); if (!SE.isLoopInvariant(IncExpr, L)) continue; @@ -3320,7 +3320,10 @@ // to keep the result normalized. N = normalizeForPostIncUse(N, TmpPostIncLoops, SE); Kind = LSRUse::ICmpZero; - S = SE.getMinusSCEV(N, S); + // FIXME: Replacing getMinusSCEV with getPointerDiff here causes + // codegen differences in regression tests. Need to figure out + // a different way to handle this. + S = SE.getPointerDiff(N, S); } // -1 and the negations of all interesting strides (except the negation @@ -4059,7 +4062,8 @@ // Determine the integer type for the base formula. Type *DstTy = Base.getType(); if (!DstTy) return; - DstTy = SE.getEffectiveSCEVType(DstTy); + if (DstTy->isPointerTy()) + return; for (Type *SrcTy : Types) { if (SrcTy != DstTy && TTI.isTruncateFree(SrcTy, DstTy)) { @@ -5297,7 +5301,7 @@ if (F.BaseGV) { // Flush the operand list to suppress SCEVExpander hoisting. if (!Ops.empty()) { - Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty); + Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), IntTy); Ops.clear(); Ops.push_back(SE.getUnknown(FullV)); } diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1161,8 +1161,7 @@ } // Check whether inverting will help: {R,+,-1} == R - {0,+,1}. - if (SE.getAddExpr(Requested->getStart(), - SE.getNegativeSCEV(Requested)) == Phi) { + if (SE.getPointerDiff(Requested->getStart(), Requested) == Phi) { InvertStep = true; return true; } @@ -1573,8 +1572,8 @@ // Rewrite an AddRec in terms of the canonical induction variable, if // its type is more narrow. if (CanonicalIV && - SE.getTypeSizeInBits(CanonicalIV->getType()) > - SE.getTypeSizeInBits(Ty)) { + SE.getTypeSizeInBits(CanonicalIV->getType()) > SE.getTypeSizeInBits(Ty) && + !S->getType()->isPointerTy()) { SmallVector NewOps(S->getNumOperands()); for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i) NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType()); diff --git a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp --- a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -374,7 +374,7 @@ // factorized but the other one is not, such as (C + (S * (A + B))) vs // (AS + BS). Get the minus scev. That will allow re-combining the expresions // and getting the simplified difference. - const SCEV *Dist = SE.getMinusSCEV(PtrSCEVB, PtrSCEVA); + const SCEV *Dist = SE.getPointerDiff(PtrSCEVB, PtrSCEVA); if (C == Dist) return true; diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -8490,7 +8490,7 @@ for (int J = I + 1; J < E && Candidates.size() > 1; ++J) { auto *GEPJ = GEPList[J]; auto *SCEVJ = SE->getSCEV(GEPList[J]); - if (isa(SE->getMinusSCEV(SCEVI, SCEVJ))) { + if (isa(SE->getPointerDiff(SCEVI, SCEVJ))) { Candidates.remove(GEPI); Candidates.remove(GEPJ); } else if (GEPI->idx_begin()->get() == GEPJ->idx_begin()->get()) { diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp --- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -96,13 +96,13 @@ const SCEV *S1 = SE.getSCEV(V1); const SCEV *S2 = SE.getSCEV(V2); - const SCEV *P0 = SE.getAddExpr(S0, S0); - const SCEV *P1 = SE.getAddExpr(S1, S1); - const SCEV *P2 = SE.getAddExpr(S2, S2); + const SCEV *P0 = SE.getAddExpr(S0, SE.getConstant(S0->getType(), 2)); + const SCEV *P1 = SE.getAddExpr(S1, SE.getConstant(S0->getType(), 2)); + const SCEV *P2 = SE.getAddExpr(S2, SE.getConstant(S0->getType(), 2)); - const SCEVMulExpr *M0 = cast(P0); - const SCEVMulExpr *M1 = cast(P1); - const SCEVMulExpr *M2 = cast(P2); + auto *M0 = cast(P0); + auto *M1 = cast(P1); + auto *M2 = cast(P2); EXPECT_EQ(cast(M0->getOperand(0))->getValue()->getZExtValue(), 2u); @@ -707,6 +707,7 @@ ReturnInst::Create(Context, nullptr, EndBB); ScalarEvolution SE = buildSE(*F); const SCEV *S = SE.getSCEV(Accum); + S = SE.getLosslessPtrToIntExpr(S); Type *I128Ty = Type::getInt128Ty(Context); SE.getZeroExtendExpr(S, I128Ty); }