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 @@ -76,7 +76,7 @@ /// Return true if the function type FTy is valid for the library function /// F, regardless of whether the function is available. bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, - const DataLayout *DL) const; + const Module *M) const; public: /// List of known vector-functions libraries. @@ -190,6 +190,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) const; + /// Get size of a C-level int or unsigned int, in bits. unsigned getIntSize() const { return SizeOfInt; @@ -401,6 +404,11 @@ 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 @@ -727,17 +727,8 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, - const DataLayout *DL) const { - LLVMContext &Ctx = FTy.getContext(); - // 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 - // SizeTTy based on DataLayout and getIntPtrType isn't always valid. - Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr; - auto IsSizeTTy = [SizeTTy](Type *Ty) { - if (!SizeTTy) - return false; - return Ty == SizeTTy; - }; + const Module *M) const { + unsigned SizeOfSizeT = M ? getSizeTSize(*M) : 0; unsigned NumParams = FTy.getNumParams(); switch (F) { @@ -761,12 +752,12 @@ FTy.getReturnType()->isIntegerTy(32)); case LibFunc_strlen_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strlen: return NumParams == 1 && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getReturnType()); + FTy.getReturnType()->isIntegerTy(SizeOfSizeT); case LibFunc_strchr: case LibFunc_strrchr: @@ -786,7 +777,7 @@ FTy.getParamType(1)->isPointerTy()); case LibFunc_strcat_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strcat: @@ -796,19 +787,19 @@ case LibFunc_strncat_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strncat: return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && FTy.getParamType(0) == FTy.getReturnType() && FTy.getParamType(1) == FTy.getReturnType() && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_strcpy_chk: case LibFunc_stpcpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strcpy: @@ -820,20 +811,20 @@ case LibFunc_strlcat_chk: case LibFunc_strlcpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strlcat: case LibFunc_strlcpy: - return NumParams == 3 && IsSizeTTy(FTy.getReturnType()) && + return NumParams == 3 && FTy.getReturnType()->isIntegerTy(SizeOfSizeT) && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2)); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT); case LibFunc_strncpy_chk: case LibFunc_stpncpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_strncpy: @@ -841,7 +832,7 @@ return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0) == FTy.getParamType(1) && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_strxfrm: return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && @@ -856,7 +847,7 @@ return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(0) == FTy.getParamType(1) && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_strspn: case LibFunc_strcspn: @@ -904,21 +895,21 @@ case LibFunc_sprintf_chk: return NumParams == 4 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(2)) && + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(3)->isPointerTy() && FTy.getReturnType()->isIntegerTy(32); case LibFunc_snprintf: return NumParams == 3 && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(1)) && + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(2)->isPointerTy() && FTy.getReturnType()->isIntegerTy(32); case LibFunc_snprintf_chk: return NumParams == 5 && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(1)) && + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(2)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(3)) && + FTy.getParamType(3)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(4)->isPointerTy() && FTy.getReturnType()->isIntegerTy(32); @@ -934,14 +925,15 @@ case LibFunc_memcmp: return NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1)->isPointerTy() && IsSizeTTy(FTy.getParamType(2)); + FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT); case LibFunc_memchr: case LibFunc_memrchr: return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(1)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_modf: case LibFunc_modff: case LibFunc_modfl: @@ -951,7 +943,7 @@ case LibFunc_mempcpy_chk: case LibFunc_memmove_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_memcpy: @@ -960,22 +952,22 @@ return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_memset_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_memset: return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isIntegerTy() && - IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_memccpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeOfSizeT)) return false; LLVM_FALLTHROUGH; case LibFunc_memccpy: @@ -987,7 +979,7 @@ case LibFunc_vec_realloc: return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && FTy.getParamType(0) == FTy.getReturnType() && - IsSizeTTy(FTy.getParamType(1))); + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT)); case LibFunc_read: return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); case LibFunc_rewind: @@ -1068,7 +1060,7 @@ return (NumParams != 0 && FTy.getParamType(0)->isPointerTy()); case LibFunc___kmpc_free_shared: return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(1))); + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT)); case LibFunc_fopen: return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && @@ -1158,14 +1150,14 @@ case LibFunc_vsprintf_chk: return NumParams == 5 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(2)) && FTy.getParamType(3)->isPointerTy(); + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(3)->isPointerTy(); case LibFunc_vsnprintf: return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(2)->isPointerTy()); case LibFunc_vsnprintf_chk: return NumParams == 6 && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(2)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(3)) && FTy.getParamType(4)->isPointerTy(); + FTy.getParamType(3)->isIntegerTy(SizeOfSizeT) && FTy.getParamType(4)->isPointerTy(); case LibFunc_open: return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); case LibFunc_opendir: @@ -1577,12 +1569,13 @@ case LibFunc_strnlen: return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(1) && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(1))); + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT)); case LibFunc_posix_memalign: return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getParamType(1)) && IsSizeTTy(FTy.getParamType(2))); + FTy.getParamType(1)->isIntegerTy(SizeOfSizeT) && + FTy.getParamType(2)->isIntegerTy(SizeOfSizeT)); case LibFunc_wcslen: return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && @@ -1622,10 +1615,10 @@ // avoid string normalization and comparison. if (FDecl.isIntrinsic()) return false; - const DataLayout *DL = - FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; + const Module *M = FDecl.getParent(); + return getLibFunc(FDecl.getName(), F) && - isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL); + isValidProtoForLibFunc(*FDecl.getFunctionType(), F, M); } void TargetLibraryInfoImpl::disableAllFunctions() { @@ -1741,6 +1734,17 @@ return 0; } +unsigned TargetLibraryInfoImpl::getSizeTSize(const Module &M) 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. + const DataLayout &DL = M.getDataLayout(); + return DL.getPointerSizeInBits(/*AddressSpace=*/0); +} + 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 @@ -3295,7 +3295,9 @@ else return nullptr; - Type *SizeTTy = DL.getIntPtrType(CI->getContext()); + unsigned SizeOfSizeT = TLI->getSizeTSize(*CI->getModule()); + assert(SizeOfSizeT && "Failed to derive size of size_t."); + Type *SizeTTy = IntegerType::get(CI->getContext(), SizeOfSizeT); 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