aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp43
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)) {