diff options
author | Dan Gohman <gohman@apple.com> | 2009-12-18 02:09:29 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-12-18 02:09:29 +0000 |
commit | d281ed2d03654b9cdb290a2d7c73dfe7b826e554 (patch) | |
tree | 8be22c3822bd10a9d53c89607be45bf060f4b864 /lib/Analysis/ScalarEvolution.cpp | |
parent | c7928f8f4eb5d15b70337fd8a6527fd6c4ed7893 (diff) |
Preserve NSW information in more places.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91656 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index babfc858dd..551c25f07c 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -1460,7 +1460,9 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops, AddRec->op_end()); AddRecOps[0] = getAddExpr(LIOps); - const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRec->getLoop()); + const SCEV *NewRec = getAddRecExpr(AddRecOps, AddRec->getLoop(), + AddRec->hasNoUnsignedWrap() && HasNUW, + AddRec->hasNoSignedWrap() && HasNSW); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -1636,7 +1638,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, } } - const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop()); + const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop(), + AddRec->hasNoUnsignedWrap() && HasNUW, + AddRec->hasNoSignedWrap() && HasNSW); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -2592,8 +2596,9 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) { /// createNodeForGEP - Expand GEP instructions into add and multiply /// operations. This allows them to be analyzed by regular SCEV code. /// -const SCEV *ScalarEvolution::createNodeForGEP(Operator *GEP) { +const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { + bool InBounds = GEP->isInBounds(); const Type *IntPtrTy = getEffectiveSCEVType(GEP->getType()); Value *Base = GEP->getOperand(0); // Don't attempt to analyze GEPs over unsized objects. @@ -2610,18 +2615,24 @@ const SCEV *ScalarEvolution::createNodeForGEP(Operator *GEP) { // For a struct, add the member offset. unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue(); TotalOffset = getAddExpr(TotalOffset, - getFieldOffsetExpr(STy, FieldNo)); + getFieldOffsetExpr(STy, FieldNo), + /*HasNUW=*/false, /*HasNSW=*/InBounds); } else { // For an array, add the element offset, explicitly scaled. const SCEV *LocalOffset = getSCEV(Index); if (!isa<PointerType>(LocalOffset->getType())) // Getelementptr indicies are signed. LocalOffset = getTruncateOrSignExtend(LocalOffset, IntPtrTy); - LocalOffset = getMulExpr(LocalOffset, getAllocSizeExpr(*GTI)); - TotalOffset = getAddExpr(TotalOffset, LocalOffset); + // Lower "inbounds" GEPs to NSW arithmetic. + bool HasNSW = GEP->isInBounds(); + LocalOffset = getMulExpr(LocalOffset, getAllocSizeExpr(*GTI), + /*HasNUW=*/false, /*HasNSW=*/InBounds); + TotalOffset = getAddExpr(TotalOffset, LocalOffset, + /*HasNUW=*/false, /*HasNSW=*/InBounds); } } - return getAddExpr(getSCEV(Base), TotalOffset); + return getAddExpr(getSCEV(Base), TotalOffset, + /*HasNUW=*/false, /*HasNSW=*/InBounds); } /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is @@ -3130,7 +3141,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { // expressions we handle are GEPs and address literals. case Instruction::GetElementPtr: - return createNodeForGEP(U); + return createNodeForGEP(cast<GEPOperator>(U)); case Instruction::PHI: return createNodeForPHI(cast<PHINode>(U)); |