Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Analysis/ScalarEvolution.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 4,125 Lines • ▼ Show 20 Lines | if (const SCEV *Replaced = MatchMinMaxNegation(MME)) | ||||
return Replaced; | return Replaced; | ||||
} | } | ||||
Type *Ty = V->getType(); | Type *Ty = V->getType(); | ||||
Ty = getEffectiveSCEVType(Ty); | Ty = getEffectiveSCEVType(Ty); | ||||
return getMinusSCEV(getMinusOne(Ty), V); | return getMinusSCEV(getMinusOne(Ty), V); | ||||
} | } | ||||
/// Compute an expression equivalent to S - getPointerBase(S). | |||||
static const SCEV *removePointerBase(ScalarEvolution *SE, const SCEV *P) { | |||||
assert(P->getType()->isPointerTy()); | |||||
if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(P)) { | |||||
// The base of an AddRec is the first operand. | |||||
SmallVector<const SCEV *> Ops{AddRec->operands()}; | |||||
Ops[0] = removePointerBase(SE, Ops[0]); | |||||
// Don't try to transfer nowrap flags for now. We could in some cases | |||||
// (for example, if pointer operand of the AddRec is a SCEVUnknown). | |||||
return SE->getAddRecExpr(Ops, AddRec->getLoop(), SCEV::FlagAnyWrap); | |||||
} | |||||
if (auto *Add = dyn_cast<SCEVAddExpr>(P)) { | |||||
// The base of an Add is the pointer operand. | |||||
SmallVector<const SCEV *> Ops{Add->operands()}; | |||||
const SCEV **PtrOp = nullptr; | |||||
for (const SCEV *&AddOp : Ops) { | |||||
if (AddOp->getType()->isPointerTy()) { | |||||
// If we find an Add with multiple pointer operands, treat it as a | |||||
// pointer base to be consistent with getPointerBase. Eventually | |||||
// we should be able to assert this is impossible. | |||||
if (PtrOp) | |||||
return SE->getZero(P->getType()); | |||||
PtrOp = &AddOp; | |||||
} | |||||
} | |||||
*PtrOp = removePointerBase(SE, *PtrOp); | |||||
// Don't try to transfer nowrap flags for now. We could in some cases | |||||
// (for example, if the pointer operand of the Add is a SCEVUnknown). | |||||
return SE->getAddExpr(Ops); | |||||
mkazantsev: I guess you forgot to modify ops somewhere. | |||||
} | |||||
// Any other expression must be a pointer base. | |||||
return SE->getZero(P->getType()); | |||||
} | |||||
const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, | const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, | ||||
SCEV::NoWrapFlags Flags, | SCEV::NoWrapFlags Flags, | ||||
unsigned Depth) { | unsigned Depth) { | ||||
// Fast path: X - X --> 0. | // Fast path: X - X --> 0. | ||||
if (LHS == RHS) | if (LHS == RHS) | ||||
return getZero(LHS->getType()); | return getZero(LHS->getType()); | ||||
// If we subtract two pointers with different pointer bases, bail. | // If we subtract two pointers with different pointer bases, bail. | ||||
// Eventually, we're going to add an assertion to getMulExpr that we | // Eventually, we're going to add an assertion to getMulExpr that we | ||||
// can't multiply by a pointer. | // can't multiply by a pointer. | ||||
if (RHS->getType()->isPointerTy()) { | if (RHS->getType()->isPointerTy()) { | ||||
if (!LHS->getType()->isPointerTy() || | if (!LHS->getType()->isPointerTy() || | ||||
getPointerBase(LHS) != getPointerBase(RHS)) | getPointerBase(LHS) != getPointerBase(RHS)) | ||||
return getCouldNotCompute(); | return getCouldNotCompute(); | ||||
LHS = removePointerBase(this, LHS); | |||||
RHS = removePointerBase(this, RHS); | |||||
} | } | ||||
// We represent LHS - RHS as LHS + (-1)*RHS. This transformation | // We represent LHS - RHS as LHS + (-1)*RHS. This transformation | ||||
// makes it so that we cannot make much use of NUW. | // makes it so that we cannot make much use of NUW. | ||||
auto AddFlags = SCEV::FlagAnyWrap; | auto AddFlags = SCEV::FlagAnyWrap; | ||||
const bool RHSIsNotMinSigned = | const bool RHSIsNotMinSigned = | ||||
!getSignedRangeMin(RHS).isMinSignedValue(); | !getSignedRangeMin(RHS).isMinSignedValue(); | ||||
if (maskFlags(Flags, SCEV::FlagNSW) == SCEV::FlagNSW) { | if (maskFlags(Flags, SCEV::FlagNSW) == SCEV::FlagNSW) { | ||||
▲ Show 20 Lines • Show All 9,699 Lines • Show Last 20 Lines |
I guess you forgot to modify ops somewhere.