10b57cec5SDimitry Andric //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements some functions that will create standard C libcalls. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BuildLibCalls.h" 140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 150b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 1681ad6265SDimitry Andric #include "llvm/Analysis/MemoryBuiltins.h" 170b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 1881ad6265SDimitry Andric #include "llvm/IR/Argument.h" 1981ad6265SDimitry Andric #include "llvm/IR/CallingConv.h" 200b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 210b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 220b57cec5SDimitry Andric #include "llvm/IR/Function.h" 230b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h" 240b57cec5SDimitry Andric #include "llvm/IR/Module.h" 250b57cec5SDimitry Andric #include "llvm/IR/Type.h" 2681ad6265SDimitry Andric #include "llvm/Support/TypeSize.h" 27bdd1243dSDimitry Andric #include <optional> 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric #define DEBUG_TYPE "build-libcalls" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric //- Infer Attributes ---------------------------------------------------------// 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric STATISTIC(NumReadNone, "Number of functions inferred as readnone"); 36e8d8bef9SDimitry Andric STATISTIC(NumInaccessibleMemOnly, 37e8d8bef9SDimitry Andric "Number of functions inferred as inaccessiblememonly"); 380b57cec5SDimitry Andric STATISTIC(NumReadOnly, "Number of functions inferred as readonly"); 3904eeddc0SDimitry Andric STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly"); 400b57cec5SDimitry Andric STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly"); 41e8d8bef9SDimitry Andric STATISTIC(NumInaccessibleMemOrArgMemOnly, 42e8d8bef9SDimitry Andric "Number of functions inferred as inaccessiblemem_or_argmemonly"); 430b57cec5SDimitry Andric STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind"); 440b57cec5SDimitry Andric STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture"); 45e8d8bef9SDimitry Andric STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly"); 460b57cec5SDimitry Andric STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly"); 470b57cec5SDimitry Andric STATISTIC(NumNoAlias, "Number of function returns inferred as noalias"); 48e8d8bef9SDimitry Andric STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns"); 490b57cec5SDimitry Andric STATISTIC(NumReturnedArg, "Number of arguments inferred as returned"); 50e8d8bef9SDimitry Andric STATISTIC(NumWillReturn, "Number of functions inferred as willreturn"); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric static bool setDoesNotAccessMemory(Function &F) { 530b57cec5SDimitry Andric if (F.doesNotAccessMemory()) 540b57cec5SDimitry Andric return false; 550b57cec5SDimitry Andric F.setDoesNotAccessMemory(); 560b57cec5SDimitry Andric ++NumReadNone; 570b57cec5SDimitry Andric return true; 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 60e8d8bef9SDimitry Andric static bool setOnlyAccessesInaccessibleMemory(Function &F) { 61e8d8bef9SDimitry Andric if (F.onlyAccessesInaccessibleMemory()) 62e8d8bef9SDimitry Andric return false; 63e8d8bef9SDimitry Andric F.setOnlyAccessesInaccessibleMemory(); 64e8d8bef9SDimitry Andric ++NumInaccessibleMemOnly; 65e8d8bef9SDimitry Andric return true; 66e8d8bef9SDimitry Andric } 67e8d8bef9SDimitry Andric 680b57cec5SDimitry Andric static bool setOnlyReadsMemory(Function &F) { 690b57cec5SDimitry Andric if (F.onlyReadsMemory()) 700b57cec5SDimitry Andric return false; 710b57cec5SDimitry Andric F.setOnlyReadsMemory(); 720b57cec5SDimitry Andric ++NumReadOnly; 730b57cec5SDimitry Andric return true; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 7604eeddc0SDimitry Andric static bool setOnlyWritesMemory(Function &F) { 7704eeddc0SDimitry Andric if (F.onlyWritesMemory()) // writeonly or readnone 7804eeddc0SDimitry Andric return false; 7904eeddc0SDimitry Andric ++NumWriteOnly; 8004eeddc0SDimitry Andric F.setOnlyWritesMemory(); 8104eeddc0SDimitry Andric return true; 8204eeddc0SDimitry Andric } 8304eeddc0SDimitry Andric 840b57cec5SDimitry Andric static bool setOnlyAccessesArgMemory(Function &F) { 850b57cec5SDimitry Andric if (F.onlyAccessesArgMemory()) 860b57cec5SDimitry Andric return false; 870b57cec5SDimitry Andric F.setOnlyAccessesArgMemory(); 880b57cec5SDimitry Andric ++NumArgMemOnly; 890b57cec5SDimitry Andric return true; 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 92e8d8bef9SDimitry Andric static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) { 93e8d8bef9SDimitry Andric if (F.onlyAccessesInaccessibleMemOrArgMem()) 94e8d8bef9SDimitry Andric return false; 95e8d8bef9SDimitry Andric F.setOnlyAccessesInaccessibleMemOrArgMem(); 96e8d8bef9SDimitry Andric ++NumInaccessibleMemOrArgMemOnly; 97e8d8bef9SDimitry Andric return true; 98e8d8bef9SDimitry Andric } 99e8d8bef9SDimitry Andric 1000b57cec5SDimitry Andric static bool setDoesNotThrow(Function &F) { 1010b57cec5SDimitry Andric if (F.doesNotThrow()) 1020b57cec5SDimitry Andric return false; 1030b57cec5SDimitry Andric F.setDoesNotThrow(); 1040b57cec5SDimitry Andric ++NumNoUnwind; 1050b57cec5SDimitry Andric return true; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric static bool setRetDoesNotAlias(Function &F) { 109349cc55cSDimitry Andric if (F.hasRetAttribute(Attribute::NoAlias)) 1100b57cec5SDimitry Andric return false; 111349cc55cSDimitry Andric F.addRetAttr(Attribute::NoAlias); 1120b57cec5SDimitry Andric ++NumNoAlias; 1130b57cec5SDimitry Andric return true; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric static bool setDoesNotCapture(Function &F, unsigned ArgNo) { 1170b57cec5SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::NoCapture)) 1180b57cec5SDimitry Andric return false; 1190b57cec5SDimitry Andric F.addParamAttr(ArgNo, Attribute::NoCapture); 1200b57cec5SDimitry Andric ++NumNoCapture; 1210b57cec5SDimitry Andric return true; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1248bcb0991SDimitry Andric static bool setDoesNotAlias(Function &F, unsigned ArgNo) { 1258bcb0991SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::NoAlias)) 1268bcb0991SDimitry Andric return false; 1278bcb0991SDimitry Andric F.addParamAttr(ArgNo, Attribute::NoAlias); 1288bcb0991SDimitry Andric ++NumNoAlias; 1298bcb0991SDimitry Andric return true; 1308bcb0991SDimitry Andric } 1318bcb0991SDimitry Andric 1320b57cec5SDimitry Andric static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) { 1330b57cec5SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly)) 1340b57cec5SDimitry Andric return false; 1350b57cec5SDimitry Andric F.addParamAttr(ArgNo, Attribute::ReadOnly); 1360b57cec5SDimitry Andric ++NumReadOnlyArg; 1370b57cec5SDimitry Andric return true; 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 140e8d8bef9SDimitry Andric static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) { 141e8d8bef9SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly)) 142e8d8bef9SDimitry Andric return false; 143e8d8bef9SDimitry Andric F.addParamAttr(ArgNo, Attribute::WriteOnly); 144e8d8bef9SDimitry Andric ++NumWriteOnlyArg; 145e8d8bef9SDimitry Andric return true; 146e8d8bef9SDimitry Andric } 147e8d8bef9SDimitry Andric 148e8d8bef9SDimitry Andric static bool setRetNoUndef(Function &F) { 149e8d8bef9SDimitry Andric if (!F.getReturnType()->isVoidTy() && 150349cc55cSDimitry Andric !F.hasRetAttribute(Attribute::NoUndef)) { 151349cc55cSDimitry Andric F.addRetAttr(Attribute::NoUndef); 152e8d8bef9SDimitry Andric ++NumNoUndef; 153e8d8bef9SDimitry Andric return true; 154e8d8bef9SDimitry Andric } 155e8d8bef9SDimitry Andric return false; 156e8d8bef9SDimitry Andric } 157e8d8bef9SDimitry Andric 158e8d8bef9SDimitry Andric static bool setArgsNoUndef(Function &F) { 159e8d8bef9SDimitry Andric bool Changed = false; 160e8d8bef9SDimitry Andric for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) { 161e8d8bef9SDimitry Andric if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) { 162e8d8bef9SDimitry Andric F.addParamAttr(ArgNo, Attribute::NoUndef); 163e8d8bef9SDimitry Andric ++NumNoUndef; 164e8d8bef9SDimitry Andric Changed = true; 165e8d8bef9SDimitry Andric } 166e8d8bef9SDimitry Andric } 167e8d8bef9SDimitry Andric return Changed; 168e8d8bef9SDimitry Andric } 169e8d8bef9SDimitry Andric 170fe6060f1SDimitry Andric static bool setArgNoUndef(Function &F, unsigned ArgNo) { 171fe6060f1SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::NoUndef)) 172fe6060f1SDimitry Andric return false; 173fe6060f1SDimitry Andric F.addParamAttr(ArgNo, Attribute::NoUndef); 174fe6060f1SDimitry Andric ++NumNoUndef; 175fe6060f1SDimitry Andric return true; 176fe6060f1SDimitry Andric } 177fe6060f1SDimitry Andric 178e8d8bef9SDimitry Andric static bool setRetAndArgsNoUndef(Function &F) { 179349cc55cSDimitry Andric bool UndefAdded = false; 180349cc55cSDimitry Andric UndefAdded |= setRetNoUndef(F); 181349cc55cSDimitry Andric UndefAdded |= setArgsNoUndef(F); 182349cc55cSDimitry Andric return UndefAdded; 183e8d8bef9SDimitry Andric } 184e8d8bef9SDimitry Andric 1850b57cec5SDimitry Andric static bool setReturnedArg(Function &F, unsigned ArgNo) { 1860b57cec5SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::Returned)) 1870b57cec5SDimitry Andric return false; 1880b57cec5SDimitry Andric F.addParamAttr(ArgNo, Attribute::Returned); 1890b57cec5SDimitry Andric ++NumReturnedArg; 1900b57cec5SDimitry Andric return true; 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric static bool setNonLazyBind(Function &F) { 1940b57cec5SDimitry Andric if (F.hasFnAttribute(Attribute::NonLazyBind)) 1950b57cec5SDimitry Andric return false; 1960b57cec5SDimitry Andric F.addFnAttr(Attribute::NonLazyBind); 1970b57cec5SDimitry Andric return true; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric static bool setDoesNotFreeMemory(Function &F) { 2010b57cec5SDimitry Andric if (F.hasFnAttribute(Attribute::NoFree)) 2020b57cec5SDimitry Andric return false; 2030b57cec5SDimitry Andric F.addFnAttr(Attribute::NoFree); 2040b57cec5SDimitry Andric return true; 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 207e8d8bef9SDimitry Andric static bool setWillReturn(Function &F) { 208e8d8bef9SDimitry Andric if (F.hasFnAttribute(Attribute::WillReturn)) 209e8d8bef9SDimitry Andric return false; 210e8d8bef9SDimitry Andric F.addFnAttr(Attribute::WillReturn); 211e8d8bef9SDimitry Andric ++NumWillReturn; 212e8d8bef9SDimitry Andric return true; 213e8d8bef9SDimitry Andric } 214e8d8bef9SDimitry Andric 21581ad6265SDimitry Andric static bool setAlignedAllocParam(Function &F, unsigned ArgNo) { 21681ad6265SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::AllocAlign)) 21781ad6265SDimitry Andric return false; 21881ad6265SDimitry Andric F.addParamAttr(ArgNo, Attribute::AllocAlign); 21981ad6265SDimitry Andric return true; 22081ad6265SDimitry Andric } 22181ad6265SDimitry Andric 22281ad6265SDimitry Andric static bool setAllocatedPointerParam(Function &F, unsigned ArgNo) { 22381ad6265SDimitry Andric if (F.hasParamAttribute(ArgNo, Attribute::AllocatedPointer)) 22481ad6265SDimitry Andric return false; 22581ad6265SDimitry Andric F.addParamAttr(ArgNo, Attribute::AllocatedPointer); 22681ad6265SDimitry Andric return true; 22781ad6265SDimitry Andric } 22881ad6265SDimitry Andric 22981ad6265SDimitry Andric static bool setAllocSize(Function &F, unsigned ElemSizeArg, 230bdd1243dSDimitry Andric std::optional<unsigned> NumElemsArg) { 23181ad6265SDimitry Andric if (F.hasFnAttribute(Attribute::AllocSize)) 23281ad6265SDimitry Andric return false; 23381ad6265SDimitry Andric F.addFnAttr(Attribute::getWithAllocSizeArgs(F.getContext(), ElemSizeArg, 23481ad6265SDimitry Andric NumElemsArg)); 23581ad6265SDimitry Andric return true; 23681ad6265SDimitry Andric } 23781ad6265SDimitry Andric 23881ad6265SDimitry Andric static bool setAllocFamily(Function &F, StringRef Family) { 23981ad6265SDimitry Andric if (F.hasFnAttribute("alloc-family")) 24081ad6265SDimitry Andric return false; 24181ad6265SDimitry Andric F.addFnAttr("alloc-family", Family); 24281ad6265SDimitry Andric return true; 24381ad6265SDimitry Andric } 24481ad6265SDimitry Andric 24581ad6265SDimitry Andric static bool setAllocKind(Function &F, AllocFnKind K) { 24681ad6265SDimitry Andric if (F.hasFnAttribute(Attribute::AllocKind)) 24781ad6265SDimitry Andric return false; 24881ad6265SDimitry Andric F.addFnAttr( 24981ad6265SDimitry Andric Attribute::get(F.getContext(), Attribute::AllocKind, uint64_t(K))); 25081ad6265SDimitry Andric return true; 25181ad6265SDimitry Andric } 25281ad6265SDimitry Andric 25381ad6265SDimitry Andric bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name, 2540b57cec5SDimitry Andric const TargetLibraryInfo &TLI) { 2550b57cec5SDimitry Andric Function *F = M->getFunction(Name); 2560b57cec5SDimitry Andric if (!F) 2570b57cec5SDimitry Andric return false; 25881ad6265SDimitry Andric return inferNonMandatoryLibFuncAttrs(*F, TLI); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 26181ad6265SDimitry Andric bool llvm::inferNonMandatoryLibFuncAttrs(Function &F, 26281ad6265SDimitry Andric const TargetLibraryInfo &TLI) { 2630b57cec5SDimitry Andric LibFunc TheLibFunc; 2640b57cec5SDimitry Andric if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) 2650b57cec5SDimitry Andric return false; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric bool Changed = false; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) 2700b57cec5SDimitry Andric Changed |= setNonLazyBind(F); 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric switch (TheLibFunc) { 2730b57cec5SDimitry Andric case LibFunc_strlen: 27404eeddc0SDimitry Andric case LibFunc_strnlen: 2750b57cec5SDimitry Andric case LibFunc_wcslen: 2760b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 2770b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 2780b57cec5SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 279e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 2800b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 281fcaf7f86SDimitry Andric break; 2820b57cec5SDimitry Andric case LibFunc_strchr: 2830b57cec5SDimitry Andric case LibFunc_strrchr: 284e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 2850b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 2860b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 287e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 288fcaf7f86SDimitry Andric break; 2890b57cec5SDimitry Andric case LibFunc_strtol: 2900b57cec5SDimitry Andric case LibFunc_strtod: 2910b57cec5SDimitry Andric case LibFunc_strtof: 2920b57cec5SDimitry Andric case LibFunc_strtoul: 2930b57cec5SDimitry Andric case LibFunc_strtoll: 2940b57cec5SDimitry Andric case LibFunc_strtold: 2950b57cec5SDimitry Andric case LibFunc_strtoull: 2960b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 297e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 2980b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 2990b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 300fcaf7f86SDimitry Andric break; 3010b57cec5SDimitry Andric case LibFunc_strcat: 3020b57cec5SDimitry Andric case LibFunc_strncat: 303fe6060f1SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 304fe6060f1SDimitry Andric Changed |= setDoesNotThrow(F); 305e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3060b57cec5SDimitry Andric Changed |= setReturnedArg(F, 0); 307fe6060f1SDimitry Andric Changed |= setDoesNotCapture(F, 1); 308fe6060f1SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 309fe6060f1SDimitry Andric Changed |= setDoesNotAlias(F, 0); 310fe6060f1SDimitry Andric Changed |= setDoesNotAlias(F, 1); 311fcaf7f86SDimitry Andric break; 312fe6060f1SDimitry Andric case LibFunc_strcpy: 313fe6060f1SDimitry Andric case LibFunc_strncpy: 314fe6060f1SDimitry Andric Changed |= setReturnedArg(F, 0); 315bdd1243dSDimitry Andric [[fallthrough]]; 3160b57cec5SDimitry Andric case LibFunc_stpcpy: 3170b57cec5SDimitry Andric case LibFunc_stpncpy: 318e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 3190b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 320e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3210b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 322e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 3230b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 324e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 0); 325e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 1); 326fcaf7f86SDimitry Andric break; 3270b57cec5SDimitry Andric case LibFunc_strxfrm: 3280b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 329e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3300b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 3310b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 3320b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 333fcaf7f86SDimitry Andric break; 3340b57cec5SDimitry Andric case LibFunc_strcmp: // 0,1 3350b57cec5SDimitry Andric case LibFunc_strspn: // 0,1 3360b57cec5SDimitry Andric case LibFunc_strncmp: // 0,1 3370b57cec5SDimitry Andric case LibFunc_strcspn: // 0,1 338e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 339e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 340e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 341e8d8bef9SDimitry Andric Changed |= setOnlyReadsMemory(F); 342e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 0); 343e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 1); 344fcaf7f86SDimitry Andric break; 345e8d8bef9SDimitry Andric case LibFunc_strcoll: 3460b57cec5SDimitry Andric case LibFunc_strcasecmp: // 0,1 3470b57cec5SDimitry Andric case LibFunc_strncasecmp: // 348e8d8bef9SDimitry Andric // Those functions may depend on the locale, which may be accessed through 349e8d8bef9SDimitry Andric // global memory. 3500b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 3510b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 352e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3530b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 3540b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 355fcaf7f86SDimitry Andric break; 3560b57cec5SDimitry Andric case LibFunc_strstr: 3570b57cec5SDimitry Andric case LibFunc_strpbrk: 358e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 3590b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 3600b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 361e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3620b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 363fcaf7f86SDimitry Andric break; 3640b57cec5SDimitry Andric case LibFunc_strtok: 3650b57cec5SDimitry Andric case LibFunc_strtok_r: 3660b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 367e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3680b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 3690b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 370fcaf7f86SDimitry Andric break; 3710b57cec5SDimitry Andric case LibFunc_scanf: 372e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 3730b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 3740b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 3750b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 376fcaf7f86SDimitry Andric break; 3770b57cec5SDimitry Andric case LibFunc_setbuf: 3780b57cec5SDimitry Andric case LibFunc_setvbuf: 379e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 3800b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 3810b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 382fcaf7f86SDimitry Andric break; 3830b57cec5SDimitry Andric case LibFunc_strndup: 384fe6060f1SDimitry Andric Changed |= setArgNoUndef(F, 1); 385bdd1243dSDimitry Andric [[fallthrough]]; 386fe6060f1SDimitry Andric case LibFunc_strdup: 38781ad6265SDimitry Andric Changed |= setAllocFamily(F, "malloc"); 388e8d8bef9SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F); 3890b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 3900b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 391e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 3920b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 3930b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 394fcaf7f86SDimitry Andric break; 3950b57cec5SDimitry Andric case LibFunc_stat: 3960b57cec5SDimitry Andric case LibFunc_statvfs: 397e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 3980b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 3990b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4000b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 4010b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 402fcaf7f86SDimitry Andric break; 4030b57cec5SDimitry Andric case LibFunc_sscanf: 404e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4050b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 4060b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4070b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 4080b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 4090b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 410fcaf7f86SDimitry Andric break; 4110b57cec5SDimitry Andric case LibFunc_sprintf: 412e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4130b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 4140b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4158bcb0991SDimitry Andric Changed |= setDoesNotAlias(F, 0); 416e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 4170b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 4180b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 419fcaf7f86SDimitry Andric break; 4200b57cec5SDimitry Andric case LibFunc_snprintf: 421e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4220b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 4230b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4248bcb0991SDimitry Andric Changed |= setDoesNotAlias(F, 0); 425e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 4260b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 2); 4270b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 2); 428fcaf7f86SDimitry Andric break; 4290b57cec5SDimitry Andric case LibFunc_setitimer: 430e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4310b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 432e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 4330b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 4340b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 2); 4350b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 436fcaf7f86SDimitry Andric break; 4370b57cec5SDimitry Andric case LibFunc_system: 4380b57cec5SDimitry Andric // May throw; "system" is a valid pthread cancellation point. 439e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4400b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4410b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 442fcaf7f86SDimitry Andric break; 44304eeddc0SDimitry Andric case LibFunc_aligned_alloc: 44481ad6265SDimitry Andric Changed |= setAlignedAllocParam(F, 0); 445bdd1243dSDimitry Andric Changed |= setAllocSize(F, 1, std::nullopt); 44681ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized | AllocFnKind::Aligned); 447bdd1243dSDimitry Andric [[fallthrough]]; 44804eeddc0SDimitry Andric case LibFunc_valloc: 4490b57cec5SDimitry Andric case LibFunc_malloc: 450e8d8bef9SDimitry Andric case LibFunc_vec_malloc: 45181ad6265SDimitry Andric Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_malloc ? "vec_malloc" 45281ad6265SDimitry Andric : "malloc"); 45381ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized); 454bdd1243dSDimitry Andric Changed |= setAllocSize(F, 0, std::nullopt); 455e8d8bef9SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemory(F); 456fe6060f1SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 4570b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 4580b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 459e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 460fcaf7f86SDimitry Andric break; 4610b57cec5SDimitry Andric case LibFunc_memcmp: 462e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 4630b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 4640b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 465e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 4660b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 4670b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 468fcaf7f86SDimitry Andric break; 4690b57cec5SDimitry Andric case LibFunc_memchr: 4700b57cec5SDimitry Andric case LibFunc_memrchr: 4710b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 472e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 473e8d8bef9SDimitry Andric Changed |= setOnlyReadsMemory(F); 474e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 475fcaf7f86SDimitry Andric break; 4760b57cec5SDimitry Andric case LibFunc_modf: 4770b57cec5SDimitry Andric case LibFunc_modff: 4780b57cec5SDimitry Andric case LibFunc_modfl: 4790b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 480e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 48106c3fb27SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 48206c3fb27SDimitry Andric Changed |= setOnlyWritesMemory(F); 4830b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 484fcaf7f86SDimitry Andric break; 4850b57cec5SDimitry Andric case LibFunc_memcpy: 4868bcb0991SDimitry Andric Changed |= setDoesNotThrow(F); 487e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 488e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 489e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 0); 490e8d8bef9SDimitry Andric Changed |= setReturnedArg(F, 0); 491e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 492e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 1); 4938bcb0991SDimitry Andric Changed |= setDoesNotCapture(F, 1); 4948bcb0991SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 495fcaf7f86SDimitry Andric break; 4960b57cec5SDimitry Andric case LibFunc_memmove: 4978bcb0991SDimitry Andric Changed |= setDoesNotThrow(F); 498e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 499e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 500e8d8bef9SDimitry Andric Changed |= setReturnedArg(F, 0); 501e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 5028bcb0991SDimitry Andric Changed |= setDoesNotCapture(F, 1); 5038bcb0991SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 504fcaf7f86SDimitry Andric break; 5050b57cec5SDimitry Andric case LibFunc_mempcpy: 5060b57cec5SDimitry Andric case LibFunc_memccpy: 5074824e7fdSDimitry Andric Changed |= setWillReturn(F); 508bdd1243dSDimitry Andric [[fallthrough]]; 5094824e7fdSDimitry Andric case LibFunc_memcpy_chk: 5100b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 511e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 512e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 0); 513e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 514e8d8bef9SDimitry Andric Changed |= setDoesNotAlias(F, 1); 5150b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 5160b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 517fcaf7f86SDimitry Andric break; 5180b57cec5SDimitry Andric case LibFunc_memalign: 51981ad6265SDimitry Andric Changed |= setAllocFamily(F, "malloc"); 52081ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Aligned | 52181ad6265SDimitry Andric AllocFnKind::Uninitialized); 522bdd1243dSDimitry Andric Changed |= setAllocSize(F, 1, std::nullopt); 52381ad6265SDimitry Andric Changed |= setAlignedAllocParam(F, 0); 524e8d8bef9SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemory(F); 525e8d8bef9SDimitry Andric Changed |= setRetNoUndef(F); 526e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 5270b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 528e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 529fcaf7f86SDimitry Andric break; 5300b57cec5SDimitry Andric case LibFunc_mkdir: 531e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5320b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5330b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 5340b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 535fcaf7f86SDimitry Andric break; 5360b57cec5SDimitry Andric case LibFunc_mktime: 537e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5380b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 539e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 5400b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 541fcaf7f86SDimitry Andric break; 5420b57cec5SDimitry Andric case LibFunc_realloc: 54304eeddc0SDimitry Andric case LibFunc_reallocf: 54481ad6265SDimitry Andric case LibFunc_vec_realloc: 54581ad6265SDimitry Andric Changed |= setAllocFamily( 54681ad6265SDimitry Andric F, TheLibFunc == LibFunc_vec_realloc ? "vec_malloc" : "malloc"); 54781ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Realloc); 54881ad6265SDimitry Andric Changed |= setAllocatedPointerParam(F, 0); 549bdd1243dSDimitry Andric Changed |= setAllocSize(F, 1, std::nullopt); 550e8d8bef9SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F); 551e8d8bef9SDimitry Andric Changed |= setRetNoUndef(F); 5520b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5530b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 554e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 5550b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 556fe6060f1SDimitry Andric Changed |= setArgNoUndef(F, 1); 557fcaf7f86SDimitry Andric break; 5580b57cec5SDimitry Andric case LibFunc_read: 5590b57cec5SDimitry Andric // May throw; "read" is a valid pthread cancellation point. 560e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5610b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 562fcaf7f86SDimitry Andric break; 5630b57cec5SDimitry Andric case LibFunc_rewind: 564e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5650b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5660b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 567fcaf7f86SDimitry Andric break; 5680b57cec5SDimitry Andric case LibFunc_rmdir: 5690b57cec5SDimitry Andric case LibFunc_remove: 5700b57cec5SDimitry Andric case LibFunc_realpath: 571e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5720b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5730b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 5740b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 575fcaf7f86SDimitry Andric break; 5760b57cec5SDimitry Andric case LibFunc_rename: 577e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5780b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5790b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 5800b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 5810b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 5820b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 583fcaf7f86SDimitry Andric break; 5840b57cec5SDimitry Andric case LibFunc_readlink: 585e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5860b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 5870b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 5880b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 5890b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 590fcaf7f86SDimitry Andric break; 5910b57cec5SDimitry Andric case LibFunc_write: 5920b57cec5SDimitry Andric // May throw; "write" is a valid pthread cancellation point. 593e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 5940b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 5950b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 596fcaf7f86SDimitry Andric break; 5970b57cec5SDimitry Andric case LibFunc_bcopy: 5980b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 599e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 600e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 6010b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 6020b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 603e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 1); 604e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 1); 605fcaf7f86SDimitry Andric break; 6060b57cec5SDimitry Andric case LibFunc_bcmp: 6070b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 608e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 6090b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 610e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 6110b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 6120b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 613fcaf7f86SDimitry Andric break; 6140b57cec5SDimitry Andric case LibFunc_bzero: 6150b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 616e8d8bef9SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 617e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 6180b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 619e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 620fcaf7f86SDimitry Andric break; 6210b57cec5SDimitry Andric case LibFunc_calloc: 622e8d8bef9SDimitry Andric case LibFunc_vec_calloc: 62381ad6265SDimitry Andric Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_calloc ? "vec_malloc" 62481ad6265SDimitry Andric : "malloc"); 62581ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Zeroed); 62681ad6265SDimitry Andric Changed |= setAllocSize(F, 0, 1); 62704eeddc0SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemory(F); 628fe6060f1SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6290b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6300b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 631e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 632fcaf7f86SDimitry Andric break; 6330b57cec5SDimitry Andric case LibFunc_chmod: 6340b57cec5SDimitry Andric case LibFunc_chown: 635e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6360b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6370b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 6380b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 639fcaf7f86SDimitry Andric break; 6400b57cec5SDimitry Andric case LibFunc_ctermid: 6410b57cec5SDimitry Andric case LibFunc_clearerr: 6420b57cec5SDimitry Andric case LibFunc_closedir: 643e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6440b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6450b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 646fcaf7f86SDimitry Andric break; 6470b57cec5SDimitry Andric case LibFunc_atoi: 6480b57cec5SDimitry Andric case LibFunc_atol: 6490b57cec5SDimitry Andric case LibFunc_atof: 6500b57cec5SDimitry Andric case LibFunc_atoll: 6510b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6520b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 653e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 6540b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 655fcaf7f86SDimitry Andric break; 6560b57cec5SDimitry Andric case LibFunc_access: 657e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6580b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6590b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 6600b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 661fcaf7f86SDimitry Andric break; 6620b57cec5SDimitry Andric case LibFunc_fopen: 663e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6640b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6650b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 6660b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 6670b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 6680b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 6690b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 670fcaf7f86SDimitry Andric break; 6710b57cec5SDimitry Andric case LibFunc_fdopen: 672e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 6730b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 6740b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 6750b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 6760b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 677fcaf7f86SDimitry Andric break; 6780b57cec5SDimitry Andric case LibFunc_feof: 679e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 680e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 681e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 0); 682fcaf7f86SDimitry Andric break; 6830b57cec5SDimitry Andric case LibFunc_free: 684e8d8bef9SDimitry Andric case LibFunc_vec_free: 68581ad6265SDimitry Andric Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_free ? "vec_malloc" 68681ad6265SDimitry Andric : "malloc"); 68781ad6265SDimitry Andric Changed |= setAllocKind(F, AllocFnKind::Free); 68881ad6265SDimitry Andric Changed |= setAllocatedPointerParam(F, 0); 689e8d8bef9SDimitry Andric Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F); 690e8d8bef9SDimitry Andric Changed |= setArgsNoUndef(F); 691e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 692e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 693e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 0); 694fcaf7f86SDimitry Andric break; 6950b57cec5SDimitry Andric case LibFunc_fseek: 6960b57cec5SDimitry Andric case LibFunc_ftell: 6970b57cec5SDimitry Andric case LibFunc_fgetc: 6980b57cec5SDimitry Andric case LibFunc_fgetc_unlocked: 6990b57cec5SDimitry Andric case LibFunc_fseeko: 7000b57cec5SDimitry Andric case LibFunc_ftello: 7010b57cec5SDimitry Andric case LibFunc_fileno: 7020b57cec5SDimitry Andric case LibFunc_fflush: 7030b57cec5SDimitry Andric case LibFunc_fclose: 7040b57cec5SDimitry Andric case LibFunc_fsetpos: 7050b57cec5SDimitry Andric case LibFunc_flockfile: 7060b57cec5SDimitry Andric case LibFunc_funlockfile: 7070b57cec5SDimitry Andric case LibFunc_ftrylockfile: 708e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7090b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7100b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 711fcaf7f86SDimitry Andric break; 7120b57cec5SDimitry Andric case LibFunc_ferror: 713e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7140b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7150b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7160b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 717fcaf7f86SDimitry Andric break; 7180b57cec5SDimitry Andric case LibFunc_fputc: 7190b57cec5SDimitry Andric case LibFunc_fputc_unlocked: 7200b57cec5SDimitry Andric case LibFunc_fstat: 721e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 722e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 723e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 1); 724fcaf7f86SDimitry Andric break; 7250b57cec5SDimitry Andric case LibFunc_frexp: 7260b57cec5SDimitry Andric case LibFunc_frexpf: 7270b57cec5SDimitry Andric case LibFunc_frexpl: 728e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 729e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 73006c3fb27SDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 73106c3fb27SDimitry Andric Changed |= setOnlyWritesMemory(F); 732e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 1); 733fcaf7f86SDimitry Andric break; 7340b57cec5SDimitry Andric case LibFunc_fstatvfs: 735e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7360b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7370b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 738fcaf7f86SDimitry Andric break; 7390b57cec5SDimitry Andric case LibFunc_fgets: 7400b57cec5SDimitry Andric case LibFunc_fgets_unlocked: 741e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7420b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7430b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 2); 744fcaf7f86SDimitry Andric break; 7450b57cec5SDimitry Andric case LibFunc_fread: 7460b57cec5SDimitry Andric case LibFunc_fread_unlocked: 747e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7480b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7490b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7500b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 3); 751fcaf7f86SDimitry Andric break; 7520b57cec5SDimitry Andric case LibFunc_fwrite: 7530b57cec5SDimitry Andric case LibFunc_fwrite_unlocked: 754e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7550b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7560b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7570b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 3); 7580b57cec5SDimitry Andric // FIXME: readonly #1? 759fcaf7f86SDimitry Andric break; 7600b57cec5SDimitry Andric case LibFunc_fputs: 7610b57cec5SDimitry Andric case LibFunc_fputs_unlocked: 762e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7630b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7640b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7650b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 7660b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 767fcaf7f86SDimitry Andric break; 7680b57cec5SDimitry Andric case LibFunc_fscanf: 7690b57cec5SDimitry Andric case LibFunc_fprintf: 770e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7710b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7720b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7730b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 7740b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 775fcaf7f86SDimitry Andric break; 7760b57cec5SDimitry Andric case LibFunc_fgetpos: 777e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7780b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7790b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 7800b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 781fcaf7f86SDimitry Andric break; 7820b57cec5SDimitry Andric case LibFunc_getc: 783e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 784e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 785e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 0); 786fcaf7f86SDimitry Andric break; 7870b57cec5SDimitry Andric case LibFunc_getlogin_r: 788e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 789e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 790e8d8bef9SDimitry Andric Changed |= setDoesNotCapture(F, 0); 791fcaf7f86SDimitry Andric break; 7920b57cec5SDimitry Andric case LibFunc_getc_unlocked: 793e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7940b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 7950b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 796fcaf7f86SDimitry Andric break; 7970b57cec5SDimitry Andric case LibFunc_getenv: 798e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 7990b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8000b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F); 8010b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 802fcaf7f86SDimitry Andric break; 8030b57cec5SDimitry Andric case LibFunc_gets: 8040b57cec5SDimitry Andric case LibFunc_getchar: 8050b57cec5SDimitry Andric case LibFunc_getchar_unlocked: 806e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8070b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 808fcaf7f86SDimitry Andric break; 8090b57cec5SDimitry Andric case LibFunc_getitimer: 810e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8110b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8120b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 813fcaf7f86SDimitry Andric break; 8140b57cec5SDimitry Andric case LibFunc_getpwnam: 815e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8160b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8170b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8180b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 819fcaf7f86SDimitry Andric break; 8200b57cec5SDimitry Andric case LibFunc_ungetc: 821e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8220b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8230b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 824fcaf7f86SDimitry Andric break; 8250b57cec5SDimitry Andric case LibFunc_uname: 826e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8270b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8280b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 829fcaf7f86SDimitry Andric break; 8300b57cec5SDimitry Andric case LibFunc_unlink: 831e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8320b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8330b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8340b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 835fcaf7f86SDimitry Andric break; 8360b57cec5SDimitry Andric case LibFunc_unsetenv: 837e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8380b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8390b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8400b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 841fcaf7f86SDimitry Andric break; 8420b57cec5SDimitry Andric case LibFunc_utime: 8430b57cec5SDimitry Andric case LibFunc_utimes: 844e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8450b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8460b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8470b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 8480b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 8490b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 850fcaf7f86SDimitry Andric break; 8510b57cec5SDimitry Andric case LibFunc_putc: 8520b57cec5SDimitry Andric case LibFunc_putc_unlocked: 853e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8540b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8550b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 856fcaf7f86SDimitry Andric break; 8570b57cec5SDimitry Andric case LibFunc_puts: 8580b57cec5SDimitry Andric case LibFunc_printf: 8590b57cec5SDimitry Andric case LibFunc_perror: 860e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8610b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8620b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8630b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 864fcaf7f86SDimitry Andric break; 8650b57cec5SDimitry Andric case LibFunc_pread: 8660b57cec5SDimitry Andric // May throw; "pread" is a valid pthread cancellation point. 867e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8680b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 869fcaf7f86SDimitry Andric break; 8700b57cec5SDimitry Andric case LibFunc_pwrite: 8710b57cec5SDimitry Andric // May throw; "pwrite" is a valid pthread cancellation point. 872e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8730b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 8740b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 875fcaf7f86SDimitry Andric break; 8760b57cec5SDimitry Andric case LibFunc_putchar: 8770b57cec5SDimitry Andric case LibFunc_putchar_unlocked: 878e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8790b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 880fcaf7f86SDimitry Andric break; 8810b57cec5SDimitry Andric case LibFunc_popen: 882e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8830b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8840b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 8850b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8860b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 8870b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 8880b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 889fcaf7f86SDimitry Andric break; 8900b57cec5SDimitry Andric case LibFunc_pclose: 891e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8920b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8930b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 894fcaf7f86SDimitry Andric break; 8950b57cec5SDimitry Andric case LibFunc_vscanf: 896e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 8970b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 8980b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 8990b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 900fcaf7f86SDimitry Andric break; 9010b57cec5SDimitry Andric case LibFunc_vsscanf: 902e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9030b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9040b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9050b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 9060b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 9070b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 908fcaf7f86SDimitry Andric break; 9090b57cec5SDimitry Andric case LibFunc_vfscanf: 910e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9110b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9120b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9130b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 9140b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 915fcaf7f86SDimitry Andric break; 9160b57cec5SDimitry Andric case LibFunc_vprintf: 917e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9180b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9190b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9200b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 921fcaf7f86SDimitry Andric break; 9220b57cec5SDimitry Andric case LibFunc_vfprintf: 9230b57cec5SDimitry Andric case LibFunc_vsprintf: 924e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9250b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9260b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9270b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 9280b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 929fcaf7f86SDimitry Andric break; 9300b57cec5SDimitry Andric case LibFunc_vsnprintf: 931e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9320b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9330b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9340b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 2); 9350b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 2); 936fcaf7f86SDimitry Andric break; 9370b57cec5SDimitry Andric case LibFunc_open: 9380b57cec5SDimitry Andric // May throw; "open" is a valid pthread cancellation point. 939e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9400b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9410b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 942fcaf7f86SDimitry Andric break; 9430b57cec5SDimitry Andric case LibFunc_opendir: 944e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9450b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9460b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 9470b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9480b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 949fcaf7f86SDimitry Andric break; 9500b57cec5SDimitry Andric case LibFunc_tmpfile: 951e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9520b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9530b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 954fcaf7f86SDimitry Andric break; 9550b57cec5SDimitry Andric case LibFunc_times: 956e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9570b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9580b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 959fcaf7f86SDimitry Andric break; 9600b57cec5SDimitry Andric case LibFunc_htonl: 9610b57cec5SDimitry Andric case LibFunc_htons: 9620b57cec5SDimitry Andric case LibFunc_ntohl: 9630b57cec5SDimitry Andric case LibFunc_ntohs: 9640b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9650b57cec5SDimitry Andric Changed |= setDoesNotAccessMemory(F); 966fcaf7f86SDimitry Andric break; 9670b57cec5SDimitry Andric case LibFunc_lstat: 968e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9690b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9700b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9710b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 9720b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 973fcaf7f86SDimitry Andric break; 9740b57cec5SDimitry Andric case LibFunc_lchown: 975e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9760b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9770b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9780b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 979fcaf7f86SDimitry Andric break; 9800b57cec5SDimitry Andric case LibFunc_qsort: 9810b57cec5SDimitry Andric // May throw; places call through function pointer. 982e8d8bef9SDimitry Andric // Cannot give undef pointer/size 983e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 9840b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 3); 985fcaf7f86SDimitry Andric break; 9860b57cec5SDimitry Andric case LibFunc_dunder_strndup: 987fe6060f1SDimitry Andric Changed |= setArgNoUndef(F, 1); 988bdd1243dSDimitry Andric [[fallthrough]]; 989fe6060f1SDimitry Andric case LibFunc_dunder_strdup: 9900b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9910b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 992e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 9930b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 9940b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 995fcaf7f86SDimitry Andric break; 9960b57cec5SDimitry Andric case LibFunc_dunder_strtok_r: 9970b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 9980b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 9990b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 1000fcaf7f86SDimitry Andric break; 10010b57cec5SDimitry Andric case LibFunc_under_IO_getc: 1002e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10030b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10040b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 1005fcaf7f86SDimitry Andric break; 10060b57cec5SDimitry Andric case LibFunc_under_IO_putc: 1007e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10080b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10090b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 1010fcaf7f86SDimitry Andric break; 10110b57cec5SDimitry Andric case LibFunc_dunder_isoc99_scanf: 1012e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10130b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10140b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10150b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 1016fcaf7f86SDimitry Andric break; 10170b57cec5SDimitry Andric case LibFunc_stat64: 10180b57cec5SDimitry Andric case LibFunc_lstat64: 10190b57cec5SDimitry Andric case LibFunc_statvfs64: 1020e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10210b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10220b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10230b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 10240b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 1025fcaf7f86SDimitry Andric break; 10260b57cec5SDimitry Andric case LibFunc_dunder_isoc99_sscanf: 1027e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10280b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10290b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10300b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 10310b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 10320b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 1033fcaf7f86SDimitry Andric break; 10340b57cec5SDimitry Andric case LibFunc_fopen64: 1035e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10360b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10370b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 10380b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10390b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 10400b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 10410b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 1042fcaf7f86SDimitry Andric break; 10430b57cec5SDimitry Andric case LibFunc_fseeko64: 10440b57cec5SDimitry Andric case LibFunc_ftello64: 1045e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10460b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10470b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 1048fcaf7f86SDimitry Andric break; 10490b57cec5SDimitry Andric case LibFunc_tmpfile64: 1050e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10510b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10520b57cec5SDimitry Andric Changed |= setRetDoesNotAlias(F); 1053fcaf7f86SDimitry Andric break; 10540b57cec5SDimitry Andric case LibFunc_fstat64: 10550b57cec5SDimitry Andric case LibFunc_fstatvfs64: 1056e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10570b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10580b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 1059fcaf7f86SDimitry Andric break; 10600b57cec5SDimitry Andric case LibFunc_open64: 10610b57cec5SDimitry Andric // May throw; "open" is a valid pthread cancellation point. 1062e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10630b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10640b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 0); 1065fcaf7f86SDimitry Andric break; 10660b57cec5SDimitry Andric case LibFunc_gettimeofday: 10670b57cec5SDimitry Andric // Currently some platforms have the restrict keyword on the arguments to 10680b57cec5SDimitry Andric // gettimeofday. To be conservative, do not add noalias to gettimeofday's 10690b57cec5SDimitry Andric // arguments. 1070e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10710b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 10720b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10730b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 1074fcaf7f86SDimitry Andric break; 10754824e7fdSDimitry Andric case LibFunc_memset_pattern4: 10764824e7fdSDimitry Andric case LibFunc_memset_pattern8: 10770b57cec5SDimitry Andric case LibFunc_memset_pattern16: 10780b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 0); 10790b57cec5SDimitry Andric Changed |= setDoesNotCapture(F, 1); 10800b57cec5SDimitry Andric Changed |= setOnlyReadsMemory(F, 1); 1081bdd1243dSDimitry Andric [[fallthrough]]; 1082e8d8bef9SDimitry Andric case LibFunc_memset: 1083e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 1084bdd1243dSDimitry Andric [[fallthrough]]; 10854824e7fdSDimitry Andric case LibFunc_memset_chk: 10864824e7fdSDimitry Andric Changed |= setOnlyAccessesArgMemory(F); 1087e8d8bef9SDimitry Andric Changed |= setOnlyWritesMemory(F, 0); 10884824e7fdSDimitry Andric Changed |= setDoesNotThrow(F); 1089fcaf7f86SDimitry Andric break; 10900b57cec5SDimitry Andric // int __nvvm_reflect(const char *) 10910b57cec5SDimitry Andric case LibFunc_nvvm_reflect: 1092e8d8bef9SDimitry Andric Changed |= setRetAndArgsNoUndef(F); 10930b57cec5SDimitry Andric Changed |= setDoesNotAccessMemory(F); 10940b57cec5SDimitry Andric Changed |= setDoesNotThrow(F); 1095fcaf7f86SDimitry Andric break; 1096e8d8bef9SDimitry Andric case LibFunc_ldexp: 1097e8d8bef9SDimitry Andric case LibFunc_ldexpf: 1098e8d8bef9SDimitry Andric case LibFunc_ldexpl: 1099e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 1100fcaf7f86SDimitry Andric break; 1101*0fca6ea1SDimitry Andric case LibFunc_remquo: 1102*0fca6ea1SDimitry Andric case LibFunc_remquof: 1103*0fca6ea1SDimitry Andric case LibFunc_remquol: 1104*0fca6ea1SDimitry Andric Changed |= setDoesNotCapture(F, 2); 1105*0fca6ea1SDimitry Andric [[fallthrough]]; 1106e8d8bef9SDimitry Andric case LibFunc_abs: 1107e8d8bef9SDimitry Andric case LibFunc_acos: 1108e8d8bef9SDimitry Andric case LibFunc_acosf: 1109e8d8bef9SDimitry Andric case LibFunc_acosh: 1110e8d8bef9SDimitry Andric case LibFunc_acoshf: 1111e8d8bef9SDimitry Andric case LibFunc_acoshl: 1112e8d8bef9SDimitry Andric case LibFunc_acosl: 1113e8d8bef9SDimitry Andric case LibFunc_asin: 1114e8d8bef9SDimitry Andric case LibFunc_asinf: 1115e8d8bef9SDimitry Andric case LibFunc_asinh: 1116e8d8bef9SDimitry Andric case LibFunc_asinhf: 1117e8d8bef9SDimitry Andric case LibFunc_asinhl: 1118e8d8bef9SDimitry Andric case LibFunc_asinl: 1119e8d8bef9SDimitry Andric case LibFunc_atan: 1120e8d8bef9SDimitry Andric case LibFunc_atan2: 1121e8d8bef9SDimitry Andric case LibFunc_atan2f: 1122e8d8bef9SDimitry Andric case LibFunc_atan2l: 1123e8d8bef9SDimitry Andric case LibFunc_atanf: 1124e8d8bef9SDimitry Andric case LibFunc_atanh: 1125e8d8bef9SDimitry Andric case LibFunc_atanhf: 1126e8d8bef9SDimitry Andric case LibFunc_atanhl: 1127e8d8bef9SDimitry Andric case LibFunc_atanl: 1128e8d8bef9SDimitry Andric case LibFunc_cbrt: 1129e8d8bef9SDimitry Andric case LibFunc_cbrtf: 1130e8d8bef9SDimitry Andric case LibFunc_cbrtl: 1131e8d8bef9SDimitry Andric case LibFunc_ceil: 1132e8d8bef9SDimitry Andric case LibFunc_ceilf: 1133e8d8bef9SDimitry Andric case LibFunc_ceill: 1134e8d8bef9SDimitry Andric case LibFunc_copysign: 1135e8d8bef9SDimitry Andric case LibFunc_copysignf: 1136e8d8bef9SDimitry Andric case LibFunc_copysignl: 1137e8d8bef9SDimitry Andric case LibFunc_cos: 1138e8d8bef9SDimitry Andric case LibFunc_cosh: 1139e8d8bef9SDimitry Andric case LibFunc_coshf: 1140e8d8bef9SDimitry Andric case LibFunc_coshl: 1141e8d8bef9SDimitry Andric case LibFunc_cosf: 1142e8d8bef9SDimitry Andric case LibFunc_cosl: 1143e8d8bef9SDimitry Andric case LibFunc_cospi: 1144e8d8bef9SDimitry Andric case LibFunc_cospif: 1145*0fca6ea1SDimitry Andric case LibFunc_erf: 1146*0fca6ea1SDimitry Andric case LibFunc_erff: 1147*0fca6ea1SDimitry Andric case LibFunc_erfl: 1148e8d8bef9SDimitry Andric case LibFunc_exp: 1149e8d8bef9SDimitry Andric case LibFunc_expf: 1150e8d8bef9SDimitry Andric case LibFunc_expl: 1151e8d8bef9SDimitry Andric case LibFunc_exp2: 1152e8d8bef9SDimitry Andric case LibFunc_exp2f: 1153e8d8bef9SDimitry Andric case LibFunc_exp2l: 1154e8d8bef9SDimitry Andric case LibFunc_expm1: 1155e8d8bef9SDimitry Andric case LibFunc_expm1f: 1156e8d8bef9SDimitry Andric case LibFunc_expm1l: 1157e8d8bef9SDimitry Andric case LibFunc_fabs: 1158e8d8bef9SDimitry Andric case LibFunc_fabsf: 1159e8d8bef9SDimitry Andric case LibFunc_fabsl: 1160e8d8bef9SDimitry Andric case LibFunc_ffs: 1161e8d8bef9SDimitry Andric case LibFunc_ffsl: 1162e8d8bef9SDimitry Andric case LibFunc_ffsll: 1163e8d8bef9SDimitry Andric case LibFunc_floor: 1164e8d8bef9SDimitry Andric case LibFunc_floorf: 1165e8d8bef9SDimitry Andric case LibFunc_floorl: 1166e8d8bef9SDimitry Andric case LibFunc_fls: 1167e8d8bef9SDimitry Andric case LibFunc_flsl: 1168e8d8bef9SDimitry Andric case LibFunc_flsll: 1169e8d8bef9SDimitry Andric case LibFunc_fmax: 1170e8d8bef9SDimitry Andric case LibFunc_fmaxf: 1171e8d8bef9SDimitry Andric case LibFunc_fmaxl: 1172e8d8bef9SDimitry Andric case LibFunc_fmin: 1173e8d8bef9SDimitry Andric case LibFunc_fminf: 1174e8d8bef9SDimitry Andric case LibFunc_fminl: 1175e8d8bef9SDimitry Andric case LibFunc_fmod: 1176e8d8bef9SDimitry Andric case LibFunc_fmodf: 1177e8d8bef9SDimitry Andric case LibFunc_fmodl: 1178e8d8bef9SDimitry Andric case LibFunc_isascii: 1179e8d8bef9SDimitry Andric case LibFunc_isdigit: 1180e8d8bef9SDimitry Andric case LibFunc_labs: 1181e8d8bef9SDimitry Andric case LibFunc_llabs: 1182e8d8bef9SDimitry Andric case LibFunc_log: 1183e8d8bef9SDimitry Andric case LibFunc_log10: 1184e8d8bef9SDimitry Andric case LibFunc_log10f: 1185e8d8bef9SDimitry Andric case LibFunc_log10l: 1186e8d8bef9SDimitry Andric case LibFunc_log1p: 1187e8d8bef9SDimitry Andric case LibFunc_log1pf: 1188e8d8bef9SDimitry Andric case LibFunc_log1pl: 1189e8d8bef9SDimitry Andric case LibFunc_log2: 1190e8d8bef9SDimitry Andric case LibFunc_log2f: 1191e8d8bef9SDimitry Andric case LibFunc_log2l: 1192e8d8bef9SDimitry Andric case LibFunc_logb: 1193e8d8bef9SDimitry Andric case LibFunc_logbf: 1194e8d8bef9SDimitry Andric case LibFunc_logbl: 1195e8d8bef9SDimitry Andric case LibFunc_logf: 1196e8d8bef9SDimitry Andric case LibFunc_logl: 1197e8d8bef9SDimitry Andric case LibFunc_nearbyint: 1198e8d8bef9SDimitry Andric case LibFunc_nearbyintf: 1199e8d8bef9SDimitry Andric case LibFunc_nearbyintl: 1200e8d8bef9SDimitry Andric case LibFunc_pow: 1201e8d8bef9SDimitry Andric case LibFunc_powf: 1202e8d8bef9SDimitry Andric case LibFunc_powl: 1203*0fca6ea1SDimitry Andric case LibFunc_remainder: 1204*0fca6ea1SDimitry Andric case LibFunc_remainderf: 1205*0fca6ea1SDimitry Andric case LibFunc_remainderl: 1206e8d8bef9SDimitry Andric case LibFunc_rint: 1207e8d8bef9SDimitry Andric case LibFunc_rintf: 1208e8d8bef9SDimitry Andric case LibFunc_rintl: 1209e8d8bef9SDimitry Andric case LibFunc_round: 1210e8d8bef9SDimitry Andric case LibFunc_roundf: 1211e8d8bef9SDimitry Andric case LibFunc_roundl: 1212e8d8bef9SDimitry Andric case LibFunc_sin: 1213e8d8bef9SDimitry Andric case LibFunc_sincospif_stret: 1214e8d8bef9SDimitry Andric case LibFunc_sinf: 1215e8d8bef9SDimitry Andric case LibFunc_sinh: 1216e8d8bef9SDimitry Andric case LibFunc_sinhf: 1217e8d8bef9SDimitry Andric case LibFunc_sinhl: 1218e8d8bef9SDimitry Andric case LibFunc_sinl: 1219e8d8bef9SDimitry Andric case LibFunc_sinpi: 1220e8d8bef9SDimitry Andric case LibFunc_sinpif: 1221e8d8bef9SDimitry Andric case LibFunc_sqrt: 1222e8d8bef9SDimitry Andric case LibFunc_sqrtf: 1223e8d8bef9SDimitry Andric case LibFunc_sqrtl: 1224e8d8bef9SDimitry Andric case LibFunc_tan: 1225e8d8bef9SDimitry Andric case LibFunc_tanf: 1226e8d8bef9SDimitry Andric case LibFunc_tanh: 1227e8d8bef9SDimitry Andric case LibFunc_tanhf: 1228e8d8bef9SDimitry Andric case LibFunc_tanhl: 1229e8d8bef9SDimitry Andric case LibFunc_tanl: 1230e8d8bef9SDimitry Andric case LibFunc_toascii: 1231e8d8bef9SDimitry Andric case LibFunc_trunc: 1232e8d8bef9SDimitry Andric case LibFunc_truncf: 1233e8d8bef9SDimitry Andric case LibFunc_truncl: 1234e8d8bef9SDimitry Andric Changed |= setDoesNotThrow(F); 1235e8d8bef9SDimitry Andric Changed |= setDoesNotFreeMemory(F); 123604eeddc0SDimitry Andric Changed |= setOnlyWritesMemory(F); 1237e8d8bef9SDimitry Andric Changed |= setWillReturn(F); 1238fcaf7f86SDimitry Andric break; 12390b57cec5SDimitry Andric default: 12400b57cec5SDimitry Andric // FIXME: It'd be really nice to cover all the library functions we're 12410b57cec5SDimitry Andric // aware of here. 1242fcaf7f86SDimitry Andric break; 12430b57cec5SDimitry Andric } 1244fcaf7f86SDimitry Andric // We have to do this step after AllocKind has been inferred on functions so 1245fcaf7f86SDimitry Andric // we can reliably identify free-like and realloc-like functions. 1246bdd1243dSDimitry Andric if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F)) 1247fcaf7f86SDimitry Andric Changed |= setDoesNotFreeMemory(F); 1248fcaf7f86SDimitry Andric return Changed; 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric 125181ad6265SDimitry Andric static void setArgExtAttr(Function &F, unsigned ArgNo, 125281ad6265SDimitry Andric const TargetLibraryInfo &TLI, bool Signed = true) { 125381ad6265SDimitry Andric Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed); 125481ad6265SDimitry Andric if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr)) 125581ad6265SDimitry Andric F.addParamAttr(ArgNo, ExtAttr); 125681ad6265SDimitry Andric } 125781ad6265SDimitry Andric 1258bdd1243dSDimitry Andric static void setRetExtAttr(Function &F, 1259bdd1243dSDimitry Andric const TargetLibraryInfo &TLI, bool Signed = true) { 1260bdd1243dSDimitry Andric Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed); 1261bdd1243dSDimitry Andric if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr)) 1262bdd1243dSDimitry Andric F.addRetAttr(ExtAttr); 1263bdd1243dSDimitry Andric } 1264bdd1243dSDimitry Andric 126581ad6265SDimitry Andric // Modeled after X86TargetLowering::markLibCallAttributes. 1266*0fca6ea1SDimitry Andric void llvm::markRegisterParameterAttributes(Function *F) { 126781ad6265SDimitry Andric if (!F->arg_size() || F->isVarArg()) 126881ad6265SDimitry Andric return; 126981ad6265SDimitry Andric 127081ad6265SDimitry Andric const CallingConv::ID CC = F->getCallingConv(); 127181ad6265SDimitry Andric if (CC != CallingConv::C && CC != CallingConv::X86_StdCall) 127281ad6265SDimitry Andric return; 127381ad6265SDimitry Andric 127481ad6265SDimitry Andric const Module *M = F->getParent(); 127581ad6265SDimitry Andric unsigned N = M->getNumberRegisterParameters(); 127681ad6265SDimitry Andric if (!N) 127781ad6265SDimitry Andric return; 127881ad6265SDimitry Andric 127981ad6265SDimitry Andric const DataLayout &DL = M->getDataLayout(); 128081ad6265SDimitry Andric 128181ad6265SDimitry Andric for (Argument &A : F->args()) { 128281ad6265SDimitry Andric Type *T = A.getType(); 128381ad6265SDimitry Andric if (!T->isIntOrPtrTy()) 128481ad6265SDimitry Andric continue; 128581ad6265SDimitry Andric 128681ad6265SDimitry Andric const TypeSize &TS = DL.getTypeAllocSize(T); 128781ad6265SDimitry Andric if (TS > 8) 128881ad6265SDimitry Andric continue; 128981ad6265SDimitry Andric 129081ad6265SDimitry Andric assert(TS <= 4 && "Need to account for parameters larger than word size"); 129181ad6265SDimitry Andric const unsigned NumRegs = TS > 4 ? 2 : 1; 129281ad6265SDimitry Andric if (N < NumRegs) 129381ad6265SDimitry Andric return; 129481ad6265SDimitry Andric 129581ad6265SDimitry Andric N -= NumRegs; 129681ad6265SDimitry Andric F->addParamAttr(A.getArgNo(), Attribute::InReg); 129781ad6265SDimitry Andric } 129881ad6265SDimitry Andric } 129981ad6265SDimitry Andric 130081ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, 130181ad6265SDimitry Andric LibFunc TheLibFunc, FunctionType *T, 130281ad6265SDimitry Andric AttributeList AttributeList) { 130381ad6265SDimitry Andric assert(TLI.has(TheLibFunc) && 130481ad6265SDimitry Andric "Creating call to non-existing library function."); 130581ad6265SDimitry Andric StringRef Name = TLI.getName(TheLibFunc); 130681ad6265SDimitry Andric FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList); 130781ad6265SDimitry Andric 130881ad6265SDimitry Andric // Make sure any mandatory argument attributes are added. 130981ad6265SDimitry Andric 131081ad6265SDimitry Andric // Any outgoing i32 argument should be handled with setArgExtAttr() which 131181ad6265SDimitry Andric // will add an extension attribute if the target ABI requires it. Adding 131281ad6265SDimitry Andric // argument extensions is typically done by the front end but when an 131381ad6265SDimitry Andric // optimizer is building a library call on its own it has to take care of 131481ad6265SDimitry Andric // this. Each such generated function must be handled here with sign or 131581ad6265SDimitry Andric // zero extensions as needed. F is retreived with cast<> because we demand 131681ad6265SDimitry Andric // of the caller to have called isLibFuncEmittable() first. 131781ad6265SDimitry Andric Function *F = cast<Function>(C.getCallee()); 131881ad6265SDimitry Andric assert(F->getFunctionType() == T && "Function type does not match."); 131981ad6265SDimitry Andric switch (TheLibFunc) { 132081ad6265SDimitry Andric case LibFunc_fputc: 132181ad6265SDimitry Andric case LibFunc_putchar: 132281ad6265SDimitry Andric setArgExtAttr(*F, 0, TLI); 132381ad6265SDimitry Andric break; 132481ad6265SDimitry Andric case LibFunc_ldexp: 132581ad6265SDimitry Andric case LibFunc_ldexpf: 132681ad6265SDimitry Andric case LibFunc_ldexpl: 132781ad6265SDimitry Andric case LibFunc_memchr: 132881ad6265SDimitry Andric case LibFunc_memrchr: 132981ad6265SDimitry Andric case LibFunc_strchr: 133081ad6265SDimitry Andric setArgExtAttr(*F, 1, TLI); 133181ad6265SDimitry Andric break; 133281ad6265SDimitry Andric case LibFunc_memccpy: 133381ad6265SDimitry Andric setArgExtAttr(*F, 2, TLI); 133481ad6265SDimitry Andric break; 133581ad6265SDimitry Andric 133681ad6265SDimitry Andric // These are functions that are known to not need any argument extension 133781ad6265SDimitry Andric // on any target: A size_t argument (which may be an i32 on some targets) 133881ad6265SDimitry Andric // should not trigger the assert below. 133981ad6265SDimitry Andric case LibFunc_bcmp: 1340bdd1243dSDimitry Andric setRetExtAttr(*F, TLI); 1341bdd1243dSDimitry Andric break; 134281ad6265SDimitry Andric case LibFunc_calloc: 134381ad6265SDimitry Andric case LibFunc_fwrite: 134481ad6265SDimitry Andric case LibFunc_malloc: 134581ad6265SDimitry Andric case LibFunc_memcmp: 134681ad6265SDimitry Andric case LibFunc_memcpy_chk: 134781ad6265SDimitry Andric case LibFunc_mempcpy: 134881ad6265SDimitry Andric case LibFunc_memset_pattern16: 134981ad6265SDimitry Andric case LibFunc_snprintf: 135081ad6265SDimitry Andric case LibFunc_stpncpy: 135181ad6265SDimitry Andric case LibFunc_strlcat: 135281ad6265SDimitry Andric case LibFunc_strlcpy: 135381ad6265SDimitry Andric case LibFunc_strncat: 135481ad6265SDimitry Andric case LibFunc_strncmp: 135581ad6265SDimitry Andric case LibFunc_strncpy: 135681ad6265SDimitry Andric case LibFunc_vsnprintf: 135781ad6265SDimitry Andric break; 135881ad6265SDimitry Andric 135981ad6265SDimitry Andric default: 136081ad6265SDimitry Andric #ifndef NDEBUG 136181ad6265SDimitry Andric for (unsigned i = 0; i < T->getNumParams(); i++) 136281ad6265SDimitry Andric assert(!isa<IntegerType>(T->getParamType(i)) && 136381ad6265SDimitry Andric "Unhandled integer argument."); 136481ad6265SDimitry Andric #endif 136581ad6265SDimitry Andric break; 136681ad6265SDimitry Andric } 136781ad6265SDimitry Andric 136881ad6265SDimitry Andric markRegisterParameterAttributes(F); 136981ad6265SDimitry Andric 137081ad6265SDimitry Andric return C; 137181ad6265SDimitry Andric } 137281ad6265SDimitry Andric 137381ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, 137481ad6265SDimitry Andric LibFunc TheLibFunc, FunctionType *T) { 137581ad6265SDimitry Andric return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList()); 137681ad6265SDimitry Andric } 137781ad6265SDimitry Andric 137881ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, 137981ad6265SDimitry Andric LibFunc TheLibFunc) { 138081ad6265SDimitry Andric StringRef FuncName = TLI->getName(TheLibFunc); 138181ad6265SDimitry Andric if (!TLI->has(TheLibFunc)) 138281ad6265SDimitry Andric return false; 138381ad6265SDimitry Andric 138481ad6265SDimitry Andric // Check if the Module already has a GlobalValue with the same name, in 138581ad6265SDimitry Andric // which case it must be a Function with the expected type. 138681ad6265SDimitry Andric if (GlobalValue *GV = M->getNamedValue(FuncName)) { 138781ad6265SDimitry Andric if (auto *F = dyn_cast<Function>(GV)) 138881ad6265SDimitry Andric return TLI->isValidProtoForLibFunc(*F->getFunctionType(), TheLibFunc, *M); 138981ad6265SDimitry Andric return false; 139081ad6265SDimitry Andric } 139181ad6265SDimitry Andric 139281ad6265SDimitry Andric return true; 139381ad6265SDimitry Andric } 139481ad6265SDimitry Andric 139581ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI, 139681ad6265SDimitry Andric StringRef Name) { 139781ad6265SDimitry Andric LibFunc TheLibFunc; 139881ad6265SDimitry Andric return TLI->getLibFunc(Name, TheLibFunc) && 139981ad6265SDimitry Andric isLibFuncEmittable(M, TLI, TheLibFunc); 140081ad6265SDimitry Andric } 140181ad6265SDimitry Andric 140281ad6265SDimitry Andric bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty, 14038bcb0991SDimitry Andric LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) { 14040b57cec5SDimitry Andric switch (Ty->getTypeID()) { 14050b57cec5SDimitry Andric case Type::HalfTyID: 14060b57cec5SDimitry Andric return false; 14070b57cec5SDimitry Andric case Type::FloatTyID: 140881ad6265SDimitry Andric return isLibFuncEmittable(M, TLI, FloatFn); 14090b57cec5SDimitry Andric case Type::DoubleTyID: 141081ad6265SDimitry Andric return isLibFuncEmittable(M, TLI, DoubleFn); 14110b57cec5SDimitry Andric default: 141281ad6265SDimitry Andric return isLibFuncEmittable(M, TLI, LongDoubleFn); 14130b57cec5SDimitry Andric } 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 141681ad6265SDimitry Andric StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI, 141781ad6265SDimitry Andric Type *Ty, LibFunc DoubleFn, LibFunc FloatFn, 141881ad6265SDimitry Andric LibFunc LongDoubleFn, LibFunc &TheLibFunc) { 141981ad6265SDimitry Andric assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) && 14200b57cec5SDimitry Andric "Cannot get name for unavailable function!"); 14210b57cec5SDimitry Andric 14220b57cec5SDimitry Andric switch (Ty->getTypeID()) { 14230b57cec5SDimitry Andric case Type::HalfTyID: 14240b57cec5SDimitry Andric llvm_unreachable("No name for HalfTy!"); 14250b57cec5SDimitry Andric case Type::FloatTyID: 142681ad6265SDimitry Andric TheLibFunc = FloatFn; 14270b57cec5SDimitry Andric return TLI->getName(FloatFn); 14280b57cec5SDimitry Andric case Type::DoubleTyID: 142981ad6265SDimitry Andric TheLibFunc = DoubleFn; 14300b57cec5SDimitry Andric return TLI->getName(DoubleFn); 14310b57cec5SDimitry Andric default: 143281ad6265SDimitry Andric TheLibFunc = LongDoubleFn; 14330b57cec5SDimitry Andric return TLI->getName(LongDoubleFn); 14340b57cec5SDimitry Andric } 14350b57cec5SDimitry Andric } 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andric //- Emit LibCalls ------------------------------------------------------------// 14380b57cec5SDimitry Andric 1439bdd1243dSDimitry Andric static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) { 1440bdd1243dSDimitry Andric return B.getIntNTy(TLI->getIntSize()); 1441bdd1243dSDimitry Andric } 1442bdd1243dSDimitry Andric 1443bdd1243dSDimitry Andric static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) { 1444bdd1243dSDimitry Andric const Module *M = B.GetInsertBlock()->getModule(); 1445bdd1243dSDimitry Andric return B.getIntNTy(TLI->getSizeTSize(*M)); 1446bdd1243dSDimitry Andric } 1447bdd1243dSDimitry Andric 14480b57cec5SDimitry Andric static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, 14490b57cec5SDimitry Andric ArrayRef<Type *> ParamTypes, 14505ffd83dbSDimitry Andric ArrayRef<Value *> Operands, IRBuilderBase &B, 14510b57cec5SDimitry Andric const TargetLibraryInfo *TLI, 14520b57cec5SDimitry Andric bool IsVaArgs = false) { 145381ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 145481ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, TheLibFunc)) 14550b57cec5SDimitry Andric return nullptr; 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric StringRef FuncName = TLI->getName(TheLibFunc); 14580b57cec5SDimitry Andric FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs); 145981ad6265SDimitry Andric FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType); 146081ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI); 14610b57cec5SDimitry Andric CallInst *CI = B.CreateCall(Callee, Operands, FuncName); 14620b57cec5SDimitry Andric if (const Function *F = 14630b57cec5SDimitry Andric dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 14640b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 14650b57cec5SDimitry Andric return CI; 14660b57cec5SDimitry Andric } 14670b57cec5SDimitry Andric 14685ffd83dbSDimitry Andric Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, 14690b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 14705f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1471bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 14725f757f3fSDimitry Andric return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI); 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric 14755ffd83dbSDimitry Andric Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B, 14768bcb0991SDimitry Andric const TargetLibraryInfo *TLI) { 14775f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 14785f757f3fSDimitry Andric return emitLibCall(LibFunc_strdup, CharPtrTy, CharPtrTy, Ptr, B, TLI); 14798bcb0991SDimitry Andric } 14808bcb0991SDimitry Andric 14815ffd83dbSDimitry Andric Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B, 14820b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 14835f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1484bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 14855f757f3fSDimitry Andric return emitLibCall(LibFunc_strchr, CharPtrTy, {CharPtrTy, IntTy}, 14865f757f3fSDimitry Andric {Ptr, ConstantInt::get(IntTy, C)}, B, TLI); 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric 14895ffd83dbSDimitry Andric Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, 14900b57cec5SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 14915f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1492bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1493bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 14940b57cec5SDimitry Andric return emitLibCall( 1495bdd1243dSDimitry Andric LibFunc_strncmp, IntTy, 14965f757f3fSDimitry Andric {CharPtrTy, CharPtrTy, SizeTTy}, 14975f757f3fSDimitry Andric {Ptr1, Ptr2, Len}, B, TLI); 14980b57cec5SDimitry Andric } 14990b57cec5SDimitry Andric 15005ffd83dbSDimitry Andric Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B, 15010b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 15025f757f3fSDimitry Andric Type *CharPtrTy = Dst->getType(); 15035f757f3fSDimitry Andric return emitLibCall(LibFunc_strcpy, CharPtrTy, {CharPtrTy, CharPtrTy}, 15045f757f3fSDimitry Andric {Dst, Src}, B, TLI); 15050b57cec5SDimitry Andric } 15060b57cec5SDimitry Andric 15075ffd83dbSDimitry Andric Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B, 15080b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 15095f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 15105f757f3fSDimitry Andric return emitLibCall(LibFunc_stpcpy, CharPtrTy, {CharPtrTy, CharPtrTy}, 15115f757f3fSDimitry Andric {Dst, Src}, B, TLI); 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric 15145ffd83dbSDimitry Andric Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, 15150b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 15165f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1517bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 15185f757f3fSDimitry Andric return emitLibCall(LibFunc_strncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy}, 15195f757f3fSDimitry Andric {Dst, Src, Len}, B, TLI); 15200b57cec5SDimitry Andric } 15210b57cec5SDimitry Andric 15225ffd83dbSDimitry Andric Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, 15230b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 15245f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1525bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 15265f757f3fSDimitry Andric return emitLibCall(LibFunc_stpncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy}, 15275f757f3fSDimitry Andric {Dst, Src, Len}, B, TLI); 15280b57cec5SDimitry Andric } 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, 15315ffd83dbSDimitry Andric IRBuilderBase &B, const DataLayout &DL, 15320b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 153381ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 153481ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_memcpy_chk)) 15350b57cec5SDimitry Andric return nullptr; 15360b57cec5SDimitry Andric 15370b57cec5SDimitry Andric AttributeList AS; 15380b57cec5SDimitry Andric AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex, 15390b57cec5SDimitry Andric Attribute::NoUnwind); 15405f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1541bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 154281ad6265SDimitry Andric FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk, 15435f757f3fSDimitry Andric AttributeList::get(M->getContext(), AS), VoidPtrTy, 15445f757f3fSDimitry Andric VoidPtrTy, VoidPtrTy, SizeTTy, SizeTTy); 15450b57cec5SDimitry Andric CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); 15460b57cec5SDimitry Andric if (const Function *F = 15470b57cec5SDimitry Andric dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts())) 15480b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 15490b57cec5SDimitry Andric return CI; 15500b57cec5SDimitry Andric } 15510b57cec5SDimitry Andric 1552e8d8bef9SDimitry Andric Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B, 1553e8d8bef9SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 15545f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1555bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 15565f757f3fSDimitry Andric return emitLibCall(LibFunc_mempcpy, VoidPtrTy, 15575f757f3fSDimitry Andric {VoidPtrTy, VoidPtrTy, SizeTTy}, 1558e8d8bef9SDimitry Andric {Dst, Src, Len}, B, TLI); 1559e8d8bef9SDimitry Andric } 1560e8d8bef9SDimitry Andric 15615ffd83dbSDimitry Andric Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, 15620b57cec5SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 15635f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1564bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1565bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 15665f757f3fSDimitry Andric return emitLibCall(LibFunc_memchr, VoidPtrTy, 15675f757f3fSDimitry Andric {VoidPtrTy, IntTy, SizeTTy}, 15685f757f3fSDimitry Andric {Ptr, Val, Len}, B, TLI); 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 157181ad6265SDimitry Andric Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B, 157281ad6265SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 15735f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1574bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1575bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 15765f757f3fSDimitry Andric return emitLibCall(LibFunc_memrchr, VoidPtrTy, 15775f757f3fSDimitry Andric {VoidPtrTy, IntTy, SizeTTy}, 15785f757f3fSDimitry Andric {Ptr, Val, Len}, B, TLI); 157981ad6265SDimitry Andric } 158081ad6265SDimitry Andric 15815ffd83dbSDimitry Andric Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, 15820b57cec5SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 15835f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1584bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1585bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 1586bdd1243dSDimitry Andric return emitLibCall(LibFunc_memcmp, IntTy, 15875f757f3fSDimitry Andric {VoidPtrTy, VoidPtrTy, SizeTTy}, 15885f757f3fSDimitry Andric {Ptr1, Ptr2, Len}, B, TLI); 15890b57cec5SDimitry Andric } 15900b57cec5SDimitry Andric 15915ffd83dbSDimitry Andric Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B, 15920b57cec5SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 15935f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1594bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1595bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 1596bdd1243dSDimitry Andric return emitLibCall(LibFunc_bcmp, IntTy, 15975f757f3fSDimitry Andric {VoidPtrTy, VoidPtrTy, SizeTTy}, 15985f757f3fSDimitry Andric {Ptr1, Ptr2, Len}, B, TLI); 15990b57cec5SDimitry Andric } 16000b57cec5SDimitry Andric 16010b57cec5SDimitry Andric Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, 16025ffd83dbSDimitry Andric IRBuilderBase &B, const TargetLibraryInfo *TLI) { 16035f757f3fSDimitry Andric Type *VoidPtrTy = B.getPtrTy(); 1604bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1605bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 16065f757f3fSDimitry Andric return emitLibCall(LibFunc_memccpy, VoidPtrTy, 16075f757f3fSDimitry Andric {VoidPtrTy, VoidPtrTy, IntTy, SizeTTy}, 16080b57cec5SDimitry Andric {Ptr1, Ptr2, Val, Len}, B, TLI); 16090b57cec5SDimitry Andric } 16100b57cec5SDimitry Andric 16110b57cec5SDimitry Andric Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, 16125ffd83dbSDimitry Andric ArrayRef<Value *> VariadicArgs, IRBuilderBase &B, 16130b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16145f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1615bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1616bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 16175f757f3fSDimitry Andric SmallVector<Value *, 8> Args{Dest, Size, Fmt}; 1618e8d8bef9SDimitry Andric llvm::append_range(Args, VariadicArgs); 1619bdd1243dSDimitry Andric return emitLibCall(LibFunc_snprintf, IntTy, 16205f757f3fSDimitry Andric {CharPtrTy, SizeTTy, CharPtrTy}, 16210b57cec5SDimitry Andric Args, B, TLI, /*IsVaArgs=*/true); 16220b57cec5SDimitry Andric } 16230b57cec5SDimitry Andric 16240b57cec5SDimitry Andric Value *llvm::emitSPrintf(Value *Dest, Value *Fmt, 16255ffd83dbSDimitry Andric ArrayRef<Value *> VariadicArgs, IRBuilderBase &B, 16260b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16275f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1628bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 16295f757f3fSDimitry Andric SmallVector<Value *, 8> Args{Dest, Fmt}; 1630e8d8bef9SDimitry Andric llvm::append_range(Args, VariadicArgs); 1631bdd1243dSDimitry Andric return emitLibCall(LibFunc_sprintf, IntTy, 16325f757f3fSDimitry Andric {CharPtrTy, CharPtrTy}, Args, B, TLI, 16330b57cec5SDimitry Andric /*IsVaArgs=*/true); 16340b57cec5SDimitry Andric } 16350b57cec5SDimitry Andric 16365ffd83dbSDimitry Andric Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B, 16370b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16385f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 16395f757f3fSDimitry Andric return emitLibCall(LibFunc_strcat, CharPtrTy, 16405f757f3fSDimitry Andric {CharPtrTy, CharPtrTy}, 16415f757f3fSDimitry Andric {Dest, Src}, B, TLI); 16420b57cec5SDimitry Andric } 16430b57cec5SDimitry Andric 16445ffd83dbSDimitry Andric Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, 16450b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16465f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1647bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 1648bdd1243dSDimitry Andric return emitLibCall(LibFunc_strlcpy, SizeTTy, 16495f757f3fSDimitry Andric {CharPtrTy, CharPtrTy, SizeTTy}, 16505f757f3fSDimitry Andric {Dest, Src, Size}, B, TLI); 16510b57cec5SDimitry Andric } 16520b57cec5SDimitry Andric 16535ffd83dbSDimitry Andric Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, 16540b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16555f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1656bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 1657bdd1243dSDimitry Andric return emitLibCall(LibFunc_strlcat, SizeTTy, 16585f757f3fSDimitry Andric {CharPtrTy, CharPtrTy, SizeTTy}, 16595f757f3fSDimitry Andric {Dest, Src, Size}, B, TLI); 16600b57cec5SDimitry Andric } 16610b57cec5SDimitry Andric 16625ffd83dbSDimitry Andric Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B, 16630b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 16645f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1665bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 16665f757f3fSDimitry Andric return emitLibCall(LibFunc_strncat, CharPtrTy, 16675f757f3fSDimitry Andric {CharPtrTy, CharPtrTy, SizeTTy}, 16685f757f3fSDimitry Andric {Dest, Src, Size}, B, TLI); 16690b57cec5SDimitry Andric } 16700b57cec5SDimitry Andric 16710b57cec5SDimitry Andric Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, 16725ffd83dbSDimitry Andric IRBuilderBase &B, const TargetLibraryInfo *TLI) { 16735f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1674bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1675bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 16760b57cec5SDimitry Andric return emitLibCall( 1677bdd1243dSDimitry Andric LibFunc_vsnprintf, IntTy, 16785f757f3fSDimitry Andric {CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()}, 16795f757f3fSDimitry Andric {Dest, Size, Fmt, VAList}, B, TLI); 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, 16835ffd83dbSDimitry Andric IRBuilderBase &B, const TargetLibraryInfo *TLI) { 16845f757f3fSDimitry Andric Type *CharPtrTy = B.getPtrTy(); 1685bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 1686bdd1243dSDimitry Andric return emitLibCall(LibFunc_vsprintf, IntTy, 16875f757f3fSDimitry Andric {CharPtrTy, CharPtrTy, VAList->getType()}, 16885f757f3fSDimitry Andric {Dest, Fmt, VAList}, B, TLI); 16890b57cec5SDimitry Andric } 16900b57cec5SDimitry Andric 16910b57cec5SDimitry Andric /// Append a suffix to the function name according to the type of 'Op'. 16920b57cec5SDimitry Andric static void appendTypeSuffix(Value *Op, StringRef &Name, 16930b57cec5SDimitry Andric SmallString<20> &NameBuffer) { 16940b57cec5SDimitry Andric if (!Op->getType()->isDoubleTy()) { 16950b57cec5SDimitry Andric NameBuffer += Name; 16960b57cec5SDimitry Andric 16970b57cec5SDimitry Andric if (Op->getType()->isFloatTy()) 16980b57cec5SDimitry Andric NameBuffer += 'f'; 16990b57cec5SDimitry Andric else 17000b57cec5SDimitry Andric NameBuffer += 'l'; 17010b57cec5SDimitry Andric 17020b57cec5SDimitry Andric Name = NameBuffer; 17030b57cec5SDimitry Andric } 17040b57cec5SDimitry Andric } 17050b57cec5SDimitry Andric 170681ad6265SDimitry Andric static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc, 170781ad6265SDimitry Andric StringRef Name, IRBuilderBase &B, 170881ad6265SDimitry Andric const AttributeList &Attrs, 170981ad6265SDimitry Andric const TargetLibraryInfo *TLI) { 17100b57cec5SDimitry Andric assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall"); 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 171381ad6265SDimitry Andric FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(), 171481ad6265SDimitry Andric Op->getType()); 17150b57cec5SDimitry Andric CallInst *CI = B.CreateCall(Callee, Op, Name); 17160b57cec5SDimitry Andric 17170b57cec5SDimitry Andric // The incoming attribute set may have come from a speculatable intrinsic, but 17180b57cec5SDimitry Andric // is being replaced with a library call which is not allowed to be 17190b57cec5SDimitry Andric // speculatable. 1720349cc55cSDimitry Andric CI->setAttributes( 1721349cc55cSDimitry Andric Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable)); 17220b57cec5SDimitry Andric if (const Function *F = 17230b57cec5SDimitry Andric dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 17240b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric return CI; 17270b57cec5SDimitry Andric } 17280b57cec5SDimitry Andric 172981ad6265SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, 173081ad6265SDimitry Andric StringRef Name, IRBuilderBase &B, 17310b57cec5SDimitry Andric const AttributeList &Attrs) { 17320b57cec5SDimitry Andric SmallString<20> NameBuffer; 17330b57cec5SDimitry Andric appendTypeSuffix(Op, Name, NameBuffer); 17340b57cec5SDimitry Andric 173581ad6265SDimitry Andric LibFunc TheLibFunc; 173681ad6265SDimitry Andric TLI->getLibFunc(Name, TheLibFunc); 173781ad6265SDimitry Andric 173881ad6265SDimitry Andric return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI); 17390b57cec5SDimitry Andric } 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, 17420b57cec5SDimitry Andric LibFunc DoubleFn, LibFunc FloatFn, 17435ffd83dbSDimitry Andric LibFunc LongDoubleFn, IRBuilderBase &B, 17440b57cec5SDimitry Andric const AttributeList &Attrs) { 17450b57cec5SDimitry Andric // Get the name of the function according to TLI. 174681ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 174781ad6265SDimitry Andric LibFunc TheLibFunc; 174881ad6265SDimitry Andric StringRef Name = getFloatFn(M, TLI, Op->getType(), DoubleFn, FloatFn, 174981ad6265SDimitry Andric LongDoubleFn, TheLibFunc); 17500b57cec5SDimitry Andric 175181ad6265SDimitry Andric return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI); 17520b57cec5SDimitry Andric } 17530b57cec5SDimitry Andric 17548bcb0991SDimitry Andric static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2, 175581ad6265SDimitry Andric LibFunc TheLibFunc, 17565ffd83dbSDimitry Andric StringRef Name, IRBuilderBase &B, 1757e8d8bef9SDimitry Andric const AttributeList &Attrs, 175881ad6265SDimitry Andric const TargetLibraryInfo *TLI) { 17598bcb0991SDimitry Andric assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); 17608bcb0991SDimitry Andric 17618bcb0991SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 176281ad6265SDimitry Andric FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(), 17638bcb0991SDimitry Andric Op1->getType(), Op2->getType()); 176481ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, Name, *TLI); 17658bcb0991SDimitry Andric CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name); 17668bcb0991SDimitry Andric 17678bcb0991SDimitry Andric // The incoming attribute set may have come from a speculatable intrinsic, but 17688bcb0991SDimitry Andric // is being replaced with a library call which is not allowed to be 17698bcb0991SDimitry Andric // speculatable. 1770349cc55cSDimitry Andric CI->setAttributes( 1771349cc55cSDimitry Andric Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable)); 17728bcb0991SDimitry Andric if (const Function *F = 17738bcb0991SDimitry Andric dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 17748bcb0991SDimitry Andric CI->setCallingConv(F->getCallingConv()); 17758bcb0991SDimitry Andric 17768bcb0991SDimitry Andric return CI; 17778bcb0991SDimitry Andric } 17788bcb0991SDimitry Andric 177981ad6265SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, 178081ad6265SDimitry Andric const TargetLibraryInfo *TLI, 178181ad6265SDimitry Andric StringRef Name, IRBuilderBase &B, 17825ffd83dbSDimitry Andric const AttributeList &Attrs) { 17830b57cec5SDimitry Andric assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andric SmallString<20> NameBuffer; 17860b57cec5SDimitry Andric appendTypeSuffix(Op1, Name, NameBuffer); 17870b57cec5SDimitry Andric 178881ad6265SDimitry Andric LibFunc TheLibFunc; 178981ad6265SDimitry Andric TLI->getLibFunc(Name, TheLibFunc); 179081ad6265SDimitry Andric 179181ad6265SDimitry Andric return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI); 17928bcb0991SDimitry Andric } 17930b57cec5SDimitry Andric 17948bcb0991SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, 17958bcb0991SDimitry Andric const TargetLibraryInfo *TLI, 17968bcb0991SDimitry Andric LibFunc DoubleFn, LibFunc FloatFn, 17975ffd83dbSDimitry Andric LibFunc LongDoubleFn, IRBuilderBase &B, 17988bcb0991SDimitry Andric const AttributeList &Attrs) { 17998bcb0991SDimitry Andric // Get the name of the function according to TLI. 180081ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 180181ad6265SDimitry Andric LibFunc TheLibFunc; 180281ad6265SDimitry Andric StringRef Name = getFloatFn(M, TLI, Op1->getType(), DoubleFn, FloatFn, 180381ad6265SDimitry Andric LongDoubleFn, TheLibFunc); 18048bcb0991SDimitry Andric 180581ad6265SDimitry Andric return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI); 18060b57cec5SDimitry Andric } 18070b57cec5SDimitry Andric 1808bdd1243dSDimitry Andric // Emit a call to putchar(int) with Char as the argument. Char must have 1809bdd1243dSDimitry Andric // the same precision as int, which need not be 32 bits. 18105ffd83dbSDimitry Andric Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B, 18110b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 181281ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 181381ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_putchar)) 18140b57cec5SDimitry Andric return nullptr; 18150b57cec5SDimitry Andric 1816bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 18170b57cec5SDimitry Andric StringRef PutCharName = TLI->getName(LibFunc_putchar); 181881ad6265SDimitry Andric FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar, 1819bdd1243dSDimitry Andric IntTy, IntTy); 182081ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI); 1821bdd1243dSDimitry Andric CallInst *CI = B.CreateCall(PutChar, Char, PutCharName); 18220b57cec5SDimitry Andric 18230b57cec5SDimitry Andric if (const Function *F = 18240b57cec5SDimitry Andric dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts())) 18250b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 18260b57cec5SDimitry Andric return CI; 18270b57cec5SDimitry Andric } 18280b57cec5SDimitry Andric 18295ffd83dbSDimitry Andric Value *llvm::emitPutS(Value *Str, IRBuilderBase &B, 18300b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 183181ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 183281ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_puts)) 18330b57cec5SDimitry Andric return nullptr; 18340b57cec5SDimitry Andric 1835bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 18360b57cec5SDimitry Andric StringRef PutsName = TLI->getName(LibFunc_puts); 1837bdd1243dSDimitry Andric FunctionCallee PutS = getOrInsertLibFunc(M, *TLI, LibFunc_puts, IntTy, 18385f757f3fSDimitry Andric B.getPtrTy()); 183981ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI); 18405f757f3fSDimitry Andric CallInst *CI = B.CreateCall(PutS, Str, PutsName); 18410b57cec5SDimitry Andric if (const Function *F = 18420b57cec5SDimitry Andric dyn_cast<Function>(PutS.getCallee()->stripPointerCasts())) 18430b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 18440b57cec5SDimitry Andric return CI; 18450b57cec5SDimitry Andric } 18460b57cec5SDimitry Andric 18475ffd83dbSDimitry Andric Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B, 18480b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 184981ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 185081ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_fputc)) 18510b57cec5SDimitry Andric return nullptr; 18520b57cec5SDimitry Andric 1853bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 18540b57cec5SDimitry Andric StringRef FPutcName = TLI->getName(LibFunc_fputc); 1855bdd1243dSDimitry Andric FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, IntTy, 1856bdd1243dSDimitry Andric IntTy, File->getType()); 18570b57cec5SDimitry Andric if (File->getType()->isPointerTy()) 185881ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI); 18590b57cec5SDimitry Andric CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); 18600b57cec5SDimitry Andric 18610b57cec5SDimitry Andric if (const Function *Fn = 18620b57cec5SDimitry Andric dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 18630b57cec5SDimitry Andric CI->setCallingConv(Fn->getCallingConv()); 18640b57cec5SDimitry Andric return CI; 18650b57cec5SDimitry Andric } 18660b57cec5SDimitry Andric 18675ffd83dbSDimitry Andric Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B, 18680b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 186981ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 187081ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_fputs)) 18710b57cec5SDimitry Andric return nullptr; 18720b57cec5SDimitry Andric 1873bdd1243dSDimitry Andric Type *IntTy = getIntTy(B, TLI); 18740b57cec5SDimitry Andric StringRef FPutsName = TLI->getName(LibFunc_fputs); 1875bdd1243dSDimitry Andric FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, IntTy, 18765f757f3fSDimitry Andric B.getPtrTy(), File->getType()); 18770b57cec5SDimitry Andric if (File->getType()->isPointerTy()) 187881ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI); 18795f757f3fSDimitry Andric CallInst *CI = B.CreateCall(F, {Str, File}, FPutsName); 18800b57cec5SDimitry Andric 18810b57cec5SDimitry Andric if (const Function *Fn = 18820b57cec5SDimitry Andric dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 18830b57cec5SDimitry Andric CI->setCallingConv(Fn->getCallingConv()); 18840b57cec5SDimitry Andric return CI; 18850b57cec5SDimitry Andric } 18860b57cec5SDimitry Andric 18875ffd83dbSDimitry Andric Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B, 18880b57cec5SDimitry Andric const DataLayout &DL, const TargetLibraryInfo *TLI) { 188981ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 189081ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_fwrite)) 18910b57cec5SDimitry Andric return nullptr; 18920b57cec5SDimitry Andric 1893bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 18940b57cec5SDimitry Andric StringRef FWriteName = TLI->getName(LibFunc_fwrite); 189581ad6265SDimitry Andric FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fwrite, 18965f757f3fSDimitry Andric SizeTTy, B.getPtrTy(), SizeTTy, 1897bdd1243dSDimitry Andric SizeTTy, File->getType()); 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric if (File->getType()->isPointerTy()) 190081ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI); 19010b57cec5SDimitry Andric CallInst *CI = 19025f757f3fSDimitry Andric B.CreateCall(F, {Ptr, Size, 1903bdd1243dSDimitry Andric ConstantInt::get(SizeTTy, 1), File}); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric if (const Function *Fn = 19060b57cec5SDimitry Andric dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 19070b57cec5SDimitry Andric CI->setCallingConv(Fn->getCallingConv()); 19080b57cec5SDimitry Andric return CI; 19090b57cec5SDimitry Andric } 19100b57cec5SDimitry Andric 19115ffd83dbSDimitry Andric Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL, 19120b57cec5SDimitry Andric const TargetLibraryInfo *TLI) { 191381ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 191481ad6265SDimitry Andric if (!isLibFuncEmittable(M, TLI, LibFunc_malloc)) 19150b57cec5SDimitry Andric return nullptr; 19160b57cec5SDimitry Andric 19170b57cec5SDimitry Andric StringRef MallocName = TLI->getName(LibFunc_malloc); 1918bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, TLI); 191981ad6265SDimitry Andric FunctionCallee Malloc = getOrInsertLibFunc(M, *TLI, LibFunc_malloc, 19205f757f3fSDimitry Andric B.getPtrTy(), SizeTTy); 192181ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI); 19220b57cec5SDimitry Andric CallInst *CI = B.CreateCall(Malloc, Num, MallocName); 19230b57cec5SDimitry Andric 19240b57cec5SDimitry Andric if (const Function *F = 19250b57cec5SDimitry Andric dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts())) 19260b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 19270b57cec5SDimitry Andric 19280b57cec5SDimitry Andric return CI; 19290b57cec5SDimitry Andric } 19300b57cec5SDimitry Andric 1931349cc55cSDimitry Andric Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B, 1932349cc55cSDimitry Andric const TargetLibraryInfo &TLI) { 193381ad6265SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 193481ad6265SDimitry Andric if (!isLibFuncEmittable(M, &TLI, LibFunc_calloc)) 19350b57cec5SDimitry Andric return nullptr; 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric StringRef CallocName = TLI.getName(LibFunc_calloc); 1938bdd1243dSDimitry Andric Type *SizeTTy = getSizeTTy(B, &TLI); 193981ad6265SDimitry Andric FunctionCallee Calloc = getOrInsertLibFunc(M, TLI, LibFunc_calloc, 19405f757f3fSDimitry Andric B.getPtrTy(), SizeTTy, SizeTTy); 194181ad6265SDimitry Andric inferNonMandatoryLibFuncAttrs(M, CallocName, TLI); 19420b57cec5SDimitry Andric CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName); 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric if (const auto *F = 19450b57cec5SDimitry Andric dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts())) 19460b57cec5SDimitry Andric CI->setCallingConv(F->getCallingConv()); 19470b57cec5SDimitry Andric 19480b57cec5SDimitry Andric return CI; 19490b57cec5SDimitry Andric } 195006c3fb27SDimitry Andric 195106c3fb27SDimitry Andric Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B, 195206c3fb27SDimitry Andric const TargetLibraryInfo *TLI, LibFunc NewFunc, 195306c3fb27SDimitry Andric uint8_t HotCold) { 195406c3fb27SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 195506c3fb27SDimitry Andric if (!isLibFuncEmittable(M, TLI, NewFunc)) 195606c3fb27SDimitry Andric return nullptr; 195706c3fb27SDimitry Andric 195806c3fb27SDimitry Andric StringRef Name = TLI->getName(NewFunc); 19595f757f3fSDimitry Andric FunctionCallee Func = M->getOrInsertFunction(Name, B.getPtrTy(), 196006c3fb27SDimitry Andric Num->getType(), B.getInt8Ty()); 196106c3fb27SDimitry Andric inferNonMandatoryLibFuncAttrs(M, Name, *TLI); 196206c3fb27SDimitry Andric CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, Name); 196306c3fb27SDimitry Andric 196406c3fb27SDimitry Andric if (const Function *F = 196506c3fb27SDimitry Andric dyn_cast<Function>(Func.getCallee()->stripPointerCasts())) 196606c3fb27SDimitry Andric CI->setCallingConv(F->getCallingConv()); 196706c3fb27SDimitry Andric 196806c3fb27SDimitry Andric return CI; 196906c3fb27SDimitry Andric } 197006c3fb27SDimitry Andric 197106c3fb27SDimitry Andric Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B, 197206c3fb27SDimitry Andric const TargetLibraryInfo *TLI, 197306c3fb27SDimitry Andric LibFunc NewFunc, uint8_t HotCold) { 197406c3fb27SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 197506c3fb27SDimitry Andric if (!isLibFuncEmittable(M, TLI, NewFunc)) 197606c3fb27SDimitry Andric return nullptr; 197706c3fb27SDimitry Andric 197806c3fb27SDimitry Andric StringRef Name = TLI->getName(NewFunc); 197906c3fb27SDimitry Andric FunctionCallee Func = 19805f757f3fSDimitry Andric M->getOrInsertFunction(Name, B.getPtrTy(), Num->getType(), 198106c3fb27SDimitry Andric NoThrow->getType(), B.getInt8Ty()); 198206c3fb27SDimitry Andric inferNonMandatoryLibFuncAttrs(M, Name, *TLI); 198306c3fb27SDimitry Andric CallInst *CI = B.CreateCall(Func, {Num, NoThrow, B.getInt8(HotCold)}, Name); 198406c3fb27SDimitry Andric 198506c3fb27SDimitry Andric if (const Function *F = 198606c3fb27SDimitry Andric dyn_cast<Function>(Func.getCallee()->stripPointerCasts())) 198706c3fb27SDimitry Andric CI->setCallingConv(F->getCallingConv()); 198806c3fb27SDimitry Andric 198906c3fb27SDimitry Andric return CI; 199006c3fb27SDimitry Andric } 199106c3fb27SDimitry Andric 199206c3fb27SDimitry Andric Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B, 199306c3fb27SDimitry Andric const TargetLibraryInfo *TLI, 199406c3fb27SDimitry Andric LibFunc NewFunc, uint8_t HotCold) { 199506c3fb27SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 199606c3fb27SDimitry Andric if (!isLibFuncEmittable(M, TLI, NewFunc)) 199706c3fb27SDimitry Andric return nullptr; 199806c3fb27SDimitry Andric 199906c3fb27SDimitry Andric StringRef Name = TLI->getName(NewFunc); 200006c3fb27SDimitry Andric FunctionCallee Func = M->getOrInsertFunction( 20015f757f3fSDimitry Andric Name, B.getPtrTy(), Num->getType(), Align->getType(), B.getInt8Ty()); 200206c3fb27SDimitry Andric inferNonMandatoryLibFuncAttrs(M, Name, *TLI); 200306c3fb27SDimitry Andric CallInst *CI = B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, Name); 200406c3fb27SDimitry Andric 200506c3fb27SDimitry Andric if (const Function *F = 200606c3fb27SDimitry Andric dyn_cast<Function>(Func.getCallee()->stripPointerCasts())) 200706c3fb27SDimitry Andric CI->setCallingConv(F->getCallingConv()); 200806c3fb27SDimitry Andric 200906c3fb27SDimitry Andric return CI; 201006c3fb27SDimitry Andric } 201106c3fb27SDimitry Andric 201206c3fb27SDimitry Andric Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align, 201306c3fb27SDimitry Andric Value *NoThrow, IRBuilderBase &B, 201406c3fb27SDimitry Andric const TargetLibraryInfo *TLI, 201506c3fb27SDimitry Andric LibFunc NewFunc, uint8_t HotCold) { 201606c3fb27SDimitry Andric Module *M = B.GetInsertBlock()->getModule(); 201706c3fb27SDimitry Andric if (!isLibFuncEmittable(M, TLI, NewFunc)) 201806c3fb27SDimitry Andric return nullptr; 201906c3fb27SDimitry Andric 202006c3fb27SDimitry Andric StringRef Name = TLI->getName(NewFunc); 202106c3fb27SDimitry Andric FunctionCallee Func = M->getOrInsertFunction( 20225f757f3fSDimitry Andric Name, B.getPtrTy(), Num->getType(), Align->getType(), 202306c3fb27SDimitry Andric NoThrow->getType(), B.getInt8Ty()); 202406c3fb27SDimitry Andric inferNonMandatoryLibFuncAttrs(M, Name, *TLI); 202506c3fb27SDimitry Andric CallInst *CI = 202606c3fb27SDimitry Andric B.CreateCall(Func, {Num, Align, NoThrow, B.getInt8(HotCold)}, Name); 202706c3fb27SDimitry Andric 202806c3fb27SDimitry Andric if (const Function *F = 202906c3fb27SDimitry Andric dyn_cast<Function>(Func.getCallee()->stripPointerCasts())) 203006c3fb27SDimitry Andric CI->setCallingConv(F->getCallingConv()); 203106c3fb27SDimitry Andric 203206c3fb27SDimitry Andric return CI; 203306c3fb27SDimitry Andric } 2034