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 @@ -53,9 +53,9 @@ return true; } -static bool hasBcmp(const Triple &TT) { - // Posix removed support from bcmp() in 2001, but the glibc and several - // implementations of the libc still have it. +static bool hasPosix2001LibCFunctions(const Triple &TT) { + // Posix removed support from some libc functions in 2001 (bcmp, bzero), but + // the glibc and several implementations of the libc still have it. if (TT.isOSLinux()) return TT.isGNUEnvironment() || TT.isMusl(); // Both NetBSD and OpenBSD are planning to remove the function. Windows does @@ -143,8 +143,10 @@ TLI.setUnavailable(LibFunc_sincospif_stret); } - if (!hasBcmp(T)) + if (!hasPosix2001LibCFunctions(T)) { + TLI.setUnavailable(LibFunc_bzero); TLI.setUnavailable(LibFunc_bcmp); + } if (T.isMacOSX() && T.getArch() == Triple::x86 && !T.isMacOSXVersionLT(10, 7)) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineBasicBlock.h" @@ -6613,8 +6614,8 @@ } SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, - SDValue Src, SDValue Size, Align Alignment, - bool isVol, bool isTailCall, + SDValue ByteValue, SDValue Size, + Align Alignment, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo) { // Check to see if we should lower the memset to stores first. // For cases within the target-specified limits, this is the best choice. @@ -6624,7 +6625,7 @@ if (ConstantSize->isNullValue()) return Chain; - SDValue Result = getMemsetStores(*this, dl, Chain, Dst, Src, + SDValue Result = getMemsetStores(*this, dl, Chain, Dst, ByteValue, ConstantSize->getZExtValue(), Alignment, isVol, DstPtrInfo); @@ -6636,39 +6637,55 @@ // code. If the target chooses to do this, this is the next best. if (TSI) { SDValue Result = TSI->EmitTargetCodeForMemset( - *this, dl, Chain, Dst, Src, Size, Alignment, isVol, DstPtrInfo); + *this, dl, Chain, Dst, ByteValue, Size, Alignment, isVol, DstPtrInfo); if (Result.getNode()) return Result; } checkAddrSpaceIsValidForLibcall(TLI, DstPtrInfo.getAddrSpace()); + const auto MakeArg = [](Type *Ty, SDValue Node) { + TargetLowering::ArgListEntry Entry; + Entry.Node = Node; + Entry.Ty = Ty; + return Entry; + }; + // Emit a library call. - TargetLowering::ArgListTy Args; - TargetLowering::ArgListEntry Entry; - Entry.Node = Dst; Entry.Ty = Type::getInt8PtrTy(*getContext()); - Args.push_back(Entry); - Entry.Node = Src; - Entry.Ty = Src.getValueType().getTypeForEVT(*getContext()); - Args.push_back(Entry); - Entry.Node = Size; - Entry.Ty = getDataLayout().getIntPtrType(*getContext()); - Args.push_back(Entry); + llvm::LLVMContext &Ctx = *getContext(); + const llvm::DataLayout &DL = getDataLayout(); + ConstantSDNode *ConstantByteValue = dyn_cast(ByteValue); + if (ConstantByteValue && ConstantByteValue->isNullValue() && + LibInfo->has(LibFunc_bzero)) { + TargetLowering::CallLoweringInfo CLI(*this); + CLI.setDebugLoc(dl) + .setChain(Chain) + .setLibCallee(CallingConv::C, Dst.getValueType().getTypeForEVT(Ctx), + getExternalSymbol(LibInfo->getName(LibFunc_bzero).data(), + TLI->getPointerTy(DL)), + {MakeArg(Type::getInt8PtrTy(Ctx), Dst), + MakeArg(DL.getIntPtrType(Ctx), Size)}) + .setDiscardResult(); + + return TLI->LowerCallTo(CLI).second; + } // FIXME: pass in SDLoc TargetLowering::CallLoweringInfo CLI(*this); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI->getLibcallCallingConv(RTLIB::MEMSET), - Dst.getValueType().getTypeForEVT(*getContext()), - getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET), - TLI->getPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee( + TLI->getLibcallCallingConv(RTLIB::MEMSET), + Dst.getValueType().getTypeForEVT(Ctx), + getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET), + TLI->getPointerTy(DL)), + {MakeArg(Type::getInt8PtrTy(Ctx), Dst), + MakeArg(ByteValue.getValueType().getTypeForEVT(Ctx), ByteValue), + MakeArg(DL.getIntPtrType(Ctx), Size)}) .setDiscardResult() .setTailCall(isTailCall); - std::pair CallResult = TLI->LowerCallTo(CLI); - return CallResult.second; + return TLI->LowerCallTo(CLI).second; } SDValue SelectionDAG::getAtomicMemset(SDValue Chain, const SDLoc &dl,