}
template<typename IndexTy>
-static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
+static Constant *ConstantFoldGetElementPtrImpl(Type *PointeeTy, Constant *C,
bool inBounds,
ArrayRef<IndexTy> Idxs) {
if (Idxs.empty()) return C;
// factored out into preceding dimensions.
bool Unknown = false;
SmallVector<Constant *, 8> NewIdxs;
- Type *Ty = C->getType();
- Type *Prev = nullptr;
- for (unsigned i = 0, e = Idxs.size(); i != e;
+ Type *Ty = PointeeTy;
+ Type *Prev = C->getType();
+ for (unsigned i = 1, e = Idxs.size(); i != e;
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
if (isa<ArrayType>(Ty) || isa<VectorType>(Ty))
if (!Unknown && !inBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs))
- return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idxs);
+ return ConstantExpr::getInBoundsGetElementPtr(PointeeTy, C, Idxs);
return nullptr;
}
Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
bool inBounds,
ArrayRef<Constant *> Idxs) {
- return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs);
+ return ConstantFoldGetElementPtrImpl(
+ cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
+ inBounds, Idxs);
}
Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
bool inBounds,
ArrayRef<Value *> Idxs) {
- return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs);
+ return ConstantFoldGetElementPtrImpl(
+ cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
+ inBounds, Idxs);
+}
+
+Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C,
+ bool inBounds,
+ ArrayRef<Constant *> Idxs) {
+ return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs);
+}
+
+Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C,
+ bool inBounds,
+ ArrayRef<Value *> Idxs) {
+ return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs);
}
ArrayRef<Constant *> Idxs);
Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds,
ArrayRef<Value *> Idxs);
+ Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool inBounds,
+ ArrayRef<Constant *> Idxs);
+ Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool inBounds,
+ ArrayRef<Value *> Idxs);
} // End llvm namespace
#endif
Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> Idxs, bool InBounds,
Type *OnlyIfReducedTy) {
- if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs))
- return FC; // Fold a few common cases.
-
if (!Ty)
Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType();
else
- assert(Ty ==
- cast<PointerType>(C->getType()->getScalarType())->getElementType());
+ assert(
+ Ty ==
+ cast<PointerType>(C->getType()->getScalarType())->getContainedType(0u));
+
+ if (Constant *FC = ConstantFoldGetElementPtr(Ty, C, InBounds, Idxs))
+ return FC; // Fold a few common cases.
+
// Get the result type of the getelementptr!
Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
assert(DestTy && "GEP indices invalid!");
if (Val >= NewGlobals.size()) Val = 0; // Out of bound array access.
Value *NewPtr = NewGlobals[Val];
- Type *NewTy = NewGlobals[Val]->getType();
+ Type *NewTy = NewGlobals[Val]->getValueType();
// Form a shorter GEP if needed.
if (GEP->getNumOperands() > 3) {
Idxs.push_back(CE->getOperand(i));
NewPtr =
ConstantExpr::getGetElementPtr(NewTy, cast<Constant>(NewPtr), Idxs);
- NewTy = GetElementPtrInst::getIndexedType(NewTy, Idxs);
} else {
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP);
SmallVector<Value*, 8> Idxs;
for (unsigned i = 3, e = GEPI->getNumOperands(); i != e; ++i)
Idxs.push_back(GEPI->getOperand(i));
NewPtr = GetElementPtrInst::Create(
- NewPtr->getType()->getPointerElementType(), NewPtr, Idxs,
- GEPI->getName() + "." + Twine(Val), GEPI);
+ NewTy, NewPtr, Idxs, GEPI->getName() + "." + Twine(Val), GEPI);
}
}
GEP->replaceAllUsesWith(NewPtr);