diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -192,6 +192,9 @@ /// This queries the 'wchar_size' metadata. unsigned getWCharSize(const Module &M) const; + /// Returns the size of the size_t type in bits or 0 if the size is unknown. + unsigned getSizeTSize(const Module &M, unsigned AddressSpace) const; + /// Get size of a C-level int or unsigned int, in bits. unsigned getIntSize() const { return SizeOfInt; @@ -403,6 +406,11 @@ return Impl->getWCharSize(M); } + /// \copydoc TargetLibraryInfoImpl::getSizeTSize() + unsigned getSizeTSize(const Module &M, unsigned AddressSpace) const { + return Impl->getSizeTSize(M, AddressSpace); + } + /// \copydoc TargetLibraryInfoImpl::getIntSize() unsigned getIntSize() const { return Impl->getIntSize(); diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -785,11 +785,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, const Module &M) const { - // FIXME: There is really no guarantee that sizeof(size_t) is equal to - // sizeof(int*) for every target. So the assumption used here to derive the - // SizeTBits based on the size of an integer pointer in address space zero - // isn't always valid. - unsigned SizeTBits = M.getDataLayout().getPointerSizeInBits(/*AddrSpace=*/0); + unsigned SizeTBits = getSizeTSize(M, /*AddressSpace=*/0); unsigned NumParams = FTy.getNumParams(); switch (F) { @@ -1796,6 +1792,19 @@ return 0; } +unsigned TargetLibraryInfoImpl::getSizeTSize(const Module &M, + unsigned AddressSpace) const { + // There is really no guarantee that sizeof(size_t) is equal to sizeof(int*) + // for every target. If that isn't true then it should be possible to derive + // the SizeTTy from the target tripe here instead and do an early return. + + // Here we assume that sizeof(size_t) is equal to sizeof(int*) in address + // space zero. This should work for most targets. + // TODO: Should this use getIndexSizeInBits instead? + const DataLayout &DL = M.getDataLayout(); + return DL.getPointerSizeInBits(AddressSpace); +} + TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() : ImmutablePass(ID), TLA(TargetLibraryInfoImpl()) { initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -3292,11 +3292,8 @@ else return nullptr; - // FIXME: There is really no guarantee that sizeof(size_t) is equal to - // sizeof(int*) for every target. So the assumption used here to derive the - // SizeTBits based on the size of an integer pointer in address space zero - // isn't always valid. - Type *SizeTTy = DL.getIntPtrType(CI->getContext(), /*AddressSpace=*/0); + unsigned SizeTBits = TLI->getSizeTSize(*CI->getModule(), /*AddressSpace=*/0); + Type *SizeTTy = IntegerType::get(CI->getContext(), SizeTBits); Value *LenV = ConstantInt::get(SizeTTy, Len); Value *Ret = emitMemCpyChk(Dst, Src, LenV, ObjSize, B, DL, TLI); // If the function was an __stpcpy_chk, and we were able to fold it into