diff options
author | Nikita Popov <npopov@redhat.com> | 2022-04-04 12:59:17 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-04-04 13:04:27 +0200 |
commit | 3c9f3f76f105196cd354a34f597b1ce88bee9b5d (patch) | |
tree | 94437ad5b5821083a91e8534a6c204ccfa16bbec /llvm/lib/IR/ConstantFold.cpp | |
parent | d092df42f342be733678a7798454557f92fe27f1 (diff) | |
download | llvm-3c9f3f76f105196cd354a34f597b1ce88bee9b5d.zip llvm-3c9f3f76f105196cd354a34f597b1ce88bee9b5d.tar.gz llvm-3c9f3f76f105196cd354a34f597b1ce88bee9b5d.tar.bz2 |
[ConstantFold] Fold zero-index GEPs with opaque pointers
With opaque pointers, we can eliminate zero-index GEPs even if
they have multiple indices, as this no longer impacts the result
type of the GEP.
This optimization is already done for instructions in InstSimplify,
but we were missing the corresponding constant expression handling.
The constexpr transform is a bit more powerful, because it can
produce a vector splat constant and also handles undef values --
it is an extension of an existing single-index transform.
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 74200b9..e38cd82 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -2036,8 +2036,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, // If inbounds, we can choose an out-of-bounds pointer as a base pointer. return InBounds ? PoisonValue::get(GEPTy) : UndefValue::get(GEPTy); - Constant *Idx0 = cast<Constant>(Idxs[0]); - if (Idxs.size() == 1 && (Idx0->isNullValue() || isa<UndefValue>(Idx0))) + auto IsNoOp = [&]() { + // For non-opaque pointers having multiple indices will change the result + // type of the GEP. + if (!C->getType()->getScalarType()->isOpaquePointerTy() && Idxs.size() != 1) + return false; + + return all_of(Idxs, [](Value *Idx) { + Constant *IdxC = cast<Constant>(Idx); + return IdxC->isNullValue() || isa<UndefValue>(IdxC); + }); + }; + if (IsNoOp()) return GEPTy->isVectorTy() && !C->getType()->isVectorTy() ? ConstantVector::getSplat( cast<VectorType>(GEPTy)->getElementCount(), C) @@ -2090,6 +2100,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C, // i32* getelementptr ([3 x i32]* %X, i64 0, i64 0) // // Don't fold if the cast is changing address spaces. + Constant *Idx0 = cast<Constant>(Idxs[0]); if (CE->isCast() && Idxs.size() > 1 && Idx0->isNullValue()) { PointerType *SrcPtrTy = dyn_cast<PointerType>(CE->getOperand(0)->getType()); |