aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-05-20 11:47:30 +0200
committerGitHub <noreply@github.com>2024-05-20 11:47:30 +0200
commit8e8d2595dafa230a3da7f410200d89f05b6e8d87 (patch)
tree7190e112d098889a149a777daf7c33c4aa977a19 /llvm/lib/Analysis/ConstantFolding.cpp
parent2217d1706a76d3f298899f824354ca9d96c45813 (diff)
downloadllvm-8e8d2595dafa230a3da7f410200d89f05b6e8d87.zip
llvm-8e8d2595dafa230a3da7f410200d89f05b6e8d87.tar.gz
llvm-8e8d2595dafa230a3da7f410200d89f05b6e8d87.tar.bz2
[ConstantFolding] Canonicalize constexpr GEPs to i8 (#89872)
This patch canonicalizes constant expression GEPs to use i8 source element type, aka ptradd. This is the ConstantFolding equivalent of the InstCombine canonicalization introduced in #68882. I believe all our optimizations working on constant expression GEPs (like GlobalOpt etc) have already been switched to work on offsets, so I don't expect any significant fallout from this change. This is part of: https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp46
1 files changed, 10 insertions, 36 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 524e84f..31667ff 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -869,7 +869,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
bool InBounds = GEP->isInBounds();
Type *SrcElemTy = GEP->getSourceElementType();
- Type *ResElemTy = GEP->getResultElementType();
Type *ResTy = GEP->getType();
if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))
return nullptr;
@@ -944,43 +943,18 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
return ConstantExpr::getIntToPtr(C, ResTy);
}
- // Otherwise form a regular getelementptr. Recompute the indices so that
- // we eliminate over-indexing of the notional static type array bounds.
- // This makes it easy to determine if the getelementptr is "inbounds".
-
- // For GEPs of GlobalValues, use the value type, otherwise use an i8 GEP.
- if (auto *GV = dyn_cast<GlobalValue>(Ptr))
- SrcElemTy = GV->getValueType();
- else
- SrcElemTy = Type::getInt8Ty(Ptr->getContext());
-
- if (!SrcElemTy->isSized())
- return nullptr;
-
- Type *ElemTy = SrcElemTy;
- SmallVector<APInt> Indices = DL.getGEPIndicesForOffset(ElemTy, Offset);
- if (Offset != 0)
- return nullptr;
-
- // Try to add additional zero indices to reach the desired result element
- // type.
- // TODO: Should we avoid extra zero indices if ResElemTy can't be reached and
- // we'll have to insert a bitcast anyway?
- while (ElemTy != ResElemTy) {
- Type *NextTy = GetElementPtrInst::getTypeAtIndex(ElemTy, (uint64_t)0);
- if (!NextTy)
- break;
-
- Indices.push_back(APInt::getZero(isa<StructType>(ElemTy) ? 32 : BitWidth));
- ElemTy = NextTy;
+ // Try to infer inbounds for GEPs of globals.
+ if (!InBounds && Offset.isNonNegative()) {
+ bool CanBeNull, CanBeFreed;
+ uint64_t DerefBytes =
+ Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
+ InBounds = DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes);
}
- SmallVector<Constant *, 32> NewIdxs;
- for (const APInt &Index : Indices)
- NewIdxs.push_back(ConstantInt::get(
- Type::getIntNTy(Ptr->getContext(), Index.getBitWidth()), Index));
-
- return ConstantExpr::getGetElementPtr(SrcElemTy, Ptr, NewIdxs, InBounds,
+ // Otherwise canonicalize this to a single ptradd.
+ LLVMContext &Ctx = Ptr->getContext();
+ return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,
+ ConstantInt::get(Ctx, Offset), InBounds,
InRange);
}