Index: include/llvm/Analysis/ConstantFolding.h =================================================================== --- include/llvm/Analysis/ConstantFolding.h +++ include/llvm/Analysis/ConstantFolding.h @@ -28,6 +28,7 @@ class TargetLibraryInfo; class Function; class Type; + class Value; template class ArrayRef; @@ -46,6 +47,12 @@ ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr); + Constant *ConstantFoldInstOperands(const Value *InstOrCE, + unsigned Opcode, Type *DestTy, + ArrayRef Ops, + const DataLayout &DL, + const TargetLibraryInfo *TLI = nullptr); + /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the /// specified operands. If successful, the constant result is returned, if not, /// null is returned. Note that this function can fail when attempting to @@ -86,7 +93,7 @@ /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would /// produce if it is constant and determinable. If this is not determinable, /// return null. -Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout &DL); +Constant *ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, const DataLayout &DL); /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the Index: include/llvm/Analysis/InstructionSimplify.h =================================================================== --- include/llvm/Analysis/InstructionSimplify.h +++ include/llvm/Analysis/InstructionSimplify.h @@ -229,7 +229,8 @@ /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. - Value *SimplifyGEPInst(ArrayRef Ops, const DataLayout &DL, + Value *SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, + const DataLayout &DL, const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, Index: include/llvm/Analysis/Loads.h =================================================================== --- include/llvm/Analysis/Loads.h +++ include/llvm/Analysis/Loads.h @@ -28,7 +28,7 @@ /// specified pointer, we do a quick local scan of the basic block containing /// ScanFrom, to determine if the address is already accessed. bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - unsigned Align); + unsigned MaxAlign, uint64_t MaxSize); /// DefMaxInstsToScan - the default number of maximum instructions /// to scan in the block, used by FindAvailableLoadedValue(). @@ -51,7 +51,7 @@ /// If AATags is non-null and a load or store is found, the AA tags from the /// load or store are recorded there. If there are no AA tags or if no access /// is found, it is left unmodified. -Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, +Value *FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan = DefMaxInstsToScan, AliasAnalysis *AA = nullptr, Index: include/llvm/Analysis/LoopAccessAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessAnalysis.h +++ include/llvm/Analysis/LoopAccessAnalysis.h @@ -264,6 +264,10 @@ SmallVector getInstructionsForAccess(Value *Ptr, bool isWrite) const; + /// \brief Find the value type read or written via \p Ptr. + /// If no unified type if found, nullptr is returned. + Type *getTypeForAccess(Value *Ptr, bool isWrite) const; + private: /// A wrapper around ScalarEvolution, used to add runtime SCEV checks, and /// applies dynamic knowledge to simplify SCEV expressions and convert them @@ -656,8 +660,8 @@ /// /// If necessary this method will version the stride of the pointer according /// to \p PtrToStride and therefore add a new predicate to \p Preds. -int isStridedPtr(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp, - const ValueToValueMap &StridesMap); +int isStridedPtr(PredicatedScalarEvolution &PSE, Value *Ptr, Type *AccessTy, + const Loop *Lp, const ValueToValueMap &StridesMap); /// \brief This analysis provides dependence information for the memory accesses /// of a loop. Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -402,7 +402,7 @@ const GlobalValue *BaseGV = nullptr; if (Ptr != nullptr) { // TODO: will remove this when pointers have an opaque type. - assert(Ptr->getType()->getScalarType()->getPointerElementType() == + assert(cast(Ptr->getType()->getScalarType())->getPointerElementType() == PointeeType && "explicit pointee type doesn't match operand's pointee type"); BaseGV = dyn_cast(Ptr->stripPointerCasts()); @@ -414,7 +414,7 @@ // Assumes the address space is 0 when Ptr is nullptr. unsigned AS = (Ptr == nullptr ? 0 : Ptr->getType()->getPointerAddressSpace()); - auto GTI = gep_type_begin(PointerType::get(PointeeType, AS), Operands); + auto GTI = gep_type_begin(PointeeType, AS, Operands); for (auto I = Operands.begin(); I != Operands.end(); ++I, ++GTI) { // We assume that the cost of Scalar GEP with constant index and the // cost of Vector GEP with splat constant index are the same. @@ -422,7 +422,12 @@ if (!ConstIdx) if (auto Splat = getSplatValue(*I)) ConstIdx = dyn_cast(Splat); - if (isa(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { + // For structures the index is always splat or scalar constant + assert(ConstIdx && "Unexpected GEP index"); + uint64_t Field = ConstIdx->getZExtValue(); + BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field); + } else { int64_t ElementSize = DL.getTypeAllocSize(GTI.getIndexedType()); if (ConstIdx) BaseOffset += ConstIdx->getSExtValue() * ElementSize; @@ -433,12 +438,6 @@ return TTI::TCC_Basic; Scale = ElementSize; } - } else { - StructType *STy = cast(*GTI); - // For structures the index is always splat or scalar constant - assert(ConstIdx && "Unexpected GEP index"); - uint64_t Field = ConstIdx->getZExtValue(); - BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field); } } @@ -478,7 +477,7 @@ const Function *F = CS.getCalledFunction(); if (!F) { // Just use the called value type. - Type *FTy = CS.getCalledValue()->getType()->getPointerElementType(); + Type *FTy = cast(CS.getCalledValue()->getType())->getPointerElementType(); return static_cast(this) ->getCallCost(cast(FTy), CS.arg_size()); } Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -240,7 +240,8 @@ /// pointer. If the context instruction is specified perform context-sensitive /// analysis and return true if the pointer is dereferenceable at the /// specified instruction. - bool isDereferenceablePointer(const Value *V, const DataLayout &DL, + bool isDereferenceablePointer(const Value *V, uint64_t Size, + const DataLayout &DL, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); @@ -249,8 +250,8 @@ /// greater or equal than requested. If the context instruction is specified /// performs context-sensitive analysis and returns true if the pointer is /// dereferenceable at the specified instruction. - bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, - const DataLayout &DL, + bool isDereferenceableAndAlignedPointer(const Value *V, uint64_t Size, + unsigned Align, const DataLayout &DL, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); Index: include/llvm/IR/DataLayout.h =================================================================== --- include/llvm/IR/DataLayout.h +++ include/llvm/IR/DataLayout.h @@ -441,8 +441,9 @@ /// \brief Returns the offset from the beginning of the type for the specified /// indices. /// + /// Note that this takes the element type, not the pointer type. /// This is used to implement getelementptr. - uint64_t getIndexedOffset(Type *Ty, ArrayRef Indices) const; + uint64_t getIndexedOffset(Type *ElemTy, ArrayRef Indices) const; /// \brief Returns a StructLayout object, indicating the alignment of the /// struct, its size, and the offsets of its fields. Index: include/llvm/IR/DerivedTypes.h =================================================================== --- include/llvm/IR/DerivedTypes.h +++ include/llvm/IR/DerivedTypes.h @@ -143,8 +143,7 @@ static_assert(AlignOf::Alignment >= AlignOf::Alignment, "Alignment sufficient for objects appended to FunctionType"); -/// CompositeType - Common super class of ArrayType, StructType, PointerType -/// and VectorType. +/// CompositeType - Common super class of ArrayType, StructType and VectorType. class CompositeType : public Type { protected: explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {} @@ -162,7 +161,6 @@ static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || - T->getTypeID() == PointerTyID || T->getTypeID() == VectorTyID; } }; @@ -294,13 +292,12 @@ } }; -/// SequentialType - This is the superclass of the array, pointer and vector -/// type classes. All of these represent "arrays" in memory. The array type -/// represents a specifically sized array, pointer types are unsized/unknown -/// size arrays, vector types represent specifically sized arrays that -/// allow for use of SIMD instructions. SequentialType holds the common -/// features of all, which stem from the fact that all three lay their -/// components out in memory identically. +/// SequentialType - This is the superclass of the array and vector type +/// classes. All of these represent "arrays" in memory. The array type +/// represents a specifically sized array, and vector types represent +/// specifically sized arrays that allow for use of SIMD instructions. +/// SequentialType holds the common features of all, which stem from +/// the fact that they both lay their components out in memory identically. /// class SequentialType : public CompositeType { Type *ContainedType; ///< Storage for the single contained type. @@ -320,7 +317,6 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || - T->getTypeID() == PointerTyID || T->getTypeID() == VectorTyID; } }; @@ -441,12 +437,19 @@ /// PointerType - Class to represent pointers. /// -class PointerType : public SequentialType { +class PointerType : public Type { + Type *PointeeType; ///< Storage for the pointee type. PointerType(const PointerType &) = delete; const PointerType &operator=(const PointerType &) = delete; explicit PointerType(Type *ElType, unsigned AddrSpace); public: + LLVM_ATTRIBUTE_DEPRECATED(Type *getElementType() const, + "renamed to getPointerElementType") { + return getPointerElementType(); + } + Type *getPointerElementType() const { return ContainedTys[0]; } + /// PointerType::get - This constructs a pointer to an object of the specified /// type in a numbered address space. static PointerType *get(Type *ElementType, unsigned AddressSpace); Index: include/llvm/IR/GetElementPtrTypeIterator.h =================================================================== --- include/llvm/IR/GetElementPtrTypeIterator.h +++ include/llvm/IR/GetElementPtrTypeIterator.h @@ -33,12 +33,6 @@ generic_gep_type_iterator() {} public: - static generic_gep_type_iterator begin(Type *Ty, ItTy It) { - generic_gep_type_iterator I; - I.CurTy.setPointer(Ty); - I.OpIt = It; - return I; - } static generic_gep_type_iterator begin(Type *Ty, unsigned AddrSpace, ItTy It) { generic_gep_type_iterator I; @@ -125,13 +119,13 @@ template inline generic_gep_type_iterator - gep_type_begin(Type *Op0, ArrayRef A) { - return generic_gep_type_iterator::begin(Op0, A.begin()); + gep_type_begin(Type *Op0, unsigned AS, ArrayRef A) { + return generic_gep_type_iterator::begin(Op0, AS, A.begin()); } template inline generic_gep_type_iterator - gep_type_end(Type * /*Op0*/, ArrayRef A) { + gep_type_end(Type * /*Op0*/, unsigned /*AS*/, ArrayRef A) { return generic_gep_type_iterator::end(A.end()); } } // end namespace llvm Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -1536,7 +1536,7 @@ CallInst *CreateCall(Value *Callee, ArrayRef Args, const Twine &Name, MDNode *FPMathTag = nullptr) { PointerType *PTy = cast(Callee->getType()); - FunctionType *FTy = cast(PTy->getElementType()); + FunctionType *FTy = cast(PTy->getPointerElementType()); return CreateCall(FTy, Callee, Args, Name, FPMathTag); } @@ -1665,7 +1665,7 @@ Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context)); Value *Difference = CreateSub(LHS_int, RHS_int); return CreateExactSDiv(Difference, - ConstantExpr::getSizeOf(ArgType->getElementType()), + ConstantExpr::getSizeOf(ArgType->getPointerElementType()), Name); } Index: include/llvm/IR/Instructions.h =================================================================== --- include/llvm/IR/Instructions.h +++ include/llvm/IR/Instructions.h @@ -190,13 +190,13 @@ Instruction *InsertBefore = nullptr); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false, Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + : LoadInst(cast(Ptr->getType())->getPointerElementType(), Ptr, NameStr, isVolatile, InsertBefore) {} LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + : LoadInst(cast(Ptr->getType())->getPointerElementType(), Ptr, NameStr, isVolatile, Align, InsertBefore) {} LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, Instruction *InsertBefore = nullptr); @@ -205,7 +205,7 @@ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, AtomicOrdering Order, SynchronizationScope SynchScope = CrossThread, Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + : LoadInst(cast(Ptr->getType())->getPointerElementType(), Ptr, NameStr, isVolatile, Align, Order, SynchScope, InsertBefore) {} LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, AtomicOrdering Order, @@ -223,7 +223,7 @@ explicit LoadInst(Value *Ptr, const char *NameStr = nullptr, bool isVolatile = false, Instruction *InsertBefore = nullptr) - : LoadInst(cast(Ptr->getType())->getElementType(), Ptr, + : LoadInst(cast(Ptr->getType())->getPointerElementType(), Ptr, NameStr, isVolatile, InsertBefore) {} LoadInst(Value *Ptr, const char *NameStr, bool isVolatile, BasicBlock *InsertAtEnd); @@ -292,6 +292,12 @@ return getPointerOperand()->getType()->getPointerAddressSpace(); } + /// \brief Returns the explicit aligment, if present, or the ABI one. + unsigned getActualAlignment() const; + + /// \brief Returns the size in bytes of the loaded value. + uint64_t getLoadedSize() const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; @@ -868,11 +874,11 @@ unsigned Values = 1 + unsigned(IdxList.size()); if (!PointeeType) PointeeType = - cast(Ptr->getType()->getScalarType())->getElementType(); + cast(Ptr->getType()->getScalarType())->getPointerElementType(); else assert( PointeeType == - cast(Ptr->getType()->getScalarType())->getElementType()); + cast(Ptr->getType()->getScalarType())->getPointerElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertBefore); } @@ -883,11 +889,11 @@ unsigned Values = 1 + unsigned(IdxList.size()); if (!PointeeType) PointeeType = - cast(Ptr->getType()->getScalarType())->getElementType(); + cast(Ptr->getType()->getScalarType())->getPointerElementType(); else assert( PointeeType == - cast(Ptr->getType()->getScalarType())->getElementType()); + cast(Ptr->getType()->getScalarType())->getPointerElementType()); return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values, NameStr, InsertAtEnd); } @@ -928,11 +934,6 @@ /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - // getType - Overload to return most specific sequential type. - SequentialType *getType() const { - return cast(Instruction::getType()); - } - Type *getSourceElementType() const { return SourceElementType; } void setSourceElementType(Type *Ty) { SourceElementType = Ty; } @@ -940,7 +941,7 @@ Type *getResultElementType() const { assert(ResultElementType == - cast(getType()->getScalarType())->getElementType()); + cast(getType()->getScalarType())->getPointerElementType()); return ResultElementType; } @@ -991,7 +992,7 @@ /// instruction, which may be a vector of pointers. static Type *getGEPReturnType(Value *Ptr, ArrayRef IdxList) { return getGEPReturnType( - cast(Ptr->getType()->getScalarType())->getElementType(), + cast(Ptr->getType()->getScalarType())->getPointerElementType(), Ptr, IdxList); } static Type *getGEPReturnType(Type *ElTy, Value *Ptr, @@ -1071,7 +1072,7 @@ SourceElementType(PointeeType), ResultElementType(getIndexedType(PointeeType, IdxList)) { assert(ResultElementType == - cast(getType()->getScalarType())->getElementType()); + cast(getType()->getScalarType())->getPointerElementType()); init(Ptr, IdxList, NameStr); } GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, @@ -1084,7 +1085,7 @@ SourceElementType(PointeeType), ResultElementType(getIndexedType(PointeeType, IdxList)) { assert(ResultElementType == - cast(getType()->getScalarType())->getElementType()); + cast(getType()->getScalarType())->getPointerElementType()); init(Ptr, IdxList, NameStr); } @@ -1367,7 +1368,7 @@ void init(Value *Func, ArrayRef Args, ArrayRef Bundles, const Twine &NameStr) { init(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, Args, Bundles, NameStr); } void init(FunctionType *FTy, Value *Func, ArrayRef Args, @@ -1383,7 +1384,7 @@ ArrayRef Bundles, const Twine &NameStr, Instruction *InsertBefore) : CallInst(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, Args, Bundles, NameStr, InsertBefore) {} inline CallInst(Value *Func, ArrayRef Args, const Twine &NameStr, @@ -1414,14 +1415,14 @@ const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, Args, Bundles, NameStr, InsertBefore); } static CallInst *Create(Value *Func, ArrayRef Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, Args, None, NameStr, InsertBefore); } static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef Args, @@ -1776,13 +1777,13 @@ /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { setCalledFunction( - cast(cast(Fn->getType())->getElementType()), + cast(cast(Fn->getType())->getPointerElementType()), Fn); } void setCalledFunction(FunctionType *FTy, Value *Fn) { this->FTy = FTy; assert(FTy == cast( - cast(Fn->getType())->getElementType())); + cast(Fn->getType())->getPointerElementType())); Op<-1>() = Fn; } @@ -1830,7 +1831,7 @@ BasicBlock *InsertAtEnd) : Instruction( cast(cast(Func->getType()) - ->getElementType())->getReturnType(), + ->getPointerElementType())->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - (Args.size() + CountBundleInputs(Bundles) + 1), unsigned(Args.size() + CountBundleInputs(Bundles) + 1), InsertAtEnd) { @@ -3338,7 +3339,7 @@ ArrayRef Args, ArrayRef Bundles, const Twine &NameStr) { init(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, IfNormal, IfException, Args, Bundles, NameStr); } void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, @@ -3353,7 +3354,7 @@ unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : InvokeInst(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, IfNormal, IfException, Args, Bundles, Values, NameStr, InsertBefore) {} @@ -3383,7 +3384,7 @@ const Twine &NameStr, Instruction *InsertBefore = nullptr) { return Create(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, IfNormal, IfException, Args, None, NameStr, InsertBefore); } @@ -3393,7 +3394,7 @@ const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { return Create(cast( - cast(Func->getType())->getElementType()), + cast(Func->getType())->getPointerElementType()), Func, IfNormal, IfException, Args, Bundles, NameStr, InsertBefore); } @@ -3681,13 +3682,13 @@ /// setCalledFunction - Set the function called. void setCalledFunction(Value* Fn) { setCalledFunction( - cast(cast(Fn->getType())->getElementType()), + cast(cast(Fn->getType())->getPointerElementType()), Fn); } void setCalledFunction(FunctionType *FTy, Value *Fn) { this->FTy = FTy; assert(FTy == cast( - cast(Fn->getType())->getElementType())); + cast(Fn->getType())->getPointerElementType())); Op<-3>() = Fn; } @@ -3762,7 +3763,7 @@ const Twine &NameStr, BasicBlock *InsertAtEnd) : TerminatorInst( cast(cast(Func->getType()) - ->getElementType())->getReturnType(), + ->getPointerElementType())->getReturnType(), Instruction::Invoke, OperandTraits::op_end(this) - Values, Values, InsertAtEnd) { init(Func, IfNormal, IfException, Args, Bundles, NameStr); Index: include/llvm/IR/Operator.h =================================================================== --- include/llvm/IR/Operator.h +++ include/llvm/IR/Operator.h @@ -401,6 +401,7 @@ } Type *getSourceElementType() const; + Type *getResultElementType() const; /// Method to return the address space of the pointer operand. unsigned getPointerAddressSpace() const { Index: include/llvm/IR/Statepoint.h =================================================================== --- include/llvm/IR/Statepoint.h +++ include/llvm/IR/Statepoint.h @@ -145,7 +145,7 @@ /// statepoint. Type *getActualReturnType() const { auto *FTy = cast( - cast(getCalledValue()->getType())->getElementType()); + cast(getCalledValue()->getType())->getPointerElementType()); return FTy->getReturnType(); } Index: include/llvm/IR/Type.h =================================================================== --- include/llvm/IR/Type.h +++ include/llvm/IR/Type.h @@ -355,8 +355,6 @@ unsigned getVectorNumElements() const; Type *getVectorElementType() const { return getSequentialElementType(); } - Type *getPointerElementType() const { return getSequentialElementType(); } - /// \brief Get the address space of this pointer or pointer vector type. unsigned getPointerAddressSpace() const; Index: lib/Analysis/AliasAnalysisEvaluator.cpp =================================================================== --- lib/Analysis/AliasAnalysisEvaluator.cpp +++ lib/Analysis/AliasAnalysisEvaluator.cpp @@ -190,12 +190,12 @@ for (SetVector::iterator I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { uint64_t I1Size = MemoryLocation::UnknownSize; - Type *I1ElTy = cast((*I1)->getType())->getElementType(); + Type *I1ElTy = cast((*I1)->getType())->getPointerElementType(); if (I1ElTy->isSized()) I1Size = DL.getTypeStoreSize(I1ElTy); for (SetVector::iterator I2 = Pointers.begin(); I2 != I1; ++I2) { uint64_t I2Size = MemoryLocation::UnknownSize; - Type *I2ElTy =cast((*I2)->getType())->getElementType(); + Type *I2ElTy =cast((*I2)->getType())->getPointerElementType(); if (I2ElTy->isSized()) I2Size = DL.getTypeStoreSize(I2ElTy); switch (AA.alias(*I1, I1Size, *I2, I2Size)) { @@ -290,7 +290,7 @@ for (SetVector::iterator V = Pointers.begin(), Ve = Pointers.end(); V != Ve; ++V) { uint64_t Size = MemoryLocation::UnknownSize; - Type *ElTy = cast((*V)->getType())->getElementType(); + Type *ElTy = cast((*V)->getType())->getPointerElementType(); if (ElTy->isSized()) Size = DL.getTypeStoreSize(ElTy); switch (AA.getModRefInfo(*C, *V, Size)) { Index: lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- lib/Analysis/BasicAliasAnalysis.cpp +++ lib/Analysis/BasicAliasAnalysis.cpp @@ -381,7 +381,7 @@ } // 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(); Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -399,9 +399,9 @@ } static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, + Type *LoadTy, const DataLayout &DL) { PointerType *PTy = cast(C->getType()); - Type *LoadTy = PTy->getElementType(); IntegerType *IntType = dyn_cast(LoadTy); // If this isn't an integer load we can't fold it directly. @@ -414,19 +414,19 @@ // an actual new load. Type *MapTy; if (LoadTy->isHalfTy()) - MapTy = Type::getInt16PtrTy(C->getContext(), AS); + MapTy = Type::getInt16Ty(C->getContext()); else if (LoadTy->isFloatTy()) - MapTy = Type::getInt32PtrTy(C->getContext(), AS); + MapTy = Type::getInt32Ty(C->getContext()); else if (LoadTy->isDoubleTy()) - MapTy = Type::getInt64PtrTy(C->getContext(), AS); + MapTy = Type::getInt64Ty(C->getContext()); else if (LoadTy->isVectorTy()) { - MapTy = PointerType::getIntNPtrTy(C->getContext(), - DL.getTypeAllocSizeInBits(LoadTy), AS); + MapTy = PointerType::getIntNTy(C->getContext(), + DL.getTypeAllocSizeInBits(LoadTy)); } else return nullptr; - C = FoldBitCast(C, MapTy, DL); - if (Constant *Res = FoldReinterpretLoadFromConstPtr(C, DL)) + C = FoldBitCast(C, MapTy->getPointerTo(AS), DL); + if (Constant *Res = FoldReinterpretLoadFromConstPtr(C, MapTy, DL)) return FoldBitCast(Res, LoadTy, DL); return nullptr; } @@ -479,13 +479,15 @@ } static Constant *ConstantFoldLoadThroughBitcast(ConstantExpr *CE, + Type *DestTy, const DataLayout &DL) { - auto *DestPtrTy = dyn_cast(CE->getType()); - if (!DestPtrTy) + auto *SrcPtr = CE->getOperand(0); + auto *SrcPtrTy = dyn_cast(SrcPtr->getType()); + if (!SrcPtrTy) return nullptr; - Type *DestTy = DestPtrTy->getElementType(); + Type *SrcTy = SrcPtrTy->getPointerElementType(); - Constant *C = ConstantFoldLoadFromConstPtr(CE->getOperand(0), DL); + Constant *C = ConstantFoldLoadFromConstPtr(SrcPtr, SrcTy, DL); if (!C) return nullptr; @@ -524,7 +526,7 @@ /// Return the value that a load from C would produce if it is constant and /// determinable. If this is not determinable, return null. -Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, +Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, const DataLayout &DL) { // First, try the easy cases: if (GlobalVariable *GV = dyn_cast(C)) @@ -533,7 +535,7 @@ if (auto *GA = dyn_cast(C)) if (GA->getAliasee() && !GA->mayBeOverridden()) - return ConstantFoldLoadFromConstPtr(GA->getAliasee(), DL); + return ConstantFoldLoadFromConstPtr(GA->getAliasee(), Ty, DL); // If the loaded value isn't a constant expr, we can't handle it. ConstantExpr *CE = dyn_cast(C); @@ -551,7 +553,7 @@ } if (CE->getOpcode() == Instruction::BitCast) - if (Constant *LoadedC = ConstantFoldLoadThroughBitcast(CE, DL)) + if (Constant *LoadedC = ConstantFoldLoadThroughBitcast(CE, Ty, DL)) return LoadedC; // Instead of loading constant c string, use corresponding integer value @@ -559,7 +561,6 @@ StringRef Str; if (getConstantStringInfo(CE, Str) && !Str.empty()) { unsigned StrLen = Str.size(); - Type *Ty = cast(CE->getType())->getElementType(); unsigned NumBits = Ty->getPrimitiveSizeInBits(); // Replace load with immediate integer if the result is an integer or fp // value. @@ -594,16 +595,15 @@ if (GlobalVariable *GV = dyn_cast(GetUnderlyingObject(CE, DL))) { if (GV->isConstant() && GV->hasDefinitiveInitializer()) { - Type *ResTy = cast(C->getType())->getElementType(); if (GV->getInitializer()->isNullValue()) - return Constant::getNullValue(ResTy); + return Constant::getNullValue(Ty); if (isa(GV->getInitializer())) - return UndefValue::get(ResTy); + return UndefValue::get(Ty); } } // Try hard to fold loads from bitcasted strange and non-type-safe things. - return FoldReinterpretLoadFromConstPtr(CE, DL); + return FoldReinterpretLoadFromConstPtr(CE, Ty, DL); } static Constant *ConstantFoldLoadInst(const LoadInst *LI, @@ -611,7 +611,7 @@ if (LI->isVolatile()) return nullptr; if (Constant *C = dyn_cast(LI->getOperand(0))) - return ConstantFoldLoadFromConstPtr(C, DL); + return ConstantFoldLoadFromConstPtr(C, LI->getType(), DL); return nullptr; } @@ -683,9 +683,7 @@ SmallVector NewIdxs; for (unsigned i = 1, e = Ops.size(); i != e; ++i) { if ((i == 1 || - !isa(GetElementPtrInst::getIndexedType( - cast(Ops[0]->getType()->getScalarType()) - ->getElementType(), + !isa(GetElementPtrInst::getIndexedType(SrcTy, Ops.slice(1, i - 1)))) && Ops[i]->getType() != IntPtrTy) { Any = true; @@ -711,16 +709,17 @@ } /// Strip the pointer casts, but preserve the address space information. -static Constant* StripPtrCastKeepAS(Constant* Ptr) { +static Constant* StripPtrCastKeepAS(Constant* Ptr, Type *&SrcTy) { assert(Ptr->getType()->isPointerTy() && "Not a pointer type"); PointerType *OldPtrTy = cast(Ptr->getType()); Ptr = Ptr->stripPointerCasts(); PointerType *NewPtrTy = cast(Ptr->getType()); + SrcTy = NewPtrTy->getPointerElementType(); + // Preserve the address space number of the pointer. if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) { - NewPtrTy = NewPtrTy->getElementType()->getPointerTo( - OldPtrTy->getAddressSpace()); + NewPtrTy = SrcTy->getPointerTo(OldPtrTy->getAddressSpace()); Ptr = ConstantExpr::getPointerCast(Ptr, NewPtrTy); } return Ptr; @@ -728,15 +727,14 @@ /// If we can symbolically evaluate the GEP constant expression, do so. static Constant *SymbolicallyEvaluateGEP(Type *SrcTy, ArrayRef Ops, - Type *ResultTy, const DataLayout &DL, + Type *ResultTy, Type *ResultElementTy, + const DataLayout &DL, const TargetLibraryInfo *TLI) { Constant *Ptr = Ops[0]; - if (!Ptr->getType()->getPointerElementType()->isSized() || - !Ptr->getType()->isPointerTy()) + if (!SrcTy->isSized() || !Ptr->getType()->isPointerTy()) return nullptr; Type *IntPtrTy = DL.getIntPtrType(Ptr->getType()); - Type *ResultElementTy = ResultTy->getPointerElementType(); // If this is a constant expr gep that is effectively computing an // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' @@ -766,9 +764,9 @@ APInt Offset = APInt(BitWidth, DL.getIndexedOffset( - Ptr->getType(), + SrcTy, makeArrayRef((Value * const *)Ops.data() + 1, Ops.size() - 1))); - Ptr = StripPtrCastKeepAS(Ptr); + Ptr = StripPtrCastKeepAS(Ptr, SrcTy); // If this is a GEP of a GEP, fold it all into a single GEP. while (GEPOperator *GEP = dyn_cast(Ptr)) { @@ -785,8 +783,9 @@ break; Ptr = cast(GEP->getOperand(0)); - Offset += APInt(BitWidth, DL.getIndexedOffset(Ptr->getType(), NestedOps)); - Ptr = StripPtrCastKeepAS(Ptr); + SrcTy = GEP->getSourceElementType(); + Offset += APInt(BitWidth, DL.getIndexedOffset(SrcTy, NestedOps)); + Ptr = StripPtrCastKeepAS(Ptr, SrcTy); } // If the base value for this address is a literal integer value, fold the @@ -813,19 +812,43 @@ SmallVector NewIdxs; do { - if (SequentialType *ATy = dyn_cast(Ty)) { - if (ATy->isPointerTy()) { + if (StructType *STy = dyn_cast(Ty)) { + // If we end up with an offset that isn't valid for this struct type, we + // can't re-form this GEP in a regular form, so bail out. The pointer + // operand likely went through casts that are necessary to make the GEP + // sensible. + const StructLayout &SL = *DL.getStructLayout(STy); + if (Offset.uge(SL.getSizeInBytes())) + break; + + // Determine which field of the struct the offset points into. The + // getZExtValue is fine as we've already ensured that the offset is + // within the range representable by the StructLayout API. + unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue()); + NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()), + ElIdx)); + Offset -= APInt(BitWidth, SL.getElementOffset(ElIdx)); + Ty = STy->getTypeAtIndex(ElIdx); + } else { + if (Ty->isPointerTy()) { // The only pointer indexing we'll do is on the first index of the GEP. if (!NewIdxs.empty()) break; + Ty = SrcTy; + // Only handle pointers to sized types, not pointers to functions. - if (!ATy->getElementType()->isSized()) + if (!Ty->isSized()) return nullptr; + } else if (auto *ATy = dyn_cast(Ty)) { + Ty = ATy->getElementType(); + } else { + // We've reached some non-indexable type. + break; } // Determine which element of the array the offset points into. - APInt ElemSize(BitWidth, DL.getTypeAllocSize(ATy->getElementType())); + APInt ElemSize(BitWidth, DL.getTypeAllocSize(Ty)); if (ElemSize == 0) // The element size is 0. This may be [0 x Ty]*, so just use a zero // index for this level and proceed to the next level to see if it can @@ -838,27 +861,6 @@ Offset -= NewIdx * ElemSize; NewIdxs.push_back(ConstantInt::get(IntPtrTy, NewIdx)); } - Ty = ATy->getElementType(); - } else if (StructType *STy = dyn_cast(Ty)) { - // If we end up with an offset that isn't valid for this struct type, we - // can't re-form this GEP in a regular form, so bail out. The pointer - // operand likely went through casts that are necessary to make the GEP - // sensible. - const StructLayout &SL = *DL.getStructLayout(STy); - if (Offset.uge(SL.getSizeInBytes())) - break; - - // Determine which field of the struct the offset points into. The - // getZExtValue is fine as we've already ensured that the offset is - // within the range representable by the StructLayout API. - unsigned ElIdx = SL.getElementContainingOffset(Offset.getZExtValue()); - NewIdxs.push_back(ConstantInt::get(Type::getInt32Ty(Ty->getContext()), - ElIdx)); - Offset -= APInt(BitWidth, SL.getElementOffset(ElIdx)); - Ty = STy->getTypeAtIndex(ElIdx); - } else { - // We've reached some non-indexable type. - break; } } while (Ty != ResultElementTy); @@ -870,7 +872,7 @@ // Create a GEP. Constant *C = ConstantExpr::getGetElementPtr(SrcTy, Ptr, NewIdxs); - assert(C->getType()->getPointerElementType() == Ty && + assert(cast(C->getType())->getPointerElementType() == Ty && "Computed GetElementPtr has unexpected type!"); // If we ended up indexing a member with a type that doesn't match @@ -959,7 +961,7 @@ EVI->getIndices()); } - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops, DL, TLI); + return ConstantFoldInstOperands(I, I->getOpcode(), I->getType(), Ops, DL, TLI); } static Constant * @@ -982,7 +984,7 @@ if (CE->isCompare()) return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1], DL, TLI); - return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), Ops, DL, TLI); + return ConstantFoldInstOperands(CE, CE->getOpcode(), CE->getType(), Ops, DL, TLI); } /// Attempt to fold the constant expression @@ -1009,6 +1011,14 @@ ArrayRef Ops, const DataLayout &DL, const TargetLibraryInfo *TLI) { + return ConstantFoldInstOperands(nullptr, Opcode, DestTy, Ops, DL, TLI); +} + +Constant *llvm::ConstantFoldInstOperands(const Value *InstOrCE, + unsigned Opcode, Type *DestTy, + ArrayRef Ops, + const DataLayout &DL, + const TargetLibraryInfo *TLI) { // Handle easy binops first. if (Instruction::isBinaryOp(Opcode)) { if (isa(Ops[0]) || isa(Ops[1])) { @@ -1089,10 +1099,14 @@ case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); case Instruction::GetElementPtr: { - Type *SrcTy = nullptr; + assert(InstOrCE && "Missing instruction/constant expression"); + auto *GEP = cast(InstOrCE); + Type *SrcTy = GEP->getSourceElementType(); + Type *DestElemTy = GEP->getResultElementType(); + if (Constant *C = CastGEPIndices(SrcTy, Ops, DestTy, DL, TLI)) return C; - if (Constant *C = SymbolicallyEvaluateGEP(SrcTy, Ops, DestTy, DL, TLI)) + if (Constant *C = SymbolicallyEvaluateGEP(SrcTy, Ops, DestTy, DestElemTy, DL, TLI)) return C; return ConstantExpr::getGetElementPtr(SrcTy, Ops[0], Ops.slice(1)); Index: lib/Analysis/GlobalsModRef.cpp =================================================================== --- lib/Analysis/GlobalsModRef.cpp +++ lib/Analysis/GlobalsModRef.cpp @@ -310,7 +310,7 @@ ++NumNonAddrTakenGlobalVars; // If this global holds a pointer type, see if it is an indirect global. - if (GV.getType()->getElementType()->isPointerTy() && + if (GV.getValueType()->isPointerTy() && AnalyzeIndirectGlobalMemory(&GV)) ++NumIndirectGlobalVars; } Index: lib/Analysis/InlineCost.cpp =================================================================== --- lib/Analysis/InlineCost.cpp +++ lib/Analysis/InlineCost.cpp @@ -501,7 +501,7 @@ COp = SimplifiedValues.lookup(Operand); if (COp) { const DataLayout &DL = F.getParent()->getDataLayout(); - if (Constant *C = ConstantFoldInstOperands(I.getOpcode(), I.getType(), + if (Constant *C = ConstantFoldInstOperands(&I, I.getOpcode(), I.getType(), COp, DL)) { SimplifiedValues[&I] = C; return true; @@ -1101,7 +1101,7 @@ // We approximate the number of loads and stores needed by dividing the // size of the byval type by the target's pointer size. PointerType *PTy = cast(CS.getArgument(I)->getType()); - unsigned TypeSize = DL.getTypeSizeInBits(PTy->getElementType()); + unsigned TypeSize = DL.getTypeSizeInBits(PTy->getPointerElementType()); unsigned PointerSize = DL.getPointerSizeInBits(); // Ceiling division. unsigned NumStores = (TypeSize + PointerSize - 1) / PointerSize; Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -3301,9 +3301,9 @@ if (LoadInst *LI = dyn_cast(I)) if (!LI->isVolatile()) - return ConstantFoldLoadFromConstPtr(ConstOps[0], Q.DL); + return ConstantFoldLoadFromConstPtr(ConstOps[0], LI->getType(), Q.DL); - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), ConstOps, + return ConstantFoldInstOperands(I, I->getOpcode(), I->getType(), ConstOps, Q.DL, Q.TLI); } } @@ -3533,13 +3533,13 @@ Ops.slice(1)); } -Value *llvm::SimplifyGEPInst(ArrayRef Ops, const DataLayout &DL, +Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef Ops, + const DataLayout &DL, const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC, const Instruction *CxtI) { - return ::SimplifyGEPInst( - cast(Ops[0]->getType()->getScalarType())->getElementType(), - Ops, Query(DL, TLI, DT, AC, CxtI), RecursionLimit); + return ::SimplifyGEPInst(SrcTy, Ops, + Query(DL, TLI, DT, AC, CxtI), RecursionLimit); } /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we @@ -3892,7 +3892,7 @@ const Query &Q, unsigned MaxRecurse) { Type *Ty = V->getType(); if (PointerType *PTy = dyn_cast(Ty)) - Ty = PTy->getElementType(); + Ty = PTy->getPointerElementType(); FunctionType *FTy = cast(Ty); // call undef -> undef @@ -4045,7 +4045,8 @@ break; case Instruction::GetElementPtr: { SmallVector Ops(I->op_begin(), I->op_end()); - Result = SimplifyGEPInst(Ops, DL, TLI, DT, AC, I); + Result = SimplifyGEPInst(cast(I)->getSourceElementType(), + Ops, DL, TLI, DT, AC, I); break; } case Instruction::InsertValue: { Index: lib/Analysis/Lint.cpp =================================================================== --- lib/Analysis/Lint.cpp +++ lib/Analysis/Lint.cpp @@ -254,7 +254,7 @@ // Check that an sret argument points to valid memory. if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { Type *Ty = - cast(Formal->getType())->getElementType(); + cast(Formal->getType())->getPointerElementType(); visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty), DL->getABITypeAlignment(Ty), Ty, MemRef::Read | MemRef::Write); @@ -435,7 +435,7 @@ // If the global may be defined differently in another compilation unit // then don't warn about funky memory accesses. if (GV->hasDefinitiveInitializer()) { - Type *GTy = GV->getType()->getElementType(); + Type *GTy = GV->getValueType(); if (GTy->isSized()) BaseSize = DL->getTypeAllocSize(GTy); BaseAlign = GV->getAlignment(); @@ -642,8 +642,7 @@ if (!VisitedBlocks.insert(BB).second) break; if (Value *U = - FindAvailableLoadedValue(L->getPointerOperand(), - BB, BBI, DefMaxInstsToScan, AA)) + FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA)) return findValueImpl(U, OffsetOk, Visited); if (BBI != BB->begin()) break; BB = BB->getUniquePredecessor(); Index: lib/Analysis/Loads.cpp =================================================================== --- lib/Analysis/Loads.cpp +++ lib/Analysis/Loads.cpp @@ -63,13 +63,10 @@ /// This uses the pointee type to determine how many bytes need to be safe to /// load from the pointer. bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - unsigned Align) { + unsigned MaxAlign, uint64_t MaxSize) { const DataLayout &DL = ScanFrom->getModule()->getDataLayout(); - // Zero alignment means that the load has the ABI alignment for the target - if (Align == 0) - Align = DL.getABITypeAlignment(V->getType()->getPointerElementType()); - assert(isPowerOf2_32(Align)); + assert(isPowerOf2_32(MaxAlign)); int64_t ByteOffset = 0; Value *Base = V; @@ -89,14 +86,11 @@ // overridden. Their size may change or they may be weak and require a test // to determine if they were in fact provided. if (!GV->mayBeOverridden()) { - BaseType = GV->getType()->getElementType(); + BaseType = GV->getValueType(); BaseAlign = GV->getAlignment(); } } - PointerType *AddrTy = cast(V->getType()); - uint64_t LoadSize = DL.getTypeStoreSize(AddrTy->getElementType()); - // If we found a base allocated type from either an alloca or global variable, // try to see if we are definitively within the allocated region. We need to // know the size of the base type and the loaded type to do anything in this @@ -105,10 +99,10 @@ if (BaseAlign == 0) BaseAlign = DL.getPrefTypeAlignment(BaseType); - if (Align <= BaseAlign) { + if (MaxAlign <= BaseAlign) { // Check if the load is within the bounds of the underlying object. - if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) && - ((ByteOffset % Align) == 0)) + if (ByteOffset + MaxSize <= DL.getTypeAllocSize(BaseType) && + ((ByteOffset % MaxAlign) == 0)) return true; } } @@ -135,20 +129,22 @@ return false; Value *AccessedPtr; + Type *AccessedTy; unsigned AccessedAlign; if (LoadInst *LI = dyn_cast(BBI)) { AccessedPtr = LI->getPointerOperand(); + AccessedTy = LI->getType(); AccessedAlign = LI->getAlignment(); } else if (StoreInst *SI = dyn_cast(BBI)) { AccessedPtr = SI->getPointerOperand(); + AccessedTy = SI->getValueOperand()->getType(); AccessedAlign = SI->getAlignment(); } else continue; - Type *AccessedTy = AccessedPtr->getType()->getPointerElementType(); if (AccessedAlign == 0) AccessedAlign = DL.getABITypeAlignment(AccessedTy); - if (AccessedAlign < Align) + if (AccessedAlign < MaxAlign) continue; // Handle trivial cases. @@ -156,7 +152,7 @@ return true; if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) && - LoadSize <= DL.getTypeStoreSize(AccessedTy)) + MaxSize <= DL.getTypeStoreSize(AccessedTy)) return true; } return false; @@ -193,14 +189,15 @@ /// If \c AATags is non-null and a load or store is found, the AA tags from the /// load or store are recorded there. If there are no AA tags or if no access is /// found, it is left unmodified. -Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, +Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan, AliasAnalysis *AA, AAMDNodes *AATags) { if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; - Type *AccessTy = cast(Ptr->getType())->getElementType(); + Value *Ptr = Load->getPointerOperand(); + Type *AccessTy = Load->getType(); const DataLayout &DL = ScanBB->getModule()->getDataLayout(); Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -430,19 +430,30 @@ PSE(PSE) {} /// \brief Register a load and whether it is only read from. - void addLoad(MemoryLocation &Loc, bool IsReadOnly) { + void addLoad(MemoryLocation &Loc, Type *AccessTy, bool IsReadOnly) { Value *Ptr = const_cast(Loc.Ptr); AST.add(Ptr, MemoryLocation::UnknownSize, Loc.AATags); - Accesses.insert(MemAccessInfo(Ptr, false)); + + auto KV = std::make_pair(MemAccessInfo(Ptr, false), AccessTy); + Type *&Ty = Accesses.insert(KV).first->second; + // If we had a type and it differs from the current one, clear it. + if (Ty && Ty != AccessTy) + Ty = nullptr; + if (IsReadOnly) ReadOnlyPtr.insert(Ptr); } /// \brief Register a store. - void addStore(MemoryLocation &Loc) { + void addStore(MemoryLocation &Loc, Type *AccessTy) { Value *Ptr = const_cast(Loc.Ptr); AST.add(Ptr, MemoryLocation::UnknownSize, Loc.AATags); - Accesses.insert(MemAccessInfo(Ptr, true)); + + auto KV = std::make_pair(MemAccessInfo(Ptr, true), AccessTy); + Type *&Ty = Accesses.insert(KV).first->second; + // If we had a type and it differs from the current one, clear it. + if (Ty && Ty != AccessTy) + Ty = nullptr; } /// \brief Check whether we can check the pointers at runtime for @@ -482,8 +493,8 @@ /// are needed and build sets of dependency check candidates. void processMemAccesses(); - /// Set of all accesses. - PtrAccessSet Accesses; + /// Map from all accesses to their value type. + MapVector Accesses; const DataLayout &DL; @@ -560,6 +571,7 @@ Value *Ptr = A.getValue(); bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true)); MemAccessInfo Access(Ptr, IsWrite); + Type *AccessTy = Accesses.lookup(Access); if (IsWrite) ++NumWritePtrChecks; @@ -569,8 +581,8 @@ if (hasComputableBounds(PSE, StridesMap, Ptr, TheLoop) && // When we run after a failing dependency check we have to make sure // we don't have wrapping pointers. - (!ShouldCheckStride || - isStridedPtr(PSE, Ptr, TheLoop, StridesMap) == 1)) { + (!ShouldCheckStride || (AccessTy && + isStridedPtr(PSE, Ptr, AccessTy, TheLoop, StridesMap) == 1))) { // The id of the dependence set. unsigned DepId; @@ -660,10 +672,13 @@ DEBUG(dbgs() << " AST: "; AST.dump()); DEBUG(dbgs() << "LAA: Accesses(" << Accesses.size() << "):\n"); DEBUG({ - for (auto A : Accesses) - dbgs() << "\t" << *A.getPointer() << " (" << - (A.getInt() ? "write" : (ReadOnlyPtr.count(A.getPointer()) ? - "read-only" : "read")) << ")\n"; + for (auto A : Accesses) { + MemAccessInfo Access = A.first; + dbgs() << "\t" << *Access.getPointer() << " (" << + (Access.getInt() ? "write" : + (ReadOnlyPtr.count(Access.getPointer()) ? + "read-only" : "read")) << ")\n"; + } }); // The AliasSetTracker has nicely partitioned our pointers by metadata @@ -686,78 +701,128 @@ // Iterate over each alias set twice, once to process read/write pointers, // and then to process read-only pointers. - for (int SetIteration = 0; SetIteration < 2; ++SetIteration) { - bool UseDeferred = SetIteration > 0; - PtrAccessSet &S = UseDeferred ? DeferredAccesses : Accesses; + for (auto AV : AS) { + Value *Ptr = AV.getValue(); - for (auto AV : AS) { - Value *Ptr = AV.getValue(); + // For a single memory access in AliasSetTracker, Accesses may contain + // both read and write, and they both need to be handled for CheckDeps. + for (auto AC : Accesses) { + if (AC.first.getPointer() != Ptr) + continue; - // For a single memory access in AliasSetTracker, Accesses may contain - // both read and write, and they both need to be handled for CheckDeps. - for (auto AC : S) { - if (AC.getPointer() != Ptr) - continue; + bool IsWrite = AC.first.getInt(); + bool IsReadOnlyPtr = ReadOnlyPtr.count(Ptr) && !IsWrite; + // The pointer must be in the PtrAccessSet, either as a + // read or a write. + assert((IsWrite || Accesses.count(MemAccessInfo(Ptr, false))) && + "Alias-set pointer not in the access set?"); + + MemAccessInfo Access(Ptr, IsWrite); + DepCands.insert(Access); + + // Memorize read-only pointers for later processing and skip them in + // the first round (they need to be checked after we have seen all + // write pointers). Note: we also mark pointer that are not + // consecutive as "read-only" pointers (so that we check + // "a[b[i]] +="). Hence, we need the second check for "!IsWrite". + if (IsReadOnlyPtr) { + DeferredAccesses.insert(Access); + continue; + } + + // If this is a write - check other reads and writes for conflicts. If + // this is a read only check other writes for conflicts (but only if + // there is no other write to the ptr - this is an optimization to + // catch "a[i] = a[i] + " without having to do a dependence check). + if ((IsWrite || IsReadOnlyPtr) && SetHasWrite) { + CheckDeps.insert(Access); + IsRTCheckAnalysisNeeded = true; + } + + if (IsWrite) + SetHasWrite = true; - bool IsWrite = AC.getInt(); + // Create sets of pointers connected by a shared alias set and + // underlying object. + typedef SmallVector ValueVector; + ValueVector TempObjects; - // If we're using the deferred access set, then it contains only - // reads. - bool IsReadOnlyPtr = ReadOnlyPtr.count(Ptr) && !IsWrite; - if (UseDeferred && !IsReadOnlyPtr) + GetUnderlyingObjects(Ptr, TempObjects, DL, LI); + DEBUG(dbgs() << "Underlying objects for pointer " << *Ptr << "\n"); + for (Value *UnderlyingObj : TempObjects) { + // nullptr never alias, don't join sets for pointer that have "null" + // in their UnderlyingObjects list. + if (isa(UnderlyingObj)) continue; - // Otherwise, the pointer must be in the PtrAccessSet, either as a - // read or a write. - assert(((IsReadOnlyPtr && UseDeferred) || IsWrite || - S.count(MemAccessInfo(Ptr, false))) && - "Alias-set pointer not in the access set?"); - - MemAccessInfo Access(Ptr, IsWrite); - DepCands.insert(Access); - - // Memorize read-only pointers for later processing and skip them in - // the first round (they need to be checked after we have seen all - // write pointers). Note: we also mark pointer that are not - // consecutive as "read-only" pointers (so that we check - // "a[b[i]] +="). Hence, we need the second check for "!IsWrite". - if (!UseDeferred && IsReadOnlyPtr) { - DeferredAccesses.insert(Access); + + UnderlyingObjToAccessMap::iterator Prev = + ObjToLastAccess.find(UnderlyingObj); + if (Prev != ObjToLastAccess.end()) + DepCands.unionSets(Access, Prev->second); + + ObjToLastAccess[UnderlyingObj] = Access; + DEBUG(dbgs() << " " << *UnderlyingObj << "\n"); + } + } + } + + for (auto AV : AS) { + Value *Ptr = AV.getValue(); + + // For a single memory access in AliasSetTracker, Accesses may contain + // both read and write, and they both need to be handled for CheckDeps. + for (auto AC : DeferredAccesses) { + if (AC.getPointer() != Ptr) + continue; + + bool IsWrite = AC.getInt(); + + // If we're using the deferred access set, then it contains only + // reads. + bool IsReadOnlyPtr = ReadOnlyPtr.count(Ptr) && !IsWrite; + if (!IsReadOnlyPtr) + continue; + // Otherwise, the pointer must be in the PtrAccessSet, either as a + // read or a write. + assert((IsReadOnlyPtr || IsWrite || + DeferredAccesses.count(MemAccessInfo(Ptr, false))) && + "Alias-set pointer not in the access set?"); + + MemAccessInfo Access(Ptr, IsWrite); + DepCands.insert(Access); + + // If this is a write - check other reads and writes for conflicts. If + // this is a read only check other writes for conflicts (but only if + // there is no other write to the ptr - this is an optimization to + // catch "a[i] = a[i] + " without having to do a dependence check). + if ((IsWrite || IsReadOnlyPtr) && SetHasWrite) { + CheckDeps.insert(Access); + IsRTCheckAnalysisNeeded = true; + } + + if (IsWrite) + SetHasWrite = true; + + // Create sets of pointers connected by a shared alias set and + // underlying object. + typedef SmallVector ValueVector; + ValueVector TempObjects; + + GetUnderlyingObjects(Ptr, TempObjects, DL, LI); + DEBUG(dbgs() << "Underlying objects for pointer " << *Ptr << "\n"); + for (Value *UnderlyingObj : TempObjects) { + // nullptr never alias, don't join sets for pointer that have "null" + // in their UnderlyingObjects list. + if (isa(UnderlyingObj)) continue; - } - // If this is a write - check other reads and writes for conflicts. If - // this is a read only check other writes for conflicts (but only if - // there is no other write to the ptr - this is an optimization to - // catch "a[i] = a[i] + " without having to do a dependence check). - if ((IsWrite || IsReadOnlyPtr) && SetHasWrite) { - CheckDeps.insert(Access); - IsRTCheckAnalysisNeeded = true; - } + UnderlyingObjToAccessMap::iterator Prev = + ObjToLastAccess.find(UnderlyingObj); + if (Prev != ObjToLastAccess.end()) + DepCands.unionSets(Access, Prev->second); - if (IsWrite) - SetHasWrite = true; - - // Create sets of pointers connected by a shared alias set and - // underlying object. - typedef SmallVector ValueVector; - ValueVector TempObjects; - - GetUnderlyingObjects(Ptr, TempObjects, DL, LI); - DEBUG(dbgs() << "Underlying objects for pointer " << *Ptr << "\n"); - for (Value *UnderlyingObj : TempObjects) { - // nullptr never alias, don't join sets for pointer that have "null" - // in their UnderlyingObjects list. - if (isa(UnderlyingObj)) - continue; - - UnderlyingObjToAccessMap::iterator Prev = - ObjToLastAccess.find(UnderlyingObj); - if (Prev != ObjToLastAccess.end()) - DepCands.unionSets(Access, Prev->second); - - ObjToLastAccess[UnderlyingObj] = Access; - DEBUG(dbgs() << " " << *UnderlyingObj << "\n"); - } + ObjToLastAccess[UnderlyingObj] = Access; + DEBUG(dbgs() << " " << *UnderlyingObj << "\n"); } } } @@ -819,14 +884,10 @@ } /// \brief Check whether the access through \p Ptr has a constant stride. -int llvm::isStridedPtr(PredicatedScalarEvolution &PSE, Value *Ptr, +int llvm::isStridedPtr(PredicatedScalarEvolution &PSE, Value *Ptr, Type *AccessTy, const Loop *Lp, const ValueToValueMap &StridesMap) { - Type *Ty = Ptr->getType(); - assert(Ty->isPointerTy() && "Unexpected non-ptr"); - // Make sure that the pointer does not point to aggregate types. - auto *PtrTy = cast(Ty); - if (PtrTy->getElementType()->isAggregateType()) { + if (AccessTy->isAggregateType()) { DEBUG(dbgs() << "LAA: Bad stride - Not a pointer to a scalar type" << *Ptr << "\n"); return 0; @@ -854,9 +915,10 @@ // An getelementptr without an inbounds attribute and unit stride would have // to access the pointer value "0" which is undefined behavior in address // space 0, therefore we can also vectorize this case. + Type *Ty = Ptr->getType(); bool IsInBoundsGEP = isInBoundsGep(Ptr); bool IsNoWrapAddRec = isNoWrapAddRec(Ptr, AR, PSE.getSE(), Lp); - bool IsInAddressSpaceZero = PtrTy->getAddressSpace() == 0; + bool IsInAddressSpaceZero = cast(Ty)->getAddressSpace() == 0; if (!IsNoWrapAddRec && !IsInBoundsGEP && !IsInAddressSpaceZero) { DEBUG(dbgs() << "LAA: Bad stride - Pointer may wrap in the address space " << *Ptr << " SCEV: " << *PtrScev << "\n"); @@ -875,7 +937,7 @@ } auto &DL = Lp->getHeader()->getModule()->getDataLayout(); - int64_t Size = DL.getTypeAllocSize(PtrTy->getElementType()); + int64_t Size = DL.getTypeAllocSize(AccessTy); const APInt &APStepVal = C->getAPInt(); // Huge step value - give up. @@ -1050,8 +1112,16 @@ const SCEV *AScev = replaceSymbolicStrideSCEV(PSE, Strides, APtr); const SCEV *BScev = replaceSymbolicStrideSCEV(PSE, Strides, BPtr); - int StrideAPtr = isStridedPtr(PSE, APtr, InnermostLoop, Strides); - int StrideBPtr = isStridedPtr(PSE, BPtr, InnermostLoop, Strides); + Type *ATy = getTypeForAccess(APtr, AIsWrite); + Type *BTy = getTypeForAccess(BPtr, BIsWrite); + + if (!ATy || !BTy) { + DEBUG(dbgs() << "Pointer access with varying load/store type\n"); + return Dependence::Unknown; + } + + int StrideAPtr = isStridedPtr(PSE, APtr, ATy, InnermostLoop, Strides); + int StrideBPtr = isStridedPtr(PSE, BPtr, BTy, InnermostLoop, Strides); const SCEV *Src = AScev; const SCEV *Sink = BScev; @@ -1090,8 +1160,6 @@ return Dependence::Unknown; } - Type *ATy = APtr->getType()->getPointerElementType(); - Type *BTy = BPtr->getType()->getPointerElementType(); auto &DL = InnermostLoop->getHeader()->getModule()->getDataLayout(); unsigned TypeByteSize = DL.getTypeAllocSize(ATy); @@ -1290,6 +1358,26 @@ return Insts; } +Type *MemoryDepChecker::getTypeForAccess(Value *Ptr, bool isWrite) const { + MemAccessInfo Access(Ptr, isWrite); + Type *Ty = nullptr; + for (auto Idx : Accesses.find(Access)->second) { + Type *AccessTy; + Instruction *I = InstMap[Idx]; + if (isWrite) + AccessTy = cast(I)->getValueOperand()->getType(); + else + AccessTy = cast(I)->getType(); + + // Make sure that the types are identical. + if (Ty && Ty != AccessTy) + return nullptr; + + Ty = AccessTy; + } + return Ty; +} + const char *MemoryDepChecker::Dependence::DepName[] = { "NoDep", "Unknown", "Forward", "ForwardButPreventsForwarding", "Backward", "BackwardVectorizable", "BackwardVectorizableButPreventsForwarding"}; @@ -1475,7 +1563,7 @@ if (blockNeedsPredication(ST->getParent(), TheLoop, DT)) Loc.AATags.TBAA = nullptr; - Accesses.addStore(Loc); + Accesses.addStore(Loc, ST->getValueOperand()->getType()); } } @@ -1499,7 +1587,8 @@ // read a few words, modify, and write a few words, and some of the // words may be written to the same address. bool IsReadOnlyPtr = false; - if (Seen.insert(Ptr).second || !isStridedPtr(PSE, Ptr, TheLoop, Strides)) { + if (Seen.insert(Ptr).second || + !isStridedPtr(PSE, Ptr, LD->getType(), TheLoop, Strides)) { ++NumReads; IsReadOnlyPtr = true; } @@ -1511,7 +1600,7 @@ if (blockNeedsPredication(LD->getParent(), TheLoop, DT)) Loc.AATags.TBAA = nullptr; - Accesses.addLoad(Loc, IsReadOnlyPtr); + Accesses.addLoad(Loc, LD->getType(), IsReadOnlyPtr); } // If we write (or read-write) to a single destination and there are no Index: lib/Analysis/MemDerefPrinter.cpp =================================================================== --- lib/Analysis/MemDerefPrinter.cpp +++ lib/Analysis/MemDerefPrinter.cpp @@ -56,9 +56,11 @@ for (auto &I: instructions(F)) { if (LoadInst *LI = dyn_cast(&I)) { Value *PO = LI->getPointerOperand(); - if (isDereferenceablePointer(PO, DL)) + uint64_t Size = LI->getLoadedSize(); + unsigned Align = LI->getActualAlignment(); + if (isDereferenceablePointer(PO, Size, DL)) Deref.push_back(PO); - if (isDereferenceableAndAlignedPointer(PO, LI->getAlignment(), DL)) + if (isDereferenceableAndAlignedPointer(PO, Size, Align, DL)) DerefAndAligned.insert(PO); } } Index: lib/Analysis/MemoryBuiltins.cpp =================================================================== --- lib/Analysis/MemoryBuiltins.cpp +++ lib/Analysis/MemoryBuiltins.cpp @@ -275,7 +275,7 @@ Type *llvm::getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI) { PointerType *PT = getMallocType(CI, TLI); - return PT ? PT->getElementType() : nullptr; + return PT ? PT->getPointerElementType() : nullptr; } /// getMallocArraySize - Returns the array size of a malloc call. If the @@ -463,7 +463,7 @@ return unknown(); } PointerType *PT = cast(A.getType()); - APInt Size(IntTyBits, DL.getTypeAllocSize(PT->getElementType())); + APInt Size(IntTyBits, DL.getTypeAllocSize(PT->getPointerElementType())); return std::make_pair(align(Size, A.getParamAlignment()), Zero); } @@ -552,7 +552,7 @@ if (!GV.hasDefinitiveInitializer()) return unknown(); - APInt Size(IntTyBits, DL.getTypeAllocSize(GV.getType()->getElementType())); + APInt Size(IntTyBits, DL.getTypeAllocSize(GV.getValueType())); return std::make_pair(align(Size, GV.getAlignment()), Zero); } Index: lib/Analysis/ObjCARCInstKind.cpp =================================================================== --- lib/Analysis/ObjCARCInstKind.cpp +++ lib/Analysis/ObjCARCInstKind.cpp @@ -97,7 +97,7 @@ if (AI == AE) // Argument is a pointer. if (PointerType *PTy = dyn_cast(A0->getType())) { - Type *ETy = PTy->getElementType(); + Type *ETy = PTy->getPointerElementType(); // Argument is i8*. if (ETy->isIntegerTy(8)) return StringSwitch(F->getName()) @@ -122,7 +122,7 @@ // Argument is i8** if (PointerType *Pte = dyn_cast(ETy)) - if (Pte->getElementType()->isIntegerTy(8)) + if (Pte->getPointerElementType()->isIntegerTy(8)) return StringSwitch(F->getName()) .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained) .Case("objc_loadWeak", ARCInstKind::LoadWeak) @@ -134,10 +134,10 @@ const Argument *A1 = &*AI++; if (AI == AE) if (PointerType *PTy = dyn_cast(A0->getType())) - if (PointerType *Pte = dyn_cast(PTy->getElementType())) - if (Pte->getElementType()->isIntegerTy(8)) + if (PointerType *Pte = dyn_cast(PTy->getPointerElementType())) + if (Pte->getPointerElementType()->isIntegerTy(8)) if (PointerType *PTy1 = dyn_cast(A1->getType())) { - Type *ETy1 = PTy1->getElementType(); + Type *ETy1 = PTy1->getPointerElementType(); // Second argument is i8* if (ETy1->isIntegerTy(8)) return StringSwitch(F->getName()) @@ -147,7 +147,7 @@ .Default(ARCInstKind::CallOrUser); // Second argument is i8**. if (PointerType *Pte1 = dyn_cast(ETy1)) - if (Pte1->getElementType()->isIntegerTy(8)) + if (Pte1->getPointerElementType()->isIntegerTy(8)) return StringSwitch(F->getName()) .Case("objc_moveWeak", ARCInstKind::MoveWeak) .Case("objc_copyWeak", ARCInstKind::CopyWeak) Index: lib/Analysis/PHITransAddr.cpp =================================================================== --- lib/Analysis/PHITransAddr.cpp +++ lib/Analysis/PHITransAddr.cpp @@ -229,7 +229,8 @@ return GEP; // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(GEPOps, DL, TLI, DT, AC)) { + if (Value *V = SimplifyGEPInst(GEP->getSourceElementType(), + GEPOps, DL, TLI, DT, AC)) { for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) RemoveInstInputs(GEPOps[i], InstInputs); Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -387,7 +387,7 @@ if (ConstantInt *CI = dyn_cast(CE->getOperand(1))) if (CI->isOne()) { AllocTy = cast(CE->getOperand(0)->getType()) - ->getElementType(); + ->getPointerElementType(); return true; } @@ -401,7 +401,7 @@ if (CE->getOpcode() == Instruction::GetElementPtr && CE->getOperand(0)->isNullValue()) { Type *Ty = - cast(CE->getOperand(0)->getType())->getElementType(); + cast(CE->getOperand(0)->getType())->getPointerElementType(); if (StructType *STy = dyn_cast(Ty)) if (!STy->isPacked() && CE->getNumOperands() == 3 && @@ -428,7 +428,7 @@ CE->getOperand(0)->isNullValue() && CE->getOperand(1)->isNullValue()) { Type *Ty = - cast(CE->getOperand(0)->getType())->getElementType(); + cast(CE->getOperand(0)->getType())->getPointerElementType(); // Ignore vector types here so that ScalarEvolutionExpander doesn't // emit getelementptrs that index into vectors. if (Ty->isStructTy() || Ty->isArrayTy()) { @@ -2965,7 +2965,12 @@ CurTy = STy->getTypeAtIndex(Index); } else { // Update CurTy to its element type. - CurTy = cast(CurTy)->getElementType(); + if (auto *PtrTy = dyn_cast(CurTy)) { + CurTy = PtrTy->getPointerElementType(); + } else { + CurTy = cast(CurTy)->getElementType(); + } + // For an array, add the element offset, explicitly scaled. const SCEV *ElementSize = getSizeOfExpr(IntPtrTy, CurTy); // Getelementptr indices are signed. @@ -4089,7 +4094,7 @@ 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 IndexExprs; @@ -5908,9 +5913,9 @@ Operands[1], DL, TLI); if (LoadInst *LI = dyn_cast(I)) { if (!LI->isVolatile()) - return ConstantFoldLoadFromConstPtr(Operands[0], DL); + return ConstantFoldLoadFromConstPtr(Operands[0], LI->getType(), DL); } - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Operands, DL, + return ConstantFoldInstOperands(I, I->getOpcode(), I->getType(), Operands, DL, TLI); } @@ -6188,10 +6193,10 @@ return nullptr; if (PointerType *PTy = dyn_cast(C->getType())) { - if (PTy->getElementType()->isStructTy()) + if (PTy->getPointerElementType()->isStructTy()) C2 = ConstantExpr::getIntegerCast( C2, Type::getInt32Ty(C->getContext()), true); - C = ConstantExpr::getGetElementPtr(PTy->getElementType(), C, C2); + C = ConstantExpr::getGetElementPtr(PTy->getPointerElementType(), C, C2); } else C = ConstantExpr::getAdd(C, C2); } @@ -6297,9 +6302,9 @@ Operands[1], DL, &TLI); else if (const LoadInst *LI = dyn_cast(I)) { if (!LI->isVolatile()) - C = ConstantFoldLoadFromConstPtr(Operands[0], DL); + C = ConstantFoldLoadFromConstPtr(Operands[0], LI->getType(), DL); } else - C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), Operands, + C = ConstantFoldInstOperands(I, I->getOpcode(), I->getType(), Operands, DL, &TLI); if (!C) return V; return getSCEV(C); Index: lib/Analysis/ScalarEvolutionExpander.cpp =================================================================== --- lib/Analysis/ScalarEvolutionExpander.cpp +++ lib/Analysis/ScalarEvolutionExpander.cpp @@ -389,7 +389,7 @@ PointerType *PTy, Type *Ty, Value *V) { - Type *OriginalElTy = PTy->getElementType(); + Type *OriginalElTy = PTy->getPointerElementType(); Type *ElTy = OriginalElTy; SmallVector GepIndices; SmallVector Ops(op_begin, op_end); Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -1338,7 +1338,7 @@ AllocaInst *AI = cast(I); unsigned Align = AI->getAlignment(); if (Align == 0) - Align = DL.getABITypeAlignment(AI->getType()->getElementType()); + Align = DL.getABITypeAlignment(AI->getAllocatedType()); if (Align > 0) KnownZero = APInt::getLowBitsSet(BitWidth, countTrailingZeros(Align)); @@ -1560,7 +1560,7 @@ Align = GO->getAlignment(); if (Align == 0) { if (auto *GVar = dyn_cast(GO)) { - Type *ObjectType = GVar->getType()->getElementType(); + Type *ObjectType = GVar->getValueType(); if (ObjectType->isSized()) { // If the object is defined in the current Module, we'll be giving // it the preferred alignment. Otherwise, we have to assume that it @@ -1577,7 +1577,7 @@ if (!Align && A->hasStructRetAttr()) { // An sret parameter has at least the ABI alignment of the return type. - Type *EltTy = cast(A->getType())->getElementType(); + Type *EltTy = cast(A->getType())->getPointerElementType(); if (EltTy->isSized()) Align = DL.getABITypeAlignment(EltTy); } @@ -2875,8 +2875,7 @@ return false; // Make sure the index-ee is a pointer to array of i8. - PointerType *PT = cast(GEP->getOperand(0)->getType()); - ArrayType *AT = dyn_cast(PT->getElementType()); + ArrayType *AT = dyn_cast(GEP->getSourceElementType()); if (!AT || !AT->getElementType()->isIntegerTy(8)) return false; @@ -3116,12 +3115,11 @@ } static bool isDereferenceableFromAttribute(const Value *BV, APInt Offset, - Type *Ty, const DataLayout &DL, + uint64_t Size, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI) { assert(Offset.isNonNegative() && "offset can't be negative"); - assert(Ty->isSized() && "must be sized"); APInt DerefBytes(Offset.getBitWidth(), 0); bool CheckForNonNull = false; @@ -3153,32 +3151,19 @@ } if (DerefBytes.getBoolValue()) - if (DerefBytes.uge(Offset + DL.getTypeStoreSize(Ty))) + if (DerefBytes.uge(Offset + Size)) if (!CheckForNonNull || isKnownNonNullAt(BV, CtxI, DT, TLI)) return true; return false; } -static bool isDereferenceableFromAttribute(const Value *V, const DataLayout &DL, - const Instruction *CtxI, - const DominatorTree *DT, - const TargetLibraryInfo *TLI) { - Type *VTy = V->getType(); - Type *Ty = VTy->getPointerElementType(); - if (!Ty->isSized()) - return false; - - APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); - return isDereferenceableFromAttribute(V, Offset, Ty, DL, CtxI, DT, TLI); -} - static bool isAligned(const Value *Base, APInt Offset, unsigned Align, const DataLayout &DL) { APInt BaseAlign(Offset.getBitWidth(), getAlignment(Base, DL)); if (!BaseAlign) { - Type *Ty = Base->getType()->getPointerElementType(); + Type *Ty = cast(Base->getType())->getPointerElementType(); BaseAlign = DL.getABITypeAlignment(Ty); } @@ -3196,8 +3181,8 @@ /// Test if V is always a pointer to allocated and suitably aligned memory for /// a simple load or store. static bool isDereferenceableAndAlignedPointer( - const Value *V, unsigned Align, const DataLayout &DL, - const Instruction *CtxI, const DominatorTree *DT, + const Value *V, uint64_t Size, unsigned Align, + const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI, SmallPtrSetImpl &Visited) { // Note that it is not safe to speculate into a malloc'd region because // malloc may return null. @@ -3214,13 +3199,20 @@ // is at least as large as for the resulting pointer type, then // we can look through the bitcast. if (const BitCastOperator *BC = dyn_cast(V)) { - Type *STy = BC->getSrcTy()->getPointerElementType(), - *DTy = BC->getDestTy()->getPointerElementType(); - if (STy->isSized() && DTy->isSized() && - (DL.getTypeStoreSize(STy) >= DL.getTypeStoreSize(DTy)) && - (DL.getABITypeAlignment(STy) >= DL.getABITypeAlignment(DTy))) - return isDereferenceableAndAlignedPointer(BC->getOperand(0), Align, DL, - CtxI, DT, TLI, Visited); + Type *STy = cast(BC->getSrcTy())->getPointerElementType(), + *DTy = cast(BC->getDestTy())->getPointerElementType(); + if (STy->isSized() && DTy->isSized()) { + uint64_t SSize = DL.getTypeStoreSize(STy); + uint64_t DSize = DL.getTypeStoreSize(DTy); + unsigned SAlign = DL.getABITypeAlignment(STy); + unsigned DAlign = DL.getABITypeAlignment(DTy); + if (SSize >= DSize && SAlign >= DAlign) { + if (Align == DAlign) + Align = SAlign; + return isDereferenceableAndAlignedPointer(BC->getOperand(0), SSize, Align, + DL, CtxI, DT, TLI, Visited); + } + } } // Global variables which can't collapse to null are ok. @@ -3233,33 +3225,36 @@ if (A->hasByValAttr()) return isAligned(V, Align, DL); - if (isDereferenceableFromAttribute(V, DL, CtxI, DT, TLI)) + Type *VTy = V->getType(); + APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); + if(isDereferenceableFromAttribute(V, Offset, Size, CtxI, DT, TLI)) return isAligned(V, Align, DL); // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast(V)) { - Type *VTy = GEP->getType(); - Type *Ty = VTy->getPointerElementType(); const Value *Base = GEP->getPointerOperand(); // Conservatively require that the base pointer be fully dereferenceable // and aligned. if (!Visited.insert(Base).second) return false; - if (!isDereferenceableAndAlignedPointer(Base, Align, DL, CtxI, DT, TLI, - Visited)) + + Type *BaseType = GEP->getSourceElementType(); + uint64_t BaseSize = DL.getTypeAllocSize(BaseType); + unsigned BaseAlign = DL.getABITypeAlignment(BaseType); + if (BaseAlign < Align) + BaseAlign = Align; + if (!isDereferenceableAndAlignedPointer(Base, BaseSize, BaseAlign, + DL, CtxI, DT, TLI, Visited)) return false; - APInt Offset(DL.getPointerTypeSizeInBits(VTy), 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(); assert(isPowerOf2_32(Align) && "must be a power of 2!"); - return (Offset + LoadSize).ule(DL.getTypeAllocSize(BaseType)) && + return (Offset + Size).ule(BaseSize) && !(Offset & APInt(Offset.getBitWidth(), Align-1)); } @@ -3268,18 +3263,20 @@ if (I->getIntrinsicID() == Intrinsic::experimental_gc_relocate) { GCRelocateOperands RelocateInst(I); return isDereferenceableAndAlignedPointer( - RelocateInst.getDerivedPtr(), Align, DL, CtxI, DT, TLI, Visited); + RelocateInst.getDerivedPtr(), Size, Align, + DL, CtxI, DT, TLI, Visited); } if (const AddrSpaceCastInst *ASC = dyn_cast(V)) - return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, DL, - CtxI, DT, TLI, Visited); + return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Size, Align, + DL, CtxI, DT, TLI, Visited); // If we don't know, assume the worst. return false; } -bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, +bool llvm::isDereferenceableAndAlignedPointer(const Value *V, uint64_t Size, + unsigned Align, const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, @@ -3288,33 +3285,25 @@ // attribute, we know exactly how many bytes are dereferenceable. If we can // determine the exact offset to the attributed variable, we can use that // information here. - Type *VTy = V->getType(); - Type *Ty = VTy->getPointerElementType(); - - // Require ABI alignment for loads without alignment specification - if (Align == 0) - Align = DL.getABITypeAlignment(Ty); + APInt Offset(DL.getTypeStoreSizeInBits(V->getType()), 0); + const Value *BV = V->stripAndAccumulateInBoundsConstantOffsets(DL, Offset); - if (Ty->isSized()) { - APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); - const Value *BV = V->stripAndAccumulateInBoundsConstantOffsets(DL, Offset); - - if (Offset.isNonNegative()) - if (isDereferenceableFromAttribute(BV, Offset, Ty, DL, CtxI, DT, TLI) && - isAligned(BV, Offset, Align, DL)) - return true; - } + if (Offset.isNonNegative()) + if (isDereferenceableFromAttribute(BV, Offset, Size, CtxI, DT, TLI) && + isAligned(BV, Offset, Align, DL)) + return true; SmallPtrSet Visited; - return ::isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT, TLI, - Visited); + return ::isDereferenceableAndAlignedPointer(V, Size, Align, DL, + CtxI, DT, TLI, Visited); } -bool llvm::isDereferenceablePointer(const Value *V, const DataLayout &DL, +bool llvm::isDereferenceablePointer(const Value *V, uint64_t Size, + const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI) { - return isDereferenceableAndAlignedPointer(V, 1, DL, CtxI, DT, TLI); + return isDereferenceableAndAlignedPointer(V, Size, 1, DL, CtxI, DT, TLI); } bool llvm::isSafeToSpeculativelyExecute(const Value *V, @@ -3372,7 +3361,8 @@ return false; const DataLayout &DL = LI->getModule()->getDataLayout(); return isDereferenceableAndAlignedPointer( - LI->getPointerOperand(), LI->getAlignment(), DL, CtxI, DT, TLI); + LI->getPointerOperand(), LI->getLoadedSize(), + LI->getActualAlignment(), DL, CtxI, DT, TLI); } case Instruction::Call: { if (const IntrinsicInst *II = dyn_cast(Inst)) { Index: lib/Analysis/VectorUtils.cpp =================================================================== --- lib/Analysis/VectorUtils.cpp +++ lib/Analysis/VectorUtils.cpp @@ -231,8 +231,7 @@ unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) { const DataLayout &DL = Gep->getModule()->getDataLayout(); unsigned LastOperand = Gep->getNumOperands() - 1; - unsigned GEPAllocSize = DL.getTypeAllocSize( - cast(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())) { @@ -318,8 +317,6 @@ // Strip off the size of access multiplication if we are still analyzing the // pointer. if (OrigPtr == Ptr) { - const DataLayout &DL = Lp->getHeader()->getModule()->getDataLayout(); - DL.getTypeAllocSize(PtrTy->getElementType()); if (const SCEVMulExpr *M = dyn_cast(V)) { if (M->getOperand(0)->getSCEVType() != scConstant) return nullptr; Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -708,7 +708,7 @@ return Error(AliaseeLoc, "An alias must have pointer type"); unsigned AddrSpace = PTy->getAddressSpace(); - if (Ty != PTy->getElementType()) + if (Ty != PTy->getPointerElementType()) return Error( ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); @@ -1066,10 +1066,10 @@ static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy, const std::string &Name) { - if (auto *FT = dyn_cast(PTy->getElementType())) + if (auto *FT = dyn_cast(PTy->getPointerElementType())) return Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); else - return new GlobalVariable(*M, PTy->getElementType(), false, + return new GlobalVariable(*M, PTy->getPointerElementType(), false, GlobalValue::ExternalWeakLinkage, nullptr, Name, nullptr, GlobalVariable::NotThreadLocal, PTy->getAddressSpace()); @@ -3002,7 +3002,7 @@ Type *BaseType = Elts[0]->getType(); auto *BasePointerType = cast(BaseType->getScalarType()); - if (Ty != BasePointerType->getElementType()) + if (Ty != BasePointerType->getPointerElementType()) return Error( ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); @@ -5808,7 +5808,7 @@ if (Ordering == Release || Ordering == AcquireRelease) return Error(Loc, "atomic load cannot use Release ordering"); - if (Ty != cast(Val->getType())->getElementType()) + if (Ty != cast(Val->getType())->getPointerElementType()) return Error(ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); @@ -5851,7 +5851,7 @@ return Error(PtrLoc, "store operand must be a pointer"); if (!Val->getType()->isFirstClassType()) return Error(Loc, "store operand must be a first class value"); - if (cast(Ptr->getType())->getElementType() != Val->getType()) + if (cast(Ptr->getType())->getPointerElementType() != Val->getType()) return Error(Loc, "stored value and pointer type do not match"); if (isAtomic && !Alignment) return Error(Loc, "atomic store must have explicit non-zero alignment"); @@ -5897,9 +5897,9 @@ return TokError("cmpxchg failure ordering cannot include release semantics"); if (!Ptr->getType()->isPointerTy()) return Error(PtrLoc, "cmpxchg operand must be a pointer"); - if (cast(Ptr->getType())->getElementType() != Cmp->getType()) + if (cast(Ptr->getType())->getPointerElementType() != Cmp->getType()) return Error(CmpLoc, "compare value and pointer type do not match"); - if (cast(Ptr->getType())->getElementType() != New->getType()) + if (cast(Ptr->getType())->getPointerElementType() != New->getType()) return Error(NewLoc, "new value and pointer type do not match"); if (!New->getType()->isIntegerTy()) return Error(NewLoc, "cmpxchg operand must be an integer"); @@ -5956,7 +5956,7 @@ return TokError("atomicrmw cannot be unordered"); if (!Ptr->getType()->isPointerTy()) return Error(PtrLoc, "atomicrmw operand must be a pointer"); - if (cast(Ptr->getType())->getElementType() != Val->getType()) + if (cast(Ptr->getType())->getPointerElementType() != Val->getType()) return Error(ValLoc, "atomicrmw value and pointer type do not match"); if (!Val->getType()->isIntegerTy()) return Error(ValLoc, "atomicrmw operand must be an integer"); @@ -6010,7 +6010,7 @@ if (!BasePointerType) return Error(Loc, "base of getelementptr must be a pointer"); - if (Ty != BasePointerType->getElementType()) + if (Ty != BasePointerType->getPointerElementType()) return Error(ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -2771,8 +2771,8 @@ if (PointeeType && PointeeType != - cast(Elts[0]->getType()->getScalarType()) - ->getElementType()) + cast(Elts[0]->getType()->getScalarType()) + ->getPointerElementType()) return error("Explicit gep operator type does not match pointee type " "of pointer operand"); @@ -2905,7 +2905,7 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; PointerType *PTy = cast(CurTy); - V = InlineAsm::get(cast(PTy->getElementType()), + V = InlineAsm::get(cast(PTy->getPointerElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack); break; } @@ -2930,7 +2930,7 @@ for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; PointerType *PTy = cast(CurTy); - V = InlineAsm::get(cast(PTy->getElementType()), + V = InlineAsm::get(cast(PTy->getPointerElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect)); break; @@ -3473,7 +3473,7 @@ if (!Ty->isPointerTy()) return error("Invalid type for value"); AddressSpace = cast(Ty)->getAddressSpace(); - Ty = cast(Ty)->getElementType(); + Ty = cast(Ty)->getPointerElementType(); } uint64_t RawLinkage = Record[3]; @@ -3546,7 +3546,7 @@ if (!Ty) return error("Invalid record"); if (auto *PTy = dyn_cast(Ty)) - Ty = PTy->getElementType(); + Ty = PTy->getPointerElementType(); auto *FTy = dyn_cast(Ty); if (!FTy) return error("Invalid type for value"); @@ -3637,7 +3637,7 @@ auto *PTy = dyn_cast(Ty); if (!PTy) return error("Invalid type for value"); - Ty = PTy->getElementType(); + Ty = PTy->getPointerElementType(); AddrSpace = PTy->getAddressSpace(); } else { AddrSpace = Record[OpNum++]; @@ -3935,7 +3935,7 @@ LLVMContext &Context = PtrType->getContext(); if (!isa(PtrType)) return error(Context, "Load/Store operand is not a pointer type"); - Type *ElemType = cast(PtrType)->getElementType(); + Type *ElemType = cast(PtrType)->getPointerElementType(); if (ValType && ValType != ElemType) return error(Context, "Explicit load/store type does not match pointee " @@ -4174,11 +4174,11 @@ return error("Invalid record"); if (!Ty) - Ty = cast(BasePtr->getType()->getScalarType()) - ->getElementType(); + Ty = cast(BasePtr->getType()->getScalarType()) + ->getPointerElementType(); else if (Ty != - cast(BasePtr->getType()->getScalarType()) - ->getElementType()) + cast(BasePtr->getType()->getScalarType()) + ->getPointerElementType()) return error( "Explicit gep type does not match pointee type of pointer operand"); @@ -4680,10 +4680,10 @@ if (!CalleeTy) return error("Callee is not a pointer"); if (!FTy) { - FTy = dyn_cast(CalleeTy->getElementType()); + FTy = dyn_cast(CalleeTy->getPointerElementType()); if (!FTy) return error("Callee is not of pointer to function type"); - } else if (CalleeTy->getElementType() != FTy) + } else if (CalleeTy->getPointerElementType() != FTy) return error("Explicit invoke type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) @@ -4828,7 +4828,7 @@ auto *PTy = dyn_cast_or_null(Ty); if (!PTy) return error("Old-style alloca with a non-pointer type"); - Ty = PTy->getElementType(); + Ty = PTy->getPointerElementType(); } Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); @@ -4858,7 +4858,7 @@ if (std::error_code EC = typeCheckLoadStoreInst(Ty, Op->getType())) return EC; if (!Ty) - Ty = cast(Op->getType())->getElementType(); + Ty = cast(Op->getType())->getPointerElementType(); unsigned Align; if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) @@ -4882,7 +4882,7 @@ if (std::error_code EC = typeCheckLoadStoreInst(Ty, Op->getType())) return EC; if (!Ty) - Ty = cast(Op->getType())->getElementType(); + Ty = cast(Op->getType())->getPointerElementType(); AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); if (Ordering == NotAtomic || Ordering == Release || @@ -4908,7 +4908,7 @@ (BitCode == bitc::FUNC_CODE_INST_STORE ? getValueTypePair(Record, OpNum, NextValueNo, Val) : popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), + cast(Ptr->getType())->getPointerElementType(), Val)) || OpNum + 2 != Record.size()) return error("Invalid record"); @@ -4932,7 +4932,7 @@ (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC ? getValueTypePair(Record, OpNum, NextValueNo, Val) : popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), + cast(Ptr->getType())->getPointerElementType(), Val)) || OpNum + 4 != Record.size()) return error("Invalid record"); @@ -4965,7 +4965,7 @@ (BitCode == bitc::FUNC_CODE_INST_CMPXCHG ? getValueTypePair(Record, OpNum, NextValueNo, Cmp) : popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), + cast(Ptr->getType())->getPointerElementType(), Cmp)) || popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || Record.size() < OpNum + 3 || Record.size() > OpNum + 5) @@ -5008,7 +5008,7 @@ Value *Ptr, *Val; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), Val) || + cast(Ptr->getType())->getPointerElementType(), Val) || OpNum+4 != Record.size()) return error("Invalid record"); AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]); @@ -5065,10 +5065,10 @@ if (!OpTy) return error("Callee is not a pointer type"); if (!FTy) { - FTy = dyn_cast(OpTy->getElementType()); + FTy = dyn_cast(OpTy->getPointerElementType()); if (!FTy) return error("Callee is not of pointer to function type"); - } else if (OpTy->getElementType() != FTy) + } else if (OpTy->getPointerElementType() != FTy) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -425,7 +425,7 @@ PointerType *PTy = cast(T); // POINTER: [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; - TypeVals.push_back(VE.getTypeID(PTy->getElementType())); + TypeVals.push_back(VE.getTypeID(PTy->getPointerElementType())); unsigned AddressSpace = PTy->getAddressSpace(); TypeVals.push_back(AddressSpace); if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -360,7 +360,7 @@ MCSymbol *GVSym = getSymbol(GV); EmitLinkage(GV, EmittedSym); // same linkage as GV const DataLayout &DL = GV->getParent()->getDataLayout(); - uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); + uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); unsigned AlignLog = getGVAlignmentLog2(GV, DL); unsigned WordSize = DL.getPointerSize(); unsigned Alignment = DL.getPointerABIAlignment(); @@ -429,7 +429,7 @@ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); const DataLayout &DL = GV->getParent()->getDataLayout(); - uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); + uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); // If the alignment is specified, we *must* obey it. Overaligning a global // with a specified alignment is a prompt way to break globals emitted to Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -84,7 +84,7 @@ // First operand points to a global struct. Value *Ptr = CE->getOperand(0); if (!isa(Ptr) || - !isa(cast(Ptr->getType())->getElementType())) + !isa(cast(Ptr->getType())->getPointerElementType())) return nullptr; // Second operand is zero. @@ -192,14 +192,14 @@ addToAccelTable = true; // GV is a merged global. DIELoc *Loc = new (DIEValueAllocator) DIELoc; - Value *Ptr = CE->getOperand(0); - MCSymbol *Sym = Asm->getSymbol(cast(Ptr)); + auto *Ptr = cast(CE->getOperand(0)); + MCSymbol *Sym = Asm->getSymbol(Ptr); DD->addArangeLabel(SymbolCU(this, Sym)); addOpAddress(*Loc, Sym); addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); SmallVector Idx(CE->op_begin() + 1, CE->op_end()); addUInt(*Loc, dwarf::DW_FORM_udata, - Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx)); + Asm->getDataLayout().getIndexedOffset(Ptr->getValueType(), Idx)); addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); } Index: lib/CodeGen/AtomicExpandPass.cpp =================================================================== --- lib/CodeGen/AtomicExpandPass.cpp +++ lib/CodeGen/AtomicExpandPass.cpp @@ -268,8 +268,7 @@ IRBuilder<> Builder(LI); AtomicOrdering Order = LI->getOrdering(); Value *Addr = LI->getPointerOperand(); - Type *Ty = cast(Addr->getType())->getElementType(); - Constant *DummyVal = Constant::getNullValue(Ty); + Constant *DummyVal = Constant::getNullValue(LI->getType()); Value *Pair = Builder.CreateAtomicCmpXchg( Addr, DummyVal, DummyVal, Order, Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -1743,7 +1743,7 @@ GlobalVariable *GV; if ((GV = dyn_cast(Val)) && GV->hasUniqueInitializer() && !GV->hasSection() && GV->getAlignment() < PrefAlign && - DL->getTypeAllocSize(GV->getType()->getElementType()) >= + DL->getTypeAllocSize(GV->getValueType()) >= MinSize + Offset2) GV->setAlignment(PrefAlign); } @@ -3431,7 +3431,7 @@ /// Add the ultimately found memory instructions to MemoryUses. static bool FindAllMemoryUses( Instruction *I, - SmallVectorImpl> &MemoryUses, + SmallVectorImpl &MemoryUses, SmallPtrSetImpl &ConsideredInsts, const TargetMachine &TM) { // If we already considered this instruction, we're done. if (!ConsideredInsts.insert(I).second) @@ -3446,14 +3446,14 @@ Instruction *UserI = cast(U.getUser()); if (LoadInst *LI = dyn_cast(UserI)) { - MemoryUses.push_back(std::make_pair(LI, U.getOperandNo())); + MemoryUses.push_back(LI); continue; } if (StoreInst *SI = dyn_cast(UserI)) { unsigned opNo = U.getOperandNo(); if (opNo == 0) return true; // Storing addr, not into addr. - MemoryUses.push_back(std::make_pair(SI, opNo)); + MemoryUses.push_back(SI); continue; } @@ -3553,7 +3553,7 @@ // check to see if their addressing modes will include this instruction. If // so, we can fold it into all uses, so it doesn't matter if it has multiple // uses. - SmallVector, 16> MemoryUses; + SmallVector MemoryUses; SmallPtrSet ConsideredInsts; if (FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TM)) return false; // Has a non-memory, non-foldable use! @@ -3564,17 +3564,21 @@ // *actually* fold the instruction. SmallVector MatchedAddrModeInsts; for (unsigned i = 0, e = MemoryUses.size(); i != e; ++i) { - Instruction *User = MemoryUses[i].first; - unsigned OpNo = MemoryUses[i].second; - - // Get the access type of this use. If the use isn't a pointer, we don't - // know what it accesses. - Value *Address = User->getOperand(OpNo); - PointerType *AddrTy = dyn_cast(Address->getType()); - if (!AddrTy) - return false; - Type *AddressAccessTy = AddrTy->getElementType(); - unsigned AS = AddrTy->getAddressSpace(); + Value *Address; + Type *AddressAccessTy; + unsigned AS; + + Instruction *User = MemoryUses[i]; + if (auto *LI = dyn_cast(User)) { + Address = LI->getPointerOperand(); + AddressAccessTy = LI->getType(); + AS = LI->getPointerAddressSpace(); + } else { + auto *SI = cast(User); + Address = SI->getPointerOperand(); + AddressAccessTy = SI->getValueOperand()->getType(); + AS = SI->getPointerAddressSpace(); + } // Do a match against the root of this address, ignoring profitability. This // will tell us if the addressing mode for the memory operation will Index: lib/CodeGen/GCRootLowering.cpp =================================================================== --- lib/CodeGen/GCRootLowering.cpp +++ lib/CodeGen/GCRootLowering.cpp @@ -170,8 +170,7 @@ for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I) if (!InitedRoots.count(*I)) { StoreInst *SI = new StoreInst( - ConstantPointerNull::get(cast( - cast((*I)->getType())->getElementType())), + ConstantPointerNull::get(cast((*I)->getAllocatedType())), *I); SI->insertAfter(*I); MadeChange = true; Index: lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FastISel.cpp +++ lib/CodeGen/SelectionDAG/FastISel.cpp @@ -513,7 +513,11 @@ } Ty = StTy->getElementType(Field); } else { - Ty = cast(Ty)->getElementType(); + if (auto *PtrTy = dyn_cast(Ty)) { + Ty = PtrTy->getPointerElementType(); + } else { + Ty = cast(Ty)->getElementType(); + } // If this is a constant subscript, handle it quickly. if (const auto *CI = dyn_cast(Idx)) { @@ -881,7 +885,7 @@ ImmutableCallSite CS(CI); PointerType *PT = cast(CS.getCalledValue()->getType()); - FunctionType *FTy = cast(PT->getElementType()); + FunctionType *FTy = cast(PT->getPointerElementType()); Type *RetTy = FTy->getReturnType(); ArgListTy Args; @@ -947,7 +951,7 @@ for (auto &Arg : CLI.getArgs()) { Type *FinalType = Arg.Ty; if (Arg.IsByVal) - FinalType = cast(Arg.Ty)->getElementType(); + FinalType = cast(Arg.Ty)->getPointerElementType(); bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); @@ -973,7 +977,7 @@ } if (Arg.IsByVal || Arg.IsInAlloca) { PointerType *Ty = cast(Arg.Ty); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Ty->getPointerElementType(); unsigned FrameSize = DL.getTypeAllocSize(ElementTy); // For ByVal, alignment should come from FE. BE will guess if this info is // not there, but there are cases it cannot get right. @@ -1011,7 +1015,7 @@ ImmutableCallSite CS(CI); PointerType *PT = cast(CS.getCalledValue()->getType()); - FunctionType *FuncTy = cast(PT->getElementType()); + FunctionType *FuncTy = cast(PT->getPointerElementType()); Type *RetTy = FuncTy->getReturnType(); ArgListTy Args; Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3000,7 +3000,12 @@ Ty = StTy->getElementType(Field); } else { - Ty = cast(Ty)->getElementType(); + if (auto *PtrTy = dyn_cast(Ty)) { + Ty = PtrTy->getPointerElementType(); + } else { + Ty = cast(Ty)->getElementType(); + } + MVT PtrTy = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout(), AS); unsigned PtrSize = PtrTy.getSizeInBits(); @@ -3120,6 +3125,7 @@ SDValue Ptr = getValue(SV); Type *Ty = I.getType(); + uint64_t Size = DAG.getDataLayout().getTypeStoreSize(Ty); bool isVolatile = I.isVolatile(); bool isNonTemporal = I.getMetadata(LLVMContext::MD_nontemporal) != nullptr; @@ -3133,7 +3139,7 @@ // throughout the function's lifetime. bool isInvariant = I.getMetadata(LLVMContext::MD_invariant_load) != nullptr && - isDereferenceablePointer(SV, DAG.getDataLayout()); + isDereferenceablePointer(SV, Size, DAG.getDataLayout()); unsigned Alignment = I.getAlignment(); AAMDNodes AAInfo; @@ -3153,8 +3159,7 @@ if (isVolatile || NumValues > MaxParallelChains) // Serialize volatile loads with other side effects. Root = getRoot(); - else if (AA->pointsToConstantMemory(MemoryLocation( - SV, DAG.getDataLayout().getTypeStoreSize(Ty), AAInfo))) { + else if (AA->pointsToConstantMemory(MemoryLocation(SV, Size, AAInfo))) { // Do not serialize (non-volatile) loads of constant memory with anything. Root = DAG.getEntryNode(); ConstantMemory = true; @@ -5343,7 +5348,7 @@ bool isTailCall, const BasicBlock *EHPadBB) { PointerType *PT = cast(CS.getCalledValue()->getType()); - FunctionType *FTy = cast(PT->getElementType()); + FunctionType *FTy = cast(PT->getPointerElementType()); Type *RetTy = FTy->getReturnType(); TargetLowering::ArgListTy Args; @@ -5413,7 +5418,7 @@ PointerType::getUnqual(LoadTy)); if (const Constant *LoadCst = ConstantFoldLoadFromConstPtr( - const_cast(LoadInput), *Builder.DL)) + const_cast(LoadInput), LoadTy, *Builder.DL)) return Builder.getValue(LoadCst); } @@ -5959,7 +5964,7 @@ llvm::PointerType *PtrTy = dyn_cast(OpTy); if (!PtrTy) report_fatal_error("Indirect operand for inline asm not a pointer!"); - OpTy = PtrTy->getElementType(); + OpTy = PtrTy->getPointerElementType(); } // Look for vector wrapped in a struct. e.g. { <16 x i8> }. @@ -7058,7 +7063,7 @@ ComputeValueVTs(*this, DL, Args[i].Ty, ValueVTs); Type *FinalType = Args[i].Ty; if (Args[i].isByVal) - FinalType = cast(Args[i].Ty)->getElementType(); + FinalType = cast(Args[i].Ty)->getPointerElementType(); bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters( FinalType, CLI.CallConv, CLI.IsVarArg); for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues; @@ -7091,7 +7096,7 @@ } if (Args[i].isByVal || Args[i].isInAlloca) { PointerType *Ty = cast(Args[i].Ty); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Ty->getPointerElementType(); Flags.setByValSize(DL.getTypeAllocSize(ElementTy)); // For ByVal, alignment should come from FE. BE will guess if this // info is not there but there are cases it cannot get right. @@ -7332,7 +7337,7 @@ unsigned PartBase = 0; Type *FinalType = I->getType(); if (F.getAttributes().hasAttribute(Idx, Attribute::ByVal)) - FinalType = cast(FinalType)->getElementType(); + FinalType = cast(FinalType)->getPointerElementType(); bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters( FinalType, F.getCallingConv(), F.isVarArg()); for (unsigned Value = 0, NumValues = ValueVTs.size(); @@ -7363,7 +7368,7 @@ } if (Flags.isByVal() || Flags.isInAlloca()) { PointerType *Ty = cast(I->getType()); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Ty->getPointerElementType(); Flags.setByValSize(DL.getTypeAllocSize(ElementTy)); // For ByVal, alignment should be passed from FE. BE will guess if // this info is not there but there are cases it cannot get right. Index: lib/CodeGen/SelectionDAG/StatepointLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -845,7 +845,7 @@ PointerType *CalleeType = cast( ImmutableStatepoint(I).getCalledValue()->getType()); Type *RetTy = - cast(CalleeType->getElementType())->getReturnType(); + cast(CalleeType->getPointerElementType())->getReturnType(); SDValue CopyFromReg = getCopyFromRegs(I, RetTy); assert(CopyFromReg.getNode()); Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -2375,7 +2375,7 @@ llvm::PointerType *PtrTy = dyn_cast(OpTy); if (!PtrTy) report_fatal_error("Indirect operand for inline asm not a pointer!"); - OpTy = PtrTy->getElementType(); + OpTy = PtrTy->getPointerElementType(); } // Look for vector wrapped in a struct. e.g. { <16 x i8> }. Index: lib/ExecutionEngine/ExecutionEngine.cpp =================================================================== --- lib/ExecutionEngine/ExecutionEngine.cpp +++ lib/ExecutionEngine/ExecutionEngine.cpp @@ -103,7 +103,7 @@ /// \brief Returns the address the GlobalVariable should be written into. The /// GVMemoryBlock object prefixes that. static char *Create(const GlobalVariable *GV, const DataLayout& TD) { - Type *ElTy = GV->getType()->getElementType(); + Type *ElTy = GV->getValueType(); size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy); void *RawMemory = ::operator new( RoundUpToAlignment(sizeof(GVMemoryBlock), @@ -1355,7 +1355,7 @@ if (!GV->isThreadLocal()) InitializeMemory(GV->getInitializer(), GA); - Type *ElTy = GV->getType()->getElementType(); + Type *ElTy = GV->getValueType(); size_t GVSize = (size_t)getDataLayout().getTypeAllocSize(ElTy); NumInitBytes += (unsigned)GVSize; ++NumGlobals; Index: lib/ExecutionEngine/Interpreter/Execution.cpp =================================================================== --- lib/ExecutionEngine/Interpreter/Execution.cpp +++ lib/ExecutionEngine/Interpreter/Execution.cpp @@ -962,7 +962,7 @@ void Interpreter::visitAllocaInst(AllocaInst &I) { ExecutionContext &SF = ECStack.back(); - Type *Ty = I.getType()->getElementType(); // Type to be allocated + Type *Ty = I.getType()->getPointerElementType(); // Type to be allocated // Get the number of elements being allocated by the array... unsigned NumElements = @@ -1007,7 +1007,13 @@ Total += SLO->getElementOffset(Index); } else { - SequentialType *ST = cast(*I); + Type *ElTy; + if (auto *PtrTy = dyn_cast(*I)) { + ElTy = PtrTy->getPointerElementType(); + } else { + ElTy = cast(*I)->getElementType(); + } + // Get the index number for the array... which must be long type... GenericValue IdxGV = getOperandValue(I.getOperand(), SF); @@ -1020,7 +1026,7 @@ assert(BitWidth == 64 && "Invalid index type for getelementptr"); Idx = (int64_t)IdxGV.IntVal.getZExtValue(); } - Total += getDataLayout().getTypeAllocSize(ST->getElementType()) * Idx; + Total += getDataLayout().getTypeAllocSize(ElTy) * Idx; } } Index: lib/ExecutionEngine/Orc/IndirectionUtils.cpp =================================================================== --- lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -116,7 +116,7 @@ ValueToValueMapTy *VMap) { assert(F.getParent() != &Dst && "Can't copy decl over existing function."); Function *NewF = - Function::Create(cast(F.getType()->getElementType()), + Function::Create(cast(F.getValueType()), F.getLinkage(), F.getName(), &Dst); NewF->copyAttributesFrom(&F); @@ -154,7 +154,7 @@ ValueToValueMapTy *VMap) { assert(GV.getParent() != &Dst && "Can't copy decl over existing global var."); GlobalVariable *NewGV = new GlobalVariable( - Dst, GV.getType()->getElementType(), GV.isConstant(), + Dst, GV.getValueType(), GV.isConstant(), GV.getLinkage(), nullptr, GV.getName(), nullptr, GV.getThreadLocalMode(), GV.getType()->getAddressSpace()); NewGV->copyAttributesFrom(&GV); Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -503,7 +503,7 @@ } case Type::PointerTyID: { PointerType *PTy = cast(Ty); - print(PTy->getElementType(), OS); + print(PTy->getPointerElementType(), OS); if (unsigned AddressSpace = PTy->getAddressSpace()) OS << " addrspace(" << AddressSpace << ')'; OS << '*'; @@ -2415,7 +2415,7 @@ Out << "addrspace(" << AddressSpace << ") "; if (GV->isExternallyInitialized()) Out << "externally_initialized "; Out << (GV->isConstant() ? "constant " : "global "); - TypePrinter.print(GV->getType()->getElementType(), Out); + TypePrinter.print(GV->getValueType(), Out); if (GV->hasInitializer()) { Out << ' '; Index: lib/IR/ConstantFold.h =================================================================== --- lib/IR/ConstantFold.h +++ lib/IR/ConstantFold.h @@ -47,10 +47,6 @@ Constant *V2); Constant *ConstantFoldCompareInstruction(unsigned short predicate, Constant *C1, Constant *C2); - Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds, - ArrayRef Idxs); - Constant *ConstantFoldGetElementPtr(Constant *C, bool inBounds, - ArrayRef Idxs); Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool inBounds, ArrayRef Idxs); Constant *ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool inBounds, Index: lib/IR/ConstantFold.cpp =================================================================== --- lib/IR/ConstantFold.cpp +++ lib/IR/ConstantFold.cpp @@ -109,20 +109,19 @@ if (PointerType *PTy = dyn_cast(V->getType())) if (PointerType *DPTy = dyn_cast(DestTy)) if (PTy->getAddressSpace() == DPTy->getAddressSpace() - && PTy->getElementType()->isSized()) { + && PTy->getPointerElementType()->isSized()) { SmallVector IdxList; Value *Zero = Constant::getNullValue(Type::getInt32Ty(DPTy->getContext())); IdxList.push_back(Zero); - Type *ElTy = PTy->getElementType(); - while (ElTy != DPTy->getElementType()) { + Type *ElTy = PTy->getPointerElementType(); + while (ElTy != DPTy->getPointerElementType()) { if (StructType *STy = dyn_cast(ElTy)) { if (STy->getNumElements() == 0) break; ElTy = STy->getElementType(0); IdxList.push_back(Zero); } else if (SequentialType *STy = dyn_cast(ElTy)) { - if (ElTy->isPointerTy()) break; // Can't index into pointers! ElTy = STy->getElementType(); IdxList.push_back(Zero); } else { @@ -130,9 +129,9 @@ } } - if (ElTy == DPTy->getElementType()) + if (ElTy == DPTy->getPointerElementType()) // This GEP is inbounds because all indices are zero. - return ConstantExpr::getInBoundsGetElementPtr(PTy->getElementType(), + return ConstantExpr::getInBoundsGetElementPtr(PTy->getPointerElementType(), V, IdxList); } @@ -381,7 +380,7 @@ // Pointer size doesn't depend on the pointee type, so canonicalize them // to an arbitrary pointee. if (PointerType *PTy = dyn_cast(Ty)) - if (!PTy->getElementType()->isIntegerTy(1)) + if (!PTy->getPointerElementType()->isIntegerTy(1)) return getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1), PTy->getAddressSpace()), @@ -446,7 +445,7 @@ // Pointer alignment doesn't depend on the pointee type, so canonicalize them // to an arbitrary pointee. if (PointerType *PTy = dyn_cast(Ty)) - if (!PTy->getElementType()->isIntegerTy(1)) + if (!PTy->getPointerElementType()->isIntegerTy(1)) return getFoldedAlignOf(PointerType::get(IntegerType::get(PTy->getContext(), 1), @@ -2002,10 +2001,6 @@ /// \brief Test whether a given ConstantInt is in-range for a SequentialType. static bool isIndexInRangeOfSequentialType(SequentialType *STy, const ConstantInt *CI) { - // And indices are valid when indexing along a pointer - if (isa(STy)) - return true; - uint64_t NumElements = 0; // Determine the number of elements in our sequential type. if (auto *ATy = dyn_cast(STy)) @@ -2040,9 +2035,8 @@ return C; if (isa(C)) { - PointerType *Ptr = cast(C->getType()); - Type *Ty = GetElementPtrInst::getIndexedType( - cast(Ptr->getScalarType())->getElementType(), Idxs); + PointerType *Ptr = cast(C->getType()->getScalarType()); + Type *Ty = GetElementPtrInst::getIndexedType(PointeeTy, Idxs); assert(Ty && "Invalid indices for GEP!"); return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace())); } @@ -2055,9 +2049,8 @@ break; } if (isNull) { - PointerType *Ptr = cast(C->getType()); - Type *Ty = GetElementPtrInst::getIndexedType( - cast(Ptr->getScalarType())->getElementType(), Idxs); + PointerType *Ptr = cast(C->getType()->getScalarType()); + Type *Ty = GetElementPtrInst::getIndexedType(PointeeTy, Idxs); assert(Ty && "Invalid indices for GEP!"); return ConstantPointerNull::get(PointerType::get(Ty, Ptr->getAddressSpace())); @@ -2096,9 +2089,13 @@ bool PerformFold = false; if (Idx0->isNullValue()) PerformFold = true; - else if (SequentialType *STy = dyn_cast_or_null(LastTy)) - if (ConstantInt *CI = dyn_cast(Idx0)) + else if (ConstantInt *CI = dyn_cast(Idx0)) { + if (SequentialType *STy = dyn_cast_or_null(LastTy)) { PerformFold = isIndexInRangeOfSequentialType(STy, CI); + } else if (isa(LastTy)) { + PerformFold = true; + } + } if (PerformFold) { SmallVector NewIndices; @@ -2151,9 +2148,9 @@ PointerType *DstPtrTy = dyn_cast(CE->getType()); if (SrcPtrTy && DstPtrTy) { ArrayType *SrcArrayTy = - dyn_cast(SrcPtrTy->getElementType()); + dyn_cast(SrcPtrTy->getPointerElementType()); ArrayType *DstArrayTy = - dyn_cast(DstPtrTy->getElementType()); + dyn_cast(DstPtrTy->getPointerElementType()); if (SrcArrayTy && DstArrayTy && SrcArrayTy->getElementType() == DstArrayTy->getElementType() && SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace()) @@ -2176,7 +2173,7 @@ if (isa(Ty) || isa(Ty)) if (CI->getSExtValue() > 0 && !isIndexInRangeOfSequentialType(cast(Ty), CI)) { - if (isa(Prev)) { + if (isa(Prev) || isa(Prev)) { // It's out of range, but we can factor it into the prior // dimension. NewIdxs.resize(Idxs.size()); @@ -2237,22 +2234,6 @@ return nullptr; } -Constant *llvm::ConstantFoldGetElementPtr(Constant *C, - bool inBounds, - ArrayRef Idxs) { - return ConstantFoldGetElementPtrImpl( - cast(C->getType()->getScalarType())->getElementType(), C, - inBounds, Idxs); -} - -Constant *llvm::ConstantFoldGetElementPtr(Constant *C, - bool inBounds, - ArrayRef Idxs) { - return ConstantFoldGetElementPtrImpl( - cast(C->getType()->getScalarType())->getElementType(), C, - inBounds, Idxs); -} - Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C, bool inBounds, ArrayRef Idxs) { Index: lib/IR/Constants.cpp =================================================================== --- lib/IR/Constants.cpp +++ lib/IR/Constants.cpp @@ -1788,8 +1788,8 @@ // bitcasting the pointer type and then converting the address space. PointerType *SrcScalarTy = cast(C->getType()->getScalarType()); PointerType *DstScalarTy = cast(DstTy->getScalarType()); - Type *DstElemTy = DstScalarTy->getElementType(); - if (SrcScalarTy->getElementType() != DstElemTy) { + Type *DstElemTy = DstScalarTy->getPointerElementType(); + if (SrcScalarTy->getPointerElementType() != DstElemTy) { Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace()); if (VectorType *VT = dyn_cast(DstTy)) { // Handle vectors of pointers. @@ -1965,7 +1965,7 @@ ArrayRef Idxs, bool InBounds, Type *OnlyIfReducedTy) { if (!Ty) - Ty = cast(C->getType()->getScalarType())->getElementType(); + Ty = cast(C->getType()->getScalarType())->getPointerElementType(); else assert( Ty == @@ -2330,12 +2330,13 @@ } GetElementPtrConstantExpr::GetElementPtrConstantExpr( - Type *SrcElementTy, Constant *C, ArrayRef IdxList, Type *DestTy) + Type *SrcElementTy, Type *ResElementTy, + Constant *C, ArrayRef IdxList, Type *DestTy) : ConstantExpr(DestTy, Instruction::GetElementPtr, OperandTraits::op_end(this) - (IdxList.size() + 1), IdxList.size() + 1), - SrcElementTy(SrcElementTy) { + SrcElementTy(SrcElementTy), ResElementTy(ResElementTy) { Op<0>() = C; Use *OperandList = getOperandList(); for (unsigned i = 0, E = IdxList.size(); i != E; ++i) @@ -2346,6 +2347,10 @@ return SrcElementTy; } +Type *GetElementPtrConstantExpr::getResultElementType() const { + return ResElementTy; +} + //===----------------------------------------------------------------------===// // ConstantData* implementations Index: lib/IR/ConstantsContext.h =================================================================== --- lib/IR/ConstantsContext.h +++ lib/IR/ConstantsContext.h @@ -225,28 +225,25 @@ /// 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 IdxList, Type *DestTy); + GetElementPtrConstantExpr(Type *SrcElementTy, Type *ResElementTy, + Constant *C, ArrayRef IdxList, + Type *DestTy); public: - static GetElementPtrConstantExpr *Create(Constant *C, - ArrayRef IdxList, - Type *DestTy, - unsigned Flags) { - return Create( - cast(C->getType()->getScalarType())->getElementType(), C, - IdxList, DestTy, Flags); - } - static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C, + static GetElementPtrConstantExpr *Create(Type *SrcElementTy, + Type *ResElementTy, Constant *C, ArrayRef IdxList, Type *DestTy, unsigned Flags) { GetElementPtrConstantExpr *Result = new (IdxList.size() + 1) - GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy); + GetElementPtrConstantExpr(SrcElementTy, ResElementTy, + C, IdxList, DestTy); Result->SubclassOptionalData = Flags; return Result; } Type *getSourceElementType() const; + Type *getResultElementType() const; /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -534,7 +531,8 @@ return GetElementPtrConstantExpr::Create( ExplicitTy ? ExplicitTy : cast(Ops[0]->getType()->getScalarType()) - ->getElementType(), + ->getPointerElementType(), + cast(Ty->getScalarType())->getPointerElementType(), Ops[0], Ops.slice(1), Ty, SubclassOptionalData); case Instruction::ICmp: return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -1644,7 +1644,7 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name) { auto *PTy = cast(unwrap(Ty)); - return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), + return wrap(GlobalAlias::create(PTy->getPointerElementType(), PTy->getAddressSpace(), GlobalValue::ExternalLinkage, Name, unwrap(Aliasee), unwrap(M))); } Index: lib/IR/DataLayout.cpp =================================================================== --- lib/IR/DataLayout.cpp +++ lib/IR/DataLayout.cpp @@ -723,36 +723,33 @@ return Max != LegalIntWidths.end() ? *Max : 0; } -uint64_t DataLayout::getIndexedOffset(Type *ptrTy, +uint64_t DataLayout::getIndexedOffset(Type *ElemTy, ArrayRef Indices) const { - Type *Ty = ptrTy; - assert(Ty->isPointerTy() && "Illegal argument for getIndexedOffset()"); uint64_t Result = 0; + // We can use 0 as the address space as we don't need + // to get pointer types back from gep_type_iterator. + unsigned AS = 0; generic_gep_type_iterator - TI = gep_type_begin(ptrTy, Indices); - for (unsigned CurIDX = 0, EndIDX = Indices.size(); CurIDX != EndIDX; - ++CurIDX, ++TI) { - if (StructType *STy = dyn_cast(*TI)) { - assert(Indices[CurIDX]->getType() == - Type::getInt32Ty(ptrTy->getContext()) && + GTI = gep_type_begin(ElemTy, AS, Indices), + GTE = gep_type_end(ElemTy, AS, Indices); + for (; GTI != GTE; ++GTI) { + Value *Idx = GTI.getOperand(); + if (StructType *STy = dyn_cast(*GTI)) { + assert(Idx->getType() == + Type::getInt32Ty(ElemTy->getContext()) && "Illegal struct idx"); - unsigned FieldNo = cast(Indices[CurIDX])->getZExtValue(); + unsigned FieldNo = cast(Idx)->getZExtValue(); // Get structure layout information... const StructLayout *Layout = getStructLayout(STy); // Add in the offset, as calculated by the structure layout info... Result += Layout->getElementOffset(FieldNo); - - // Update Ty to refer to current element - Ty = STy->getElementType(FieldNo); } else { - // Update Ty to refer to current element - Ty = cast(Ty)->getElementType(); - + Type *Ty = GTI.getIndexedType(); // Get the array index and the size of each array element. - if (int64_t arrayIdx = cast(Indices[CurIDX])->getSExtValue()) + if (int64_t arrayIdx = cast(Idx)->getSExtValue()) Result += (uint64_t)arrayIdx * getTypeAllocSize(Ty); } } @@ -764,7 +761,7 @@ /// global. This includes an explicitly requested alignment (if the global /// has one). unsigned DataLayout::getPreferredAlignment(const GlobalVariable *GV) const { - Type *ElemType = GV->getType()->getElementType(); + Type *ElemType = GV->getValueType(); unsigned Alignment = getPrefTypeAlignment(ElemType); unsigned GVAlignment = GV->getAlignment(); if (GVAlignment >= Alignment) { Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -471,7 +471,7 @@ std::string Result; if (PointerType* PTyp = dyn_cast(Ty)) { Result += "p" + llvm::utostr(PTyp->getAddressSpace()) + - getMangledTypeStr(PTyp->getElementType()); + getMangledTypeStr(PTyp->getPointerElementType()); } else if (ArrayType* ATyp = dyn_cast(Ty)) { Result += "a" + llvm::utostr(ATyp->getNumElements()) + getMangledTypeStr(ATyp->getElementType()); Index: lib/IR/Globals.cpp =================================================================== --- lib/IR/Globals.cpp +++ lib/IR/Globals.cpp @@ -200,7 +200,7 @@ setGlobalVariableNumOperands(0); } } else { - assert(InitVal->getType() == getType()->getElementType() && + assert(InitVal->getType() == getValueType() && "Initializer type must match GlobalVariable type"); // Note, the num operands is used to compute the offset of the operand, so // the order here matters. We need to set num operands to 1 first so that @@ -258,8 +258,8 @@ GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, GlobalValue *Aliasee) { PointerType *PTy = Aliasee->getType(); - return create(PTy->getElementType(), PTy->getAddressSpace(), Link, Name, - Aliasee); + return create(PTy->getPointerElementType(), PTy->getAddressSpace(), + Link, Name, Aliasee); } GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) { Index: lib/IR/IRBuilder.cpp =================================================================== --- lib/IR/IRBuilder.cpp +++ lib/IR/IRBuilder.cpp @@ -45,7 +45,7 @@ Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { PointerType *PT = cast(Ptr->getType()); - if (PT->getElementType()->isIntegerTy(8)) + if (PT->getPointerElementType()->isIntegerTy(8)) return Ptr; // Otherwise, we need to insert a bitcast. @@ -214,7 +214,7 @@ const Twine &Name) { assert(Ptr->getType()->isPointerTy() && "Ptr must be of pointer type"); // DataTy is the overloaded type - Type *DataTy = cast(Ptr->getType())->getElementType(); + Type *DataTy = cast(Ptr->getType())->getPointerElementType(); assert(DataTy->isVectorTy() && "Ptr should point to a vector"); if (!PassThru) PassThru = UndefValue::get(DataTy); @@ -277,7 +277,7 @@ const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast(ActualCallee->getType()); - assert(isa(FuncPtrType->getElementType()) && + assert(isa(FuncPtrType->getPointerElementType()) && "actual callee must be a callable value"); Module *M = Builder->GetInsertBlock()->getParent()->getParent(); @@ -328,7 +328,7 @@ ArrayRef DeoptArgs, ArrayRef GCArgs, const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast(ActualInvokee->getType()); - assert(isa(FuncPtrType->getElementType()) && + assert(isa(FuncPtrType->getPointerElementType()) && "actual callee must be a callable value"); Module *M = Builder->GetInsertBlock()->getParent()->getParent(); Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -256,7 +256,7 @@ void CallInst::init(Value *Func, const Twine &NameStr) { FTy = - cast(cast(Func->getType())->getElementType()); + cast(cast(Func->getType())->getPointerElementType()); assert(getNumOperands() == 1 && "NumOperands not set up?"); Op<-1>() = Func; @@ -268,7 +268,7 @@ CallInst::CallInst(Value *Func, const Twine &Name, Instruction *InsertBefore) : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), + ->getPointerElementType())->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - 1, 1, InsertBefore) { @@ -278,7 +278,7 @@ CallInst::CallInst(Value *Func, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(cast(cast(Func->getType()) - ->getElementType())->getReturnType(), + ->getPointerElementType())->getReturnType(), Instruction::Call, OperandTraits::op_end(this) - 1, 1, InsertAtEnd) { @@ -1222,7 +1222,7 @@ unsigned Align, AtomicOrdering Order, SynchronizationScope SynchScope, Instruction *InsertBef) : UnaryInstruction(Ty, Load, Ptr, InsertBef) { - assert(Ty == cast(Ptr->getType())->getElementType()); + assert(Ty == cast(Ptr->getType())->getPointerElementType()); setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SynchScope); @@ -1234,7 +1234,7 @@ unsigned Align, AtomicOrdering Order, SynchronizationScope SynchScope, BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), + : UnaryInstruction(cast(Ptr->getType())->getPointerElementType(), Load, Ptr, InsertAE) { setVolatile(isVolatile); setAlignment(Align); @@ -1244,7 +1244,7 @@ } LoadInst::LoadInst(Value *Ptr, const char *Name, Instruction *InsertBef) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), + : UnaryInstruction(cast(Ptr->getType())->getPointerElementType(), Load, Ptr, InsertBef) { setVolatile(false); setAlignment(0); @@ -1254,7 +1254,7 @@ } LoadInst::LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), + : UnaryInstruction(cast(Ptr->getType())->getPointerElementType(), Load, Ptr, InsertAE) { setVolatile(false); setAlignment(0); @@ -1266,7 +1266,7 @@ LoadInst::LoadInst(Type *Ty, Value *Ptr, const char *Name, bool isVolatile, Instruction *InsertBef) : UnaryInstruction(Ty, Load, Ptr, InsertBef) { - assert(Ty == cast(Ptr->getType())->getElementType()); + assert(Ty == cast(Ptr->getType())->getPointerElementType()); setVolatile(isVolatile); setAlignment(0); setAtomic(NotAtomic); @@ -1276,7 +1276,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile, BasicBlock *InsertAE) - : UnaryInstruction(cast(Ptr->getType())->getElementType(), + : UnaryInstruction(cast(Ptr->getType())->getPointerElementType(), Load, Ptr, InsertAE) { setVolatile(isVolatile); setAlignment(0); @@ -1294,6 +1294,20 @@ assert(getAlignment() == Align && "Alignment representation error!"); } +unsigned LoadInst::getActualAlignment() const { + unsigned Align = getAlignment(); + if (Align == 0) { + const DataLayout &DL = getModule()->getDataLayout(); + return DL.getABITypeAlignment(getType()); + } + return Align; +} + +uint64_t LoadInst::getLoadedSize() const { + const DataLayout &DL = getModule()->getDataLayout(); + return DL.getTypeStoreSize(getType()); +} + //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// @@ -1303,7 +1317,7 @@ assert(getOperand(1)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(0)->getType() == - cast(getOperand(1)->getType())->getElementType() + cast(getOperand(1)->getType())->getPointerElementType() && "Ptr must be a pointer to Val type!"); assert(!(isAtomic() && getAlignment() == 0) && "Alignment required for atomic store"); @@ -1394,10 +1408,10 @@ assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(1)->getType() == - cast(getOperand(0)->getType())->getElementType() + cast(getOperand(0)->getType())->getPointerElementType() && "Ptr must be a pointer to Cmp type!"); assert(getOperand(2)->getType() == - cast(getOperand(0)->getType())->getElementType() + cast(getOperand(0)->getType())->getPointerElementType() && "Ptr must be a pointer to NewVal type!"); assert(SuccessOrdering != NotAtomic && "AtomicCmpXchg instructions must be atomic!"); @@ -1453,7 +1467,7 @@ assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type!"); assert(getOperand(1)->getType() == - cast(getOperand(0)->getType())->getElementType() + cast(getOperand(0)->getType())->getPointerElementType() && "Ptr must be a pointer to Val type!"); assert(Ordering != NotAtomic && "AtomicRMW instructions must be atomic!"); @@ -1550,7 +1564,7 @@ unsigned CurIdx = 1; for (; CurIdx != IdxList.size(); ++CurIdx) { CompositeType *CT = dyn_cast(Agg); - if (!CT || CT->isPointerTy()) return nullptr; + if (!CT) return nullptr; IndexTy Index = IdxList[CurIdx]; if (!CT->indexValid(Index)) return nullptr; Agg = CT->getTypeAtIndex(Index); @@ -2528,8 +2542,11 @@ case 14: // bitcast, addrspacecast -> addrspacecast if the element type of // bitcast's source is the same as that of addrspacecast's destination. - if (SrcTy->getPointerElementType() == DstTy->getPointerElementType()) - return Instruction::AddrSpaceCast; + if (auto *SrcPtrTy = dyn_cast(SrcTy)) + if (auto *DstPtrTy = dyn_cast(DstTy)) + if (SrcPtrTy->getPointerElementType() == + DstPtrTy->getPointerElementType()) + return Instruction::AddrSpaceCast; return 0; case 15: Index: lib/IR/Mangler.cpp =================================================================== --- lib/IR/Mangler.cpp +++ lib/IR/Mangler.cpp @@ -96,7 +96,7 @@ Type *Ty = AI->getType(); // 'Dereference' type in case of byval or inalloca parameter attribute. if (AI->hasByValOrInAllocaAttr()) - Ty = cast(Ty)->getElementType(); + Ty = cast(Ty)->getPointerElementType(); // Size should be aligned to pointer size. unsigned PtrSize = DL.getPointerSize(); ArgWords += RoundUpToAlignment(DL.getTypeAllocSize(Ty), PtrSize); Index: lib/IR/Operator.cpp =================================================================== --- lib/IR/Operator.cpp +++ lib/IR/Operator.cpp @@ -12,6 +12,12 @@ return cast(this)->getSourceElementType(); } +Type *GEPOperator::getResultElementType() const { + if (auto *I = dyn_cast(this)) + return I->getResultElementType(); + return cast(this)->getResultElementType(); +} + bool GEPOperator::accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { assert(Offset.getBitWidth() == Index: lib/IR/Type.cpp =================================================================== --- lib/IR/Type.cpp +++ lib/IR/Type.cpp @@ -745,13 +745,12 @@ PointerType::PointerType(Type *E, unsigned AddrSpace) - : SequentialType(PointerTyID, E) { -#ifndef NDEBUG - const unsigned oldNCT = NumContainedTys; -#endif + : Type(E->getContext(), PointerTyID), PointeeType(E) { + ContainedTys = &PointeeType; + NumContainedTys = 1; setSubclassData(AddrSpace); // Check for miscompile. PR11652. - assert(oldNCT == NumContainedTys && "bitfield written out of bounds?"); + assert(NumContainedTys == 1 && "bitfield written out of bounds?"); } PointerType *Type::getPointerTo(unsigned addrs) const { Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -471,7 +471,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { if (GV.hasInitializer()) { - Assert(GV.getInitializer()->getType() == GV.getType()->getElementType(), + Assert(GV.getInitializer()->getType() == GV.getValueType(), "Global variable initializer type does not match global " "variable type!", &GV); @@ -509,7 +509,7 @@ if (STy->getNumElements() == 3) { Type *ETy = STy->getTypeAtIndex(2); Assert(ETy->isPointerTy() && - cast(ETy)->getElementType()->isIntegerTy(8), + cast(ETy)->getPointerElementType()->isIntegerTy(8), "wrong type for intrinsic global variable", &GV); } } @@ -1347,7 +1347,7 @@ if (PointerType *PTy = dyn_cast(Ty)) { SmallPtrSet Visited; - if (!PTy->getElementType()->isSized(&Visited)) { + if (!PTy->getPointerElementType()->isSized(&Visited)) { Assert(!Attrs.hasAttribute(Idx, Attribute::ByVal) && !Attrs.hasAttribute(Idx, Attribute::InAlloca), "Attributes 'byval' and 'inalloca' do not support unsized types!", @@ -1576,9 +1576,9 @@ const Value *Target = CS.getArgument(2); auto *PT = dyn_cast(Target->getType()); - Assert(PT && PT->getElementType()->isFunctionTy(), + Assert(PT && PT->getPointerElementType()->isFunctionTy(), "gc.statepoint callee must be of function pointer type", &CI, Target); - FunctionType *TargetFuncType = cast(PT->getElementType()); + FunctionType *TargetFuncType = cast(PT->getPointerElementType()); const Value *NumCallArgsV = CS.getArgument(3); Assert(isa(NumCallArgsV), @@ -2299,10 +2299,10 @@ "Called function must be a pointer!", I); PointerType *FPTy = cast(CS.getCalledValue()->getType()); - Assert(FPTy->getElementType()->isFunctionTy(), + Assert(FPTy->getPointerElementType()->isFunctionTy(), "Called function is not pointer to function type!", I); - Assert(FPTy->getElementType() == CS.getFunctionType(), + Assert(FPTy->getPointerElementType() == CS.getFunctionType(), "Called function is not the same type as the call!", I); FunctionType *FTy = CS.getFunctionType(); @@ -2774,7 +2774,7 @@ void Verifier::visitStoreInst(StoreInst &SI) { PointerType *PTy = dyn_cast(SI.getOperand(1)->getType()); Assert(PTy, "Store operand must be a pointer.", &SI); - Type *ElTy = PTy->getElementType(); + Type *ElTy = PTy->getPointerElementType(); Assert(ElTy == SI.getOperand(0)->getType(), "Stored value type does not match pointer operand type!", &SI, ElTy); Assert(SI.getAlignment() <= Value::MaximumAlignment, @@ -2833,7 +2833,7 @@ PointerType *PTy = dyn_cast(CXI.getOperand(0)->getType()); Assert(PTy, "First cmpxchg operand must be a pointer.", &CXI); - Type *ElTy = PTy->getElementType(); + Type *ElTy = PTy->getPointerElementType(); Assert(ElTy->isIntegerTy(), "cmpxchg operand must have integer type!", &CXI, ElTy); checkAtomicMemAccessSize(M, ElTy, &CXI); @@ -2852,7 +2852,7 @@ "atomicrmw instructions cannot be unordered.", &RMWI); PointerType *PTy = dyn_cast(RMWI.getOperand(0)->getType()); Assert(PTy, "First atomicrmw operand must be a pointer.", &RMWI); - Type *ElTy = PTy->getElementType(); + Type *ElTy = PTy->getPointerElementType(); Assert(ElTy->isIntegerTy(), "atomicrmw operand must have integer type!", &RMWI, ElTy); checkAtomicMemAccessSize(M, ElTy, &RMWI); @@ -3312,7 +3312,7 @@ case IITDescriptor::Pointer: { PointerType *PT = dyn_cast(Ty); return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace || - VerifyIntrinsicType(PT->getElementType(), Infos, ArgTys); + VerifyIntrinsicType(PT->getPointerElementType(), Infos, ArgTys); } case IITDescriptor::Struct: { @@ -3400,7 +3400,7 @@ return true; Type * ReferenceType = ArgTys[D.getArgumentNumber()]; PointerType *ThisArgType = dyn_cast(Ty); - return (!ThisArgType || ThisArgType->getElementType() != ReferenceType); + return (!ThisArgType || ThisArgType->getPointerElementType() != ReferenceType); } case IITDescriptor::VecOfPtrsToElt: { if (D.getArgumentNumber() >= ArgTys.size()) @@ -3416,7 +3416,7 @@ dyn_cast(ThisArgVecTy->getVectorElementType()); if (!ThisArgEltTy) return true; - return ThisArgEltTy->getElementType() != + return ThisArgEltTy->getPointerElementType() != ReferenceType->getVectorElementType(); } } @@ -3641,7 +3641,7 @@ // Assert that result type matches wrapped callee. const Value *Target = StatepointCS.getArgument(2); auto *PT = cast(Target->getType()); - auto *TargetFuncType = cast(PT->getElementType()); + auto *TargetFuncType = cast(PT->getPointerElementType()); Assert(CS.getType() == TargetFuncType->getReturnType(), "gc.result result type does not match wrapped callee", CS); break; Index: lib/Linker/IRMover.cpp =================================================================== --- lib/Linker/IRMover.cpp +++ lib/Linker/IRMover.cpp @@ -702,7 +702,7 @@ // identical version of the symbol over in the dest module... the // initializer will be filled in later by LinkGlobalInits. GlobalVariable *NewDGV = - new GlobalVariable(DstM, TypeMap.get(SGVar->getType()->getElementType()), + new GlobalVariable(DstM, TypeMap.get(SGVar->getValueType()), SGVar->isConstant(), GlobalValue::ExternalLinkage, /*init*/ nullptr, SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), @@ -742,7 +742,7 @@ NewGV = copyGlobalAliasProto(cast(SGV)); else NewGV = new GlobalVariable( - DstM, TypeMap.get(SGV->getType()->getElementType()), + DstM, TypeMap.get(SGV->getValueType()), /*isConstant*/ false, GlobalValue::ExternalLinkage, /*init*/ nullptr, SGV->getName(), /*insertbefore*/ nullptr, SGV->getThreadLocalMode(), @@ -775,8 +775,8 @@ } // Unify the element type of appending arrays. - ArrayType *DAT = cast(DGV->getType()->getElementType()); - ArrayType *SAT = cast(SGV.getType()->getElementType()); + ArrayType *DAT = cast(DGV->getValueType()); + ArrayType *SAT = cast(SGV.getValueType()); TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType()); } @@ -847,7 +847,7 @@ /// Return true on error. Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, const GlobalVariable *SrcGV) { - Type *EltTy = cast(TypeMap.get(SrcGV->getType()->getElementType())) + Type *EltTy = cast(TypeMap.get(SrcGV->getValueType())) ->getElementType(); StringRef Name = SrcGV->getName(); @@ -868,7 +868,7 @@ } if (DstGV) { - ArrayType *DstTy = cast(DstGV->getType()->getElementType()); + ArrayType *DstTy = cast(DstGV->getValueType()); if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) { emitError( Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -459,10 +459,8 @@ const DataLayout &DstDL = DstM.getDataLayout(); const DataLayout &SrcDL = SrcM.getDataLayout(); - uint64_t DstSize = - DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType()); - uint64_t SrcSize = - SrcDL.getTypeAllocSize(SrcGV->getType()->getPointerElementType()); + uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); + uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); if (Result == Comdat::SelectionKind::ExactMatch) { if (SrcGV->getInitializer() != DstGV->getInitializer()) return emitError("Linking COMDATs named '" + ComdatName + @@ -586,8 +584,8 @@ } const DataLayout &DL = Dest.getParent()->getDataLayout(); - uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType()); - uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType()); + uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); + uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); LinkFromSrc = SrcSize > DestSize; return false; } Index: lib/Target/AArch64/AArch64FastISel.cpp =================================================================== --- lib/Target/AArch64/AArch64FastISel.cpp +++ lib/Target/AArch64/AArch64FastISel.cpp @@ -4825,7 +4825,11 @@ TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field); Ty = StTy->getElementType(Field); } else { - Ty = cast(Ty)->getElementType(); + if (auto *PtrTy = dyn_cast(Ty)) { + Ty = PtrTy->getPointerElementType(); + } else { + Ty = cast(Ty)->getElementType(); + } // If this is a constant subscript, handle it quickly. if (const auto *CI = dyn_cast(Idx)) { if (CI->isZero()) Index: lib/Target/AArch64/AArch64ISelDAGToDAG.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -687,7 +687,7 @@ const GlobalValue *GV = GAN->getGlobal(); unsigned Alignment = GV->getAlignment(); - Type *Ty = GV->getType()->getElementType(); + Type *Ty = GV->getValueType(); if (Alignment == 0 && Ty->isSized()) Alignment = DL.getABITypeAlignment(Ty); Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -6784,10 +6784,10 @@ case Intrinsic::aarch64_ldxr: { PointerType *PtrTy = cast(I.getArgOperand(0)->getType()); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getElementType()); + Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); Info.ptrVal = I.getArgOperand(0); Info.offset = 0; - Info.align = DL.getABITypeAlignment(PtrTy->getElementType()); + Info.align = DL.getABITypeAlignment(PtrTy->getPointerElementType()); Info.vol = true; Info.readMem = true; Info.writeMem = false; @@ -6797,10 +6797,10 @@ case Intrinsic::aarch64_stxr: { PointerType *PtrTy = cast(I.getArgOperand(1)->getType()); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getElementType()); + Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); Info.ptrVal = I.getArgOperand(1); Info.offset = 0; - Info.align = DL.getABITypeAlignment(PtrTy->getElementType()); + Info.align = DL.getABITypeAlignment(PtrTy->getPointerElementType()); Info.vol = true; Info.readMem = false; Info.writeMem = true; @@ -9920,7 +9920,7 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr, AtomicOrdering Ord) const { Module *M = Builder.GetInsertBlock()->getParent()->getParent(); - Type *ValTy = cast(Addr->getType())->getElementType(); + Type *ValTy = cast(Addr->getType())->getPointerElementType(); bool IsAcquire = isAtLeastAcquire(Ord); // Since i128 isn't legal and intrinsics don't get type-lowered, the ldrexd @@ -9949,7 +9949,7 @@ return Builder.CreateTruncOrBitCast( Builder.CreateCall(Ldxr, Addr), - cast(Addr->getType())->getElementType()); + cast(Addr->getType())->getPointerElementType()); } void AArch64TargetLowering::emitAtomicCmpXchgNoStoreLLBalance( Index: lib/Target/AMDGPU/AMDGPUISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -792,7 +792,7 @@ unsigned Offset; if (MFI->LocalMemoryObjects.count(GV) == 0) { - uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); + uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); Offset = MFI->LDSSize; MFI->LocalMemoryObjects[GV] = Offset; // XXX: Account for alignment? @@ -806,7 +806,7 @@ } case AMDGPUAS::CONSTANT_ADDRESS: { MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); - Type *EltType = GV->getType()->getElementType(); + Type *EltType = GV->getValueType(); unsigned Size = DL.getTypeAllocSize(EltType); unsigned Alignment = DL.getPrefTypeAlignment(EltType); Index: lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -78,8 +78,7 @@ for (Module::global_iterator I = Mod->global_begin(), E = Mod->global_end(); I != E; ++I) { GlobalVariable *GV = &*I; - PointerType *GVTy = GV->getType(); - if (GVTy->getAddressSpace() != AMDGPUAS::LOCAL_ADDRESS) + if (GV->getType()->getAddressSpace() != AMDGPUAS::LOCAL_ADDRESS) continue; for (Value::use_iterator U = GV->use_begin(), UE = GV->use_end(); U != UE; ++U) { @@ -88,7 +87,7 @@ continue; if (Use->getParent()->getParent() == &F) LocalMemAvailable -= - Mod->getDataLayout().getTypeAllocSize(GVTy->getElementType()); + Mod->getDataLayout().getTypeAllocSize(GV->getValueType()); } } } @@ -360,7 +359,7 @@ Value *V = *i; CallInst *Call = dyn_cast(V); if (!Call) { - Type *EltTy = V->getType()->getPointerElementType(); + Type *EltTy = cast(V->getType())->getPointerElementType(); PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS); // The operand's value should be corrected on its own. Index: lib/Target/AMDGPU/SITypeRewriter.cpp =================================================================== --- lib/Target/AMDGPU/SITypeRewriter.cpp +++ lib/Target/AMDGPU/SITypeRewriter.cpp @@ -74,7 +74,7 @@ void SITypeRewriter::visitLoadInst(LoadInst &I) { Value *Ptr = I.getPointerOperand(); Type *PtrTy = Ptr->getType(); - Type *ElemTy = PtrTy->getPointerElementType(); + Type *ElemTy = cast(PtrTy)->getPointerElementType(); IRBuilder<> Builder(&I); if (ElemTy == v16i8) { Value *BitCast = Builder.CreateBitCast(Ptr, Index: lib/Target/ARM/ARMFastISel.cpp =================================================================== --- lib/Target/ARM/ARMFastISel.cpp +++ lib/Target/ARM/ARMFastISel.cpp @@ -2293,7 +2293,7 @@ // TODO: Avoid some calling conventions? PointerType *PT = cast(CS.getCalledValue()->getType()); - FunctionType *FTy = cast(PT->getElementType()); + FunctionType *FTy = cast(PT->getPointerElementType()); bool isVarArg = FTy->isVarArg(); // Handle *simple* calls for now. Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -11769,10 +11769,10 @@ auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); PointerType *PtrTy = cast(I.getArgOperand(0)->getType()); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getElementType()); + Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); Info.ptrVal = I.getArgOperand(0); Info.offset = 0; - Info.align = DL.getABITypeAlignment(PtrTy->getElementType()); + Info.align = DL.getABITypeAlignment(PtrTy->getPointerElementType()); Info.vol = true; Info.readMem = true; Info.writeMem = false; @@ -11783,10 +11783,10 @@ auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); PointerType *PtrTy = cast(I.getArgOperand(1)->getType()); Info.opc = ISD::INTRINSIC_W_CHAIN; - Info.memVT = MVT::getVT(PtrTy->getElementType()); + Info.memVT = MVT::getVT(PtrTy->getPointerElementType()); Info.ptrVal = I.getArgOperand(1); Info.offset = 0; - Info.align = DL.getABITypeAlignment(PtrTy->getElementType()); + Info.align = DL.getABITypeAlignment(PtrTy->getPointerElementType()); Info.vol = true; Info.readMem = false; Info.writeMem = true; @@ -11997,7 +11997,7 @@ Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr, AtomicOrdering Ord) const { Module *M = Builder.GetInsertBlock()->getParent()->getParent(); - Type *ValTy = cast(Addr->getType())->getElementType(); + Type *ValTy = cast(Addr->getType())->getPointerElementType(); bool IsAcquire = isAtLeastAcquire(Ord); // Since i64 isn't legal and intrinsics don't get type-lowered, the ldrexd @@ -12027,7 +12027,7 @@ return Builder.CreateTruncOrBitCast( Builder.CreateCall(Ldrex, Addr), - cast(Addr->getType())->getElementType()); + cast(Addr->getType())->getPointerElementType()); } void ARMTargetLowering::emitAtomicCmpXchgNoStoreLLBalance( Index: lib/Target/CppBackend/CPPBackend.cpp =================================================================== --- lib/Target/CppBackend/CPPBackend.cpp +++ lib/Target/CppBackend/CPPBackend.cpp @@ -437,7 +437,7 @@ if (const GlobalVariable* GV = dyn_cast(val)) { name = std::string("gvar_") + - getTypePrefix(GV->getType()->getElementType()); + getTypePrefix(GV->getValueType()); } else if (isa(val)) { name = std::string("func_"); } else if (const Constant* C = dyn_cast(val)) { @@ -654,7 +654,7 @@ } case Type::PointerTyID: { PointerType* PT = cast(Ty); - Type* ET = PT->getElementType(); + Type* ET = PT->getPointerElementType(); printType(ET); if (DefinedTypes.find(Ty) == DefinedTypes.end()) { std::string elemName(getCppName(ET)); @@ -997,13 +997,13 @@ if (is_inline) { Out << " = mod->getGlobalVariable(mod->getContext(), "; printEscapedString(GV->getName()); - Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)"; + Out << ", " << getCppName(GV->getValueType()) << ",true)"; nl(Out) << "if (!" << getCppName(GV) << ") {"; in(); nl(Out) << getCppName(GV); } Out << " = new GlobalVariable(/*Module=*/*mod, "; nl(Out) << "/*Type=*/"; - printCppName(GV->getType()->getElementType()); + printCppName(GV->getValueType()); Out << ","; nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false"); Out << ","; Index: lib/Target/Hexagon/HexagonCommonGEP.cpp =================================================================== --- lib/Target/Hexagon/HexagonCommonGEP.cpp +++ lib/Target/Hexagon/HexagonCommonGEP.cpp @@ -183,8 +183,11 @@ Type *next_type(Type *Ty, Value *Idx) { // Advance the type. if (!Ty->isStructTy()) { - Type *NexTy = cast(Ty)->getElementType(); - return NexTy; + if (auto *PtrTy = dyn_cast(Ty)) { + return PtrTy->getPointerElementType(); + } else { + return cast(Ty)->getElementType(); + } } // Otherwise it is a struct type. ConstantInt *CI = dyn_cast(Idx); @@ -358,7 +361,7 @@ // Skip the first index operand, since we only handle 0. This dereferences // the pointer operand. GepNode *PN = N; - Type *PtrTy = cast(PtrOp->getType())->getElementType(); + Type *PtrTy = cast(PtrOp->getType())->getPointerElementType(); for (User::op_iterator OI = GepI->idx_begin()+1, OE = GepI->idx_end(); OI != OE; ++OI) { Value *Op = *OI; @@ -1119,7 +1122,7 @@ } ArrayRef A(IdxList, IdxC); Type *InpTy = Input->getType(); - Type *ElTy = cast(InpTy->getScalarType())->getElementType(); + Type *ElTy = cast(InpTy->getScalarType())->getPointerElementType(); NewInst = GetElementPtrInst::Create(ElTy, Input, A, "cgep", &*At); DEBUG(dbgs() << "new GEP: " << *NewInst << '\n'); Input = NewInst; Index: lib/Target/Hexagon/HexagonISelLowering.cpp =================================================================== --- lib/Target/Hexagon/HexagonISelLowering.cpp +++ lib/Target/Hexagon/HexagonISelLowering.cpp @@ -2853,7 +2853,7 @@ AtomicOrdering Ord) const { BasicBlock *BB = Builder.GetInsertBlock(); Module *M = BB->getParent()->getParent(); - Type *Ty = cast(Addr->getType())->getElementType(); + Type *Ty = cast(Addr->getType())->getPointerElementType(); unsigned SZ = Ty->getPrimitiveSizeInBits(); assert((SZ == 32 || SZ == 64) && "Only 32/64-bit atomic loads supported"); Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_L2_loadw_locked Index: lib/Target/Hexagon/HexagonTargetObjectFile.cpp =================================================================== --- lib/Target/Hexagon/HexagonTargetObjectFile.cpp +++ lib/Target/Hexagon/HexagonTargetObjectFile.cpp @@ -74,7 +74,7 @@ return false; if (Kind.isBSS() || Kind.isData() || Kind.isCommon()) { - Type *Ty = GV->getType()->getElementType(); + Type *Ty = GV->getValueType(); return IsInSmallSection( GV->getParent()->getDataLayout().getTypeAllocSize(Ty)); } Index: lib/Target/Mips/Mips16HardFloat.cpp =================================================================== --- lib/Target/Mips/Mips16HardFloat.cpp +++ lib/Target/Mips/Mips16HardFloat.cpp @@ -433,7 +433,7 @@ PointerType *PFT = nullptr; if (T) PFT = dyn_cast(T); FunctionType *FT = nullptr; - if (PFT) FT = dyn_cast(PFT->getElementType()); + if (PFT) FT = dyn_cast(PFT->getPointerElementType()); Function *F_ = CI->getCalledFunction(); if (FT && needsFPReturnHelper(*FT) && !(F_ && isIntrinsicInline(F_))) { Index: lib/Target/Mips/MipsTargetObjectFile.cpp =================================================================== --- lib/Target/Mips/MipsTargetObjectFile.cpp +++ lib/Target/Mips/MipsTargetObjectFile.cpp @@ -106,7 +106,7 @@ GV->hasCommonLinkage())) return false; - Type *Ty = GV->getType()->getElementType(); + Type *Ty = GV->getValueType(); return IsInSmallSection( GV->getParent()->getDataLayout().getTypeAllocSize(Ty)); } Index: lib/Target/NVPTX/NVPTXAsmPrinter.cpp =================================================================== --- lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -1030,7 +1030,7 @@ // GlobalVariables are always constant pointers themselves. PointerType *PTy = GVar->getType(); - Type *ETy = PTy->getElementType(); + Type *ETy = GVar->getValueType(); if (GVar->hasExternalLinkage()) { if (GVar->hasInitializer()) @@ -1341,11 +1341,10 @@ const DataLayout &DL = getDataLayout(); // GlobalVariables are always constant pointers themselves. - PointerType *PTy = GVar->getType(); - Type *ETy = PTy->getElementType(); + Type *ETy = GVar->getValueType(); O << "."; - emitPTXAddressSpace(PTy->getAddressSpace(), O); + emitPTXAddressSpace(GVar->getType()->getAddressSpace(), O); if (GVar->getAlignment() == 0) O << " .align " << (int)DL.getPrefTypeAlignment(ETy); else @@ -1497,7 +1496,7 @@ if (static_cast(TM).getDrvInterface() != NVPTX::CUDA) { - Type *ETy = PTy->getElementType(); + Type *ETy = PTy->getPointerElementType(); int addrSpace = PTy->getAddressSpace(); switch (addrSpace) { default: @@ -1552,7 +1551,7 @@ // param has byVal attribute. So should be a pointer auto *PTy = dyn_cast(Ty); assert(PTy && "Param with byval attribute should be a pointer type"); - Type *ETy = PTy->getElementType(); + Type *ETy = PTy->getPointerElementType(); if (isABI || isKernelFunc) { // Just print .param .align .b8 .param[size]; @@ -1715,9 +1714,8 @@ return; } if (const GlobalValue *GVar = dyn_cast(CPV)) { - PointerType *PTy = dyn_cast(GVar->getType()); bool IsNonGenericPointer = false; - if (PTy && PTy->getAddressSpace() != 0) { + if (GVar->getType()->getAddressSpace() != 0) { IsNonGenericPointer = true; } if (EmitGeneric && !isa(CPV) && !IsNonGenericPointer) { Index: lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp =================================================================== --- lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp +++ lib/Target/NVPTX/NVPTXFavorNonGenericAddrSpaces.cpp @@ -133,7 +133,7 @@ // the address space but not the type. If the type also changes, we could // still get rid of the addrspacecast by adding an extra bitcast, but we // rarely see such scenarios. - if (SrcTy->getElementType() != DestTy->getElementType()) + if (SrcTy->getPointerElementType() != DestTy->getPointerElementType()) return false; // Checks whether the addrspacecast is from a non-generic address space to the @@ -197,7 +197,7 @@ // BC' = addrspacecast Cast' Value *Src = Cast->getOperand(0); Type *TypeOfNewCast = - PointerType::get(BC->getType()->getPointerElementType(), + PointerType::get(cast(BC->getType())->getPointerElementType(), Src->getType()->getPointerAddressSpace()); Value *NewBC; if (BitCastInst *BCI = dyn_cast(BC)) { Index: lib/Target/NVPTX/NVPTXGenericToNVVM.cpp =================================================================== --- lib/Target/NVPTX/NVPTXGenericToNVVM.cpp +++ lib/Target/NVPTX/NVPTXGenericToNVVM.cpp @@ -86,7 +86,7 @@ !llvm::isTexture(*GV) && !llvm::isSurface(*GV) && !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) { GlobalVariable *NewGV = new GlobalVariable( - M, GV->getType()->getElementType(), GV->isConstant(), + M, GV->getValueType(), GV->isConstant(), GV->getLinkage(), GV->hasInitializer() ? GV->getInitializer() : nullptr, "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL); @@ -172,7 +172,7 @@ // See if the address space conversion requires the operand to be bitcast // to i8 addrspace(n)* first. - EVT ExtendedGVType = EVT::getEVT(GVType->getElementType(), true); + EVT ExtendedGVType = EVT::getEVT(GV->getValueType(), true); if (!ExtendedGVType.isInteger() && !ExtendedGVType.isFloatingPoint()) { // A bitcast to i8 addrspace(n)* on the operand is needed. LLVMContext &Context = M->getContext(); @@ -191,12 +191,12 @@ // Another bitcast from i8 * to * is // required. DestTy = - PointerType::get(GVType->getElementType(), llvm::ADDRESS_SPACE_GENERIC); + PointerType::get(GV->getValueType(), llvm::ADDRESS_SPACE_GENERIC); CVTA = Builder.CreateBitCast(CVTA, DestTy, "cvta"); } else { // A simple CVTA is enough. SmallVector ParamTypes; - ParamTypes.push_back(PointerType::get(GVType->getElementType(), + ParamTypes.push_back(PointerType::get(GV->getValueType(), llvm::ADDRESS_SPACE_GENERIC)); ParamTypes.push_back(GVType); Function *CVTAFunction = Intrinsic::getDeclaration( Index: lib/Target/NVPTX/NVPTXISelLowering.cpp =================================================================== --- lib/Target/NVPTX/NVPTXISelLowering.cpp +++ lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -988,7 +988,7 @@ } auto *PTy = dyn_cast(Ty); assert(PTy && "Param with byval attribute should be a pointer type"); - Type *ETy = PTy->getElementType(); + Type *ETy = PTy->getPointerElementType(); unsigned align = Outs[OIdx].Flags.getByValAlign(); unsigned sz = DL.getTypeAllocSize(ETy); @@ -1325,7 +1325,7 @@ SmallVector Offsets; auto *PTy = dyn_cast(Args[i].Ty); assert(PTy && "Type of a byval parameter should be pointer"); - ComputePTXValueVTs(*this, DAG.getDataLayout(), PTy->getElementType(), + ComputePTXValueVTs(*this, DAG.getDataLayout(), PTy->getPointerElementType(), vtparts, &Offsets, 0); // declare .param .align .b8 .param[]; @@ -2041,7 +2041,7 @@ if (!context) return false; - auto *STy = dyn_cast(PTy->getElementType()); + auto *STy = dyn_cast(PTy->getPointerElementType()); const std::string TypeName = STy && !STy->isLiteral() ? STy->getName() : ""; return std::find(std::begin(specialTypes), std::end(specialTypes), Index: lib/Target/NVPTX/NVPTXLowerAlloca.cpp =================================================================== --- lib/Target/NVPTX/NVPTXLowerAlloca.cpp +++ lib/Target/NVPTX/NVPTXLowerAlloca.cpp @@ -67,7 +67,7 @@ if (auto allocaInst = dyn_cast(&I)) { Changed = true; auto PTy = dyn_cast(allocaInst->getType()); - auto ETy = PTy->getElementType(); + auto ETy = PTy->getPointerElementType(); auto LocalAddrTy = PointerType::get(ETy, ADDRESS_SPACE_LOCAL); auto NewASCToLocal = new AddrSpaceCastInst(allocaInst, LocalAddrTy, ""); auto GenericAddrTy = PointerType::get(ETy, ADDRESS_SPACE_GENERIC); Index: lib/Target/NVPTX/NVPTXLowerKernelArgs.cpp =================================================================== --- lib/Target/NVPTX/NVPTXLowerKernelArgs.cpp +++ lib/Target/NVPTX/NVPTXLowerKernelArgs.cpp @@ -147,7 +147,7 @@ assert(PType && "Expecting pointer type in handleByValParam"); - Type *StructType = PType->getElementType(); + Type *StructType = PType->getPointerElementType(); AllocaInst *AllocA = new AllocaInst(StructType, Arg->getName(), FirstInst); // Set the alignment to alignment of the byval parameter. This is because, // later load/stores assume that alignment, and we are going to replace @@ -179,7 +179,7 @@ } Instruction *PtrInGlobal = new AddrSpaceCastInst( - Ptr, PointerType::get(Ptr->getType()->getPointerElementType(), + Ptr, PointerType::get(cast(Ptr->getType())->getPointerElementType(), ADDRESS_SPACE_GLOBAL), Ptr->getName(), &*InsertPt); Value *PtrInGeneric = new AddrSpaceCastInst(PtrInGlobal, Ptr->getType(), Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -4091,7 +4091,7 @@ Callee.getOpcode() == ISD::TargetGlobalTLSAddress) return false; - return G->getGlobal()->getType()->getElementType()->isFunctionTy(); + return G->getGlobal()->getValueType()->isFunctionTy(); } return false; Index: lib/Target/PowerPC/PPCLoopPreIncPrep.cpp =================================================================== --- lib/Target/PowerPC/PPCLoopPreIncPrep.cpp +++ lib/Target/PowerPC/PPCLoopPreIncPrep.cpp @@ -204,7 +204,7 @@ // There are no update forms for Altivec vector load/stores. if (ST && ST->hasAltivec() && - PtrValue->getType()->getPointerElementType()->isVectorTy()) + cast(PtrValue->getType())->getPointerElementType()->isVectorTy()) continue; if (L->isLoopInvariant(PtrValue)) Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -1048,7 +1048,7 @@ // but since it is not part of the function type, any check will misfire. PointerType *Ty = cast(CalleeFn->arg_begin()->getType()); - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Ty->getPointerElementType(); return DAG.getDataLayout().getTypeAllocSize(ElementTy); } Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -19101,8 +19101,9 @@ TargetLowering::AtomicExpansionKind X86TargetLowering::shouldExpandAtomicLoadInIR(LoadInst *LI) const { auto PTy = cast(LI->getPointerOperand()->getType()); - return needsCmpXchgNb(PTy->getElementType()) ? AtomicExpansionKind::CmpXChg - : AtomicExpansionKind::None; + auto ValTy = PTy->getPointerElementType(); + return needsCmpXchgNb(ValTy) ? AtomicExpansionKind::CmpXChg + : AtomicExpansionKind::None; } TargetLowering::AtomicExpansionKind Index: lib/Target/XCore/XCoreAsmPrinter.cpp =================================================================== --- lib/Target/XCore/XCoreAsmPrinter.cpp +++ lib/Target/XCore/XCoreAsmPrinter.cpp @@ -93,8 +93,7 @@ assert( ( GV->hasExternalLinkage() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() ) && "Unexpected linkage"); - if (ArrayType *ATy = dyn_cast( - cast(GV->getType())->getElementType())) { + if (ArrayType *ATy = dyn_cast(GV->getValueType())) { MCSymbol *SymGlob = OutContext.getOrCreateSymbol( Twine(Sym->getName() + StringRef(".globound"))); Index: lib/Target/XCore/XCoreISelLowering.cpp =================================================================== --- lib/Target/XCore/XCoreISelLowering.cpp +++ lib/Target/XCore/XCoreISelLowering.cpp @@ -257,7 +257,7 @@ // FIXME there is no actual debug info here SDLoc dl(GA); - if (GV->getType()->getElementType()->isFunctionTy()) + if (GV->getValueType()->isFunctionTy()) return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA); const auto *GVar = dyn_cast(GV); @@ -272,7 +272,7 @@ if (XTL.getTargetMachine().getCodeModel() == CodeModel::Small) return true; - Type *ObjType = GV->getType()->getPointerElementType(); + Type *ObjType = GV->getValueType(); if (!ObjType->isSized()) return false; Index: lib/Target/XCore/XCoreLowerThreadLocal.cpp =================================================================== --- lib/Target/XCore/XCoreLowerThreadLocal.cpp +++ lib/Target/XCore/XCoreLowerThreadLocal.cpp @@ -189,7 +189,7 @@ return false; // Create replacement global. - ArrayType *NewType = createLoweredType(GV->getType()->getElementType()); + ArrayType *NewType = createLoweredType(GV->getValueType()); Constant *NewInitializer = nullptr; if (GV->hasInitializer()) NewInitializer = createLoweredInitializer(NewType, Index: lib/Target/XCore/XCoreTargetObjectFile.cpp =================================================================== --- lib/Target/XCore/XCoreTargetObjectFile.cpp +++ lib/Target/XCore/XCoreTargetObjectFile.cpp @@ -122,7 +122,7 @@ if (Kind.isMergeableConst8()) return MergeableConst8Section; if (Kind.isMergeableConst16()) return MergeableConst16Section; } - Type *ObjType = GV->getType()->getPointerElementType(); + Type *ObjType = GV->getValueType(); auto &DL = GV->getParent()->getDataLayout(); if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() || DL.getTypeAllocSize(ObjType) < CodeModelLargeSize) { Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -85,7 +85,7 @@ bool isDenselyPacked(Type *type, const DataLayout &DL); bool canPaddingBeAccessed(Argument *Arg); CallGraphNode *PromoteArguments(CallGraphNode *CGN); - bool isSafeToPromoteArgument(Argument *Arg, bool isByVal, + bool isSafeToPromoteArgument(Argument *Arg, Type *ElemTy, bool isByVal, AAResults &AAR) const; CallGraphNode *DoPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, @@ -141,13 +141,12 @@ if (DL.getTypeSizeInBits(type) != DL.getTypeAllocSizeInBits(type)) return false; - if (!isa(type)) + if (!isa(type) || isa(type)) return true; // For homogenous sequential types, check for padding within members. if (SequentialType *seqTy = dyn_cast(type)) - return isa(seqTy) || - isDenselyPacked(seqTy->getElementType(), DL); + return isDenselyPacked(seqTy->getElementType(), DL); // Check for padding within and between elements of a struct. StructType *StructTy = cast(type); @@ -256,7 +255,7 @@ SmallPtrSet ByValArgsToTransform; for (unsigned i = 0, e = PointerArgs.size(); i != e; ++i) { Argument *PtrArg = PointerArgs[i]; - Type *AgTy = cast(PtrArg->getType())->getElementType(); + Type *AgTy = cast(PtrArg->getType())->getPointerElementType(); // Replace sret attribute with noalias. This reduces register pressure by // avoiding a register copy. @@ -328,7 +327,7 @@ } // Otherwise, see if we can promote the pointer to its value. - if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValOrInAllocaAttr(), AAR)) + if (isSafeToPromoteArgument(PtrArg, AgTy, PtrArg->hasByValOrInAllocaAttr(), AAR)) ArgsToPromote.insert(PtrArg); } @@ -341,11 +340,12 @@ /// AllCallersPassInValidPointerForArgument - Return true if we can prove that /// all callees pass in a valid pointer for the specified function argument. -static bool AllCallersPassInValidPointerForArgument(Argument *Arg) { +static bool AllCallersPassInValidPointerForArgument(Argument *Arg, Type *ElemTy) { Function *Callee = Arg->getParent(); const DataLayout &DL = Callee->getParent()->getDataLayout(); unsigned ArgNo = Arg->getArgNo(); + uint64_t Size = DL.getTypeStoreSize(ElemTy); // Look at all call sites of the function. At this pointer we know we only // have direct callees. @@ -353,7 +353,7 @@ CallSite CS(U); assert(CS && "Should only have direct calls!"); - if (!isDereferenceablePointer(CS.getArgument(ArgNo), DL)) + if (!isDereferenceablePointer(CS.getArgument(ArgNo), Size, DL)) return false; } return true; @@ -428,7 +428,7 @@ /// This method limits promotion of aggregates to only promote up to three /// elements of the aggregate in order to avoid exploding the number of /// arguments passed in. -bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, +bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, Type *ElemTy, bool isByValOrInAlloca, AAResults &AAR) const { typedef std::set GEPIndicesSet; @@ -462,7 +462,7 @@ GEPIndicesSet ToPromote; // If the pointer is always valid, any load with first index 0 is valid. - if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg)) + if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg, ElemTy)) SafeToUnconditionallyLoad.insert(IndicesVector(1, 0)); // First, iterate the entry block and mark loads of (geps of) arguments as @@ -518,7 +518,7 @@ // TODO: This runs the above loop over and over again for dead GEPs // Couldn't we just do increment the UI iterator earlier and erase the // use? - return isSafeToPromoteArgument(Arg, isByValOrInAlloca, AAR); + return isSafeToPromoteArgument(Arg, ElemTy, isByValOrInAlloca, AAR); } // Ensure that all of the indices are constants. @@ -648,7 +648,7 @@ ++I, ++ArgIndex) { if (ByValArgsToTransform.count(&*I)) { // Simple byval argument? Just add all the struct element types. - Type *AgTy = cast(I->getType())->getElementType(); + Type *AgTy = cast(I->getType())->getPointerElementType(); StructType *STy = cast(AgTy); Params.insert(Params.end(), STy->element_begin(), STy->element_end()); ++NumByValArgsPromoted; @@ -704,7 +704,7 @@ E = ArgIndices.end(); SI != E; ++SI) { // not allowed to dereference ->begin() if size() is 0 Params.push_back(GetElementPtrInst::getIndexedType( - cast(I->getType()->getScalarType())->getElementType(), + cast(I->getType()->getScalarType())->getPointerElementType(), SI->second)); assert(Params.back()); } @@ -783,7 +783,7 @@ } } else if (ByValArgsToTransform.count(&*I)) { // Emit a GEP and load for each element of the struct. - Type *AgTy = cast(I->getType())->getElementType(); + Type *AgTy = cast(I->getType())->getPointerElementType(); StructType *STy = cast(AgTy); Value *Idxs[2] = { ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), nullptr }; @@ -817,7 +817,11 @@ Type::getInt64Ty(F->getContext())); Ops.push_back(ConstantInt::get(IdxTy, *II)); // Keep track of the type we're currently indexing. - ElTy = cast(ElTy)->getTypeAtIndex(*II); + if (auto *PtrTy = dyn_cast(ElTy)) { + ElTy = PtrTy->getPointerElementType(); + } else { + ElTy = cast(ElTy)->getTypeAtIndex(*II); + } } // And create a GEP to extract those indices. V = GetElementPtrInst::Create(SI->first, V, Ops, @@ -910,7 +914,7 @@ Instruction *InsertPt = &NF->begin()->front(); // Just add all the struct element types. - Type *AgTy = cast(I->getType())->getElementType(); + Type *AgTy = cast(I->getType())->getPointerElementType(); Value *TheAlloca = new AllocaInst(AgTy, nullptr, "", InsertPt); StructType *STy = cast(AgTy); Value *Idxs[2] = { Index: lib/Transforms/IPO/ExtractGV.cpp =================================================================== --- lib/Transforms/IPO/ExtractGV.cpp +++ lib/Transforms/IPO/ExtractGV.cpp @@ -128,7 +128,7 @@ makeVisible(*CurI, Delete); if (Delete) { - Type *Ty = CurI->getType()->getElementType(); + Type *Ty = CurI->getValueType(); CurI->removeFromParent(); llvm::Value *Declaration; Index: lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- lib/Transforms/IPO/GlobalOpt.cpp +++ lib/Transforms/IPO/GlobalOpt.cpp @@ -121,7 +121,7 @@ return false; SmallVector Types; - Types.push_back(cast(GV->getType())->getElementType()); + Types.push_back(GV->getValueType()); unsigned Limit = 20; do { @@ -330,7 +330,7 @@ // we already know what the result of any load from that GEP is. // TODO: Handle splats. if (Init && isa(Init) && GEP->isInBounds()) - SubInit = Constant::getNullValue(GEP->getType()->getElementType()); + SubInit = Constant::getNullValue(GEP->getResultElementType()); } Changed |= CleanupConstantGlobalUsers(GEP, SubInit, DL, TLI); @@ -871,9 +871,8 @@ } Constant *RepValue = NewGV; - if (NewGV->getType() != GV->getType()->getElementType()) - RepValue = ConstantExpr::getBitCast(RepValue, - GV->getType()->getElementType()); + if (NewGV->getType() != GV->getValueType()) + RepValue = ConstantExpr::getBitCast(RepValue, GV->getValueType()); // If there is a comparison against null, we will insert a global bool to // keep track of whether the global was initialized yet or not. @@ -1174,7 +1173,7 @@ // field. PointerType *PTy = cast(PN->getType()); - StructType *ST = cast(PTy->getElementType()); + StructType *ST = cast(PTy->getPointerElementType()); unsigned AS = PTy->getAddressSpace(); PHINode *NewPN = @@ -1403,8 +1402,8 @@ // Insert a store of null into each global. for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) { - PointerType *PT = cast(FieldGlobals[i]->getType()); - Constant *Null = Constant::getNullValue(PT->getElementType()); + Type *ValTy = cast(FieldGlobals[i])->getValueType(); + Constant *Null = Constant::getNullValue(ValTy); new StoreInst(Null, FieldGlobals[i], SI); } // Erase the original store. @@ -1594,7 +1593,7 @@ /// boolean and select between the two values whenever it is used. This exposes /// the values to other scalar optimizations. static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { - Type *GVElType = GV->getType()->getElementType(); + Type *GVElType = GV->getValueType(); // If GVElType is already i1, it is already shrunk. If the type of the GV is // an FP value, pointer or vector, don't do this optimization because a select @@ -1872,7 +1871,7 @@ // If the global is in different address space, don't bring it to stack. if (!GS.HasMultipleAccessingFunctions && GS.AccessingFunction && - GV->getType()->getElementType()->isSingleValueType() && + GV->getValueType()->isSingleValueType() && GV->getType()->getAddressSpace() == 0 && !GV->isExternallyInitialized() && allNonInstructionUsersCanBeMadeInstructions(GV) && @@ -1881,7 +1880,7 @@ DEBUG(dbgs() << "LOCALIZING GLOBAL: " << *GV << "\n"); Instruction &FirstI = const_cast(*GS.AccessingFunction ->getEntryBlock().begin()); - Type *ElemTy = GV->getType()->getElementType(); + Type *ElemTy = GV->getValueType(); // FIXME: Pass Global's alignment when globals have alignment AllocaInst *Alloca = new AllocaInst(ElemTy, nullptr, GV->getName(), &FirstI); @@ -2187,10 +2186,10 @@ /// another pointer type, we punt. We basically just support direct accesses to /// globals and GEP's of globals. This should be kept up to date with /// CommitValueTo. -static bool isSimpleEnoughPointerToCommit(Constant *C) { +static bool isSimpleEnoughPointerToCommit(Constant *C, Type *ValTy) { // Conservatively, avoid aggregate types. This is because we don't // want to worry about them partially overlapping other stores. - if (!cast(C->getType())->getElementType()->isSingleValueType()) + if (!ValTy->isSingleValueType()) return false; if (GlobalVariable *GV = dyn_cast(C)) @@ -2427,19 +2426,20 @@ DEBUG(dbgs() << "Store is not simple! Can not evaluate.\n"); return false; // no volatile/atomic accesses. } - Constant *Ptr = getVal(SI->getOperand(1)); + Constant *Ptr = getVal(SI->getPointerOperand()); if (ConstantExpr *CE = dyn_cast(Ptr)) { DEBUG(dbgs() << "Folding constant ptr expression: " << *Ptr); Ptr = ConstantFoldConstantExpression(CE, DL, TLI); DEBUG(dbgs() << "; To: " << *Ptr << "\n"); } - if (!isSimpleEnoughPointerToCommit(Ptr)) { + Type *ValTy = SI->getValueOperand()->getType(); + if (!isSimpleEnoughPointerToCommit(Ptr, ValTy)) { // If this is too complex for us to commit, reject it. DEBUG(dbgs() << "Pointer is too complex for us to evaluate store."); return false; } - Constant *Val = getVal(SI->getOperand(0)); + Constant *Val = getVal(SI->getValueOperand()); // If this might be too difficult for the backend to handle (e.g. the addr // of one global variable divided by another) then we can't commit it. @@ -2457,7 +2457,7 @@ // stored value. Ptr = CE->getOperand(0); - Type *NewTy = cast(Ptr->getType())->getElementType(); + Type *NewTy = cast(Ptr->getType())->getPointerElementType(); // In order to push the bitcast onto the stored value, a bitcast // from NewTy to Val's type must be legal. If it's not, we can try @@ -2567,7 +2567,7 @@ DEBUG(dbgs() << "Found an array alloca. Can not evaluate.\n"); return false; // Cannot handle array allocs. } - Type *Ty = AI->getType()->getElementType(); + Type *Ty = AI->getAllocatedType(); AllocaTmps.push_back( make_unique(Ty, false, GlobalValue::InternalLinkage, UndefValue::get(Ty), AI->getName())); @@ -2625,7 +2625,7 @@ Value *PtrArg = getVal(II->getArgOperand(1)); Value *Ptr = PtrArg->stripPointerCasts(); if (GlobalVariable *GV = dyn_cast(Ptr)) { - Type *ElemTy = cast(GV->getType())->getElementType(); + Type *ElemTy = GV->getValueType(); if (!Size->isAllOnesValue() && Size->getValue().getLimitedValue() >= DL.getTypeStoreSize(ElemTy)) { Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -106,7 +106,7 @@ MDNode *CopyMD = nullptr; if (StrippedDest != MI->getArgOperand(0)) { Type *SrcETy = cast(StrippedDest->getType()) - ->getElementType(); + ->getPointerElementType(); if (SrcETy->isSized() && DL.getTypeStoreSize(SrcETy) == Size) { // The SrcETy might be something like {{{double}}} or [1 x double]. Rip // down through these levels if so. @@ -1778,7 +1778,7 @@ II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); // isDereferenceablePointer -> deref attribute - if (isDereferenceablePointer(DerivedPtr, DL)) { + if (isDereferenceablePointer(DerivedPtr, 1, DL)) { if (Argument *A = dyn_cast(DerivedPtr)) { uint64_t Bytes = A->getDereferenceableBytes(); II->addDereferenceableAttr(AttributeSet::ReturnIndex, Bytes); @@ -1825,8 +1825,8 @@ return true; Type* SrcTy = - cast(CI->getOperand(0)->getType())->getElementType(); - Type* DstTy = cast(CI->getType())->getElementType(); + cast(CI->getOperand(0)->getType())->getPointerElementType(); + Type* DstTy = cast(CI->getType())->getPointerElementType(); if (!SrcTy->isSized() || !DstTy->isSized()) return false; if (DL.getTypeAllocSize(SrcTy) != DL.getTypeAllocSize(DstTy)) @@ -2021,7 +2021,7 @@ return transformCallThroughTrampoline(CS, II); PointerType *PTy = cast(Callee->getType()); - FunctionType *FTy = cast(PTy->getElementType()); + FunctionType *FTy = cast(PTy->getPointerElementType()); if (FTy->isVarArg()) { int ix = FTy->getNumParams(); // See if we can optimize any arguments passed through the varargs area of @@ -2149,12 +2149,12 @@ CallerPAL.getParamAttributes(i + 1).hasAttribute(i + 1, Attribute::ByVal)) { PointerType *ParamPTy = dyn_cast(ParamTy); - if (!ParamPTy || !ParamPTy->getElementType()->isSized()) + if (!ParamPTy || !ParamPTy->getPointerElementType()->isSized()) return false; - Type *CurElTy = ActTy->getPointerElementType(); + Type *CurElTy = cast(ActTy)->getPointerElementType(); if (DL.getTypeAllocSize(CurElTy) != - DL.getTypeAllocSize(ParamPTy->getElementType())) + DL.getTypeAllocSize(ParamPTy->getPointerElementType())) return false; } } @@ -2168,16 +2168,16 @@ // call. We don't want to introduce a varargs call where one doesn't // already exist. PointerType *APTy = cast(CS.getCalledValue()->getType()); - if (FT->isVarArg()!=cast(APTy->getElementType())->isVarArg()) + if (FT->isVarArg()!=cast(APTy->getPointerElementType())->isVarArg()) return false; // If both the callee and the cast type are varargs, we still have to make // sure the number of fixed parameters are the same or we have the same // ABI issues as if we introduce a varargs call. if (FT->isVarArg() && - cast(APTy->getElementType())->isVarArg() && + cast(APTy->getPointerElementType())->isVarArg() && FT->getNumParams() != - cast(APTy->getElementType())->getNumParams()) + cast(APTy->getPointerElementType())->getNumParams()) return false; } @@ -2340,7 +2340,7 @@ IntrinsicInst *Tramp) { Value *Callee = CS.getCalledValue(); PointerType *PTy = cast(Callee->getType()); - FunctionType *FTy = cast(PTy->getElementType()); + FunctionType *FTy = cast(PTy->getPointerElementType()); const AttributeSet &Attrs = CS.getAttributes(); // If the call already has the 'nest' attribute somewhere then give up - @@ -2352,8 +2352,7 @@ "transformCallThroughTrampoline called with incorrect CallSite."); Function *NestF =cast(Tramp->getArgOperand(1)->stripPointerCasts()); - PointerType *NestFPTy = cast(NestF->getType()); - FunctionType *NestFTy = cast(NestFPTy->getElementType()); + FunctionType *NestFTy = cast(NestF->getValueType()); const AttributeSet &NestAttrs = NestF->getAttributes(); if (!NestAttrs.isEmpty()) { Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -87,7 +87,7 @@ // Get the type really allocated and the type casted to. Type *AllocElTy = AI.getAllocatedType(); - Type *CastElTy = PTy->getElementType(); + Type *CastElTy = PTy->getPointerElementType(); if (!AllocElTy->isSized() || !CastElTy->isSized()) return nullptr; unsigned AllocElTyAlign = DL.getABITypeAlignment(AllocElTy); @@ -1800,8 +1800,8 @@ if (PointerType *DstPTy = dyn_cast(DestTy)) { PointerType *SrcPTy = cast(SrcTy); - Type *DstElTy = DstPTy->getElementType(); - Type *SrcElTy = SrcPTy->getElementType(); + Type *DstElTy = DstPTy->getPointerElementType(); + Type *SrcElTy = SrcPTy->getPointerElementType(); // If we are casting a alloca to a pointer to a type of the same // size, rewrite the allocation instruction to allocate the "right" type. @@ -1816,7 +1816,7 @@ // This can enhance SROA and other transforms that want type-safe pointers. unsigned NumZeros = 0; while (SrcElTy != DstElTy && - isa(SrcElTy) && !SrcElTy->isPointerTy() && + isa(SrcElTy) && SrcElTy->getNumContainedTypes() /* not "{}" */) { SrcElTy = cast(SrcElTy)->getTypeAtIndex(0U); ++NumZeros; @@ -1918,8 +1918,8 @@ PointerType *SrcTy = cast(Src->getType()->getScalarType()); PointerType *DestTy = cast(CI.getType()->getScalarType()); - Type *DestElemTy = DestTy->getElementType(); - if (SrcTy->getElementType() != DestElemTy) { + Type *DestElemTy = DestTy->getPointerElementType(); + if (SrcTy->getPointerElementType() != DestElemTy) { Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace()); if (VectorType *VT = dyn_cast(CI.getType())) { // Handle vectors of pointers. Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -635,7 +635,7 @@ if (!GV->hasDefinitiveInitializer() || !GV->isConstant()) return false; - uint64_t InitSize = DL.getTypeAllocSize(GV->getType()->getElementType()); + uint64_t InitSize = DL.getTypeAllocSize(GV->getValueType()); if (InitSize > MaxSize) return false; continue; @@ -692,10 +692,8 @@ return false; SmallVector Ops(GEPI->idx_begin(), GEPI->idx_begin() + Idx); - Type *AllocTy = GetElementPtrInst::getIndexedType( - cast(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(); @@ -791,7 +789,7 @@ BasicBlock::iterator BBI(LI); AAMDNodes AATags; if (Value *AvailableVal = - FindAvailableLoadedValue(Op, LI.getParent(), BBI, + FindAvailableLoadedValue(&LI, LI.getParent(), BBI, DefMaxInstsToScan, AA, &AATags)) { if (LoadInst *NLI = dyn_cast(AvailableVal)) { unsigned KnownIDs[] = { @@ -849,15 +847,15 @@ // if (SelectInst *SI = dyn_cast(Op)) { // load (select (Cond, &V1, &V2)) --> select(Cond, load &V1, load &V2). - unsigned Align = LI.getAlignment(); - if (isSafeToLoadUnconditionally(SI->getOperand(1), SI, Align) && - isSafeToLoadUnconditionally(SI->getOperand(2), SI, Align)) { + uint64_t Size = DL.getTypeStoreSize(LI.getType()); + if (isSafeToLoadUnconditionally(SI->getOperand(1), SI, EffectiveLoadAlign, Size) && + isSafeToLoadUnconditionally(SI->getOperand(2), SI, EffectiveLoadAlign, Size)) { LoadInst *V1 = Builder->CreateLoad(SI->getOperand(1), SI->getOperand(1)->getName()+".val"); LoadInst *V2 = Builder->CreateLoad(SI->getOperand(2), SI->getOperand(2)->getName()+".val"); - V1->setAlignment(Align); - V2->setAlignment(Align); + V1->setAlignment(LoadAlign); + V2->setAlignment(LoadAlign); return SelectInst::Create(SI->getCondition(), V1, V2); } Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -931,7 +931,7 @@ /// element type, otherwise return null. Type *InstCombiner::FindElementAtOffset(PointerType *PtrTy, int64_t Offset, SmallVectorImpl &NewIndices) { - Type *Ty = PtrTy->getElementType(); + Type *Ty = PtrTy->getPointerElementType(); if (!Ty->isSized()) return nullptr; @@ -1334,7 +1334,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { SmallVector Ops(GEP.op_begin(), GEP.op_end()); - if (Value *V = SimplifyGEPInst(Ops, DL, TLI, DT, AC)) + if (Value *V = SimplifyGEPInst(GEP.getSourceElementType(), Ops, DL, TLI, DT, AC)) return ReplaceInstUsesWith(GEP, V); Value *PtrOp = GEP.getOperand(0); @@ -1349,19 +1349,18 @@ 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(*GTI); - if (!SeqTy) + if (isa(*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(*I) || !cast(*I)->isNullValue()) { *I = Constant::getNullValue(NewIndexType); MadeChange = true; @@ -1405,7 +1404,7 @@ 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()) @@ -1419,7 +1418,7 @@ // The first two arguments can vary for any GEP, the rest have to be // static for struct slots - if (J > 1 && CurTy->isStructTy()) + if (J > 1 && CurTy && CurTy->isStructTy()) return nullptr; DI = J; @@ -1436,7 +1435,9 @@ // Sink down a layer of the type for the next iteration. if (J > 0) { - if (CompositeType *CT = dyn_cast(CurTy)) { + if (J == 1) { + CurTy = Op1->getSourceElementType(); + } else if (CompositeType *CT = dyn_cast(CurTy)) { CurTy = CT->getTypeAtIndex(Op1->getOperand(J)); } else { CurTy = nullptr; @@ -1565,8 +1566,7 @@ 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; @@ -1629,15 +1629,14 @@ // // This occurs when the program declares an array extern like "int X[];" if (HasZeroPointerIndex) { - PointerType *CPTy = cast(PtrOp->getType()); if (ArrayType *CATy = - dyn_cast(CPTy->getElementType())) { + dyn_cast(GEP.getSourceElementType())) { // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ? - if (CATy->getElementType() == StrippedPtrTy->getElementType()) { + if (CATy->getElementType() == StrippedPtrTy->getPointerElementType()) { // -> GEP i8* X, ... SmallVector Idx(GEP.idx_begin()+1, GEP.idx_end()); GetElementPtrInst *Res = GetElementPtrInst::Create( - StrippedPtrTy->getElementType(), StrippedPtr, Idx, GEP.getName()); + StrippedPtrTy->getPointerElementType(), StrippedPtr, Idx, GEP.getName()); Res->setIsInBounds(GEP.isInBounds()); if (StrippedPtrTy->getAddressSpace() == GEP.getAddressSpace()) return Res; @@ -1651,7 +1650,7 @@ } if (ArrayType *XATy = - dyn_cast(StrippedPtrTy->getElementType())){ + dyn_cast(StrippedPtrTy->getPointerElementType())){ // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ? if (CATy->getElementType() == XATy->getElementType()) { // -> GEP [10 x i8]* X, i32 0, ... @@ -1687,8 +1686,8 @@ // Transform things like: // %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 *SrcElTy = StrippedPtrTy->getPointerElementType(); + Type *ResElTy = GEP.getSourceElementType(); if (SrcElTy->isArrayTy() && DL.getTypeAllocSize(SrcElTy->getArrayElementType()) == DL.getTypeAllocSize(ResElTy)) { Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1184,7 +1184,7 @@ } bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) { - Type *Ty = cast(G->getType())->getElementType(); + Type *Ty = G->getValueType(); DEBUG(dbgs() << "GLOBAL: " << *G << "\n"); if (GlobalsMD.get(G).IsBlacklisted) return false; @@ -1338,8 +1338,7 @@ M, MD.Name.empty() ? G->getName() : MD.Name, /*AllowMerging*/ true); - PointerType *PtrTy = cast(G->getType()); - Type *Ty = PtrTy->getElementType(); + Type *Ty = G->getValueType(); uint64_t SizeInBytes = DL.getTypeAllocSize(Ty); uint64_t MinRZ = MinRedzoneSizeForGlobal(); // MinRZ <= RZ <= kMaxGlobalRedzone Index: lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -134,7 +134,7 @@ StringRef GetGlobalTypeString(const GlobalValue &G) { // Types of GlobalVariables are always pointer types. - Type *GType = G.getType()->getElementType(); + Type *GType = G.getValueType(); // For now we support blacklisting struct types only. if (StructType *SGType = dyn_cast(GType)) { if (!SGType->isLiteral()) @@ -166,7 +166,7 @@ if (isIn(*GA.getParent(), Category)) return true; - if (isa(GA.getType()->getElementType())) + if (isa(GA.getValueType())) return SCL->inSection("fun", GA.getName(), Category); return SCL->inSection("global", GA.getName(), Category) || @@ -406,7 +406,7 @@ i != e; ++i) { FunctionType *FT; if (isa(*i) && (FT = dyn_cast(cast( - *i)->getElementType()))) { + *i)->getPointerElementType()))) { ArgTypes.push_back(getTrampolineFunctionType(FT)->getPointerTo()); ArgTypes.push_back(Type::getInt8PtrTy(*Ctx)); } else { @@ -1413,7 +1413,7 @@ return; assert(!(cast( - CS.getCalledValue()->getType()->getPointerElementType())->isVarArg() && + cast(CS.getCalledValue()->getType())->getPointerElementType())->isVarArg() && dyn_cast(CS.getInstruction()))); IRBuilder<> IRB(CS.getInstruction()); @@ -1469,7 +1469,7 @@ FunctionType *ParamFT; if (isa(T) && (ParamFT = dyn_cast( - cast(T)->getElementType()))) { + cast(T)->getPointerElementType()))) { std::string TName = "dfst"; TName += utostr(FT->getNumParams() - n); TName += "$"; @@ -1532,7 +1532,7 @@ } FunctionType *FT = cast( - CS.getCalledValue()->getType()->getPointerElementType()); + cast(CS.getCalledValue()->getType())->getPointerElementType()); if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) { for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) { IRB.CreateStore(DFSF.getShadow(CS.getArgument(i)), Index: lib/Transforms/Instrumentation/GCOVProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -874,7 +874,7 @@ GlobalVariable *GV = CountersBySP[j].first; unsigned Arcs = - cast(GV->getType()->getElementType())->getNumElements(); + cast(GV->getValueType())->getNumElements(); Builder.CreateCall(EmitArcs, {Builder.getInt32(Arcs), Builder.CreateConstGEP2_64(GV, 0, 0)}); } @@ -966,7 +966,7 @@ I = CountersBySP.begin(), E = CountersBySP.end(); I != E; ++I) { GlobalVariable *GV = I->first; - Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); + Constant *Null = Constant::getNullValue(GV->getValueType()); Builder.CreateStore(Null, GV); } Index: lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1095,7 +1095,7 @@ } unsigned Size = FArg.hasByValAttr() - ? DL.getTypeAllocSize(FArg.getType()->getPointerElementType()) + ? DL.getTypeAllocSize(cast(FArg.getType())->getPointerElementType()) : DL.getTypeAllocSize(FArg.getType()); if (A == &FArg) { bool Overflow = ArgOffset + Size > kParamTLSSize; @@ -1106,7 +1106,7 @@ // Figure out maximal valid memcpy alignment. unsigned ArgAlign = FArg.getParamAlignment(); if (ArgAlign == 0) { - Type *EltType = A->getType()->getPointerElementType(); + Type *EltType = cast(A->getType())->getPointerElementType(); ArgAlign = DL.getABITypeAlignment(EltType); } if (Overflow) { @@ -2477,7 +2477,7 @@ if (CS.paramHasAttr(i + 1, Attribute::ByVal)) { assert(A->getType()->isPointerTy() && "ByVal argument is not a pointer!"); - Size = DL.getTypeAllocSize(A->getType()->getPointerElementType()); + Size = DL.getTypeAllocSize(cast(A->getType())->getPointerElementType()); if (ArgOffset + Size > kParamTLSSize) break; unsigned ParamAlignment = CS.getParamAlignment(i + 1); unsigned Alignment = std::min(ParamAlignment, kShadowTLSAlignment); @@ -2815,7 +2815,7 @@ if (IsByVal) { // ByVal arguments always go to the overflow area. assert(A->getType()->isPointerTy()); - Type *RealTy = A->getType()->getPointerElementType(); + Type *RealTy = cast(A->getType())->getPointerElementType(); uint64_t ArgSize = DL.getTypeAllocSize(RealTy); Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset); OverflowOffset += RoundUpToAlignment(ArgSize, 8); Index: lib/Transforms/Instrumentation/SafeStack.cpp =================================================================== --- lib/Transforms/Instrumentation/SafeStack.cpp +++ lib/Transforms/Instrumentation/SafeStack.cpp @@ -401,7 +401,7 @@ if (!Arg.hasByValAttr()) continue; uint64_t Size = - DL->getTypeStoreSize(Arg.getType()->getPointerElementType()); + DL->getTypeStoreSize(cast(Arg.getType())->getPointerElementType()); if (IsSafeStackAlloca(&Arg, Size)) continue; @@ -476,7 +476,7 @@ // Compute maximum alignment among static objects on the unsafe stack. unsigned MaxAlignment = 0; for (Argument *Arg : ByValArguments) { - Type *Ty = Arg->getType()->getPointerElementType(); + Type *Ty = cast(Arg->getType())->getPointerElementType(); unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), Arg->getParamAlignment()); if (Align > MaxAlignment) @@ -504,7 +504,7 @@ IRB.SetInsertPoint(BasePointer->getNextNode()); for (Argument *Arg : ByValArguments) { - Type *Ty = Arg->getType()->getPointerElementType(); + Type *Ty = cast(Arg->getType())->getPointerElementType(); uint64_t Size = DL->getTypeStoreSize(Ty); if (Size == 0) Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -94,7 +94,7 @@ SmallVectorImpl &All, const DataLayout &DL); bool addrPointsToConstantData(Value *Addr); - int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL); + int getMemoryAccessFuncIndex(Type *OrigTy, const DataLayout &DL); Type *IntptrTy; IntegerType *OrdTy; @@ -410,7 +410,10 @@ Value *Addr = IsWrite ? cast(I)->getPointerOperand() : cast(I)->getPointerOperand(); - int Idx = getMemoryAccessFuncIndex(Addr, DL); + Type *OrigTy = IsWrite + ? cast(I)->getValueOperand()->getType() + : cast(I)->getType(); + int Idx = getMemoryAccessFuncIndex(OrigTy, DL); if (Idx < 0) return false; if (IsWrite && isVtableAccess(I)) { @@ -440,7 +443,6 @@ const unsigned Alignment = IsWrite ? cast(I)->getAlignment() : cast(I)->getAlignment(); - Type *OrigTy = cast(Addr->getType())->getElementType(); const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy); Value *OnAccessFunc = nullptr; if (Alignment == 0 || Alignment >= 8 || (Alignment % (TypeSize / 8)) == 0) @@ -508,7 +510,7 @@ IRBuilder<> IRB(I); if (LoadInst *LI = dyn_cast(I)) { Value *Addr = LI->getPointerOperand(); - int Idx = getMemoryAccessFuncIndex(Addr, DL); + int Idx = getMemoryAccessFuncIndex(LI->getType(), DL); if (Idx < 0) return false; const unsigned ByteSize = 1U << Idx; @@ -522,7 +524,8 @@ } else if (StoreInst *SI = dyn_cast(I)) { Value *Addr = SI->getPointerOperand(); - int Idx = getMemoryAccessFuncIndex(Addr, DL); + Value *Val = SI->getValueOperand(); + int Idx = getMemoryAccessFuncIndex(Val->getType(), DL); if (Idx < 0) return false; const unsigned ByteSize = 1U << Idx; @@ -530,13 +533,14 @@ Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize); Type *PtrTy = Ty->getPointerTo(); Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy), - IRB.CreateIntCast(SI->getValueOperand(), Ty, false), + IRB.CreateIntCast(Val, Ty, false), createOrdering(&IRB, SI->getOrdering())}; CallInst *C = CallInst::Create(TsanAtomicStore[Idx], Args); ReplaceInstWithInst(I, C); } else if (AtomicRMWInst *RMWI = dyn_cast(I)) { Value *Addr = RMWI->getPointerOperand(); - int Idx = getMemoryAccessFuncIndex(Addr, DL); + Value *Val = RMWI->getValOperand(); + int Idx = getMemoryAccessFuncIndex(Val->getType(), DL); if (Idx < 0) return false; Function *F = TsanAtomicRMW[RMWI->getOperation()][Idx]; @@ -547,13 +551,14 @@ Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize); Type *PtrTy = Ty->getPointerTo(); Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy), - IRB.CreateIntCast(RMWI->getValOperand(), Ty, false), + IRB.CreateIntCast(Val, Ty, false), createOrdering(&IRB, RMWI->getOrdering())}; CallInst *C = CallInst::Create(F, Args); ReplaceInstWithInst(I, C); } else if (AtomicCmpXchgInst *CASI = dyn_cast(I)) { Value *Addr = CASI->getPointerOperand(); - int Idx = getMemoryAccessFuncIndex(Addr, DL); + Value *CmpVal = CASI->getCompareOperand(); + int Idx = getMemoryAccessFuncIndex(CmpVal->getType(), DL); if (Idx < 0) return false; const unsigned ByteSize = 1U << Idx; @@ -561,12 +566,12 @@ Type *Ty = Type::getIntNTy(IRB.getContext(), BitSize); Type *PtrTy = Ty->getPointerTo(); Value *Args[] = {IRB.CreatePointerCast(Addr, PtrTy), - IRB.CreateIntCast(CASI->getCompareOperand(), Ty, false), + IRB.CreateIntCast(CmpVal, Ty, false), IRB.CreateIntCast(CASI->getNewValOperand(), Ty, false), createOrdering(&IRB, CASI->getSuccessOrdering()), createOrdering(&IRB, CASI->getFailureOrdering())}; CallInst *C = IRB.CreateCall(TsanAtomicCAS[Idx], Args); - Value *Success = IRB.CreateICmpEQ(C, CASI->getCompareOperand()); + Value *Success = IRB.CreateICmpEQ(C, CmpVal); Value *Res = IRB.CreateInsertValue(UndefValue::get(CASI->getType()), C, 0); Res = IRB.CreateInsertValue(Res, Success, 1); @@ -583,10 +588,8 @@ return true; } -int ThreadSanitizer::getMemoryAccessFuncIndex(Value *Addr, +int ThreadSanitizer::getMemoryAccessFuncIndex(Type *OrigTy, const DataLayout &DL) { - Type *OrigPtrTy = Addr->getType(); - Type *OrigTy = cast(OrigPtrTy)->getElementType(); assert(OrigTy->isSized()); uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy); if (TypeSize != 8 && TypeSize != 16 && Index: lib/Transforms/ObjCARC/ObjCARCOpts.cpp =================================================================== --- lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -717,7 +717,7 @@ if (IsNullOrUndef(CI->getArgOperand(0))) { Changed = true; Type *Ty = CI->getArgOperand(0)->getType(); - new StoreInst(UndefValue::get(cast(Ty)->getElementType()), + new StoreInst(UndefValue::get(cast(Ty)->getPointerElementType()), Constant::getNullValue(Ty), CI); llvm::Value *NewValue = UndefValue::get(CI->getType()); @@ -736,7 +736,7 @@ IsNullOrUndef(CI->getArgOperand(1))) { Changed = true; Type *Ty = CI->getArgOperand(0)->getType(); - new StoreInst(UndefValue::get(cast(Ty)->getElementType()), + new StoreInst(UndefValue::get(cast(Ty)->getPointerElementType()), Constant::getNullValue(Ty), CI); Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -1117,7 +1117,7 @@ Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, OffsetCst); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); - if (ConstantFoldLoadFromConstPtr(Src, DL)) + if (ConstantFoldLoadFromConstPtr(Src, LoadTy, DL)) return Offset; return -1; } @@ -1279,7 +1279,7 @@ Src = ConstantExpr::getGetElementPtr(Type::getInt8Ty(Src->getContext()), Src, OffsetCst); Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS)); - return ConstantFoldLoadFromConstPtr(Src, DL); + return ConstantFoldLoadFromConstPtr(Src, LoadTy, DL); } Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1833,7 +1833,7 @@ // We could handle pointer IVs other than i8*, but we need to compensate for // gep index scaling. See canExpandBackedgeTakenCount comments. assert(SE->getSizeOfExpr(IntegerType::getInt64Ty(IndVar->getContext()), - cast(GEPBase->getType())->getElementType())->isOne() + cast(GEPBase->getType())->getPointerElementType())->isOne() && "unit stride pointer IV must be i8*"); IRBuilder<> Builder(L->getLoopPreheader()->getTerminator()); Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -948,7 +948,7 @@ BasicBlock::iterator BBIt(LI); if (Value *AvailableVal = - FindAvailableLoadedValue(LoadedPtr, LoadBB, BBIt, DefMaxInstsToScan)) { + FindAvailableLoadedValue(LI, LoadBB, BBIt, DefMaxInstsToScan)) { // If the value of the load is locally available within the block, just use // it. This frequently occurs for reg2mem'd allocas. //cerr << "LOAD ELIMINATED:\n" << *BBIt << *LI << "\n"; @@ -993,7 +993,7 @@ // Scan the predecessor to see if the value is available in the pred. BBIt = PredBB->end(); AAMDNodes ThisAATags; - Value *PredAvailable = FindAvailableLoadedValue(LoadedPtr, PredBB, BBIt, + Value *PredAvailable = FindAvailableLoadedValue(LI, PredBB, BBIt, DefMaxInstsToScan, nullptr, &ThisAATags); if (!PredAvailable) { Index: lib/Transforms/Scalar/LoopLoadElimination.cpp =================================================================== --- lib/Transforms/Scalar/LoopLoadElimination.cpp +++ lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -64,12 +64,11 @@ bool isDependenceDistanceOfOne(PredicatedScalarEvolution &PSE) const { Value *LoadPtr = Load->getPointerOperand(); Value *StorePtr = Store->getPointerOperand(); - Type *LoadPtrType = LoadPtr->getType(); - Type *LoadType = LoadPtrType->getPointerElementType(); + Type *LoadType = Load->getType(); - assert(LoadPtrType->getPointerAddressSpace() == + assert(LoadPtr->getType()->getPointerAddressSpace() == StorePtr->getType()->getPointerAddressSpace() && - LoadType == StorePtr->getType()->getPointerElementType() && + LoadType == Store->getValueOperand()->getType() && "Should be a known dependence"); auto &DL = Load->getParent()->getModule()->getDataLayout(); Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -146,6 +146,9 @@ /// range. Value *StartPtr; + /// DestTy - The type used for writing to the start of the range. + Type *DestTy; + /// Alignment - The known alignment of the first store. unsigned Alignment; @@ -221,18 +224,24 @@ } void addStore(int64_t OffsetFromFirst, StoreInst *SI) { - int64_t StoreSize = DL.getTypeStoreSize(SI->getOperand(0)->getType()); + Type *DestTy = SI->getValueOperand()->getType(); + int64_t StoreSize = DL.getTypeStoreSize(DestTy); addRange(OffsetFromFirst, StoreSize, - SI->getPointerOperand(), SI->getAlignment(), SI); + SI->getPointerOperand(), DestTy, + SI->getAlignment(), SI); } void addMemSet(int64_t OffsetFromFirst, MemSetInst *MSI) { + Type *DestTy = Type::getInt8Ty(MSI->getContext()); int64_t Size = cast(MSI->getLength())->getZExtValue(); - addRange(OffsetFromFirst, Size, MSI->getDest(), MSI->getAlignment(), MSI); + + addRange(OffsetFromFirst, Size, MSI->getDest(), + DestTy, MSI->getAlignment(), MSI); } - void addRange(int64_t Start, int64_t Size, Value *Ptr, + void addRange(int64_t Start, int64_t Size, + Value *Ptr, Type *DestTy, unsigned Alignment, Instruction *Inst); }; @@ -243,7 +252,8 @@ /// Add a new store to the MemsetRanges data structure. This adds a /// new range for the specified store at the specified offset, merging into /// existing ranges as appropriate. -void MemsetRanges::addRange(int64_t Start, int64_t Size, Value *Ptr, +void MemsetRanges::addRange(int64_t Start, int64_t Size, + Value *Ptr, Type *DestTy, unsigned Alignment, Instruction *Inst) { int64_t End = Start+Size; @@ -258,6 +268,7 @@ R.Start = Start; R.End = End; R.StartPtr = Ptr; + R.DestTy = DestTy; R.Alignment = Alignment; R.TheStores.push_back(Inst); return; @@ -280,6 +291,7 @@ if (Start < I->Start) { I->Start = Start; I->StartPtr = Ptr; + I->DestTy = DestTy; I->Alignment = Alignment; } @@ -453,11 +465,8 @@ // Determine alignment unsigned Alignment = Range.Alignment; - if (Alignment == 0) { - Type *EltType = - cast(StartPtr->getType())->getElementType(); - Alignment = DL.getABITypeAlignment(EltType); - } + if (Alignment == 0) + Alignment = DL.getABITypeAlignment(Range.DestTy); AMemSet = Builder.CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment); @@ -637,7 +646,7 @@ if (!A->hasStructRetAttr()) return false; - Type *StructTy = cast(A->getType())->getElementType(); + Type *StructTy = cast(A->getType())->getPointerElementType(); if (!StructTy->isSized()) { // The call may never return and hence the copy-instruction may never // be executed, and therefore it's not safe to say "the destination @@ -1071,7 +1080,7 @@ const DataLayout &DL = CS.getCaller()->getParent()->getDataLayout(); // Find out what feeds this byval argument. Value *ByValArg = CS.getArgument(ArgNo); - Type *ByValTy = cast(ByValArg->getType())->getElementType(); + Type *ByValTy = cast(ByValArg->getType())->getPointerElementType(); uint64_t ByValSize = DL.getTypeAllocSize(ByValTy); MemDepResult DepInfo = MD->getPointerDependencyFrom( MemoryLocation(ByValArg, ByValSize), true, Index: lib/Transforms/Scalar/NaryReassociate.cpp =================================================================== --- lib/Transforms/Scalar/NaryReassociate.cpp +++ lib/Transforms/Scalar/NaryReassociate.cpp @@ -315,7 +315,10 @@ gep_type_iterator GTI = gep_type_begin(GEP); for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I, ++GTI) { - if (isa(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { + uint64_t Field = cast(*I)->getZExtValue(); + BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field); + } else { int64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType()); if (ConstantInt *ConstIdx = dyn_cast(*I)) { BaseOffset += ConstIdx->getSExtValue() * ElementSize; @@ -327,15 +330,11 @@ } Scale = ElementSize; } - } else { - StructType *STy = cast(*GTI); - uint64_t Field = cast(*I)->getZExtValue(); - BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field); } } unsigned AddrSpace = GEP->getPointerAddressSpace(); - return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV, + return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace); } @@ -346,11 +345,12 @@ gep_type_iterator GTI = gep_type_begin(*GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) { - if (isa(*GTI++)) { + if (isa(*GTI) || isa(*GTI)) { + GTI++; if (auto *NewGEP = tryReassociateGEPAtIndex(GEP, I - 1, *GTI)) { return NewGEP; } - } + } else GTI++; } return nullptr; } @@ -434,7 +434,7 @@ // NewGEP = (char *)Candidate + RHS * sizeof(IndexedType) uint64_t IndexedSize = DL->getTypeAllocSize(IndexedType); - Type *ElementType = GEP->getType()->getElementType(); + Type *ElementType = cast(GEP->getType())->getPointerElementType(); 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 Index: lib/Transforms/Scalar/PlaceSafepoints.cpp =================================================================== --- lib/Transforms/Scalar/PlaceSafepoints.cpp +++ lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -762,7 +762,7 @@ // path call - where we need to insert a safepoint (parsepoint). auto *F = M->getFunction(GCSafepointPollName); - assert(F->getType()->getElementType() == + assert(F->getValueType() == FunctionType::get(Type::getVoidTy(M->getContext()), false) && "gc.safepoint_poll declared with wrong type"); assert(!F->empty() && "gc.safepoint_poll must be a non-empty function"); Index: lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1801,8 +1801,7 @@ auto InsertClobbersAt = [&](Instruction *IP) { for (auto *AI : ToClobber) { - auto AIType = cast(AI->getType()); - auto PT = cast(AIType->getElementType()); + auto PT = cast(AI->getAllocatedType()); Constant *CPN = ConstantPointerNull::get(PT); StoreInst *Store = new StoreInst(CPN, AI); Store->insertBefore(IP); @@ -2137,7 +2136,7 @@ } else if (GetElementPtrInst *GEP = dyn_cast(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 Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -228,7 +228,7 @@ /// performing Interprocedural SCCP. void TrackValueOfGlobalVariable(GlobalVariable *GV) { // We only track the contents of scalar globals. - if (GV->getType()->getElementType()->isSingleValueType()) { + if (GV->getValueType()->isSingleValueType()) { LatticeVal &IV = TrackedGlobals[GV]; if (!isa(GV->getInitializer())) IV.markConstant(GV->getInitializer()); @@ -1079,7 +1079,7 @@ } // Transform load from a constant into a constant if possible. - if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, DL)) + if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL)) return markConstant(IV, &I, C); // Otherwise we cannot say for certain what value this load will produce. Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -1143,7 +1143,10 @@ // TODO: Allow recursive phi users. // TODO: Allow stores. BasicBlock *BB = PN.getParent(); + const DataLayout &DL = PN.getModule()->getDataLayout(); + unsigned MaxAlign = 0; + uint64_t MaxSize = 0; bool HaveLoad = false; for (User *U : PN.users()) { LoadInst *LI = dyn_cast(U); @@ -1162,15 +1165,17 @@ if (BBI->mayWriteToMemory()) return false; - MaxAlign = std::max(MaxAlign, LI->getAlignment()); + unsigned Align = LI->getActualAlignment(); + uint64_t Size = LI->getLoadedSize(); + + MaxAlign = std::max(MaxAlign, Align); + MaxSize = std::max(MaxSize, Size); HaveLoad = true; } if (!HaveLoad) return false; - const DataLayout &DL = PN.getModule()->getDataLayout(); - // We can only transform this if it is safe to push the loads into the // predecessor blocks. The only thing to watch out for is that we can't put // a possibly trapping load in the predecessor if it is a critical edge. @@ -1192,8 +1197,8 @@ // If this pointer is always safe to load, or if we can prove that there // is already a load in the block, then we can move the load to the pred // block. - if (isDereferenceablePointer(InVal, DL) || - isSafeToLoadUnconditionally(InVal, TI, MaxAlign)) + if (isDereferenceablePointer(InVal, MaxSize, DL) || + isSafeToLoadUnconditionally(InVal, TI, MaxAlign, MaxSize)) continue; return false; @@ -1205,7 +1210,7 @@ static void speculatePHINodeLoads(PHINode &PN) { DEBUG(dbgs() << " original: " << PN << "\n"); - Type *LoadTy = cast(PN.getType())->getElementType(); + Type *LoadTy = cast(PN.getType())->getPointerElementType(); IRBuilderTy PHIBuilder(&PN); PHINode *NewPN = PHIBuilder.CreatePHI(LoadTy, PN.getNumIncomingValues(), PN.getName() + ".sroa.speculated"); @@ -1261,26 +1266,31 @@ static bool isSafeSelectToSpeculate(SelectInst &SI) { Value *TValue = SI.getTrueValue(); Value *FValue = SI.getFalseValue(); + uint64_t MaxTSize = 0, MaxFSize = 0; const DataLayout &DL = SI.getModule()->getDataLayout(); - bool TDerefable = isDereferenceablePointer(TValue, DL); - bool FDerefable = isDereferenceablePointer(FValue, DL); for (User *U : SI.users()) { LoadInst *LI = dyn_cast(U); if (!LI || !LI->isSimple()) return false; + unsigned Align = LI->getActualAlignment(); + uint64_t Size = LI->getLoadedSize(); + // Both operands to the select need to be dereferencable, either // absolutely (e.g. allocas) or at this point because we can see other // accesses to it. - if (!TDerefable && - !isSafeToLoadUnconditionally(TValue, LI, LI->getAlignment())) - return false; - if (!FDerefable && - !isSafeToLoadUnconditionally(FValue, LI, LI->getAlignment())) - return false; + if (!isSafeToLoadUnconditionally(TValue, LI, Align, Size)) + MaxTSize = std::max(MaxTSize, Size); + if (!isSafeToLoadUnconditionally(FValue, LI, Align, Size)) + MaxFSize = std::max(MaxFSize, Size); } + if (MaxTSize && !isDereferenceablePointer(TValue, MaxTSize, DL)) + return false; + if (MaxFSize && !isDereferenceablePointer(FValue, MaxFSize, DL)) + return false; + return true; } @@ -1479,7 +1489,7 @@ if (Ty == IRB.getInt8PtrTy(Ty->getAddressSpace()) && TargetTy->isIntegerTy(8)) return nullptr; - Type *ElementTy = Ty->getElementType(); + Type *ElementTy = Ty->getPointerElementType(); if (!ElementTy->isSized()) return nullptr; // We can't GEP through an unsized element. APInt ElementSize(Offset.getBitWidth(), DL.getTypeAllocSize(ElementTy)); @@ -1527,7 +1537,7 @@ Value *Int8Ptr = nullptr; APInt Int8PtrOffset(Offset.getBitWidth(), 0); - Type *TargetTy = PointerTy->getPointerElementType(); + Type *TargetTy = cast(PointerTy)->getPointerElementType(); do { // First fold any existing GEPs into the offset. @@ -1758,13 +1768,13 @@ if (II->getIntrinsicID() != Intrinsic::lifetime_start && II->getIntrinsicID() != Intrinsic::lifetime_end) return false; - } else if (U->get()->getType()->getPointerElementType()->isStructTy()) { - // Disable vector promotion when there are loads or stores of an FCA. - return false; } else if (LoadInst *LI = dyn_cast(U->getUser())) { if (LI->isVolatile()) return false; Type *LTy = LI->getType(); + // Disable vector promotion when there are loads or stores of an FCA. + if (LTy->isStructTy()) + return false; if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) { assert(LTy->isIntegerTy()); LTy = SplitIntTy; @@ -1775,6 +1785,9 @@ if (SI->isVolatile()) return false; Type *STy = SI->getValueOperand()->getType(); + // Disable vector promotion when there are loads or stores of an FCA. + if (STy->isStructTy()) + return false; if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) { assert(STy->isIntegerTy()); STy = SplitIntTy; @@ -3220,10 +3233,6 @@ return nullptr; if (SequentialType *SeqTy = dyn_cast(Ty)) { - // We can't partition pointers... - if (SeqTy->isPointerTy()) - return nullptr; - Type *ElementTy = SeqTy->getElementType(); uint64_t ElementSize = DL.getTypeAllocSize(ElementTy); uint64_t NumSkippedElements = Offset / ElementSize; Index: lib/Transforms/Scalar/ScalarReplAggregates.cpp =================================================================== --- lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -510,15 +510,11 @@ if (GetElementPtrInst *GEP = dyn_cast(UI)) { // If this is a GEP with a variable indices, we can't handle it. - PointerType* PtrTy = dyn_cast(GEP->getPointerOperandType()); - if (!PtrTy) - return false; - // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); Value *GEPNonConstantIdx = nullptr; if (!GEP->hasAllConstantIndices()) { - if (!isa(PtrTy->getElementType())) + if (!isa(GEP->getSourceElementType())) return false; if (NonConstantIdx) return false; @@ -528,7 +524,7 @@ HadDynamicAccess = true; } else GEPNonConstantIdx = NonConstantIdx; - uint64_t GEPOffset = DL.getIndexedOffset(PtrTy, + uint64_t GEPOffset = DL.getIndexedOffset(GEP->getSourceElementType(), Indices); // See if all uses can be converted. if (!CanConvertToScalar(GEP, Offset+GEPOffset, GEPNonConstantIdx)) @@ -623,7 +619,7 @@ GEPNonConstantIdx = Indices.pop_back_val(); } else GEPNonConstantIdx = NonConstantIdx; - uint64_t GEPOffset = DL.getIndexedOffset(GEP->getPointerOperandType(), + uint64_t GEPOffset = DL.getIndexedOffset(GEP->getSourceElementType(), Indices); ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8, GEPNonConstantIdx); GEP->eraseFromParent(); @@ -710,7 +706,7 @@ PointerType* SPTy = cast(SrcPtr->getType()); PointerType* AIPTy = cast(NewAI->getType()); if (SPTy->getAddressSpace() != AIPTy->getAddressSpace()) { - AIPTy = PointerType::get(AIPTy->getElementType(), + AIPTy = PointerType::get(NewAI->getAllocatedType(), SPTy->getAddressSpace()); } SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy); @@ -727,7 +723,7 @@ PointerType* DPTy = cast(MTI->getDest()->getType()); PointerType* AIPTy = cast(NewAI->getType()); if (DPTy->getAddressSpace() != AIPTy->getAddressSpace()) { - AIPTy = PointerType::get(AIPTy->getElementType(), + AIPTy = PointerType::get(NewAI->getAllocatedType(), DPTy->getAddressSpace()); } Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy); @@ -1141,25 +1137,28 @@ /// the select can be loaded unconditionally. static bool isSafeSelectToSpeculate(SelectInst *SI) { const DataLayout &DL = SI->getModule()->getDataLayout(); - bool TDerefable = isDereferenceablePointer(SI->getTrueValue(), DL); - bool FDerefable = isDereferenceablePointer(SI->getFalseValue(), DL); + uint64_t MaxTSize = 0, MaxFSize = 0; for (User *U : SI->users()) { LoadInst *LI = dyn_cast(U); if (!LI || !LI->isSimple()) return false; + unsigned Align = LI->getActualAlignment(); + uint64_t Size = LI->getLoadedSize(); + // Both operands to the select need to be dereferencable, either absolutely // (e.g. allocas) or at this point because we can see other accesses to it. - if (!TDerefable && - !isSafeToLoadUnconditionally(SI->getTrueValue(), LI, - LI->getAlignment())) - return false; - if (!FDerefable && - !isSafeToLoadUnconditionally(SI->getFalseValue(), LI, - LI->getAlignment())) - return false; + if (!isSafeToLoadUnconditionally(SI->getTrueValue(), LI, Align, Size)) + MaxTSize = std::max(MaxTSize, Size); + if (!isSafeToLoadUnconditionally(SI->getFalseValue(), LI, Align, Size)) + MaxFSize = std::max(MaxFSize, Size); } + if (MaxTSize && !isDereferenceablePointer(SI->getTrueValue(), MaxTSize, DL)) + return false; + if (MaxFSize && !isDereferenceablePointer(SI->getFalseValue(), MaxFSize, DL)) + return false; + return true; } @@ -1185,7 +1184,10 @@ // TODO: Allow recursive phi users. // TODO: Allow stores. BasicBlock *BB = PN->getParent(); + const DataLayout &DL = PN->getModule()->getDataLayout(); + unsigned MaxAlign = 0; + uint64_t MaxSize = 0; for (User *U : PN->users()) { LoadInst *LI = dyn_cast(U); if (!LI || !LI->isSimple()) return false; @@ -1200,10 +1202,12 @@ if (BBI->mayWriteToMemory()) return false; - MaxAlign = std::max(MaxAlign, LI->getAlignment()); - } + unsigned Align = LI->getActualAlignment(); + uint64_t Size = LI->getLoadedSize(); - const DataLayout &DL = PN->getModule()->getDataLayout(); + MaxAlign = std::max(MaxAlign, Align); + MaxSize = std::max(MaxSize, Size); + } // Okay, we know that we have one or more loads in the same block as the PHI. // We can transform this if it is safe to push the loads into the predecessor @@ -1229,8 +1233,9 @@ // If this pointer is always safe to load, or if we can prove that there is // already a load in the block, then we can move the load to the pred block. - if (isDereferenceablePointer(InVal, DL) || - isSafeToLoadUnconditionally(InVal, Pred->getTerminator(), MaxAlign)) + if (isDereferenceablePointer(InVal, MaxSize, DL) || + isSafeToLoadUnconditionally(InVal, Pred->getTerminator(), + MaxAlign, MaxSize)) continue; return false; @@ -1366,7 +1371,7 @@ continue; } - Type *LoadTy = cast(PN->getType())->getElementType(); + Type *LoadTy = AI->getAllocatedType(); PHINode *NewPN = PHINode::Create(LoadTy, PN->getNumIncomingValues(), PN->getName()+".ld", PN); @@ -1749,7 +1754,7 @@ Indices.pop_back(); const DataLayout &DL = GEPI->getModule()->getDataLayout(); - Offset += DL.getIndexedOffset(GEPI->getPointerOperandType(), Indices); + Offset += DL.getIndexedOffset(GEPI->getSourceElementType(), Indices); if (!TypeHasComponent(Info.AI->getAllocatedType(), Offset, NonConstantIdxSize, DL)) MarkUnsafe(Info, GEPI); @@ -2065,7 +2070,7 @@ Value* NonConstantIdx = nullptr; if (!GEPI->hasAllConstantIndices()) NonConstantIdx = Indices.pop_back_val(); - Offset += DL.getIndexedOffset(GEPI->getPointerOperandType(), Indices); + Offset += DL.getIndexedOffset(GEPI->getSourceElementType(), Indices); RewriteForScalarRepl(GEPI, AI, Offset, NewElts); @@ -2219,8 +2224,7 @@ // If the pointer is not the right type, insert a bitcast to the right // type. - Type *NewTy = - PointerType::get(AI->getType()->getElementType(), AddrSpace); + Type *NewTy = PointerType::get(AI->getAllocatedType(), AddrSpace); if (OtherPtr->getType() != NewTy) OtherPtr = new BitCastInst(OtherPtr, NewTy, OtherPtr->getName(), MI); @@ -2244,8 +2248,7 @@ OtherPtr->getName()+"."+Twine(i), MI); uint64_t EltOffset; - PointerType *OtherPtrTy = cast(OtherPtr->getType()); - Type *OtherTy = OtherPtrTy->getElementType(); + Type *OtherTy = AI->getAllocatedType(); if (StructType *ST = dyn_cast(OtherTy)) { EltOffset = DL.getStructLayout(ST)->getElementOffset(i); } else { @@ -2262,7 +2265,7 @@ } Value *EltPtr = NewElts[i]; - Type *EltTy = cast(EltPtr->getType())->getElementType(); + Type *EltTy = NewElts[i]->getAllocatedType(); // If we got down to a scalar, insert a load or store as appropriate. if (EltTy->isSingleValueType()) { @@ -2494,8 +2497,7 @@ // Load the value from the alloca. If the NewElt is an aggregate, cast // the pointer to an integer of the same size before doing the load. Value *SrcField = NewElts[i]; - Type *FieldTy = - cast(SrcField->getType())->getElementType(); + Type *FieldTy = NewElts[i]->getAllocatedType(); uint64_t FieldSizeBits = DL.getTypeSizeInBits(FieldTy); // Ignore zero sized fields like {}, they obviously contain no data. Index: lib/Transforms/Scalar/Scalarizer.cpp =================================================================== --- lib/Transforms/Scalar/Scalarizer.cpp +++ lib/Transforms/Scalar/Scalarizer.cpp @@ -49,7 +49,7 @@ // insert them before BBI in BB. If Cache is nonnull, use it to cache // the results. Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v, - ValueVector *cachePtr = nullptr); + Type *VecTy, ValueVector *cachePtr = nullptr); // Return component I, creating a new Value for it if necessary. Value *operator[](unsigned I); @@ -161,7 +161,7 @@ } private: - Scatterer scatter(Instruction *, Value *); + Scatterer scatter(Instruction *, Value *, Type *VecTy = nullptr); void gather(Instruction *, const ValueVector &); bool canTransferMetadata(unsigned Kind); void transferMetadata(Instruction *, const ValueVector &); @@ -183,13 +183,10 @@ "Scalarize vector operations", false, false) Scatterer::Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v, - ValueVector *cachePtr) + Type *VecTy, ValueVector *cachePtr) : BB(bb), BBI(bbi), V(v), CachePtr(cachePtr) { - Type *Ty = V->getType(); - PtrTy = dyn_cast(Ty); - if (PtrTy) - Ty = PtrTy->getElementType(); - Size = Ty->getVectorNumElements(); + PtrTy = dyn_cast(V->getType()); + Size = VecTy->getVectorNumElements(); if (!CachePtr) Tmp.resize(Size, nullptr); else if (CachePtr->empty()) @@ -208,7 +205,7 @@ if (PtrTy) { if (!CV[0]) { Type *Ty = - PointerType::get(PtrTy->getElementType()->getVectorElementType(), + PointerType::get(PtrTy->getPointerElementType()->getVectorElementType(), PtrTy->getAddressSpace()); CV[0] = Builder.CreateBitCast(V, Ty, V->getName() + ".i0"); } @@ -268,24 +265,26 @@ // Return a scattered form of V that can be accessed by Point. V must be a // vector or a pointer to a vector. -Scatterer Scalarizer::scatter(Instruction *Point, Value *V) { +Scatterer Scalarizer::scatter(Instruction *Point, Value *V, Type *VecTy) { + if (!VecTy) + VecTy = V->getType(); if (Argument *VArg = dyn_cast(V)) { // Put the scattered form of arguments in the entry block, // so that it can be used everywhere. Function *F = VArg->getParent(); BasicBlock *BB = &F->getEntryBlock(); - return Scatterer(BB, BB->begin(), V, &Scattered[V]); + return Scatterer(BB, BB->begin(), V, VecTy, &Scattered[V]); } if (Instruction *VOp = dyn_cast(V)) { // Put the scattered form of an instruction directly after the // instruction. BasicBlock *BB = VOp->getParent(); return Scatterer(BB, std::next(BasicBlock::iterator(VOp)), - V, &Scattered[V]); + V, VecTy, &Scattered[V]); } // In the fallback case, just put the scattered before Point and // keep the result local to Point. - return Scatterer(Point->getParent(), Point->getIterator(), V); + return Scatterer(Point->getParent(), Point->getIterator(), V, VecTy); } // Replace Op with the gathered form of the components in CV. Defer the @@ -601,7 +600,7 @@ unsigned NumElems = Layout.VecTy->getNumElements(); IRBuilder<> Builder(&LI); - Scatterer Ptr = scatter(&LI, LI.getPointerOperand()); + Scatterer Ptr = scatter(&LI, LI.getPointerOperand(), LI.getType()); ValueVector Res; Res.resize(NumElems); @@ -620,13 +619,14 @@ VectorLayout Layout; Value *FullValue = SI.getValueOperand(); - if (!getVectorLayout(FullValue->getType(), SI.getAlignment(), Layout, + Type *ValTy = FullValue->getType(); + if (!getVectorLayout(ValTy, SI.getAlignment(), Layout, SI.getModule()->getDataLayout())) return false; unsigned NumElems = Layout.VecTy->getNumElements(); IRBuilder<> Builder(&SI); - Scatterer Ptr = scatter(&SI, SI.getPointerOperand()); + Scatterer Ptr = scatter(&SI, SI.getPointerOperand(), ValTy); Scatterer Val = scatter(&SI, FullValue); ValueVector Stores; Index: lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp =================================================================== --- lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp +++ lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp @@ -722,7 +722,7 @@ for (User::op_iterator I = GEP->op_begin() + 1, E = GEP->op_end(); I != E; ++I, ++GTI) { // Skip struct member indices which must be i32. - if (isa(*GTI)) { + if (isa(*GTI) || isa(*GTI)) { if ((*I)->getType() != IntPtrTy) { *I = CastInst::CreateIntegerCast(*I, IntPtrTy, true, "idxprom", GEP); Changed = true; @@ -739,7 +739,17 @@ int64_t AccumulativeByteOffset = 0; gep_type_iterator GTI = gep_type_begin(*GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) { - if (isa(*GTI)) { + if (StructType *StTy = dyn_cast(*GTI)) { + if (LowerGEP) { + uint64_t Field = cast(GEP->getOperand(I))->getZExtValue(); + // Skip field 0 as the offset is always 0. + if (Field != 0) { + NeedsExtraction = true; + AccumulativeByteOffset += + DL->getStructLayout(StTy)->getElementOffset(Field); + } + } + } else { // Tries to extract a constant offset from this GEP index. int64_t ConstantOffset = ConstantOffsetExtractor::Find(GEP->getOperand(I), GEP, DT); @@ -751,15 +761,6 @@ AccumulativeByteOffset += ConstantOffset * DL->getTypeAllocSize(GTI.getIndexedType()); } - } else if (LowerGEP) { - StructType *StTy = cast(*GTI); - uint64_t Field = cast(GEP->getOperand(I))->getZExtValue(); - // Skip field 0 as the offset is always 0. - if (Field != 0) { - NeedsExtraction = true; - AccumulativeByteOffset += - DL->getStructLayout(StTy)->getElementOffset(Field); - } } } return AccumulativeByteOffset; @@ -787,7 +788,7 @@ // Create an ugly GEP for each sequential index. We don't create GEPs for // structure indices, as they are accumulated in the constant offset index. for (unsigned I = 1, E = Variadic->getNumOperands(); I != E; ++I, ++GTI) { - if (isa(*GTI)) { + if (isa(*GTI) || isa(*GTI)) { Value *Idx = Variadic->getOperand(I); // Skip zero indices. if (ConstantInt *CI = dyn_cast(Idx)) @@ -848,7 +849,7 @@ // don't create arithmetics for structure indices, as they are accumulated // in the constant offset index. for (unsigned I = 1, E = Variadic->getNumOperands(); I != E; ++I, ++GTI) { - if (isa(*GTI)) { + if (isa(*GTI) || isa(*GTI)) { Value *Idx = Variadic->getOperand(I); // Skip zero indices. if (ConstantInt *CI = dyn_cast(Idx)) @@ -911,7 +912,7 @@ getAnalysis().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)) { @@ -928,7 +929,7 @@ // handle the constant offset and won't need a new structure index. gep_type_iterator GTI = gep_type_begin(*GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) { - if (isa(*GTI)) { + if (isa(*GTI) || isa(*GTI)) { // Splits this GEP index into a variadic part and a constant offset, and // uses the variadic part as the new index. Value *OldIdx = GEP->getOperand(I); @@ -1018,7 +1019,7 @@ // unsigned.. Therefore, we cast ElementTypeSizeOfGEP to signed because it is // used with unsigned integers later. int64_t ElementTypeSizeOfGEP = static_cast( - 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 Index: lib/Transforms/Scalar/StraightLineStrengthReduce.cpp =================================================================== --- lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ lib/Transforms/Scalar/StraightLineStrengthReduce.cpp @@ -250,7 +250,10 @@ gep_type_iterator GTI = gep_type_begin(GEP); for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I, ++GTI) { - if (isa(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { + uint64_t Field = cast(*I)->getZExtValue(); + BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field); + } else { int64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType()); if (ConstantInt *ConstIdx = dyn_cast(*I)) { BaseOffset += ConstIdx->getSExtValue() * ElementSize; @@ -262,15 +265,11 @@ } Scale = ElementSize; } - } else { - StructType *STy = cast(*GTI); - uint64_t Field = cast(*I)->getZExtValue(); - BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field); } } unsigned AddrSpace = GEP->getPointerAddressSpace(); - return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV, + return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace); } @@ -520,8 +519,11 @@ gep_type_iterator GTI = gep_type_begin(GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) { - if (!isa(*GTI++)) + if (!isa(*GTI) && !isa(*GTI)) { + GTI++; continue; + } + GTI++; const SCEV *OrigIndexExpr = IndexExprs[I - 1]; IndexExprs[I - 1] = SE->getZero(OrigIndexExpr->getType()); @@ -566,8 +568,7 @@ if (Basis.CandidateKind == Candidate::GEP) { APInt ElementSize( IndexOffset.getBitWidth(), - DL->getTypeAllocSize( - cast(Basis.Ins)->getType()->getElementType())); + DL->getTypeAllocSize(cast(Basis.Ins)->getResultElementType())); APInt Q, R; APInt::sdivrem(IndexOffset, ElementSize, Q, R); if (R.getSExtValue() == 0) Index: lib/Transforms/Scalar/TailRecursionElimination.cpp =================================================================== --- lib/Transforms/Scalar/TailRecursionElimination.cpp +++ lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -456,9 +456,10 @@ // does not write to memory and the load provably won't trap. // FIXME: Writes to memory only matter if they may alias the pointer // being loaded from. + unsigned Align = L->getActualAlignment(); + uint64_t Size = L->getLoadedSize(); if (CI->mayWriteToMemory() || - !isSafeToLoadUnconditionally(L->getPointerOperand(), L, - L->getAlignment())) + !isSafeToLoadUnconditionally(L->getPointerOperand(), L, Align, Size)) return false; } } Index: lib/Transforms/Utils/CloneModule.cpp =================================================================== --- lib/Transforms/Utils/CloneModule.cpp +++ lib/Transforms/Utils/CloneModule.cpp @@ -53,7 +53,7 @@ for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = new GlobalVariable(*New, - I->getType()->getElementType(), + I->getValueType(), I->isConstant(), I->getLinkage(), (Constant*) nullptr, I->getName(), (GlobalVariable*) nullptr, @@ -66,7 +66,7 @@ // Loop over the functions in the module, making external functions as before for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *NF = - Function::Create(cast(I->getType()->getElementType()), + Function::Create(cast(I->getValueType()), I->getLinkage(), I->getName(), New.get()); NF->copyAttributesFrom(&*I); VMap[&*I] = NF; Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -833,7 +833,7 @@ static void HandleByValArgumentInit(Value *Dst, Value *Src, Module *M, BasicBlock *InsertBlock, InlineFunctionInfo &IFI) { - Type *AggTy = cast(Src->getType())->getElementType(); + Type *AggTy = cast(Src->getType())->getPointerElementType(); IRBuilder<> Builder(InsertBlock, InsertBlock->begin()); Value *Size = Builder.getInt64(M->getDataLayout().getTypeStoreSize(AggTy)); @@ -851,7 +851,7 @@ InlineFunctionInfo &IFI, unsigned ByValAlignment) { PointerType *ArgTy = cast(Arg->getType()); - Type *AggTy = ArgTy->getElementType(); + Type *AggTy = ArgTy->getPointerElementType(); Function *Caller = TheCall->getParent()->getParent(); Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -1084,7 +1084,7 @@ /// Determine whether this alloca is either a VLA or an array. static bool isArray(AllocaInst *AI) { return AI->isArrayAllocation() || - AI->getType()->getElementType()->isArrayTy(); + AI->getType()->getPointerElementType()->isArrayTy(); } /// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set Index: lib/Transforms/Utils/LoopUtils.cpp =================================================================== --- lib/Transforms/Utils/LoopUtils.cpp +++ lib/Transforms/Utils/LoopUtils.cpp @@ -689,7 +689,7 @@ } assert(PhiTy->isPointerTy() && "The PHI must be a pointer"); - Type *PointerElementType = PhiTy->getPointerElementType(); + Type *PointerElementType = cast(PhiTy)->getPointerElementType(); // The pointer stride cannot be determined if the pointer element type is not // sized. if (!PointerElementType->isSized()) Index: lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- lib/Transforms/Utils/ModuleUtils.cpp +++ lib/Transforms/Utils/ModuleUtils.cpp @@ -33,7 +33,7 @@ if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { // If there is a global_ctors array, use the existing struct type, which can // have 2 or 3 fields. - ArrayType *ATy = cast(GVCtor->getType()->getElementType()); + ArrayType *ATy = cast(GVCtor->getValueType()); EltTy = cast(ATy->getElementType()); if (Constant *Init = GVCtor->getInitializer()) { unsigned n = Init->getNumOperands(); Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -3860,7 +3860,7 @@ COps[1], DL); } - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), COps, DL); + return ConstantFoldInstOperands(I, I->getOpcode(), I->getType(), COps, DL); } /// Try to determine the resulting constant values in phi nodes Index: lib/Transforms/Vectorize/BBVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/BBVectorize.cpp +++ lib/Transforms/Vectorize/BBVectorize.cpp @@ -610,7 +610,9 @@ // after I; if OffsetInElmts == -1 then I accesses the memory // directly after J. bool getPairPtrInfo(Instruction *I, Instruction *J, - Value *&IPtr, Value *&JPtr, unsigned &IAlignment, unsigned &JAlignment, + Value *&IPtr, Value *&JPtr, + Type *&ITy, Type *&JTy, + unsigned &IAlignment, unsigned &JAlignment, unsigned &IAddressSpace, unsigned &JAddressSpace, int64_t &OffsetInElmts, bool ComputeOffset = true) { OffsetInElmts = 0; @@ -618,6 +620,8 @@ LoadInst *LJ = cast(J); IPtr = LI->getPointerOperand(); JPtr = LJ->getPointerOperand(); + ITy = LI->getType(); + JTy = LJ->getType(); IAlignment = LI->getAlignment(); JAlignment = LJ->getAlignment(); IAddressSpace = LI->getPointerAddressSpace(); @@ -626,6 +630,8 @@ StoreInst *SI = cast(I), *SJ = cast(J); IPtr = SI->getPointerOperand(); JPtr = SJ->getPointerOperand(); + ITy = SI->getValueOperand()->getType(); + JTy = SJ->getValueOperand()->getType(); IAlignment = SI->getAlignment(); JAlignment = SJ->getAlignment(); IAddressSpace = SI->getPointerAddressSpace(); @@ -647,12 +653,10 @@ ConstantInt *IntOff = ConstOffSCEV->getValue(); int64_t Offset = IntOff->getSExtValue(); const DataLayout &DL = I->getModule()->getDataLayout(); - Type *VTy = IPtr->getType()->getPointerElementType(); - int64_t VTyTSS = (int64_t)DL.getTypeStoreSize(VTy); + int64_t VTyTSS = (int64_t)DL.getTypeStoreSize(ITy); - Type *VTy2 = JPtr->getType()->getPointerElementType(); - if (VTy != VTy2 && Offset < 0) { - int64_t VTy2TSS = (int64_t)DL.getTypeStoreSize(VTy2); + if (ITy != JTy && Offset < 0) { + int64_t VTy2TSS = (int64_t)DL.getTypeStoreSize(JTy); OffsetInElmts = Offset/VTy2TSS; return (std::abs(Offset) % VTy2TSS) == 0; } @@ -981,19 +985,16 @@ if (IsSimpleLoadStore) { Value *IPtr, *JPtr; + Type *aTypeI, *aTypeJ; unsigned IAlignment, JAlignment, IAddressSpace, JAddressSpace; int64_t OffsetInElmts = 0; - if (getPairPtrInfo(I, J, IPtr, JPtr, IAlignment, JAlignment, + if (getPairPtrInfo(I, J, IPtr, JPtr, aTypeI, aTypeJ, IAlignment, JAlignment, IAddressSpace, JAddressSpace, OffsetInElmts) && std::abs(OffsetInElmts) == 1) { FixedOrder = (int) OffsetInElmts; unsigned BottomAlignment = IAlignment; if (OffsetInElmts < 0) BottomAlignment = JAlignment; - Type *aTypeI = isa(I) ? - cast(I)->getValueOperand()->getType() : I->getType(); - Type *aTypeJ = isa(J) ? - cast(J)->getValueOperand()->getType() : J->getType(); Type *VType = getVecTypeForPair(aTypeI, aTypeJ); if (Config.AlignedOnly) { @@ -2302,20 +2303,19 @@ Value *BBVectorize::getReplacementPointerInput(LLVMContext& Context, Instruction *I, Instruction *J, unsigned o) { Value *IPtr, *JPtr; + Type *ArgTypeI, *ArgTypeJ; unsigned IAlignment, JAlignment, IAddressSpace, JAddressSpace; int64_t OffsetInElmts; // Note: the analysis might fail here, that is why the pair order has // been precomputed (OffsetInElmts must be unused here). - (void) getPairPtrInfo(I, J, IPtr, JPtr, IAlignment, JAlignment, + (void) getPairPtrInfo(I, J, IPtr, JPtr, ArgTypeI, ArgTypeJ, + IAlignment, JAlignment, IAddressSpace, JAddressSpace, OffsetInElmts, false); // The pointer value is taken to be the one with the lowest offset. Value *VPtr = IPtr; - - Type *ArgTypeI = IPtr->getType()->getPointerElementType(); - Type *ArgTypeJ = JPtr->getType()->getPointerElementType(); Type *VArgType = getVecTypeForPair(ArgTypeI, ArgTypeJ); Type *VArgPtrType = PointerType::get(VArgType, Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1236,7 +1236,7 @@ /// 0 - Stride is unknown or non-consecutive. /// 1 - Address is consecutive. /// -1 - Address is consecutive, and decreasing. - int isConsecutivePtr(Value *Ptr); + int isConsecutivePtr(Value *Ptr, Type *DataType = nullptr); /// Returns true if the value V is uniform within the loop. bool isUniform(Value *V); @@ -1275,12 +1275,12 @@ /// Returns true if the target machine supports masked store operation /// for the given \p DataType and kind of access to \p Ptr. bool isLegalMaskedStore(Type *DataType, Value *Ptr) { - return isConsecutivePtr(Ptr) && TTI->isLegalMaskedStore(DataType); + return isConsecutivePtr(Ptr, DataType) && TTI->isLegalMaskedStore(DataType); } /// Returns true if the target machine supports masked load operation /// for the given \p DataType and kind of access to \p Ptr. bool isLegalMaskedLoad(Type *DataType, Value *Ptr) { - return isConsecutivePtr(Ptr) && TTI->isLegalMaskedLoad(DataType); + return isConsecutivePtr(Ptr, DataType) && TTI->isLegalMaskedLoad(DataType); } /// Returns true if vector representation of the instruction \p I /// requires mask. @@ -1984,11 +1984,11 @@ return Builder.CreateAdd(Val, Step, "induction"); } -int LoopVectorizationLegality::isConsecutivePtr(Value *Ptr) { +int LoopVectorizationLegality::isConsecutivePtr(Value *Ptr, Type *DataType) { assert(Ptr->getType()->isPointerTy() && "Unexpected non-ptr"); auto *SE = PSE.getSE(); // Make sure that the pointer does not point to structs. - if (Ptr->getType()->getPointerElementType()->isAggregateType()) + if (DataType && DataType->isAggregateType()) return 0; // If this value is a pointer induction variable we know it is consecutive. @@ -2010,8 +2010,7 @@ if (Phi && Inductions.count(Phi)) { // Make sure that the pointer does not point to structs. - PointerType *GepPtrType = cast(GpPtr->getType()); - if (GepPtrType->getElementType()->isAggregateType()) + if (Gep->getSourceElementType()->isAggregateType()) return 0; // Make sure that all of the index operands are loop invariant. @@ -2381,7 +2380,7 @@ // If the pointer is loop invariant or if it is non-consecutive, // scalarize the load. - int ConsecutiveStride = Legal->isConsecutivePtr(Ptr); + int ConsecutiveStride = Legal->isConsecutivePtr(Ptr, ScalarDataTy); bool Reverse = ConsecutiveStride < 0; bool UniformLoad = LI && Legal->isUniform(Ptr); if (!ConsecutiveStride || UniformLoad) @@ -4581,7 +4580,8 @@ StoreInst *SI = dyn_cast(I); Value *Ptr = LI ? LI->getPointerOperand() : SI->getPointerOperand(); - int Stride = isStridedPtr(PSE, Ptr, TheLoop, Strides); + Type *AccessTy = LI ? LI->getType() : SI->getValueOperand()->getType(); + int Stride = isStridedPtr(PSE, Ptr, AccessTy, TheLoop, Strides); // The factor of the corresponding interleave group. unsigned Factor = std::abs(Stride); @@ -4591,13 +4591,12 @@ continue; const SCEV *Scev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr); - PointerType *PtrTy = dyn_cast(Ptr->getType()); - unsigned Size = DL.getTypeAllocSize(PtrTy->getElementType()); + unsigned Size = DL.getTypeAllocSize(AccessTy); // An alignment of 0 means target ABI alignment. unsigned Align = LI ? LI->getAlignment() : SI->getAlignment(); if (!Align) - Align = DL.getABITypeAlignment(PtrTy->getElementType()); + Align = DL.getABITypeAlignment(AccessTy); StrideAccesses[I] = StrideDescriptor(Stride, Scev, Size, Align); } @@ -5480,7 +5479,7 @@ } // Scalarized loads/stores. - int ConsecutiveStride = Legal->isConsecutivePtr(Ptr); + int ConsecutiveStride = Legal->isConsecutivePtr(Ptr, ValTy); bool Reverse = ConsecutiveStride < 0; const DataLayout &DL = I->getModule()->getDataLayout(); unsigned ScalarAllocatedSize = DL.getTypeAllocSize(ValTy); @@ -5623,12 +5622,14 @@ bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) { // Check for a store. - if (StoreInst *ST = dyn_cast(Inst)) - return Legal->isConsecutivePtr(ST->getPointerOperand()) != 0; + if (StoreInst *ST = dyn_cast(Inst)) { + Type *Ty = ST->getValueOperand()->getType(); + return Legal->isConsecutivePtr(ST->getPointerOperand(), Ty) != 0; + } // Check for a load. if (LoadInst *LI = dyn_cast(Inst)) - return Legal->isConsecutivePtr(LI->getPointerOperand()) != 0; + return Legal->isConsecutivePtr(LI->getPointerOperand(), LI->getType()) != 0; return false; } Index: lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- lib/Transforms/Vectorize/SLPVectorizer.cpp +++ lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -435,6 +435,10 @@ /// \returns NULL if this is not a valid Load/Store instruction. static Value *getPointerOperand(Value *I); + /// \brief Take the acccessed type from the Load/Store instruction. + /// \returns NULL if this is not a valid Load/Store instruction. + static Type *getAccessType(Value *I); + /// \brief Take the address space operand from the Load/Store instruction. /// \returns -1 if this is not a valid Load/Store instruction. static unsigned getAddressSpaceOperand(Value *I); @@ -1839,6 +1843,14 @@ return nullptr; } +Type *BoUpSLP::getAccessType(Value *I) { + if (LoadInst *LI = dyn_cast(I)) + return LI->getType(); + if (StoreInst *SI = dyn_cast(I)) + return SI->getValueOperand()->getType(); + return nullptr; +} + unsigned BoUpSLP::getAddressSpaceOperand(Value *I) { if (LoadInst *L = dyn_cast(I)) return L->getPointerAddressSpace(); @@ -1858,11 +1870,13 @@ return false; // Make sure that A and B are different pointers of the same type. - if (PtrA == PtrB || PtrA->getType() != PtrB->getType()) + Type *TyA = getAccessType(A); + Type *TyB = getAccessType(B); + if (PtrA == PtrB || TyA != TyB) return false; unsigned PtrBitWidth = DL.getPointerSizeInBits(ASA); - Type *Ty = cast(PtrA->getType())->getElementType(); + Type *Ty = TyA; APInt Size(PtrBitWidth, DL.getTypeStoreSize(Ty)); APInt OffsetA(PtrBitWidth, 0), OffsetB(PtrBitWidth, 0); Index: tools/bugpoint/CrashDebugger.cpp =================================================================== --- tools/bugpoint/CrashDebugger.cpp +++ tools/bugpoint/CrashDebugger.cpp @@ -278,7 +278,7 @@ continue; } - PointerType *Ty = cast(Alias.getType()); + PointerType *Ty = Alias.getType(); Constant *Replacement = ConstantPointerNull::get(Ty); Alias.replaceAllUsesWith(Replacement); ToRemove.push_back(&Alias); Index: tools/llvm-nm/llvm-nm.cpp =================================================================== --- tools/llvm-nm/llvm-nm.cpp +++ tools/llvm-nm/llvm-nm.cpp @@ -792,7 +792,7 @@ } static char getSymbolNMTypeChar(const GlobalValue &GV) { - if (GV.getType()->getElementType()->isFunctionTy()) + if (GV.getValueType()->isFunctionTy()) return 't'; // FIXME: should we print 'b'? At the IR level we cannot be sure if this // will be in bss or not, but we could approximate.