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. @@ -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) 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) 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,15 +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.getIntPtrType(Ctx, /*AddressSpace=*/0); - auto IsSizeTTy = [SizeTTy](Type *Ty) { - return Ty == SizeTTy; - }; + const Module &M) const { + unsigned SizeTBits = getSizeTSize(M); unsigned NumParams = FTy.getNumParams(); switch (F) { @@ -759,12 +752,12 @@ FTy.getReturnType()->isIntegerTy(32)); case LibFunc_strlen_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_strlen: return NumParams == 1 && FTy.getParamType(0)->isPointerTy() && - IsSizeTTy(FTy.getReturnType()); + FTy.getReturnType()->isIntegerTy(SizeTBits); case LibFunc_strchr: case LibFunc_strrchr: @@ -784,7 +777,7 @@ FTy.getParamType(1)->isPointerTy()); case LibFunc_strcat_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_strcat: @@ -794,19 +787,19 @@ case LibFunc_strncat_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) 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(SizeTBits)); case LibFunc_strcpy_chk: case LibFunc_stpcpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_strcpy: @@ -818,20 +811,20 @@ case LibFunc_strlcat_chk: case LibFunc_strlcpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_strlcat: case LibFunc_strlcpy: - return NumParams == 3 && IsSizeTTy(FTy.getReturnType()) && + return NumParams == 3 && FTy.getReturnType()->isIntegerTy(SizeTBits) && FTy.getParamType(0)->isPointerTy() && FTy.getParamType(1)->isPointerTy() && - IsSizeTTy(FTy.getParamType(2)); + FTy.getParamType(2)->isIntegerTy(SizeTBits); case LibFunc_strncpy_chk: case LibFunc_stpncpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_strncpy: @@ -839,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(SizeTBits)); case LibFunc_strxfrm: return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && @@ -854,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(SizeTBits)); case LibFunc_strspn: case LibFunc_strcspn: @@ -902,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(SizeTBits) && 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(SizeTBits) && 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(SizeTBits) && FTy.getParamType(2)->isIntegerTy(32) && - IsSizeTTy(FTy.getParamType(3)) && + FTy.getParamType(3)->isIntegerTy(SizeTBits) && FTy.getParamType(4)->isPointerTy() && FTy.getReturnType()->isIntegerTy(32); @@ -932,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(SizeTBits); 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(SizeTBits)); case LibFunc_modf: case LibFunc_modff: case LibFunc_modfl: @@ -949,7 +943,7 @@ case LibFunc_mempcpy_chk: case LibFunc_memmove_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_memcpy: @@ -958,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(SizeTBits)); case LibFunc_memset_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) 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(SizeTBits)); case LibFunc_memccpy_chk: --NumParams; - if (!IsSizeTTy(FTy.getParamType(NumParams))) + if (!FTy.getParamType(NumParams)->isIntegerTy(SizeTBits)) return false; LLVM_FALLTHROUGH; case LibFunc_memccpy: @@ -985,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(SizeTBits)); case LibFunc_read: return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); case LibFunc_rewind: @@ -1066,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(SizeTBits)); case LibFunc_fopen: return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && @@ -1156,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(SizeTBits) && 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(SizeTBits) && FTy.getParamType(4)->isPointerTy(); case LibFunc_open: return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); case LibFunc_opendir: @@ -1575,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(SizeTBits)); 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(SizeTBits) && + FTy.getParamType(2)->isIntegerTy(SizeTBits)); case LibFunc_wcslen: return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && @@ -1624,7 +1619,7 @@ assert(M && "Expecting FDecl to be connected to a Module."); return getLibFunc(FDecl.getName(), F) && - isValidProtoForLibFunc(*FDecl.getFunctionType(), F, M->getDataLayout()); + isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M); } void TargetLibraryInfoImpl::disableAllFunctions() { @@ -1740,6 +1735,18 @@ 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. + // TODO: Should this use getIndexSizeInBits instead? + 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,8 @@ else return nullptr; - Type *SizeTTy = DL.getIntPtrType(CI->getContext()); + 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