Added SCEV::NoWrapFlags to manage unsigned, signed, and self wrap

properties.
Added the self-wrap flag for SCEV::AddRecExpr.
A slew of temporary FIXMEs indicate the intention of the no-self-wrap flag
without changing behavior in this revision.

llvm-svn: 127590
This commit is contained in:
Andrew Trick 2011-03-14 16:50:06 +00:00
parent e0442babf1
commit 5d45b563c5
7 changed files with 307 additions and 182 deletions

View File

@ -72,6 +72,29 @@ namespace llvm {
void operator=(const SCEV &); // DO NOT IMPLEMENT
public:
/// NoWrapFlags are bitfield indices into SubclassData.
///
/// Add and Mul expressions may have no-unsigned-wrap <NUW> or
/// no-signed-wrap <NSW> properties, which are derived from the IR
/// operator. NSW is a misnomer that we use to mean no signed overflow or
/// underflow.
///
/// AddRec expression may have a no-self-wraparound <NW> property if the
/// result can never reach the start value. This property is independent of
/// the actual start value and step direction. Self-wraparound is defined
/// purely in terms of the recurrence's loop, step size, and
/// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
/// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
///
/// Note that NUW and NSW are also valid properties of a recurrence, and
/// either implies NW. For convenience, NW will be set for a recurrence
/// whenever either NUW or NSW are set.
enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee.
FlagNW = (1 << 0), // No self-wrap.
FlagNUW = (1 << 1), // No unsigned wrap.
FlagNSW = (1 << 2), // No signed wrap.
NoWrapMask = (1 << 3) -1 };
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
@ -159,6 +182,20 @@ namespace llvm {
ProperlyDominatesBlock ///< The SCEV properly dominates the block.
};
/// Convenient NoWrapFlags manipulation that hides enum casts and is
/// visible in the ScalarEvolution name space.
static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) {
return (SCEV::NoWrapFlags)(Flags & Mask);
}
static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OnFlags) {
return (SCEV::NoWrapFlags)(Flags | OnFlags);
}
static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OffFlags) {
return (SCEV::NoWrapFlags)(Flags & ~OffFlags);
}
private:
/// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
/// notified whenever a Value is deleted.
@ -465,44 +502,41 @@ namespace llvm {
const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty);
const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW = false, bool HasNSW = false);
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false) {
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getAddExpr(Ops, HasNUW, HasNSW);
return getAddExpr(Ops, Flags);
}
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1,
const SCEV *Op2,
bool HasNUW = false, bool HasNSW = false) {
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 3> Ops;
Ops.push_back(Op0);
Ops.push_back(Op1);
Ops.push_back(Op2);
return getAddExpr(Ops, HasNUW, HasNSW);
return getAddExpr(Ops, Flags);
}
const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW = false, bool HasNSW = false);
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false) {
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap)
{
SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getMulExpr(Ops, HasNUW, HasNSW);
return getMulExpr(Ops, Flags);
}
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
const Loop *L,
bool HasNUW = false, bool HasNSW = false);
const Loop *L, SCEV::NoWrapFlags Flags);
const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
const Loop *L,
bool HasNUW = false, bool HasNSW = false);
const Loop *L, SCEV::NoWrapFlags Flags);
const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands,
const Loop *L,
bool HasNUW = false, bool HasNSW = false) {
const Loop *L, SCEV::NoWrapFlags Flags) {
SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, HasNUW, HasNSW);
return getAddRecExpr(NewOp, L, Flags);
}
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
@ -537,11 +571,9 @@ namespace llvm {
///
const SCEV *getNotSCEV(const SCEV *V);
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1,
/// and thus the HasNUW and HasNSW bits apply to the resultant add, not
/// whether the sub would have overflowed.
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
bool HasNUW = false, bool HasNSW = false);
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be

View File

