aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp15
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());