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 @@ -193,6 +193,9 @@ /// This queries the 'wchar_size' metadata. unsigned getWCharSize(const Module &M) const; + /// Returns the size of the size_t type in bits. + unsigned getSizeTSize(const Module &M) const; + /// Get size of a C-level int or unsigned int, in bits. unsigned getIntSize() const { return SizeOfInt; @@ -406,6 +409,9 @@ return Impl->getWCharSize(M); } + /// \copydoc TargetLibraryInfoImpl::getSizeTSize() + unsigned getSizeTSize(const Module &M) const { return Impl->getSizeTSize(M); } + /// \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 @@ -1051,12 +1051,8 @@ break; } - // FIXME: There is 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 IntBits = getIntSize(); - unsigned SizeTBits = M.getDataLayout().getPointerSizeInBits(/*AddrSpace=*/0); + unsigned SizeTBits = getSizeTSize(M); unsigned Idx = 0; // Iterate over the type ids in the function prototype, matching each @@ -1231,6 +1227,22 @@ return 0; } +unsigned TargetLibraryInfoImpl::getSizeTSize(const Module &M) const { + // There is really no guarantee that sizeof(size_t) is equal to sizeof(int*). + // If that isn't true then it should be possible to derive the SizeTTy from + // the target triple here instead and do an early return. + + // Historically LLVM assume that size_t has same size as intptr_t (hence + // deriving the size from sizeof(int*) in address space zero). This should + // work for most targets. For future consideration: DataLayout also implement + // getIndexSizeInBits which might map better to size_t compared to + // getPointerSizeInBits. Hard coding address space zero here might be + // unfortunate as well. Maybe getDefaultGlobalsAddressSpace() or + // getAllocaAddrSpace() is better. + unsigned AddressSpace = 0; + return M.getDataLayout().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 @@ -3876,11 +3876,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()); + 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