@ -160,13 +160,8 @@ namespace llvm {
const Type *getType() const { return getOperand(0)->getType(); }
bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
void setHasNoUnsignedWrap(bool B) {
SubclassData = (SubclassData & ~(1 << 0)) | (B << 0);
}
bool hasNoSignedWrap() const { return SubclassData & (1 << 1); }
void setHasNoSignedWrap(bool B) {
SubclassData = (SubclassData & ~(1 << 1)) | (B << 1);
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
return (NoWrapFlags)(SubclassData & Mask);
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@ -199,6 +194,11 @@ namespace llvm {
S->getSCEVType() == scSMaxExpr ||
S->getSCEVType() == scUMaxExpr;
}
/// Set flags for a non-recurrence without clearing previously set flags.
void setNoWrapFlags(NoWrapFlags Flags) {
SubclassData |= Flags;
}
};
@ -305,11 +305,12 @@ namespace llvm {
/// getStepRecurrence - This method constructs and returns the recurrence
/// indicating how much this expression steps by. If this is a polynomial
/// of degree N, it returns a chrec of degree N-1.
/// We cannot determine whether the step recurrence has self-wraparound.
const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
if (isAffine()) return getOperand(1);
return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
op_end()),
getLoop());
getLoop(), FlagAnyWrap);
}
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
@ -327,6 +328,15 @@ namespace llvm {
return getNumOperands() == 3;
}
/// Set flags for a recurrence without clearing any previously set flags.
/// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
/// to make it easier to propagate flags.
void setNoWrapFlags(NoWrapFlags Flags) {
if (Flags & (FlagNUW | FlagNSW))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= Flags;
}
/// evaluateAtIteration - Return the value of this chain of recurrences at
/// the specified iteration number.
const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
@ -364,8 +374,7 @@ namespace llvm {
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:
@ -387,8 +396,7 @@ namespace llvm {
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:

View File

@ -157,10 +157,13 @@ void SCEV::print(raw_ostream &OS) const {
for (unsigned i = 1, e = AR->getNumOperands(); i != e; ++i)
OS << ",+," << *AR->getOperand(i);
OS << "}<";
if (AR->hasNoUnsignedWrap())
if (AR->getNoWrapFlags(FlagNUW))
OS << "nuw><";
if (AR->hasNoSignedWrap())
if (AR->getNoWrapFlags(FlagNSW))
OS << "nsw><";
if (AR->getNoWrapFlags(FlagNW) &&
!AR->getNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW)))
OS << "nw><";
WriteAsOperand(OS, AR->getLoop()->getHeader(), /*PrintType=*/false);
OS << ">";
return;
@ -830,7 +833,7 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op,
Operands.push_back(S);
}
if (!hasTrunc)
return getAddExpr(Operands, false, false);
return getAddExpr(Operands);
UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL.
}
@ -845,7 +848,7 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op,
Operands.push_back(S);
}
if (!hasTrunc)
return getMulExpr(Operands, false, false);
return getMulExpr(Operands);
UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL.
}
@ -854,7 +857,7 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op,
SmallVector<const SCEV *, 4> Operands;
for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i)
Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty));
return getAddRecExpr(Operands, AddRec->getLoop());
return getAddRecExpr(Operands, AddRec->getLoop(), SCEV::FlagAnyWrap);
}
// As a special case, fold trunc(undef) to undef. We don't want to
@ -926,10 +929,11 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// If we have special knowledge that this addrec won't overflow,
// we don't need to do any further analysis.
if (AR->hasNoUnsignedWrap())
if (AR->getNoWrapFlags(SCEV::FlagNUW))
return getAddRecExpr(getZeroExtendExpr(Start, Ty),
getZeroExtendExpr(Step, Ty),
L);
// FIXME: Can use SCEV::FlagNUW
L, SCEV::FlagAnyWrap);
// Check whether the backedge-taken count is SCEVCouldNotCompute.
// Note that this serves two purposes: It filters out loops that are
@ -963,7 +967,8 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getZeroExtendExpr(Start, Ty),
getZeroExtendExpr(Step, Ty),
L);
// FIXME: can use FlagNUW
L, SCEV::FlagAnyWrap);
// Similar to above, only this time treat the step value as signed.
// This covers loops that count down.
@ -977,7 +982,8 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getZeroExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use FlagNW
L, SCEV::FlagAnyWrap);
}
// If the backedge is guarded by a comparison with the pre-inc value
@ -994,7 +1000,8 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getZeroExtendExpr(Start, Ty),
getZeroExtendExpr(Step, Ty),
L);
// FIXME: can use FlagNUW
L, SCEV::FlagAnyWrap);
} else if (isKnownNegative(Step)) {
const SCEV *N = getConstant(APInt::getMaxValue(BitWidth) -
getSignedRange(Step).getSignedMin());
@ -1002,10 +1009,12 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
(isLoopEntryGuardedByCond(L, ICmpInst::ICMP_UGT, Start, N) &&
isLoopBackedgeGuardedByCond(L, ICmpInst::ICMP_UGT,
AR->getPostIncExpr(*this), N)))
// Return the expression with the addrec on the outside.
// Return the expression with the addrec on the outside. The
// negative step causes unsigned wrap, but it still can't self-wrap.
return getAddRecExpr(getZeroExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use FlagNW
L, SCEV::FlagAnyWrap);
}
}
}
@ -1080,10 +1089,11 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// If we have special knowledge that this addrec won't overflow,
// we don't need to do any further analysis.
if (AR->hasNoSignedWrap())
if (AR->getNoWrapFlags(SCEV::FlagNSW))
return getAddRecExpr(getSignExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use SCEV::FlagNSW
L, SCEV::FlagAnyWrap);
// Check whether the backedge-taken count is SCEVCouldNotCompute.
// Note that this serves two purposes: It filters out loops that are
@ -1117,7 +1127,8 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getSignExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use SCEV::FlagNSW
L, SCEV::FlagAnyWrap);
// Similar to above, only this time treat the step value as unsigned.
// This covers loops that count up with an unsigned step.
@ -1131,7 +1142,8 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getSignExtendExpr(Start, Ty),
getZeroExtendExpr(Step, Ty),
L);
// FIXME: can use SCEV::FlagNSW
L, SCEV::FlagAnyWrap);
}
// If the backedge is guarded by a comparison with the pre-inc value
@ -1148,7 +1160,8 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getSignExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use SCEV::FlagNSW
L, SCEV::FlagAnyWrap);
} else if (isKnownNegative(Step)) {
const SCEV *N = getConstant(APInt::getSignedMaxValue(BitWidth) -
getSignedRange(Step).getSignedMin());
@ -1159,7 +1172,8 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// Return the expression with the addrec on the outside.
return getAddRecExpr(getSignExtendExpr(Start, Ty),
getSignExtendExpr(Step, Ty),
L);
// FIXME: can use SCEV::FlagNSW
L, SCEV::FlagAnyWrap);
}
}
}
@ -1213,7 +1227,8 @@ const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op,
for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end();
I != E; ++I)
Ops.push_back(getAnyExtendExpr(*I, Ty));
return getAddRecExpr(Ops, AR->getLoop());
// FIXME: can use AR->getNoWrapFlags(SCEV::FlagNW)
return getAddRecExpr(Ops, AR->getLoop(), SCEV::FlagAnyWrap);
}
// As a special case, fold anyext(undef) to undef. We don't want to
@ -1334,7 +1349,9 @@ namespace {
/// getAddExpr - Get a canonical add expression, or something simpler if
/// possible.
const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW, bool HasNSW) {
SCEV::NoWrapFlags Flags) {
assert(!(Flags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
assert(!Ops.empty() && "Cannot get empty add!");
if (Ops.size() == 1) return Ops[0];
#ifndef NDEBUG
@ -1344,8 +1361,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
"SCEVAddExpr operand types don't match!");
#endif
// If HasNSW is true and all the operands are non-negative, infer HasNUW.
if (!HasNUW && HasNSW) {
// If FlagNSW is true and all the operands are non-negative, infer FlagNUW.
if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) {
bool All = true;
for (SmallVectorImpl<const SCEV *>::const_iterator I = Ops.begin(),
E = Ops.end(); I != E; ++I)
@ -1353,7 +1370,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
All = false;
break;
}
if (All) HasNUW = true;
if (All) Flags = setFlags(Flags, SCEV::FlagNUW);
}
// Sort by complexity, this groups all similar expression types together.
@ -1404,7 +1421,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
FoundMatch = true;
}
if (FoundMatch)
return getAddExpr(Ops, HasNUW, HasNSW);
return getAddExpr(Ops, Flags);
// Check for truncates. If all the operands are truncated from the same
// type, see if factoring out the truncate would permit the result to be
@ -1454,7 +1471,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
}
if (Ok) {
// Evaluate the expression in the larger type.
const SCEV *Fold = getAddExpr(LargeOps, HasNUW, HasNSW);
const SCEV *Fold = getAddExpr(LargeOps, Flags);
// If it folds to something simple, use it. Otherwise, don't.
if (isa<SCEVConstant>(Fold) || isa<SCEVUnknown>(Fold))
return getTruncateExpr(Fold, DstType);
@ -1625,9 +1642,10 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
// Build the new addrec. Propagate the NUW and NSW flags if both the
// outer add and the inner addrec are guaranteed to have no overflow.
const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRecLoop,
HasNUW && AddRec->hasNoUnsignedWrap(),
HasNSW && AddRec->hasNoSignedWrap());
// FIXME: Always propagate NW
// AddRec->getNoWrapFlags(setFlags(Flags, SCEV::FlagNW))
Flags = AddRec->getNoWrapFlags(Flags);
const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRecLoop, Flags);
// If all of the other operands were loop invariant, we are done.
if (Ops.size() == 1) return NewRec;
@ -1668,7 +1686,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
}
Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
}
Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop);
// Step size has changed, so we cannot guarantee no self-wraparound.
Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop, SCEV::FlagAnyWrap);
return getAddExpr(Ops);
}
@ -1692,15 +1711,16 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
S->setNoWrapFlags(Flags);
return S;
}
/// getMulExpr - Get a canonical multiply expression, or something simpler if
/// possible.
const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW, bool HasNSW) {
SCEV::NoWrapFlags Flags) {
assert(Flags == maskFlags(Flags, SCEV::FlagNUW | SCEV::FlagNSW) &&
"only nuw or nsw allowed");
assert(!Ops.empty() && "Cannot get empty mul!");
if (Ops.size() == 1) return Ops[0];
#ifndef NDEBUG
@ -1710,8 +1730,8 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
"SCEVMulExpr operand types don't match!");
#endif
// If HasNSW is true and all the operands are non-negative, infer HasNUW.
if (!HasNUW && HasNSW) {
// If FlagNSW is true and all the operands are non-negative, infer FlagNUW.
if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) {
bool All = true;
for (SmallVectorImpl<const SCEV *>::const_iterator I = Ops.begin(),
E = Ops.end(); I != E; ++I)
@ -1719,7 +1739,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
All = false;
break;
}
if (All) HasNUW = true;
if (All) Flags = setFlags(Flags, SCEV::FlagNUW);
}
// Sort by complexity, this groups all similar expression types together.
@ -1759,12 +1779,12 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
} else if (Ops[0]->isAllOnesValue()) {
// If we have a mul by -1 of an add, try distributing the -1 among the
// add operands.
if (Ops.size() == 2)
if (Ops.size() == 2) {
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1])) {
SmallVector<const SCEV *, 4> NewOps;
bool AnyFolded = false;
for (SCEVAddRecExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
I != E; ++I) {
for (SCEVAddRecExpr::op_iterator I = Add->op_begin(),
E = Add->op_end(); I != E; ++I) {
const SCEV *Mul = getMulExpr(Ops[0], *I);
if (!isa<SCEVMulExpr>(Mul)) AnyFolded = true;
NewOps.push_back(Mul);
@ -1772,6 +1792,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
if (AnyFolded)
return getAddExpr(NewOps);
}
}
}
if (Ops.size() == 1)
@ -1831,9 +1852,11 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// Build the new addrec. Propagate the NUW and NSW flags if both the
// outer mul and the inner addrec are guaranteed to have no overflow.
const SCEV *NewRec = getAddRecExpr(NewOps, AddRecLoop,
HasNUW && AddRec->hasNoUnsignedWrap(),
HasNSW && AddRec->hasNoSignedWrap());
//
// No self-wrap cannot be guaranteed after changing the step size, but
// will be infered if either NUW or NSW is true.
Flags = AddRec->getNoWrapFlags(clearFlags(Flags, SCEV::FlagNW));
const SCEV *NewRec = getAddRecExpr(NewOps, AddRecLoop, Flags);
// If all of the other operands were loop invariant, we are done.
if (Ops.size() == 1) return NewRec;
@ -1869,7 +1892,8 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
getMulExpr(G, B),
getMulExpr(B, D));
const SCEV *NewAddRec = getAddRecExpr(NewStart, NewStep,
F->getLoop());
F->getLoop(),
SCEV::FlagAnyWrap);
if (Ops.size() == 2) return NewAddRec;
Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
@ -1897,8 +1921,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
S->setNoWrapFlags(Flags);
return S;
}
@ -1938,11 +1961,13 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
getZeroExtendExpr(AR, ExtTy) ==
getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
getZeroExtendExpr(Step, ExtTy),
AR->getLoop())) {
AR->getLoop(), SCEV::FlagAnyWrap)) {
SmallVector<const SCEV *, 4> Operands;
for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i)
Operands.push_back(getUDivExpr(AR->getOperand(i), RHS));
return getAddRecExpr(Operands, AR->getLoop());
return getAddRecExpr(Operands, AR->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
SCEV::FlagAnyWrap);
}
// (A*B)/C --> A*(B/C) if safe and B/C can be folded.
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) {
@ -2006,27 +2031,27 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
/// getAddRecExpr - Get an add recurrence expression for the specified loop.
/// Simplify the expression as much as possible.
const SCEV *ScalarEvolution::getAddRecExpr(const SCEV *Start,
const SCEV *Step, const Loop *L,
bool HasNUW, bool HasNSW) {
const SCEV *ScalarEvolution::getAddRecExpr(const SCEV *Start, const SCEV *Step,
const Loop *L,
SCEV::NoWrapFlags Flags) {
SmallVector<const SCEV *, 4> Operands;
Operands.push_back(Start);
if (const SCEVAddRecExpr *StepChrec = dyn_cast<SCEVAddRecExpr>(Step))
if (StepChrec->getLoop() == L) {
Operands.append(StepChrec->op_begin(), StepChrec->op_end());
return getAddRecExpr(Operands, L);
// FIXME: can use maskFlags(Flags, SCEV::FlagNW)
return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap);
}
Operands.push_back(Step);
return getAddRecExpr(Operands, L, HasNUW, HasNSW);
return getAddRecExpr(Operands, L, Flags);
}
/// getAddRecExpr - Get an add recurrence expression for the specified loop.
/// Simplify the expression as much as possible.
const SCEV *
ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
const Loop *L,
bool HasNUW, bool HasNSW) {
const Loop *L, SCEV::NoWrapFlags Flags) {
if (Operands.size() == 1) return Operands[0];
#ifndef NDEBUG
const Type *ETy = getEffectiveSCEVType(Operands[0]->getType());
@ -2040,7 +2065,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
if (Operands.back()->isZero()) {
Operands.pop_back();
return getAddRecExpr(Operands, L, HasNUW, HasNSW); // {X,+,0} --> X
return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); // {X,+,0} --> X
}
// It's tempting to want to call getMaxBackedgeTakenCount count here and
@ -2049,8 +2074,8 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
// meaningful BE count at this point (and if we don't, we'd be stuck
// with a SCEVCouldNotCompute as the cached BE count).
// If HasNSW is true and all the operands are non-negative, infer HasNUW.
if (!HasNUW && HasNSW) {
// If FlagNSW is true and all the operands are non-negative, infer FlagNUW.
if (!(Flags & SCEV::FlagNUW) && (Flags & SCEV::FlagNSW)) {
bool All = true;
for (SmallVectorImpl<const SCEV *>::const_iterator I = Operands.begin(),
E = Operands.end(); I != E; ++I)
@ -2058,7 +2083,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
All = false;
break;
}
if (All) HasNUW = true;
if (All) Flags = setFlags(Flags, SCEV::FlagNUW);
}
// Canonicalize nested AddRecs in by nesting them in order of loop depth.
@ -2081,16 +2106,31 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
break;
}
if (AllInvariant) {
NestedOperands[0] = getAddRecExpr(Operands, L);
// Create a recurrence for the outer loop with the same step size.
//
// FIXME:
// The outer recurrence keeps its NW flag but only keeps NUW/NSW if the
// inner recurrence has the same property.
// maskFlags(Flags, SCEV::FlagNW | NestedAR->getNoWrapFlags());
SCEV::NoWrapFlags OuterFlags = SCEV::FlagAnyWrap;
NestedOperands[0] = getAddRecExpr(Operands, L, OuterFlags);
AllInvariant = true;
for (unsigned i = 0, e = NestedOperands.size(); i != e; ++i)
if (!isLoopInvariant(NestedOperands[i], NestedLoop)) {
AllInvariant = false;
break;
}
if (AllInvariant)
if (AllInvariant) {
// Ok, both add recurrences are valid after the transformation.
return getAddRecExpr(NestedOperands, NestedLoop, HasNUW, HasNSW);
//
// FIXME:
// The inner recurrence keeps its NW flag but only keeps NUW/NSW if
// the outer recurrence has the same property.
// maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | Flags);
SCEV::NoWrapFlags InnerFlags = SCEV::FlagAnyWrap;
return getAddRecExpr(NestedOperands, NestedLoop, InnerFlags);
}
}
// Reset Operands to its original state.
Operands[0] = NestedAR;
@ -2114,8 +2154,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
O, Operands.size(), L);
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
S->setNoWrapFlags(Flags);
return S;
}
@ -2510,17 +2549,17 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) {
return getMinusSCEV(AllOnes, V);
}
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1,
/// and thus the HasNUW and HasNSW bits apply to the resultant add, not
/// whether the sub would have overflowed.
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
///
/// FIXME: prohibit FlagNUW here, as soon as getMinusSCEVForExitTest goes.
const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
bool HasNUW, bool HasNSW) {
SCEV::NoWrapFlags Flags) {
// Fast path: X - X --> 0.
if (LHS == RHS)
return getConstant(LHS->getType(), 0);
// X - Y --> X + -Y
return getAddExpr(LHS, getNegativeSCEV(RHS), HasNUW, HasNSW);
return getAddExpr(LHS, getNegativeSCEV(RHS), Flags);
}
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the
@ -2773,44 +2812,35 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
if (isLoopInvariant(Accum, L) ||
(isa<SCEVAddRecExpr>(Accum) &&
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
bool HasNUW = false;
bool HasNSW = false;
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
// If the increment doesn't overflow, then neither the addrec nor
// the post-increment will overflow.
if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV)) {
if (OBO->hasNoUnsignedWrap())
HasNUW = true;
Flags = setFlags(Flags, SCEV::FlagNUW);
if (OBO->hasNoSignedWrap())
HasNSW = true;
Flags = setFlags(Flags, SCEV::FlagNSW);
} else if (const GEPOperator *GEP =
dyn_cast<GEPOperator>(BEValueV)) {
// If the increment is a GEP, then we know it won't perform a
// signed overflow, because the address space cannot be
// wrapped around.
//
// NOTE: This isn't strictly true, because you could have an
// object straddling the 2G address boundary in a 32-bit address
// space (for example). We really want to model this as a "has
// no signed/unsigned wrap" where the base pointer is treated as
// unsigned and the increment is known to not have signed
// wrapping.
//
// This is a highly theoretical concern though, and this is good
// enough for all cases we know of at this point. :)
//
HasNSW |= GEP->isInBounds();
dyn_cast<GEPOperator>(BEValueV)) {
// If the increment is an inbounds GEP, then we know the address
// space cannot be wrapped around. We cannot make any guarantee
// about signed or unsigned overflow because pointers are
// unsigned but we may have a negative index from the base
// pointer.
if (GEP->isInBounds())
// FIXME: should be SCEV::FlagNW
Flags = setFlags(Flags, SCEV::FlagNSW);
}
const SCEV *StartVal = getSCEV(StartValueV);
const SCEV *PHISCEV =
getAddRecExpr(StartVal, Accum, L, HasNUW, HasNSW);
const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags);
// Since the no-wrap flags are on the increment, they apply to the
// post-incremented value as well.
if (isLoopInvariant(Accum, L))
(void)getAddRecExpr(getAddExpr(StartVal, Accum),
Accum, L, HasNUW, HasNSW);
Accum, L, Flags);
// Okay, for the entire analysis of this edge we assumed the PHI
// to be symbolic. We now need to go back and purge all of the
@ -2834,8 +2864,11 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
// initial step of the addrec evolution.
if (StartVal == getMinusSCEV(AddRec->getOperand(0),
AddRec->getOperand(1))) {
// FIXME: For constant StartVal, we should be able to infer
// no-wrap flags.
const SCEV *PHISCEV =
getAddRecExpr(StartVal, AddRec->getOperand(1), L);
getAddRecExpr(StartVal, AddRec->getOperand(1), L,
SCEV::FlagAnyWrap);
// Okay, for the entire analysis of this edge we assumed the PHI
// to be symbolic. We now need to go back and purge all of the
@ -2899,8 +2932,9 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
IndexS = getTruncateOrSignExtend(IndexS, IntPtrTy);
// Multiply the index by the element size to compute the element offset.
const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize, /*NUW*/ false,
/*NSW*/ isInBounds);
const SCEV *LocalOffset = getMulExpr(IndexS, ElementSize,
isInBounds ? SCEV::FlagNSW :
SCEV::FlagAnyWrap);
// Add the element offset to the running total offset.
TotalOffset = getAddExpr(TotalOffset, LocalOffset);
@ -2911,8 +2945,8 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
const SCEV *BaseS = getSCEV(Base);
// Add the total offset from all the GEP indices to the base.
return getAddExpr(BaseS, TotalOffset, /*NUW*/ false,
/*NSW*/ isInBounds);
return getAddExpr(BaseS, TotalOffset,
isInBounds ? SCEV::FlagNSW : SCEV::FlagAnyWrap);
}
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
@ -3074,7 +3108,8 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
// If there's no unsigned wrap, the value will never be less than its
// initial value.
if (AddRec->hasNoUnsignedWrap())
// FIXME: can broaden to FlagNW?
if (AddRec->getNoWrapFlags(SCEV::FlagNUW))
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(AddRec->getStart()))
if (!C->getValue()->isZero())
ConservativeResult =
@ -3216,7 +3251,7 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
// If there's no signed wrap, and all the operands have the same sign or
// zero, the value won't ever change sign.
if (AddRec->hasNoSignedWrap()) {
if (AddRec->getNoWrapFlags(SCEV::FlagNSW)) {
bool AllNonNeg = true;
bool AllNonPos = true;
for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) {
@ -3411,10 +3446,8 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
// transfer the no-wrap flags, since an or won't introduce a wrap.
if (const SCEVAddRecExpr *NewAR = dyn_cast<SCEVAddRecExpr>(S)) {
const SCEVAddRecExpr *OldAR = cast<SCEVAddRecExpr>(LHS);
if (OldAR->hasNoUnsignedWrap())
const_cast<SCEVAddRecExpr *>(NewAR)->setHasNoUnsignedWrap(true);
if (OldAR->hasNoSignedWrap())
const_cast<SCEVAddRecExpr *>(NewAR)->setHasNoSignedWrap(true);
const_cast<SCEVAddRecExpr *>(NewAR)->setNoWrapFlags(
OldAR->getNoWrapFlags());
}
return S;
}
@ -4031,7 +4064,7 @@ isSimpleUnwrappingAddRec(const SCEV *S, const Loop *L) {
return 0;
// The SCEV must be known to not wrap in some way to be interesting.
if (!SA->hasNoUnsignedWrap() && !SA->hasNoSignedWrap())
if (!SA->getNoWrapFlags(SCEV::FlagNW))
return 0;
// The stride must be a constant so that we know if it is striding up or down.
@ -4046,14 +4079,15 @@ isSimpleUnwrappingAddRec(const SCEV *S, const Loop *L) {
/// advantage of the fact that this subtraction is only being used in a
/// comparison by zero context.
///
/// FIXME: this can be completely removed once AddRec FlagNWs are propagated.
static const SCEV *getMinusSCEVForExitTest(const SCEV *LHS, const SCEV *RHS,
const Loop *L, ScalarEvolution &SE) {
// If either LHS or RHS is an AddRec SCEV (of this loop) that is known to not
// wrap (either NSW or NUW), then we know that the value will either become
// the other one (and thus the loop terminates), that the loop will terminate
// through some other exit condition first, or that the loop has undefined
// behavior. This information is useful when the addrec has a stride that is
// != 1 or -1, because it means we can't "miss" the exit value.
// self-wrap, then we know that the value will either become the other one
// (and thus the loop terminates), that the loop will terminate through some
// other exit condition first, or that the loop has undefined behavior. This
// information is useful when the addrec has a stride that is != 1 or -1,
// because it means we can't "miss" the exit value.
//
// In any of these three cases, it is safe to turn the exit condition into a
// "counting down" AddRec (to zero) by subtracting the two inputs as normal,
@ -4090,7 +4124,7 @@ static const SCEV *getMinusSCEVForExitTest(const SCEV *LHS, const SCEV *RHS,
if (Stride->getValue().isNegative())
std::swap(LHS, RHS);
return SE.getMinusSCEV(RHS, LHS, true /*HasNUW*/);
return SE.getMinusSCEV(RHS, LHS, SCEV::FlagNUW);
}
// If both LHS and RHS are interesting, we have something like:
@ -4118,7 +4152,7 @@ static const SCEV *getMinusSCEVForExitTest(const SCEV *LHS, const SCEV *RHS,
std::swap(LHS, RHS);
}
return SE.getMinusSCEV(LHS, RHS, true /*HasNUW*/);
return SE.getMinusSCEV(LHS, RHS, SCEV::FlagNUW);
}
/// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of times the
@ -4180,6 +4214,8 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
switch (Cond) {
case ICmpInst::ICMP_NE: { // while (X != Y)
// Convert to: while (X-Y != 0)
// FIXME: Once AddRec FlagNW are propagated, should be:
// BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L);
BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEVForExitTest(LHS, RHS, L,
*this), L);
if (BTI.hasAnyInfo()) return BTI;
@ -4706,7 +4742,10 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
for (++i; i != e; ++i)
NewOps.push_back(getSCEVAtScope(AddRec->getOperand(i), L));
AddRec = cast<SCEVAddRecExpr>(getAddRecExpr(NewOps, AddRec->getLoop()));
AddRec = cast<SCEVAddRecExpr>(
getAddRecExpr(NewOps, AddRec->getLoop(),
// FIXME: AddRec->getNoWrapFlags(SCEV::FlagNW)
SCEV::FlagAnyWrap));
break;
}
@ -4871,6 +4910,11 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) {
/// HowFarToZero - Return the number of times a backedge comparing the specified
/// value to zero will execute. If not computable, return CouldNotCompute.
///
/// This is only used for loops with a "x != y" exit test. The exit condition is
/// now expressed as a single expression, V = x-y. So the exit test is
/// effectively V != 0. We know and take advantage of the fact that this
/// expression only being used in a comparison by zero context.
ScalarEvolution::BackedgeTakenInfo
ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
// If the value is a constant
@ -4939,21 +4983,34 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
// down, it cannot "miss" 0 (which would cause it to wrap), regardless of what
// the stride is. As such, NUW addrec's will always become zero in
// "start / -stride" steps, and we know that the division is exact.
if (AddRec->hasNoUnsignedWrap())
if (AddRec->getNoWrapFlags(SCEV::FlagNUW))
// FIXME: We really want an "isexact" bit for udiv.
return getUDivExpr(Start, getNegativeSCEV(Step));
// For now we handle only constant steps.
//
// TODO: Handle a nonconstant Step given AddRec<NUW>. If the
// AddRec is NUW, then (in an unsigned sense) it cannot be counting up to wrap
// to 0, it must be counting down to equal 0. Consequently, N = Start / -Step.
// We have not yet seen any such cases.
const SCEVConstant *StepC = dyn_cast<SCEVConstant>(Step);
if (StepC == 0)
return getCouldNotCompute();
// First, handle unitary steps.
// For positive steps (counting up until unsigned overflow):
// N = -Start/Step (as unsigned)
// For negative steps (counting down to zero):
// N = Start/-Step
// First compute the unsigned distance from zero in the direction of Step.
const SCEV *Distance = StepC->getValue()->getValue().isNonNegative() ?
getNegativeSCEV(Start) : Start;
// Handle unitary steps, which cannot wraparound.
if (StepC->getValue()->equalsInt(1)) // 1*N = -Start (mod 2^BW), so:
return getNegativeSCEV(Start); // N = -Start (as unsigned)
return Distance; // N = -Start (as unsigned)
if (StepC->getValue()->isAllOnesValue()) // -1*N = -Start (mod 2^BW), so:
return Start; // N = Start (as unsigned)
return Distance; // N = Start (as unsigned)
// Then, try to solve the above equation provided that Start is constant.
if (const SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start))
@ -5220,12 +5277,12 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
case ICmpInst::ICMP_SLE:
if (!getSignedRange(RHS).getSignedMax().isMaxSignedValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS,
/*HasNUW=*/false, /*HasNSW=*/true);
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SLT;
Changed = true;
} else if (!getSignedRange(LHS).getSignedMin().isMinSignedValue()) {
LHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), LHS,
/*HasNUW=*/false, /*HasNSW=*/true);
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SLT;
Changed = true;
}
@ -5233,12 +5290,12 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
case ICmpInst::ICMP_SGE:
if (!getSignedRange(RHS).getSignedMin().isMinSignedValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS,
/*HasNUW=*/false, /*HasNSW=*/true);
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SGT;
Changed = true;
} else if (!getSignedRange(LHS).getSignedMax().isMaxSignedValue()) {
LHS = getAddExpr(getConstant(RHS->getType(), 1, true), LHS,
/*HasNUW=*/false, /*HasNSW=*/true);
SCEV::FlagNSW);
Pred = ICmpInst::ICMP_SGT;
Changed = true;
}
@ -5246,12 +5303,12 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
case ICmpInst::ICMP_ULE:
if (!getUnsignedRange(RHS).getUnsignedMax().isMaxValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), 1, true), RHS,
/*HasNUW=*/true, /*HasNSW=*/false);
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_ULT;
Changed = true;
} else if (!getUnsignedRange(LHS).getUnsignedMin().isMinValue()) {
LHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), LHS,
/*HasNUW=*/true, /*HasNSW=*/false);
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_ULT;
Changed = true;
}
@ -5259,12 +5316,12 @@ bool ScalarEvolution::SimplifyICmpOperands(ICmpInst::Predicate &Pred,
case ICmpInst::ICMP_UGE:
if (!getUnsignedRange(RHS).getUnsignedMin().isMinValue()) {
RHS = getAddExpr(getConstant(RHS->getType(), (uint64_t)-1, true), RHS,
/*HasNUW=*/true, /*HasNSW=*/false);
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
} else if (!getUnsignedRange(LHS).getUnsignedMax().isMaxValue()) {
LHS = getAddExpr(getConstant(RHS->getType(), 1, true), LHS,
/*HasNUW=*/true, /*HasNSW=*/false);
SCEV::FlagNUW);
Pred = ICmpInst::ICMP_UGT;
Changed = true;
}
@ -5690,8 +5747,8 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
return getCouldNotCompute();
// Check to see if we have a flag which makes analysis easy.
bool NoWrap = isSigned ? AddRec->hasNoSignedWrap() :
AddRec->hasNoUnsignedWrap();
bool NoWrap = isSigned ? AddRec->getNoWrapFlags(SCEV::FlagNSW) :
AddRec->getNoWrapFlags(SCEV::FlagNUW);
if (AddRec->isAffine()) {
unsigned BitWidth = getTypeSizeInBits(AddRec->getType());
@ -5807,7 +5864,9 @@ const SCEV *SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range,
if (!SC->getValue()->isZero()) {
SmallVector<const SCEV *, 4> Operands(op_begin(), op_end());
Operands[0] = SE.getConstant(SC->getType(), 0);
const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop());
const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop(),
// FIXME: getNoWrapFlags(FlagNW)
FlagAnyWrap);
if (const SCEVAddRecExpr *ShiftedAddRec =
dyn_cast<SCEVAddRecExpr>(Shifted))
return ShiftedAddRec->getNumIterationsInRange(
@ -5868,7 +5927,9 @@ const SCEV *SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range,
// Range.getUpper() is crossed.
SmallVector<const SCEV *, 4> NewOps(op_begin(), op_end());
NewOps[0] = SE.getNegativeSCEV(SE.getConstant(Range.getUpper()));
const SCEV *NewAddRec = SE.getAddRecExpr(NewOps, getLoop());
const SCEV *NewAddRec = SE.getAddRecExpr(NewOps, getLoop(),
// getNoWrapFlags(FlagNW)
FlagAnyWrap);
// Next, solve the constructed addrec
std::pair<const SCEV *,const SCEV *> Roots =

View File

@ -262,7 +262,8 @@ static bool FactorOutConstant(const SCEV *&S,
const SCEV *Start = A->getStart();
if (!FactorOutConstant(Start, Remainder, Factor, SE, TD))
return false;
S = SE.getAddRecExpr(Start, Step, A->getLoop());
// FIXME: can use A->getNoWrapFlags(FlagNW)
S = SE.getAddRecExpr(Start, Step, A->getLoop(), SCEV::FlagAnyWrap);
return true;
}
@ -314,7 +315,9 @@ static void SplitAddRecs(SmallVectorImpl<const SCEV *> &Ops,
const SCEV *Zero = SE.getConstant(Ty, 0);
AddRecs.push_back(SE.getAddRecExpr(Zero,
A->getStepRecurrence(SE),
A->getLoop()));
A->getLoop(),
// FIXME: A->getNoWrapFlags(FlagNW)
SCEV::FlagAnyWrap));
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Start)) {
Ops[i] = Zero;
Ops.append(Add->op_begin(), Add->op_end());
@ -823,7 +826,9 @@ static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest,
Rest = SE.getAddExpr(Rest,
SE.getAddRecExpr(SE.getConstant(A->getType(), 0),
A->getStepRecurrence(SE),
A->getLoop()));
A->getLoop(),
// FIXME: A->getNoWrapFlags(FlagNW)
SCEV::FlagAnyWrap));
}
if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(Base)) {
Base = A->getOperand(A->getNumOperands()-1);
@ -1005,10 +1010,11 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
if (!SE.properlyDominates(Start, L->getHeader())) {
PostLoopOffset = Start;
Start = SE.getConstant(Normalized->getType(), 0);
Normalized =
cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start,
Normalized->getStepRecurrence(SE),
Normalized->getLoop()));
Normalized = cast<SCEVAddRecExpr>(
SE.getAddRecExpr(Start, Normalized->getStepRecurrence(SE),
Normalized->getLoop(),
// FIXME: Normalized->getNoWrapFlags(FlagNW)
SCEV::FlagAnyWrap));
}
// Strip off any non-loop-dominating component from the addrec step.
@ -1019,7 +1025,10 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
Step = SE.getConstant(Normalized->getType(), 1);
Normalized =
cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start, Step,
Normalized->getLoop()));
Normalized->getLoop(),
// FIXME: Normalized
// ->getNoWrapFlags(FlagNW)
SCEV::FlagAnyWrap));
}
// Expand the core addrec. If we need post-loop scaling, force it to
@ -1082,7 +1091,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
SmallVector<const SCEV *, 4> NewOps(S->getNumOperands());
for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i)
NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType());
Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop()));
Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop(),
// FIXME: S->getNoWrapFlags(FlagNW)
SCEV::FlagAnyWrap));
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
BasicBlock::iterator NewInsertPt =
@ -1099,7 +1110,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
if (!S->getStart()->isZero()) {
SmallVector<const SCEV *, 4> NewOps(S->op_begin(), S->op_end());
NewOps[0] = SE.getConstant(Ty, 0);
const SCEV *Rest = SE.getAddRecExpr(NewOps, L);
// FIXME: can use S->getNoWrapFlags()
const SCEV *Rest = SE.getAddRecExpr(NewOps, L, SCEV::FlagAnyWrap);
// Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the
// comments on expandAddToGEP for details.
@ -1334,7 +1346,7 @@ void SCEVExpander::rememberInstruction(Value *I) {
InsertedValues.insert(I);
// If we just claimed an existing instruction and that instruction had
// been the insert point, adjust the insert point forward so that
// been the insert point, adjust the insert point forward so that
// subsequently inserted code will be dominated.
if (Builder.GetInsertPoint() == I) {
BasicBlock::iterator It = cast<Instruction>(I);
@ -1362,8 +1374,9 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
assert(Ty->isIntegerTy() && "Can only insert integer induction variables!");
// Build a SCEV for {0,+,1}<L>.
// Conservatively use FlagAnyWrap for now.
const SCEV *H = SE.getAddRecExpr(SE.getConstant(Ty, 0),
SE.getConstant(Ty, 1), L);
SE.getConstant(Ty, 1), L, SCEV::FlagAnyWrap);
// Emit code for it.
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();

View File

@ -97,7 +97,8 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind,
const SCEV *N = TransformForPostIncUse(Kind, O, LUser, 0, Loops, SE, DT);
Operands.push_back(N);
}
const SCEV *Result = SE.getAddRecExpr(Operands, L);
// Conservatively use AnyWrap until/unless we need FlagNW.
const SCEV *Result = SE.getAddRecExpr(Operands, L, SCEV::FlagAnyWrap);
switch (Kind) {
default: llvm_unreachable("Unexpected transform name!");
case NormalizeAutodetect:

View File

@ -485,10 +485,10 @@ processLoopStridedStore(Value *DestPtr, unsigned StoreSize,
BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr);
const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1),
true /*no unsigned overflow*/);
SCEV::FlagNUW);
if (StoreSize != 1)
NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize),
true /*no unsigned overflow*/);
SCEV::FlagNUW);
Value *NumBytes =
Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator());
@ -581,10 +581,10 @@ processLoopStoreOfLoopLoad(StoreInst *SI, unsigned StoreSize,
BECount = SE->getTruncateOrZeroExtend(BECount, IntPtr);
const SCEV *NumBytesS = SE->getAddExpr(BECount, SE->getConstant(IntPtr, 1),
true /*no unsigned overflow*/);
SCEV::FlagNUW);
if (StoreSize != 1)
NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtr, StoreSize),
true /*no unsigned overflow*/);
SCEV::FlagNUW);
Value *NumBytes =
Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator());

