}
Type *getSourceElementType() const;
+ Type *getResultElementType() const;
/// Method to return the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
}
// Don't attempt to analyze GEPs over unsized objects.
- if (!GEPOp->getOperand(0)->getType()->getPointerElementType()->isSized())
+ if (!GEPOp->getSourceElementType()->isSized())
return V;
unsigned AS = GEPOp->getPointerAddressSpace();
/// operations. This allows them to be analyzed by regular SCEV code.
///
const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
- Value *Base = GEP->getOperand(0);
// Don't attempt to analyze GEPs over unsized objects.
- if (!Base->getType()->getPointerElementType()->isSized())
+ if (!GEP->getSourceElementType()->isSized())
return getUnknown(GEP);
SmallVector<const SCEV *, 4> IndexExprs;
for (auto Index = GEP->idx_begin(); Index != GEP->idx_end(); ++Index)
IndexExprs.push_back(getSCEV(*Index));
- return getGEPExpr(GEP->getSourceElementType(), getSCEV(Base), IndexExprs,
- GEP->isInBounds());
+ return getGEPExpr(GEP->getSourceElementType(),
+ getSCEV(GEP->getPointerOperand()),
+ IndexExprs, GEP->isInBounds());
}
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
return false;
// Make sure the index-ee is a pointer to array of i8.
- PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
- ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
+ ArrayType *AT = dyn_cast<ArrayType>(GEP->getSourceElementType());
if (!AT || !AT->getElementType()->isIntegerTy(8))
return false;
// For GEPs, determine if the indexing lands within the allocated object.
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
- Type *VTy = GEP->getType();
- Type *Ty = VTy->getPointerElementType();
+ Type *Ty = GEP->getResultElementType();
const Value *Base = GEP->getPointerOperand();
// Conservatively require that the base pointer be fully dereferenceable
Visited))
return false;
- APInt Offset(DL.getPointerTypeSizeInBits(VTy), 0);
+ APInt Offset(DL.getPointerTypeSizeInBits(GEP->getType()), 0);
if (!GEP->accumulateConstantOffset(DL, Offset))
return false;
// Check if the load is within the bounds of the underlying object
// and offset is aligned.
uint64_t LoadSize = DL.getTypeStoreSize(Ty);
- Type *BaseType = Base->getType()->getPointerElementType();
+ Type *BaseType = GEP->getSourceElementType();
assert(isPowerOf2_32(Align) && "must be a power of 2!");
return (Offset + LoadSize).ule(DL.getTypeAllocSize(BaseType)) &&
!(Offset & APInt(Offset.getBitWidth(), Align-1));
unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) {
const DataLayout &DL = Gep->getModule()->getDataLayout();
unsigned LastOperand = Gep->getNumOperands() - 1;
- unsigned GEPAllocSize = DL.getTypeAllocSize(
- cast<PointerType>(Gep->getType()->getScalarType())->getElementType());
+ unsigned GEPAllocSize = DL.getTypeAllocSize(Gep->getResultElementType());
// Walk backwards and try to peel off zeros.
while (LastOperand > 1 && match(Gep->getOperand(LastOperand), m_Zero())) {
}
Ty = StTy->getElementType(Field);
} else {
- Ty = cast<SequentialType>(Ty)->getElementType();
+ if (Ty->isPointerTy()) {
+ // The only pointer type is for the very first index,
+ // therefore the next type is the source element type.
+ Ty = cast<GEPOperator>(I)->getSourceElementType();
+ } else {
+ Ty = cast<SequentialType>(Ty)->getElementType();
+ }
// If this is a constant subscript, handle it quickly.
if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
Ty = StTy->getElementType(Field);
} else {
- Ty = cast<SequentialType>(Ty)->getElementType();
+ if (Ty->isPointerTy()) {
+ // The only pointer type is for the very first index,
+ // therefore the next type is the source element type.
+ Ty = cast<GEPOperator>(&I)->getSourceElementType();
+ } else {
+ Ty = cast<SequentialType>(Ty)->getElementType();
+ }
+
MVT PtrTy =
DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout(), AS);
unsigned PtrSize = PtrTy.getSizeInBits();
if (isa<UndefValue>(C)) {
PointerType *PtrTy = cast<PointerType>(C->getType()->getScalarType());
- Type *Ty = GetElementPtrInst::getIndexedType(PtrTy->getElementType(), Idxs);
+ Type *Ty = GetElementPtrInst::getIndexedType(PointeeTy, Idxs);
assert(Ty && "Invalid indices for GEP!");
Type *GEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
if (VectorType *VT = dyn_cast<VectorType>(C->getType()))
}
if (isNull) {
PointerType *PtrTy = cast<PointerType>(C->getType()->getScalarType());
- Type *Ty =
- GetElementPtrInst::getIndexedType(PtrTy->getElementType(), Idxs);
+ Type *Ty = GetElementPtrInst::getIndexedType(PointeeTy, Idxs);
+
assert(Ty && "Invalid indices for GEP!");
Type *GEPTy = PointerType::get(Ty, PtrTy->getAddressSpace());
if (VectorType *VT = dyn_cast<VectorType>(C->getType()))
return nullptr;
}
-Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
- bool inBounds,
- ArrayRef<Constant *> Idxs) {
- return ConstantFoldGetElementPtrImpl(
- cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
- inBounds, Idxs);
-}
-
-Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
- bool inBounds,
- ArrayRef<Value *> Idxs) {
- return ConstantFoldGetElementPtrImpl(
- cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
- inBounds, Idxs);
-}
-
Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C,
bool inBounds,
ArrayRef<Constant *> Idxs) {
Constant *V2);
Constant *ConstantFoldCompareInstruction(unsigned short predicate,
Constant *C1, Constant *C2);
- Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds,
- 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,
OperandTraits<GetElementPtrConstantExpr>::op_end(this) -
(IdxList.size() + 1),
IdxList.size() + 1),
- SrcElementTy(SrcElementTy) {
+ SrcElementTy(SrcElementTy),
+ ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)) {
Op<0>() = C;
Use *OperandList = getOperandList();
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
return SrcElementTy;
}
+Type *GetElementPtrConstantExpr::getResultElementType() const {
+ return ResElementTy;
+}
+
//===----------------------------------------------------------------------===//
// ConstantData* implementations
/// used behind the scenes to implement getelementpr constant exprs.
class GetElementPtrConstantExpr : public ConstantExpr {
Type *SrcElementTy;
+ Type *ResElementTy;
void anchor() override;
GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
ArrayRef<Constant *> IdxList, Type *DestTy);
public:
- static GetElementPtrConstantExpr *Create(Constant *C,
- ArrayRef<Constant*> IdxList,
- Type *DestTy,
- unsigned Flags) {
- return Create(
- cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
- IdxList, DestTy, Flags);
- }
static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
ArrayRef<Constant *> IdxList,
Type *DestTy, unsigned Flags) {
return Result;
}
Type *getSourceElementType() const;
+ Type *getResultElementType() const;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
return cast<GetElementPtrConstantExpr>(this)->getSourceElementType();
}
+Type *GEPOperator::getResultElementType() const {
+ if (auto *I = dyn_cast<GetElementPtrInst>(this))
+ return I->getResultElementType();
+ return cast<GetElementPtrConstantExpr>(this)->getResultElementType();
+}
+
bool GEPOperator::accumulateConstantOffset(const DataLayout &DL,
APInt &Offset) const {
assert(Offset.getBitWidth() ==
TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
Ty = StTy->getElementType(Field);
} else {
- Ty = cast<SequentialType>(Ty)->getElementType();
+ if (Ty->isPointerTy()) {
+ // The only pointer type is for the very first index,
+ // therefore the next type is the source element type.
+ Ty = cast<GEPOperator>(I)->getSourceElementType();
+ } else {
+ Ty = cast<SequentialType>(Ty)->getElementType();
+ }
// If this is a constant subscript, handle it quickly.
if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
if (CI->isZero())
// we already know what the result of any load from that GEP is.
// TODO: Handle splats.
if (Init && isa<ConstantAggregateZero>(Init) && GEP->isInBounds())
- SubInit = Constant::getNullValue(GEP->getType()->getElementType());
+ SubInit = Constant::getNullValue(GEP->getResultElementType());
}
Changed |= CleanupConstantGlobalUsers(GEP, SubInit, DL, TLI);
return false;
SmallVector<Value *, 4> Ops(GEPI->idx_begin(), GEPI->idx_begin() + Idx);
- Type *AllocTy = GetElementPtrInst::getIndexedType(
- cast<PointerType>(GEPI->getOperand(0)->getType()->getScalarType())
- ->getElementType(),
- Ops);
+ Type *AllocTy =
+ GetElementPtrInst::getIndexedType(GEPI->getSourceElementType(), Ops);
if (!AllocTy || !AllocTy->isSized())
return false;
const DataLayout &DL = IC.getDataLayout();
for (User::op_iterator I = GEP.op_begin() + 1, E = GEP.op_end(); I != E;
++I, ++GTI) {
// Skip indices into struct types.
- SequentialType *SeqTy = dyn_cast<SequentialType>(*GTI);
- if (!SeqTy)
+ if (isa<StructType>(*GTI))
continue;
// Index type should have the same width as IntPtr
Type *IndexTy = (*I)->getType();
Type *NewIndexType = IndexTy->isVectorTy() ?
VectorType::get(IntPtrTy, IndexTy->getVectorNumElements()) : IntPtrTy;
-
+
// If the element type has zero size then any index over it is equivalent
// to an index of zero, so replace it with zero if it is not zero already.
- if (SeqTy->getElementType()->isSized() &&
- DL.getTypeAllocSize(SeqTy->getElementType()) == 0)
+ Type *EltTy = GTI.getIndexedType();
+ if (EltTy->isSized() && DL.getTypeAllocSize(EltTy) == 0)
if (!isa<Constant>(*I) || !cast<Constant>(*I)->isNullValue()) {
*I = Constant::getNullValue(NewIndexType);
MadeChange = true;
return nullptr;
// Keep track of the type as we walk the GEP.
- Type *CurTy = Op1->getOperand(0)->getType()->getScalarType();
+ Type *CurTy = nullptr;
for (unsigned J = 0, F = Op1->getNumOperands(); J != F; ++J) {
if (Op1->getOperand(J)->getType() != Op2->getOperand(J)->getType())
// Sink down a layer of the type for the next iteration.
if (J > 0) {
- if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ if (J == 1) {
+ CurTy = Op1->getSourceElementType();
+ } else if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
CurTy = CT->getTypeAtIndex(Op1->getOperand(J));
} else {
CurTy = nullptr;
unsigned AS = GEP.getPointerAddressSpace();
if (GEP.getOperand(1)->getType()->getScalarSizeInBits() ==
DL.getPointerSizeInBits(AS)) {
- Type *PtrTy = GEP.getPointerOperandType();
- Type *Ty = PtrTy->getPointerElementType();
+ Type *Ty = GEP.getSourceElementType();
uint64_t TyAllocSize = DL.getTypeAllocSize(Ty);
bool Matched = false;
//
// This occurs when the program declares an array extern like "int X[];"
if (HasZeroPointerIndex) {
- PointerType *CPTy = cast<PointerType>(PtrOp->getType());
if (ArrayType *CATy =
- dyn_cast<ArrayType>(CPTy->getElementType())) {
+ dyn_cast<ArrayType>(GEP.getSourceElementType())) {
// GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
// -> GEP i8* X, ...
// %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
// into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
Type *SrcElTy = StrippedPtrTy->getElementType();
- Type *ResElTy = PtrOp->getType()->getPointerElementType();
+ Type *ResElTy = GEP.getSourceElementType();
if (SrcElTy->isArrayTy() &&
DL.getTypeAllocSize(SrcElTy->getArrayElementType()) ==
DL.getTypeAllocSize(ResElTy)) {
}
unsigned AddrSpace = GEP->getPointerAddressSpace();
- return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV,
+ return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV,
BaseOffset, HasBaseReg, Scale, AddrSpace);
}
// NewGEP = (char *)Candidate + RHS * sizeof(IndexedType)
uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType);
- Type *ElementType = GEP->getType()->getElementType();
+ Type *ElementType = GEP->getResultElementType();
uint64_t ElementSize = DL->getTypeAllocSize(ElementType);
// Another less rare case: because I is not necessarily the last index of the
// GEP, the size of the type at the I-th index (IndexedSize) is not
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Instr)) {
// Cost of the address calculation
- Type *ValTy = GEP->getPointerOperandType()->getPointerElementType();
+ Type *ValTy = GEP->getSourceElementType();
Cost += TTI.getAddressComputationCost(ValTy);
// And cost of the GEP itself
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(UI)) {
// If this is a GEP with a variable indices, we can't handle it.
- PointerType* PtrTy = dyn_cast<PointerType>(GEP->getPointerOperandType());
- if (!PtrTy)
- return false;
-
// Compute the offset that this GEP adds to the pointer.
SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end());
Value *GEPNonConstantIdx = nullptr;
if (!GEP->hasAllConstantIndices()) {
- if (!isa<VectorType>(PtrTy->getElementType()))
+ if (!isa<VectorType>(GEP->getSourceElementType()))
return false;
if (NonConstantIdx)
return false;
HadDynamicAccess = true;
} else
GEPNonConstantIdx = NonConstantIdx;
- uint64_t GEPOffset = DL.getIndexedOffset(PtrTy,
+ uint64_t GEPOffset = DL.getIndexedOffset(GEP->getPointerOperandType(),
Indices);
// See if all uses can be converted.
if (!CanConvertToScalar(GEP, Offset+GEPOffset, GEPNonConstantIdx))
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
*GEP->getParent()->getParent());
unsigned AddrSpace = GEP->getPointerAddressSpace();
- if (!TTI.isLegalAddressingMode(GEP->getType()->getElementType(),
+ if (!TTI.isLegalAddressingMode(GEP->getResultElementType(),
/*BaseGV=*/nullptr, AccumulativeByteOffset,
/*HasBaseReg=*/true, /*Scale=*/0,
AddrSpace)) {
// unsigned.. Therefore, we cast ElementTypeSizeOfGEP to signed because it is
// used with unsigned integers later.
int64_t ElementTypeSizeOfGEP = static_cast<int64_t>(
- DL->getTypeAllocSize(GEP->getType()->getElementType()));
+ DL->getTypeAllocSize(GEP->getResultElementType()));
Type *IntPtrTy = DL->getIntPtrType(GEP->getType());
if (AccumulativeByteOffset % ElementTypeSizeOfGEP == 0) {
// Very likely. As long as %gep is natually aligned, the byte offset we
}
unsigned AddrSpace = GEP->getPointerAddressSpace();
- return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV,
+ return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV,
BaseOffset, HasBaseReg, Scale, AddrSpace);
}
if (Basis.CandidateKind == Candidate::GEP) {
APInt ElementSize(
IndexOffset.getBitWidth(),
- DL->getTypeAllocSize(
- cast<GetElementPtrInst>(Basis.Ins)->getType()->getElementType()));
+ DL->getTypeAllocSize(cast<GetElementPtrInst>(Basis.Ins)->getResultElementType()));
APInt Q, R;
APInt::sdivrem(IndexOffset, ElementSize, Q, R);
if (R.getSExtValue() == 0)