diff options
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 6b2e88d..6139b5b 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -828,7 +828,7 @@ Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1, /// that they aren't implicitly casted by the getelementptr. Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops, Type *ResultTy, bool InBounds, - std::optional<unsigned> InRangeIndex, + std::optional<ConstantRange> InRange, const DataLayout &DL, const TargetLibraryInfo *TLI) { Type *IntIdxTy = DL.getIndexType(ResultTy); Type *IntIdxScalarTy = IntIdxTy->getScalarType(); @@ -856,8 +856,8 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops, if (!Any) return nullptr; - Constant *C = ConstantExpr::getGetElementPtr( - SrcElemTy, Ops[0], NewIdxs, InBounds, InRangeIndex); + Constant *C = ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs, + InBounds, InRange); return ConstantFoldConstant(C, DL, TLI); } @@ -866,7 +866,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, ArrayRef<Constant *> Ops, const DataLayout &DL, const TargetLibraryInfo *TLI) { - const GEPOperator *InnermostGEP = GEP; bool InBounds = GEP->isInBounds(); Type *SrcElemTy = GEP->getSourceElementType(); @@ -875,9 +874,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy)) return nullptr; - if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, - GEP->isInBounds(), GEP->getInRangeIndex(), - DL, TLI)) + if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, GEP->isInBounds(), + GEP->getInRange(), DL, TLI)) return C; Constant *Ptr = Ops[0]; @@ -896,9 +894,12 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, DL.getIndexedOffsetInType( SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1))); + std::optional<ConstantRange> InRange = GEP->getInRange(); + if (InRange) + InRange = InRange->sextOrTrunc(BitWidth); + // If this is a GEP of a GEP, fold it all into a single GEP. while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) { - InnermostGEP = GEP; InBounds &= GEP->isInBounds(); SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands())); @@ -913,6 +914,14 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, if (!AllConstantInt) break; + // TODO: Try to intersect two inrange attributes? + if (!InRange) { + InRange = GEP->getInRange(); + if (InRange) + // Adjust inrange by offset until now. + InRange = InRange->sextOrTrunc(BitWidth).subtract(Offset); + } + Ptr = cast<Constant>(GEP->getOperand(0)); SrcElemTy = GEP->getSourceElementType(); Offset += APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps)); @@ -971,21 +980,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, NewIdxs.push_back(ConstantInt::get( Type::getIntNTy(Ptr->getContext(), Index.getBitWidth()), Index)); - // Preserve the inrange index from the innermost GEP if possible. We must - // have calculated the same indices up to and including the inrange index. - std::optional<unsigned> InRangeIndex; - if (std::optional<unsigned> LastIRIndex = InnermostGEP->getInRangeIndex()) - if (SrcElemTy == InnermostGEP->getSourceElementType() && - NewIdxs.size() > *LastIRIndex) { - InRangeIndex = LastIRIndex; - for (unsigned I = 0; I <= *LastIRIndex; ++I) - if (NewIdxs[I] != InnermostGEP->getOperand(I + 1)) - return nullptr; - } - - // Create a GEP. return ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs, InBounds, - InRangeIndex); + InRange); } /// Attempt to constant fold an instruction with the @@ -1033,8 +1029,7 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode, return C; return ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], Ops.slice(1), - GEP->isInBounds(), - GEP->getInRangeIndex()); + GEP->isInBounds(), GEP->getInRange()); } if (auto *CE = dyn_cast<ConstantExpr>(InstOrCE)) { |