View File

@ -253,7 +253,8 @@ static void DoInitialMatch(const SCEV *S, Loop *L,
DoInitialMatch(AR->getStart(), L, Good, Bad, SE);
DoInitialMatch(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0),
AR->getStepRecurrence(SE),
AR->getLoop()),
// FIXME: AR->getNoWrapFlags()
AR->getLoop(), SCEV::FlagAnyWrap),
L, Good, Bad, SE);
return;
}
@ -455,7 +456,10 @@ static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS,
const SCEV *Start = getExactSDiv(AR->getStart(), RHS, SE,
IgnoreSignificantBits);
if (!Start) return 0;
return SE.getAddRecExpr(Start, Step, AR->getLoop());
// FlagNW is independent of the start value, step direction, and is
// preserved with smaller magnitude steps.
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
return SE.getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagAnyWrap);
}
return 0;
}
@ -520,7 +524,9 @@ static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE) {
SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
int64_t Result = ExtractImmediate(NewOps.front(), SE);
if (Result != 0)
S = SE.getAddRecExpr(NewOps, AR->getLoop());
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
SCEV::FlagAnyWrap);
return Result;
}
return 0;
@ -545,7 +551,9 @@ static GlobalValue *ExtractSymbol(const SCEV *&S, ScalarEvolution &SE) {
SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
GlobalValue *Result = ExtractSymbol(NewOps.front(), SE);
if (Result)
S = SE.getAddRecExpr(NewOps, AR->getLoop());
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
SCEV::FlagAnyWrap);
return Result;
}
return 0;
@ -2236,7 +2244,9 @@ static void CollectSubexprs(const SCEV *S, const SCEVConstant *C,
if (!AR->getStart()->isZero()) {
CollectSubexprs(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0),
AR->getStepRecurrence(SE),
AR->getLoop()),
AR->getLoop(),
//FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
SCEV::FlagAnyWrap),
C, Ops, L, SE);
CollectSubexprs(AR->getStart(), C, Ops, L, SE);
return;
@ -3047,7 +3057,7 @@ void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
}
}
/// NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters - Call
/// NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters - Call
/// FilterOutUndesirableDedicatedRegisters again, if necessary, now that
/// we've done more filtering, as it may be able to find more formulae to
/// eliminate.