diff options
author | Nikita Popov <npopov@redhat.com> | 2024-05-20 11:47:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-20 11:47:30 +0200 |
commit | 8e8d2595dafa230a3da7f410200d89f05b6e8d87 (patch) | |
tree | 7190e112d098889a149a777daf7c33c4aa977a19 /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | 2217d1706a76d3f298899f824354ca9d96c45813 (diff) | |
download | llvm-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.cpp | 46 |
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); } |