diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 2 |
3 files changed, 13 insertions, 5 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 7a0a4e1e..783c32e 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -681,6 +681,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, // This makes it easy to determine if the getelementptr is "inbounds". // Also, this helps GlobalOpt do SROA on GlobalVariables. Type *Ty = Ptr->getType(); + assert(Ty->isPointerTy() && "Forming regular GEP of non-pointer type"); SmallVector<Constant*, 32> NewIdxs; do { if (SequentialType *ATy = dyn_cast<SequentialType>(Ty)) { @@ -711,10 +712,17 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops, } Ty = ATy->getElementType(); } else if (StructType *STy = dyn_cast<StructType>(Ty)) { - // Determine which field of the struct the offset points into. The - // getZExtValue is at least as safe as the StructLayout API because we - // know the offset is within the struct at this point. + // If we end up with an offset that isn't valid for this struct type, we + // can't re-form this GEP in a regular form, so bail out. The pointer + // operand likely went through casts that are necessary to make the GEP + // sensible. const StructLayout &SL = *TD->getStructLayout(STy); + if (Offset.uge(SL.getSizeInBytes())) + break; + + // Determine which field of the struct the offset points into. The + // getZExtValue is fine as we've already ensured that the offset is + // within the range representable by the StructLayout API. unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue()); NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()), ElIdx)); diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 1d55642..205227c 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -3187,7 +3187,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { // Add the total offset from all the GEP indices to the base. return getAddExpr(BaseS, TotalOffset, - isInBounds ? SCEV::FlagNUW : SCEV::FlagAnyWrap); + isInBounds ? SCEV::FlagNSW : SCEV::FlagAnyWrap); } /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index a430f62..1418e01 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -564,7 +564,7 @@ void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne, Depth+1); // If it's known zero, our sign bit is also zero. if (LHSKnownZero.isNegative()) - KnownZero |= LHSKnownZero; + KnownZero.setBit(BitWidth - 1); } break; |