diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -582,6 +582,19 @@ /// big as that of a pointer of the given pointer (vector of pointer) type. Type *getIntPtrType(Type *) const; + + /// Returns an integer type with size equal to the integral range of a pointer + /// in the given address space. This can be used to obtain an integer that + /// can be used for the type of a ptrtoint instruction. + IntegerType *getPtrToIntResultType(LLVMContext &C, + unsigned AddressSpace) const; + + /// Returns an integer (or vector of integer) type with size at least as + /// big as that of the pointer range for the given pointer (or vector of + /// pointers). This can be used to obtain an integer (or vector of integer) + /// that can be used for the type of a ptrtoint instruction. + Type *getPtrToIntResultType(Type *) const; + /// Returns the smallest integer type with size at least as big as /// Width bits. Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const; diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -876,6 +876,22 @@ return IntTy; } +IntegerType *DataLayout::getPtrToIntResultType(LLVMContext &C, + unsigned AddressSpace) const { + return IntegerType::get(C, getPointerIntegralSizeInBits(AddressSpace)); +} + +Type *DataLayout::getPtrToIntResultType(Type *Ty) const { + assert(Ty->isPtrOrPtrVectorTy() && + "Expected a pointer or pointer vector type."); + unsigned NumBits = + getPointerIntegralSizeInBits(cast(Ty)->getAddressSpace()); + IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); + if (VectorType *VecTy = dyn_cast(Ty)) + return VectorType::get(IntTy, VecTy); + return IntTy; +} + Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const { for (unsigned LegalIntWidth : LegalIntWidths) if (Width <= LegalIntWidth) diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -970,7 +970,7 @@ // if the only "reduction" is combining a bitcast + ptrtoint. CstPtr = CstPtr->stripPointerCasts(); if (auto *CstInt = dyn_cast_or_null(ConstantExpr::getPtrToInt( - const_cast(CstPtr), DL.getIntPtrType(getType()), + const_cast(CstPtr), DL.getPtrToIntResultType(getType()), /*OnlyIfReduced=*/true))) { size_t TrailingZeros = CstInt->getValue().countTrailingZeros(); // While the actual alignment may be large, elsewhere we have