1204792Srdivacky//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// 2204792Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6204792Srdivacky// 7204792Srdivacky//===----------------------------------------------------------------------===// 8204792Srdivacky// 9204792Srdivacky// This file implements some functions that will create standard C libcalls. 10204792Srdivacky// 11204792Srdivacky//===----------------------------------------------------------------------===// 12204792Srdivacky 13204792Srdivacky#include "llvm/Transforms/Utils/BuildLibCalls.h" 14239462Sdim#include "llvm/ADT/SmallString.h" 15309124Sdim#include "llvm/ADT/Statistic.h" 16296417Sdim#include "llvm/Analysis/TargetLibraryInfo.h" 17249423Sdim#include "llvm/IR/Constants.h" 18249423Sdim#include "llvm/IR/DataLayout.h" 19249423Sdim#include "llvm/IR/Function.h" 20249423Sdim#include "llvm/IR/IRBuilder.h" 21249423Sdim#include "llvm/IR/Intrinsics.h" 22249423Sdim#include "llvm/IR/LLVMContext.h" 23249423Sdim#include "llvm/IR/Module.h" 24249423Sdim#include "llvm/IR/Type.h" 25353358Sdim#include "llvm/Analysis/MemoryBuiltins.h" 26204792Srdivacky 27204792Srdivackyusing namespace llvm; 28204792Srdivacky 29309124Sdim#define DEBUG_TYPE "build-libcalls" 30309124Sdim 31309124Sdim//- Infer Attributes ---------------------------------------------------------// 32309124Sdim 33309124SdimSTATISTIC(NumReadNone, "Number of functions inferred as readnone"); 34309124SdimSTATISTIC(NumReadOnly, "Number of functions inferred as readonly"); 35309124SdimSTATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly"); 36309124SdimSTATISTIC(NumNoUnwind, "Number of functions inferred as nounwind"); 37309124SdimSTATISTIC(NumNoCapture, "Number of arguments inferred as nocapture"); 38309124SdimSTATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly"); 39309124SdimSTATISTIC(NumNoAlias, "Number of function returns inferred as noalias"); 40309124SdimSTATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns"); 41344779SdimSTATISTIC(NumReturnedArg, "Number of arguments inferred as returned"); 42309124Sdim 43309124Sdimstatic bool setDoesNotAccessMemory(Function &F) { 44309124Sdim if (F.doesNotAccessMemory()) 45309124Sdim return false; 46309124Sdim F.setDoesNotAccessMemory(); 47309124Sdim ++NumReadNone; 48309124Sdim return true; 49309124Sdim} 50309124Sdim 51309124Sdimstatic bool setOnlyReadsMemory(Function &F) { 52309124Sdim if (F.onlyReadsMemory()) 53309124Sdim return false; 54309124Sdim F.setOnlyReadsMemory(); 55309124Sdim ++NumReadOnly; 56309124Sdim return true; 57309124Sdim} 58309124Sdim 59309124Sdimstatic bool setOnlyAccessesArgMemory(Function &F) { 60309124Sdim if (F.onlyAccessesArgMemory()) 61309124Sdim return false; 62321369Sdim F.setOnlyAccessesArgMemory(); 63309124Sdim ++NumArgMemOnly; 64309124Sdim return true; 65309124Sdim} 66309124Sdim 67309124Sdimstatic bool setDoesNotThrow(Function &F) { 68309124Sdim if (F.doesNotThrow()) 69309124Sdim return false; 70309124Sdim F.setDoesNotThrow(); 71309124Sdim ++NumNoUnwind; 72309124Sdim return true; 73309124Sdim} 74309124Sdim 75321369Sdimstatic bool setRetDoesNotAlias(Function &F) { 76321369Sdim if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias)) 77309124Sdim return false; 78321369Sdim F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); 79321369Sdim ++NumNoAlias; 80309124Sdim return true; 81309124Sdim} 82309124Sdim 83321369Sdimstatic bool setDoesNotCapture(Function &F, unsigned ArgNo) { 84321369Sdim if (F.hasParamAttribute(ArgNo, Attribute::NoCapture)) 85309124Sdim return false; 86321369Sdim F.addParamAttr(ArgNo, Attribute::NoCapture); 87321369Sdim ++NumNoCapture; 88309124Sdim return true; 89309124Sdim} 90309124Sdim 91360784Sdimstatic bool setDoesNotAlias(Function &F, unsigned ArgNo) { 92360784Sdim if (F.hasParamAttribute(ArgNo, Attribute::NoAlias)) 93360784Sdim return false; 94360784Sdim F.addParamAttr(ArgNo, Attribute::NoAlias); 95360784Sdim ++NumNoAlias; 96360784Sdim return true; 97360784Sdim} 98360784Sdim 99321369Sdimstatic bool setOnlyReadsMemory(Function &F, unsigned ArgNo) { 100321369Sdim if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly)) 101309124Sdim return false; 102321369Sdim F.addParamAttr(ArgNo, Attribute::ReadOnly); 103321369Sdim ++NumReadOnlyArg; 104309124Sdim return true; 105309124Sdim} 106309124Sdim 107321369Sdimstatic bool setRetNonNull(Function &F) { 108321369Sdim assert(F.getReturnType()->isPointerTy() && 109309124Sdim "nonnull applies only to pointers"); 110321369Sdim if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull)) 111309124Sdim return false; 112321369Sdim F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull); 113309124Sdim ++NumNonNull; 114309124Sdim return true; 115309124Sdim} 116309124Sdim 117344779Sdimstatic bool setReturnedArg(Function &F, unsigned ArgNo) { 118344779Sdim if (F.hasParamAttribute(ArgNo, Attribute::Returned)) 119344779Sdim return false; 120344779Sdim F.addParamAttr(ArgNo, Attribute::Returned); 121344779Sdim ++NumReturnedArg; 122344779Sdim return true; 123344779Sdim} 124344779Sdim 125341825Sdimstatic bool setNonLazyBind(Function &F) { 126341825Sdim if (F.hasFnAttribute(Attribute::NonLazyBind)) 127341825Sdim return false; 128341825Sdim F.addFnAttr(Attribute::NonLazyBind); 129341825Sdim return true; 130341825Sdim} 131341825Sdim 132353358Sdimstatic bool setDoesNotFreeMemory(Function &F) { 133353358Sdim if (F.hasFnAttribute(Attribute::NoFree)) 134353358Sdim return false; 135353358Sdim F.addFnAttr(Attribute::NoFree); 136353358Sdim return true; 137353358Sdim} 138353358Sdim 139341825Sdimbool llvm::inferLibFuncAttributes(Module *M, StringRef Name, 140341825Sdim const TargetLibraryInfo &TLI) { 141341825Sdim Function *F = M->getFunction(Name); 142341825Sdim if (!F) 143341825Sdim return false; 144341825Sdim return inferLibFuncAttributes(*F, TLI); 145341825Sdim} 146341825Sdim 147309124Sdimbool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) { 148321369Sdim LibFunc TheLibFunc; 149309124Sdim if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc))) 150309124Sdim return false; 151309124Sdim 152309124Sdim bool Changed = false; 153341825Sdim 154353358Sdim if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI)) 155353358Sdim Changed |= setDoesNotFreeMemory(F); 156353358Sdim 157341825Sdim if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT()) 158341825Sdim Changed |= setNonLazyBind(F); 159341825Sdim 160309124Sdim switch (TheLibFunc) { 161321369Sdim case LibFunc_strlen: 162321369Sdim case LibFunc_wcslen: 163309124Sdim Changed |= setOnlyReadsMemory(F); 164309124Sdim Changed |= setDoesNotThrow(F); 165321369Sdim Changed |= setOnlyAccessesArgMemory(F); 166321369Sdim Changed |= setDoesNotCapture(F, 0); 167309124Sdim return Changed; 168321369Sdim case LibFunc_strchr: 169321369Sdim case LibFunc_strrchr: 170309124Sdim Changed |= setOnlyReadsMemory(F); 171309124Sdim Changed |= setDoesNotThrow(F); 172309124Sdim return Changed; 173321369Sdim case LibFunc_strtol: 174321369Sdim case LibFunc_strtod: 175321369Sdim case LibFunc_strtof: 176321369Sdim case LibFunc_strtoul: 177321369Sdim case LibFunc_strtoll: 178321369Sdim case LibFunc_strtold: 179321369Sdim case LibFunc_strtoull: 180309124Sdim Changed |= setDoesNotThrow(F); 181321369Sdim Changed |= setDoesNotCapture(F, 1); 182321369Sdim Changed |= setOnlyReadsMemory(F, 0); 183309124Sdim return Changed; 184321369Sdim case LibFunc_strcpy: 185344779Sdim case LibFunc_strncpy: 186360784Sdim Changed |= setDoesNotAlias(F, 0); 187360784Sdim Changed |= setDoesNotAlias(F, 1); 188360784Sdim LLVM_FALLTHROUGH; 189321369Sdim case LibFunc_strcat: 190321369Sdim case LibFunc_strncat: 191344779Sdim Changed |= setReturnedArg(F, 0); 192344779Sdim LLVM_FALLTHROUGH; 193344779Sdim case LibFunc_stpcpy: 194321369Sdim case LibFunc_stpncpy: 195309124Sdim Changed |= setDoesNotThrow(F); 196321369Sdim Changed |= setDoesNotCapture(F, 1); 197321369Sdim Changed |= setOnlyReadsMemory(F, 1); 198309124Sdim return Changed; 199321369Sdim case LibFunc_strxfrm: 200309124Sdim Changed |= setDoesNotThrow(F); 201321369Sdim Changed |= setDoesNotCapture(F, 0); 202309124Sdim Changed |= setDoesNotCapture(F, 1); 203321369Sdim Changed |= setOnlyReadsMemory(F, 1); 204309124Sdim return Changed; 205321369Sdim case LibFunc_strcmp: // 0,1 206321369Sdim case LibFunc_strspn: // 0,1 207321369Sdim case LibFunc_strncmp: // 0,1 208321369Sdim case LibFunc_strcspn: // 0,1 209321369Sdim case LibFunc_strcoll: // 0,1 210321369Sdim case LibFunc_strcasecmp: // 0,1 211321369Sdim case LibFunc_strncasecmp: // 212309124Sdim Changed |= setOnlyReadsMemory(F); 213309124Sdim Changed |= setDoesNotThrow(F); 214321369Sdim Changed |= setDoesNotCapture(F, 0); 215309124Sdim Changed |= setDoesNotCapture(F, 1); 216309124Sdim return Changed; 217321369Sdim case LibFunc_strstr: 218321369Sdim case LibFunc_strpbrk: 219309124Sdim Changed |= setOnlyReadsMemory(F); 220309124Sdim Changed |= setDoesNotThrow(F); 221321369Sdim Changed |= setDoesNotCapture(F, 1); 222309124Sdim return Changed; 223321369Sdim case LibFunc_strtok: 224321369Sdim case LibFunc_strtok_r: 225309124Sdim Changed |= setDoesNotThrow(F); 226309124Sdim Changed |= setDoesNotCapture(F, 1); 227309124Sdim Changed |= setOnlyReadsMemory(F, 1); 228309124Sdim return Changed; 229321369Sdim case LibFunc_scanf: 230309124Sdim Changed |= setDoesNotThrow(F); 231321369Sdim Changed |= setDoesNotCapture(F, 0); 232321369Sdim Changed |= setOnlyReadsMemory(F, 0); 233309124Sdim return Changed; 234321369Sdim case LibFunc_setbuf: 235321369Sdim case LibFunc_setvbuf: 236309124Sdim Changed |= setDoesNotThrow(F); 237321369Sdim Changed |= setDoesNotCapture(F, 0); 238321369Sdim return Changed; 239321369Sdim case LibFunc_strdup: 240321369Sdim case LibFunc_strndup: 241321369Sdim Changed |= setDoesNotThrow(F); 242321369Sdim Changed |= setRetDoesNotAlias(F); 243321369Sdim Changed |= setDoesNotCapture(F, 0); 244321369Sdim Changed |= setOnlyReadsMemory(F, 0); 245321369Sdim return Changed; 246321369Sdim case LibFunc_stat: 247321369Sdim case LibFunc_statvfs: 248321369Sdim Changed |= setDoesNotThrow(F); 249321369Sdim Changed |= setDoesNotCapture(F, 0); 250309124Sdim Changed |= setDoesNotCapture(F, 1); 251321369Sdim Changed |= setOnlyReadsMemory(F, 0); 252309124Sdim return Changed; 253321369Sdim case LibFunc_sscanf: 254309124Sdim Changed |= setDoesNotThrow(F); 255321369Sdim Changed |= setDoesNotCapture(F, 0); 256309124Sdim Changed |= setDoesNotCapture(F, 1); 257321369Sdim Changed |= setOnlyReadsMemory(F, 0); 258309124Sdim Changed |= setOnlyReadsMemory(F, 1); 259309124Sdim return Changed; 260321369Sdim case LibFunc_sprintf: 261309124Sdim Changed |= setDoesNotThrow(F); 262321369Sdim Changed |= setDoesNotCapture(F, 0); 263360784Sdim Changed |= setDoesNotAlias(F, 0); 264309124Sdim Changed |= setDoesNotCapture(F, 1); 265309124Sdim Changed |= setOnlyReadsMemory(F, 1); 266309124Sdim return Changed; 267321369Sdim case LibFunc_snprintf: 268309124Sdim Changed |= setDoesNotThrow(F); 269321369Sdim Changed |= setDoesNotCapture(F, 0); 270360784Sdim Changed |= setDoesNotAlias(F, 0); 271309124Sdim Changed |= setDoesNotCapture(F, 2); 272309124Sdim Changed |= setOnlyReadsMemory(F, 2); 273309124Sdim return Changed; 274321369Sdim case LibFunc_setitimer: 275309124Sdim Changed |= setDoesNotThrow(F); 276309124Sdim Changed |= setDoesNotCapture(F, 1); 277309124Sdim Changed |= setDoesNotCapture(F, 2); 278321369Sdim Changed |= setOnlyReadsMemory(F, 1); 279309124Sdim return Changed; 280321369Sdim case LibFunc_system: 281309124Sdim // May throw; "system" is a valid pthread cancellation point. 282321369Sdim Changed |= setDoesNotCapture(F, 0); 283321369Sdim Changed |= setOnlyReadsMemory(F, 0); 284309124Sdim return Changed; 285321369Sdim case LibFunc_malloc: 286309124Sdim Changed |= setDoesNotThrow(F); 287321369Sdim Changed |= setRetDoesNotAlias(F); 288309124Sdim return Changed; 289321369Sdim case LibFunc_memcmp: 290309124Sdim Changed |= setOnlyReadsMemory(F); 291309124Sdim Changed |= setDoesNotThrow(F); 292321369Sdim Changed |= setDoesNotCapture(F, 0); 293309124Sdim Changed |= setDoesNotCapture(F, 1); 294309124Sdim return Changed; 295321369Sdim case LibFunc_memchr: 296321369Sdim case LibFunc_memrchr: 297309124Sdim Changed |= setOnlyReadsMemory(F); 298309124Sdim Changed |= setDoesNotThrow(F); 299309124Sdim return Changed; 300321369Sdim case LibFunc_modf: 301321369Sdim case LibFunc_modff: 302321369Sdim case LibFunc_modfl: 303309124Sdim Changed |= setDoesNotThrow(F); 304321369Sdim Changed |= setDoesNotCapture(F, 1); 305309124Sdim return Changed; 306321369Sdim case LibFunc_memcpy: 307360784Sdim Changed |= setDoesNotAlias(F, 0); 308360784Sdim Changed |= setDoesNotAlias(F, 1); 309360784Sdim Changed |= setReturnedArg(F, 0); 310360784Sdim Changed |= setDoesNotThrow(F); 311360784Sdim Changed |= setDoesNotCapture(F, 1); 312360784Sdim Changed |= setOnlyReadsMemory(F, 1); 313360784Sdim return Changed; 314344779Sdim case LibFunc_memmove: 315344779Sdim Changed |= setReturnedArg(F, 0); 316360784Sdim Changed |= setDoesNotThrow(F); 317360784Sdim Changed |= setDoesNotCapture(F, 1); 318360784Sdim Changed |= setOnlyReadsMemory(F, 1); 319360784Sdim return Changed; 320321369Sdim case LibFunc_mempcpy: 321321369Sdim case LibFunc_memccpy: 322360784Sdim Changed |= setDoesNotAlias(F, 0); 323360784Sdim Changed |= setDoesNotAlias(F, 1); 324309124Sdim Changed |= setDoesNotThrow(F); 325321369Sdim Changed |= setDoesNotCapture(F, 1); 326321369Sdim Changed |= setOnlyReadsMemory(F, 1); 327309124Sdim return Changed; 328321369Sdim case LibFunc_memcpy_chk: 329309124Sdim Changed |= setDoesNotThrow(F); 330309124Sdim return Changed; 331321369Sdim case LibFunc_memalign: 332321369Sdim Changed |= setRetDoesNotAlias(F); 333309124Sdim return Changed; 334321369Sdim case LibFunc_mkdir: 335309124Sdim Changed |= setDoesNotThrow(F); 336321369Sdim Changed |= setDoesNotCapture(F, 0); 337321369Sdim Changed |= setOnlyReadsMemory(F, 0); 338309124Sdim return Changed; 339321369Sdim case LibFunc_mktime: 340309124Sdim Changed |= setDoesNotThrow(F); 341321369Sdim Changed |= setDoesNotCapture(F, 0); 342309124Sdim return Changed; 343321369Sdim case LibFunc_realloc: 344309124Sdim Changed |= setDoesNotThrow(F); 345321369Sdim Changed |= setRetDoesNotAlias(F); 346321369Sdim Changed |= setDoesNotCapture(F, 0); 347309124Sdim return Changed; 348321369Sdim case LibFunc_read: 349309124Sdim // May throw; "read" is a valid pthread cancellation point. 350321369Sdim Changed |= setDoesNotCapture(F, 1); 351309124Sdim return Changed; 352321369Sdim case LibFunc_rewind: 353309124Sdim Changed |= setDoesNotThrow(F); 354321369Sdim Changed |= setDoesNotCapture(F, 0); 355309124Sdim return Changed; 356321369Sdim case LibFunc_rmdir: 357321369Sdim case LibFunc_remove: 358321369Sdim case LibFunc_realpath: 359309124Sdim Changed |= setDoesNotThrow(F); 360321369Sdim Changed |= setDoesNotCapture(F, 0); 361321369Sdim Changed |= setOnlyReadsMemory(F, 0); 362309124Sdim return Changed; 363321369Sdim case LibFunc_rename: 364309124Sdim Changed |= setDoesNotThrow(F); 365321369Sdim Changed |= setDoesNotCapture(F, 0); 366309124Sdim Changed |= setDoesNotCapture(F, 1); 367321369Sdim Changed |= setOnlyReadsMemory(F, 0); 368309124Sdim Changed |= setOnlyReadsMemory(F, 1); 369309124Sdim return Changed; 370321369Sdim case LibFunc_readlink: 371309124Sdim Changed |= setDoesNotThrow(F); 372321369Sdim Changed |= setDoesNotCapture(F, 0); 373309124Sdim Changed |= setDoesNotCapture(F, 1); 374321369Sdim Changed |= setOnlyReadsMemory(F, 0); 375309124Sdim return Changed; 376321369Sdim case LibFunc_write: 377309124Sdim // May throw; "write" is a valid pthread cancellation point. 378321369Sdim Changed |= setDoesNotCapture(F, 1); 379321369Sdim Changed |= setOnlyReadsMemory(F, 1); 380309124Sdim return Changed; 381321369Sdim case LibFunc_bcopy: 382309124Sdim Changed |= setDoesNotThrow(F); 383321369Sdim Changed |= setDoesNotCapture(F, 0); 384309124Sdim Changed |= setDoesNotCapture(F, 1); 385321369Sdim Changed |= setOnlyReadsMemory(F, 0); 386309124Sdim return Changed; 387321369Sdim case LibFunc_bcmp: 388309124Sdim Changed |= setDoesNotThrow(F); 389309124Sdim Changed |= setOnlyReadsMemory(F); 390321369Sdim Changed |= setDoesNotCapture(F, 0); 391309124Sdim Changed |= setDoesNotCapture(F, 1); 392309124Sdim return Changed; 393321369Sdim case LibFunc_bzero: 394309124Sdim Changed |= setDoesNotThrow(F); 395321369Sdim Changed |= setDoesNotCapture(F, 0); 396309124Sdim return Changed; 397321369Sdim case LibFunc_calloc: 398309124Sdim Changed |= setDoesNotThrow(F); 399321369Sdim Changed |= setRetDoesNotAlias(F); 400309124Sdim return Changed; 401321369Sdim case LibFunc_chmod: 402321369Sdim case LibFunc_chown: 403309124Sdim Changed |= setDoesNotThrow(F); 404321369Sdim Changed |= setDoesNotCapture(F, 0); 405321369Sdim Changed |= setOnlyReadsMemory(F, 0); 406309124Sdim return Changed; 407321369Sdim case LibFunc_ctermid: 408321369Sdim case LibFunc_clearerr: 409321369Sdim case LibFunc_closedir: 410309124Sdim Changed |= setDoesNotThrow(F); 411321369Sdim Changed |= setDoesNotCapture(F, 0); 412309124Sdim return Changed; 413321369Sdim case LibFunc_atoi: 414321369Sdim case LibFunc_atol: 415321369Sdim case LibFunc_atof: 416321369Sdim case LibFunc_atoll: 417309124Sdim Changed |= setDoesNotThrow(F); 418309124Sdim Changed |= setOnlyReadsMemory(F); 419321369Sdim Changed |= setDoesNotCapture(F, 0); 420309124Sdim return Changed; 421321369Sdim case LibFunc_access: 422309124Sdim Changed |= setDoesNotThrow(F); 423321369Sdim Changed |= setDoesNotCapture(F, 0); 424321369Sdim Changed |= setOnlyReadsMemory(F, 0); 425321369Sdim return Changed; 426321369Sdim case LibFunc_fopen: 427321369Sdim Changed |= setDoesNotThrow(F); 428321369Sdim Changed |= setRetDoesNotAlias(F); 429321369Sdim Changed |= setDoesNotCapture(F, 0); 430309124Sdim Changed |= setDoesNotCapture(F, 1); 431321369Sdim Changed |= setOnlyReadsMemory(F, 0); 432309124Sdim Changed |= setOnlyReadsMemory(F, 1); 433309124Sdim return Changed; 434321369Sdim case LibFunc_fdopen: 435309124Sdim Changed |= setDoesNotThrow(F); 436321369Sdim Changed |= setRetDoesNotAlias(F); 437309124Sdim Changed |= setDoesNotCapture(F, 1); 438309124Sdim Changed |= setOnlyReadsMemory(F, 1); 439309124Sdim return Changed; 440321369Sdim case LibFunc_feof: 441321369Sdim case LibFunc_free: 442321369Sdim case LibFunc_fseek: 443321369Sdim case LibFunc_ftell: 444321369Sdim case LibFunc_fgetc: 445341825Sdim case LibFunc_fgetc_unlocked: 446321369Sdim case LibFunc_fseeko: 447321369Sdim case LibFunc_ftello: 448321369Sdim case LibFunc_fileno: 449321369Sdim case LibFunc_fflush: 450321369Sdim case LibFunc_fclose: 451321369Sdim case LibFunc_fsetpos: 452321369Sdim case LibFunc_flockfile: 453321369Sdim case LibFunc_funlockfile: 454321369Sdim case LibFunc_ftrylockfile: 455309124Sdim Changed |= setDoesNotThrow(F); 456321369Sdim Changed |= setDoesNotCapture(F, 0); 457309124Sdim return Changed; 458321369Sdim case LibFunc_ferror: 459309124Sdim Changed |= setDoesNotThrow(F); 460321369Sdim Changed |= setDoesNotCapture(F, 0); 461321369Sdim Changed |= setOnlyReadsMemory(F); 462309124Sdim return Changed; 463321369Sdim case LibFunc_fputc: 464341825Sdim case LibFunc_fputc_unlocked: 465321369Sdim case LibFunc_fstat: 466321369Sdim case LibFunc_frexp: 467321369Sdim case LibFunc_frexpf: 468321369Sdim case LibFunc_frexpl: 469321369Sdim case LibFunc_fstatvfs: 470309124Sdim Changed |= setDoesNotThrow(F); 471309124Sdim Changed |= setDoesNotCapture(F, 1); 472309124Sdim return Changed; 473321369Sdim case LibFunc_fgets: 474341825Sdim case LibFunc_fgets_unlocked: 475309124Sdim Changed |= setDoesNotThrow(F); 476309124Sdim Changed |= setDoesNotCapture(F, 2); 477309124Sdim return Changed; 478321369Sdim case LibFunc_fread: 479341825Sdim case LibFunc_fread_unlocked: 480309124Sdim Changed |= setDoesNotThrow(F); 481321369Sdim Changed |= setDoesNotCapture(F, 0); 482309124Sdim Changed |= setDoesNotCapture(F, 3); 483309124Sdim return Changed; 484321369Sdim case LibFunc_fwrite: 485341825Sdim case LibFunc_fwrite_unlocked: 486309124Sdim Changed |= setDoesNotThrow(F); 487321369Sdim Changed |= setDoesNotCapture(F, 0); 488321369Sdim Changed |= setDoesNotCapture(F, 3); 489321369Sdim // FIXME: readonly #1? 490309124Sdim return Changed; 491321369Sdim case LibFunc_fputs: 492341825Sdim case LibFunc_fputs_unlocked: 493309124Sdim Changed |= setDoesNotThrow(F); 494321369Sdim Changed |= setDoesNotCapture(F, 0); 495309124Sdim Changed |= setDoesNotCapture(F, 1); 496321369Sdim Changed |= setOnlyReadsMemory(F, 0); 497309124Sdim return Changed; 498321369Sdim case LibFunc_fscanf: 499321369Sdim case LibFunc_fprintf: 500309124Sdim Changed |= setDoesNotThrow(F); 501321369Sdim Changed |= setDoesNotCapture(F, 0); 502309124Sdim Changed |= setDoesNotCapture(F, 1); 503309124Sdim Changed |= setOnlyReadsMemory(F, 1); 504309124Sdim return Changed; 505321369Sdim case LibFunc_fgetpos: 506309124Sdim Changed |= setDoesNotThrow(F); 507321369Sdim Changed |= setDoesNotCapture(F, 0); 508309124Sdim Changed |= setDoesNotCapture(F, 1); 509309124Sdim return Changed; 510321369Sdim case LibFunc_getc: 511321369Sdim case LibFunc_getlogin_r: 512321369Sdim case LibFunc_getc_unlocked: 513309124Sdim Changed |= setDoesNotThrow(F); 514321369Sdim Changed |= setDoesNotCapture(F, 0); 515309124Sdim return Changed; 516321369Sdim case LibFunc_getenv: 517309124Sdim Changed |= setDoesNotThrow(F); 518321369Sdim Changed |= setOnlyReadsMemory(F); 519321369Sdim Changed |= setDoesNotCapture(F, 0); 520309124Sdim return Changed; 521321369Sdim case LibFunc_gets: 522321369Sdim case LibFunc_getchar: 523341825Sdim case LibFunc_getchar_unlocked: 524309124Sdim Changed |= setDoesNotThrow(F); 525309124Sdim return Changed; 526321369Sdim case LibFunc_getitimer: 527309124Sdim Changed |= setDoesNotThrow(F); 528321369Sdim Changed |= setDoesNotCapture(F, 1); 529309124Sdim return Changed; 530321369Sdim case LibFunc_getpwnam: 531309124Sdim Changed |= setDoesNotThrow(F); 532321369Sdim Changed |= setDoesNotCapture(F, 0); 533321369Sdim Changed |= setOnlyReadsMemory(F, 0); 534309124Sdim return Changed; 535321369Sdim case LibFunc_ungetc: 536309124Sdim Changed |= setDoesNotThrow(F); 537309124Sdim Changed |= setDoesNotCapture(F, 1); 538309124Sdim return Changed; 539321369Sdim case LibFunc_uname: 540309124Sdim Changed |= setDoesNotThrow(F); 541321369Sdim Changed |= setDoesNotCapture(F, 0); 542309124Sdim return Changed; 543321369Sdim case LibFunc_unlink: 544309124Sdim Changed |= setDoesNotThrow(F); 545321369Sdim Changed |= setDoesNotCapture(F, 0); 546321369Sdim Changed |= setOnlyReadsMemory(F, 0); 547309124Sdim return Changed; 548321369Sdim case LibFunc_unsetenv: 549309124Sdim Changed |= setDoesNotThrow(F); 550321369Sdim Changed |= setDoesNotCapture(F, 0); 551321369Sdim Changed |= setOnlyReadsMemory(F, 0); 552309124Sdim return Changed; 553321369Sdim case LibFunc_utime: 554321369Sdim case LibFunc_utimes: 555309124Sdim Changed |= setDoesNotThrow(F); 556321369Sdim Changed |= setDoesNotCapture(F, 0); 557309124Sdim Changed |= setDoesNotCapture(F, 1); 558321369Sdim Changed |= setOnlyReadsMemory(F, 0); 559309124Sdim Changed |= setOnlyReadsMemory(F, 1); 560309124Sdim return Changed; 561321369Sdim case LibFunc_putc: 562341825Sdim case LibFunc_putc_unlocked: 563309124Sdim Changed |= setDoesNotThrow(F); 564309124Sdim Changed |= setDoesNotCapture(F, 1); 565309124Sdim return Changed; 566321369Sdim case LibFunc_puts: 567321369Sdim case LibFunc_printf: 568321369Sdim case LibFunc_perror: 569309124Sdim Changed |= setDoesNotThrow(F); 570321369Sdim Changed |= setDoesNotCapture(F, 0); 571321369Sdim Changed |= setOnlyReadsMemory(F, 0); 572309124Sdim return Changed; 573321369Sdim case LibFunc_pread: 574321369Sdim // May throw; "pread" is a valid pthread cancellation point. 575309124Sdim Changed |= setDoesNotCapture(F, 1); 576309124Sdim return Changed; 577321369Sdim case LibFunc_pwrite: 578309124Sdim // May throw; "pwrite" is a valid pthread cancellation point. 579321369Sdim Changed |= setDoesNotCapture(F, 1); 580321369Sdim Changed |= setOnlyReadsMemory(F, 1); 581309124Sdim return Changed; 582321369Sdim case LibFunc_putchar: 583341825Sdim case LibFunc_putchar_unlocked: 584309124Sdim Changed |= setDoesNotThrow(F); 585309124Sdim return Changed; 586321369Sdim case LibFunc_popen: 587309124Sdim Changed |= setDoesNotThrow(F); 588321369Sdim Changed |= setRetDoesNotAlias(F); 589321369Sdim Changed |= setDoesNotCapture(F, 0); 590309124Sdim Changed |= setDoesNotCapture(F, 1); 591321369Sdim Changed |= setOnlyReadsMemory(F, 0); 592309124Sdim Changed |= setOnlyReadsMemory(F, 1); 593309124Sdim return Changed; 594321369Sdim case LibFunc_pclose: 595309124Sdim Changed |= setDoesNotThrow(F); 596321369Sdim Changed |= setDoesNotCapture(F, 0); 597309124Sdim return Changed; 598321369Sdim case LibFunc_vscanf: 599309124Sdim Changed |= setDoesNotThrow(F); 600321369Sdim Changed |= setDoesNotCapture(F, 0); 601321369Sdim Changed |= setOnlyReadsMemory(F, 0); 602321369Sdim return Changed; 603321369Sdim case LibFunc_vsscanf: 604321369Sdim Changed |= setDoesNotThrow(F); 605321369Sdim Changed |= setDoesNotCapture(F, 0); 606309124Sdim Changed |= setDoesNotCapture(F, 1); 607321369Sdim Changed |= setOnlyReadsMemory(F, 0); 608309124Sdim Changed |= setOnlyReadsMemory(F, 1); 609309124Sdim return Changed; 610321369Sdim case LibFunc_vfscanf: 611309124Sdim Changed |= setDoesNotThrow(F); 612321369Sdim Changed |= setDoesNotCapture(F, 0); 613309124Sdim Changed |= setDoesNotCapture(F, 1); 614309124Sdim Changed |= setOnlyReadsMemory(F, 1); 615309124Sdim return Changed; 616321369Sdim case LibFunc_valloc: 617309124Sdim Changed |= setDoesNotThrow(F); 618321369Sdim Changed |= setRetDoesNotAlias(F); 619309124Sdim return Changed; 620321369Sdim case LibFunc_vprintf: 621309124Sdim Changed |= setDoesNotThrow(F); 622321369Sdim Changed |= setDoesNotCapture(F, 0); 623321369Sdim Changed |= setOnlyReadsMemory(F, 0); 624309124Sdim return Changed; 625321369Sdim case LibFunc_vfprintf: 626321369Sdim case LibFunc_vsprintf: 627309124Sdim Changed |= setDoesNotThrow(F); 628321369Sdim Changed |= setDoesNotCapture(F, 0); 629309124Sdim Changed |= setDoesNotCapture(F, 1); 630309124Sdim Changed |= setOnlyReadsMemory(F, 1); 631309124Sdim return Changed; 632321369Sdim case LibFunc_vsnprintf: 633309124Sdim Changed |= setDoesNotThrow(F); 634321369Sdim Changed |= setDoesNotCapture(F, 0); 635309124Sdim Changed |= setDoesNotCapture(F, 2); 636309124Sdim Changed |= setOnlyReadsMemory(F, 2); 637309124Sdim return Changed; 638321369Sdim case LibFunc_open: 639309124Sdim // May throw; "open" is a valid pthread cancellation point. 640321369Sdim Changed |= setDoesNotCapture(F, 0); 641321369Sdim Changed |= setOnlyReadsMemory(F, 0); 642309124Sdim return Changed; 643321369Sdim case LibFunc_opendir: 644309124Sdim Changed |= setDoesNotThrow(F); 645321369Sdim Changed |= setRetDoesNotAlias(F); 646321369Sdim Changed |= setDoesNotCapture(F, 0); 647321369Sdim Changed |= setOnlyReadsMemory(F, 0); 648309124Sdim return Changed; 649321369Sdim case LibFunc_tmpfile: 650309124Sdim Changed |= setDoesNotThrow(F); 651321369Sdim Changed |= setRetDoesNotAlias(F); 652309124Sdim return Changed; 653321369Sdim case LibFunc_times: 654309124Sdim Changed |= setDoesNotThrow(F); 655321369Sdim Changed |= setDoesNotCapture(F, 0); 656309124Sdim return Changed; 657321369Sdim case LibFunc_htonl: 658321369Sdim case LibFunc_htons: 659321369Sdim case LibFunc_ntohl: 660321369Sdim case LibFunc_ntohs: 661309124Sdim Changed |= setDoesNotThrow(F); 662309124Sdim Changed |= setDoesNotAccessMemory(F); 663309124Sdim return Changed; 664321369Sdim case LibFunc_lstat: 665309124Sdim Changed |= setDoesNotThrow(F); 666321369Sdim Changed |= setDoesNotCapture(F, 0); 667309124Sdim Changed |= setDoesNotCapture(F, 1); 668321369Sdim Changed |= setOnlyReadsMemory(F, 0); 669309124Sdim return Changed; 670321369Sdim case LibFunc_lchown: 671309124Sdim Changed |= setDoesNotThrow(F); 672321369Sdim Changed |= setDoesNotCapture(F, 0); 673321369Sdim Changed |= setOnlyReadsMemory(F, 0); 674309124Sdim return Changed; 675321369Sdim case LibFunc_qsort: 676309124Sdim // May throw; places call through function pointer. 677321369Sdim Changed |= setDoesNotCapture(F, 3); 678309124Sdim return Changed; 679321369Sdim case LibFunc_dunder_strdup: 680321369Sdim case LibFunc_dunder_strndup: 681309124Sdim Changed |= setDoesNotThrow(F); 682321369Sdim Changed |= setRetDoesNotAlias(F); 683321369Sdim Changed |= setDoesNotCapture(F, 0); 684321369Sdim Changed |= setOnlyReadsMemory(F, 0); 685321369Sdim return Changed; 686321369Sdim case LibFunc_dunder_strtok_r: 687321369Sdim Changed |= setDoesNotThrow(F); 688309124Sdim Changed |= setDoesNotCapture(F, 1); 689309124Sdim Changed |= setOnlyReadsMemory(F, 1); 690309124Sdim return Changed; 691321369Sdim case LibFunc_under_IO_getc: 692309124Sdim Changed |= setDoesNotThrow(F); 693321369Sdim Changed |= setDoesNotCapture(F, 0); 694309124Sdim return Changed; 695321369Sdim case LibFunc_under_IO_putc: 696309124Sdim Changed |= setDoesNotThrow(F); 697309124Sdim Changed |= setDoesNotCapture(F, 1); 698309124Sdim return Changed; 699321369Sdim case LibFunc_dunder_isoc99_scanf: 700309124Sdim Changed |= setDoesNotThrow(F); 701321369Sdim Changed |= setDoesNotCapture(F, 0); 702321369Sdim Changed |= setOnlyReadsMemory(F, 0); 703309124Sdim return Changed; 704321369Sdim case LibFunc_stat64: 705321369Sdim case LibFunc_lstat64: 706321369Sdim case LibFunc_statvfs64: 707309124Sdim Changed |= setDoesNotThrow(F); 708321369Sdim Changed |= setDoesNotCapture(F, 0); 709309124Sdim Changed |= setDoesNotCapture(F, 1); 710321369Sdim Changed |= setOnlyReadsMemory(F, 0); 711309124Sdim return Changed; 712321369Sdim case LibFunc_dunder_isoc99_sscanf: 713309124Sdim Changed |= setDoesNotThrow(F); 714321369Sdim Changed |= setDoesNotCapture(F, 0); 715309124Sdim Changed |= setDoesNotCapture(F, 1); 716321369Sdim Changed |= setOnlyReadsMemory(F, 0); 717309124Sdim Changed |= setOnlyReadsMemory(F, 1); 718309124Sdim return Changed; 719321369Sdim case LibFunc_fopen64: 720309124Sdim Changed |= setDoesNotThrow(F); 721321369Sdim Changed |= setRetDoesNotAlias(F); 722321369Sdim Changed |= setDoesNotCapture(F, 0); 723309124Sdim Changed |= setDoesNotCapture(F, 1); 724321369Sdim Changed |= setOnlyReadsMemory(F, 0); 725309124Sdim Changed |= setOnlyReadsMemory(F, 1); 726309124Sdim return Changed; 727321369Sdim case LibFunc_fseeko64: 728321369Sdim case LibFunc_ftello64: 729309124Sdim Changed |= setDoesNotThrow(F); 730321369Sdim Changed |= setDoesNotCapture(F, 0); 731309124Sdim return Changed; 732321369Sdim case LibFunc_tmpfile64: 733309124Sdim Changed |= setDoesNotThrow(F); 734321369Sdim Changed |= setRetDoesNotAlias(F); 735309124Sdim return Changed; 736321369Sdim case LibFunc_fstat64: 737321369Sdim case LibFunc_fstatvfs64: 738309124Sdim Changed |= setDoesNotThrow(F); 739321369Sdim Changed |= setDoesNotCapture(F, 1); 740309124Sdim return Changed; 741321369Sdim case LibFunc_open64: 742309124Sdim // May throw; "open" is a valid pthread cancellation point. 743321369Sdim Changed |= setDoesNotCapture(F, 0); 744321369Sdim Changed |= setOnlyReadsMemory(F, 0); 745309124Sdim return Changed; 746321369Sdim case LibFunc_gettimeofday: 747309124Sdim // Currently some platforms have the restrict keyword on the arguments to 748309124Sdim // gettimeofday. To be conservative, do not add noalias to gettimeofday's 749309124Sdim // arguments. 750309124Sdim Changed |= setDoesNotThrow(F); 751321369Sdim Changed |= setDoesNotCapture(F, 0); 752309124Sdim Changed |= setDoesNotCapture(F, 1); 753309124Sdim return Changed; 754321369Sdim case LibFunc_Znwj: // new(unsigned int) 755321369Sdim case LibFunc_Znwm: // new(unsigned long) 756321369Sdim case LibFunc_Znaj: // new[](unsigned int) 757321369Sdim case LibFunc_Znam: // new[](unsigned long) 758321369Sdim case LibFunc_msvc_new_int: // new(unsigned int) 759321369Sdim case LibFunc_msvc_new_longlong: // new(unsigned long long) 760321369Sdim case LibFunc_msvc_new_array_int: // new[](unsigned int) 761321369Sdim case LibFunc_msvc_new_array_longlong: // new[](unsigned long long) 762309124Sdim // Operator new always returns a nonnull noalias pointer 763321369Sdim Changed |= setRetNonNull(F); 764321369Sdim Changed |= setRetDoesNotAlias(F); 765309124Sdim return Changed; 766341825Sdim // TODO: add LibFunc entries for: 767341825Sdim // case LibFunc_memset_pattern4: 768341825Sdim // case LibFunc_memset_pattern8: 769321369Sdim case LibFunc_memset_pattern16: 770309124Sdim Changed |= setOnlyAccessesArgMemory(F); 771321369Sdim Changed |= setDoesNotCapture(F, 0); 772309124Sdim Changed |= setDoesNotCapture(F, 1); 773321369Sdim Changed |= setOnlyReadsMemory(F, 1); 774309124Sdim return Changed; 775309124Sdim // int __nvvm_reflect(const char *) 776321369Sdim case LibFunc_nvvm_reflect: 777309124Sdim Changed |= setDoesNotAccessMemory(F); 778309124Sdim Changed |= setDoesNotThrow(F); 779309124Sdim return Changed; 780309124Sdim 781309124Sdim default: 782309124Sdim // FIXME: It'd be really nice to cover all the library functions we're 783309124Sdim // aware of here. 784309124Sdim return false; 785309124Sdim } 786309124Sdim} 787309124Sdim 788360784Sdimbool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty, 789360784Sdim LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) { 790341825Sdim switch (Ty->getTypeID()) { 791344779Sdim case Type::HalfTyID: 792344779Sdim return false; 793341825Sdim case Type::FloatTyID: 794341825Sdim return TLI->has(FloatFn); 795341825Sdim case Type::DoubleTyID: 796341825Sdim return TLI->has(DoubleFn); 797341825Sdim default: 798341825Sdim return TLI->has(LongDoubleFn); 799341825Sdim } 800341825Sdim} 801341825Sdim 802360784SdimStringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty, 803360784Sdim LibFunc DoubleFn, LibFunc FloatFn, 804360784Sdim LibFunc LongDoubleFn) { 805360784Sdim assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) && 806344779Sdim "Cannot get name for unavailable function!"); 807344779Sdim 808344779Sdim switch (Ty->getTypeID()) { 809344779Sdim case Type::HalfTyID: 810344779Sdim llvm_unreachable("No name for HalfTy!"); 811344779Sdim case Type::FloatTyID: 812344779Sdim return TLI->getName(FloatFn); 813344779Sdim case Type::DoubleTyID: 814344779Sdim return TLI->getName(DoubleFn); 815344779Sdim default: 816344779Sdim return TLI->getName(LongDoubleFn); 817344779Sdim } 818344779Sdim} 819344779Sdim 820309124Sdim//- Emit LibCalls ------------------------------------------------------------// 821309124Sdim 822309124SdimValue *llvm::castToCStr(Value *V, IRBuilder<> &B) { 823276479Sdim unsigned AS = V->getType()->getPointerAddressSpace(); 824276479Sdim return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr"); 825204792Srdivacky} 826204792Srdivacky 827353358Sdimstatic Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType, 828353358Sdim ArrayRef<Type *> ParamTypes, 829353358Sdim ArrayRef<Value *> Operands, IRBuilder<> &B, 830353358Sdim const TargetLibraryInfo *TLI, 831353358Sdim bool IsVaArgs = false) { 832353358Sdim if (!TLI->has(TheLibFunc)) 833276479Sdim return nullptr; 834239462Sdim 835309124Sdim Module *M = B.GetInsertBlock()->getModule(); 836353358Sdim StringRef FuncName = TLI->getName(TheLibFunc); 837353358Sdim FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs); 838353358Sdim FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType); 839353358Sdim inferLibFuncAttributes(M, FuncName, *TLI); 840353358Sdim CallInst *CI = B.CreateCall(Callee, Operands, FuncName); 841353358Sdim if (const Function *F = 842353358Sdim dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 843204792Srdivacky CI->setCallingConv(F->getCallingConv()); 844204792Srdivacky return CI; 845204792Srdivacky} 846204792Srdivacky 847353358SdimValue *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, 848353358Sdim const TargetLibraryInfo *TLI) { 849353358Sdim LLVMContext &Context = B.GetInsertBlock()->getContext(); 850353358Sdim return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context), 851353358Sdim B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI); 852353358Sdim} 853353358Sdim 854360784SdimValue *llvm::emitStrDup(Value *Ptr, IRBuilder<> &B, 855360784Sdim const TargetLibraryInfo *TLI) { 856360784Sdim return emitLibCall(LibFunc_strdup, B.getInt8PtrTy(), B.getInt8PtrTy(), 857360784Sdim castToCStr(Ptr, B), B, TLI); 858360784Sdim} 859360784Sdim 860309124SdimValue *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B, 861288943Sdim const TargetLibraryInfo *TLI) { 862226633Sdim Type *I8Ptr = B.getInt8PtrTy(); 863226633Sdim Type *I32Ty = B.getInt32Ty(); 864353358Sdim return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty}, 865353358Sdim {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI); 866204792Srdivacky} 867204792Srdivacky 868309124SdimValue *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, 869288943Sdim const DataLayout &DL, const TargetLibraryInfo *TLI) { 870210299Sed LLVMContext &Context = B.GetInsertBlock()->getContext(); 871353358Sdim return emitLibCall( 872353358Sdim LibFunc_strncmp, B.getInt32Ty(), 873353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, 874353358Sdim {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); 875210299Sed} 876210299Sed 877309124SdimValue *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, 878353358Sdim const TargetLibraryInfo *TLI) { 879353358Sdim Type *I8Ptr = B.getInt8PtrTy(); 880353358Sdim return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr}, 881353358Sdim {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); 882353358Sdim} 883239462Sdim 884353358SdimValue *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B, 885353358Sdim const TargetLibraryInfo *TLI) { 886226633Sdim Type *I8Ptr = B.getInt8PtrTy(); 887353358Sdim return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr}, 888353358Sdim {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI); 889204792Srdivacky} 890204792Srdivacky 891309124SdimValue *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, 892353358Sdim const TargetLibraryInfo *TLI) { 893353358Sdim Type *I8Ptr = B.getInt8PtrTy(); 894353358Sdim return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, 895353358Sdim {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); 896353358Sdim} 897239462Sdim 898353358SdimValue *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B, 899353358Sdim const TargetLibraryInfo *TLI) { 900226633Sdim Type *I8Ptr = B.getInt8PtrTy(); 901353358Sdim return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()}, 902353358Sdim {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI); 903205218Srdivacky} 904205218Srdivacky 905309124SdimValue *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, 906288943Sdim IRBuilder<> &B, const DataLayout &DL, 907239462Sdim const TargetLibraryInfo *TLI) { 908321369Sdim if (!TLI->has(LibFunc_memcpy_chk)) 909276479Sdim return nullptr; 910239462Sdim 911309124Sdim Module *M = B.GetInsertBlock()->getModule(); 912321369Sdim AttributeList AS; 913321369Sdim AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex, 914321369Sdim Attribute::NoUnwind); 915206083Srdivacky LLVMContext &Context = B.GetInsertBlock()->getContext(); 916353358Sdim FunctionCallee MemCpy = M->getOrInsertFunction( 917321369Sdim "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(), 918288943Sdim B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), 919321369Sdim DL.getIntPtrType(Context)); 920309124Sdim Dst = castToCStr(Dst, B); 921309124Sdim Src = castToCStr(Src, B); 922288943Sdim CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); 923353358Sdim if (const Function *F = 924353358Sdim dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts())) 925206083Srdivacky CI->setCallingConv(F->getCallingConv()); 926206083Srdivacky return CI; 927206083Srdivacky} 928206083Srdivacky 929309124SdimValue *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, 930288943Sdim const DataLayout &DL, const TargetLibraryInfo *TLI) { 931204792Srdivacky LLVMContext &Context = B.GetInsertBlock()->getContext(); 932353358Sdim return emitLibCall( 933353358Sdim LibFunc_memchr, B.getInt8PtrTy(), 934353358Sdim {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)}, 935353358Sdim {castToCStr(Ptr, B), Val, Len}, B, TLI); 936204792Srdivacky} 937204792Srdivacky 938309124SdimValue *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, 939288943Sdim const DataLayout &DL, const TargetLibraryInfo *TLI) { 940353358Sdim LLVMContext &Context = B.GetInsertBlock()->getContext(); 941353358Sdim return emitLibCall( 942353358Sdim LibFunc_memcmp, B.getInt32Ty(), 943353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, 944353358Sdim {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); 945353358Sdim} 946239462Sdim 947353358SdimValue *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, 948353358Sdim const DataLayout &DL, const TargetLibraryInfo *TLI) { 949204792Srdivacky LLVMContext &Context = B.GetInsertBlock()->getContext(); 950353358Sdim return emitLibCall( 951353358Sdim LibFunc_bcmp, B.getInt32Ty(), 952353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)}, 953353358Sdim {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI); 954353358Sdim} 955204792Srdivacky 956353358SdimValue *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len, 957353358Sdim IRBuilder<> &B, const TargetLibraryInfo *TLI) { 958353358Sdim return emitLibCall( 959353358Sdim LibFunc_memccpy, B.getInt8PtrTy(), 960353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()}, 961353358Sdim {Ptr1, Ptr2, Val, Len}, B, TLI); 962353358Sdim} 963204792Srdivacky 964353358SdimValue *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt, 965353358Sdim ArrayRef<Value *> VariadicArgs, IRBuilder<> &B, 966353358Sdim const TargetLibraryInfo *TLI) { 967353358Sdim SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)}; 968353358Sdim Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); 969353358Sdim return emitLibCall(LibFunc_snprintf, B.getInt32Ty(), 970353358Sdim {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()}, 971353358Sdim Args, B, TLI, /*IsVaArgs=*/true); 972204792Srdivacky} 973204792Srdivacky 974353358SdimValue *llvm::emitSPrintf(Value *Dest, Value *Fmt, 975353358Sdim ArrayRef<Value *> VariadicArgs, IRBuilder<> &B, 976353358Sdim const TargetLibraryInfo *TLI) { 977353358Sdim SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)}; 978353358Sdim Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end()); 979353358Sdim return emitLibCall(LibFunc_sprintf, B.getInt32Ty(), 980353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI, 981353358Sdim /*IsVaArgs=*/true); 982353358Sdim} 983353358Sdim 984353358SdimValue *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B, 985353358Sdim const TargetLibraryInfo *TLI) { 986353358Sdim return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(), 987353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy()}, 988353358Sdim {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI); 989353358Sdim} 990353358Sdim 991353358SdimValue *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, 992353358Sdim const TargetLibraryInfo *TLI) { 993353358Sdim return emitLibCall(LibFunc_strlcpy, Size->getType(), 994353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, 995353358Sdim {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); 996353358Sdim} 997353358Sdim 998353358SdimValue *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, 999353358Sdim const TargetLibraryInfo *TLI) { 1000353358Sdim return emitLibCall(LibFunc_strlcat, Size->getType(), 1001353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, 1002353358Sdim {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); 1003353358Sdim} 1004353358Sdim 1005353358SdimValue *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B, 1006353358Sdim const TargetLibraryInfo *TLI) { 1007353358Sdim return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(), 1008353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()}, 1009353358Sdim {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI); 1010353358Sdim} 1011353358Sdim 1012353358SdimValue *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList, 1013353358Sdim IRBuilder<> &B, const TargetLibraryInfo *TLI) { 1014353358Sdim return emitLibCall( 1015353358Sdim LibFunc_vsnprintf, B.getInt32Ty(), 1016353358Sdim {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()}, 1017353358Sdim {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI); 1018353358Sdim} 1019353358Sdim 1020353358SdimValue *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, 1021353358Sdim IRBuilder<> &B, const TargetLibraryInfo *TLI) { 1022353358Sdim return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(), 1023353358Sdim {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()}, 1024353358Sdim {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI); 1025353358Sdim} 1026353358Sdim 1027276479Sdim/// Append a suffix to the function name according to the type of 'Op'. 1028309124Sdimstatic void appendTypeSuffix(Value *Op, StringRef &Name, 1029309124Sdim SmallString<20> &NameBuffer) { 1030276479Sdim if (!Op->getType()->isDoubleTy()) { 1031276479Sdim NameBuffer += Name; 1032276479Sdim 1033276479Sdim if (Op->getType()->isFloatTy()) 1034276479Sdim NameBuffer += 'f'; 1035276479Sdim else 1036276479Sdim NameBuffer += 'l'; 1037276479Sdim 1038276479Sdim Name = NameBuffer; 1039341825Sdim } 1040276479Sdim} 1041276479Sdim 1042344779Sdimstatic Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name, 1043344779Sdim IRBuilder<> &B, 1044344779Sdim const AttributeList &Attrs) { 1045344779Sdim assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall"); 1046204792Srdivacky 1047309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1048353358Sdim FunctionCallee Callee = 1049353358Sdim M->getOrInsertFunction(Name, Op->getType(), Op->getType()); 1050204792Srdivacky CallInst *CI = B.CreateCall(Callee, Op, Name); 1051321369Sdim 1052321369Sdim // The incoming attribute set may have come from a speculatable intrinsic, but 1053321369Sdim // is being replaced with a library call which is not allowed to be 1054321369Sdim // speculatable. 1055321369Sdim CI->setAttributes(Attrs.removeAttribute(B.getContext(), 1056321369Sdim AttributeList::FunctionIndex, 1057321369Sdim Attribute::Speculatable)); 1058353358Sdim if (const Function *F = 1059353358Sdim dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 1060204792Srdivacky CI->setCallingConv(F->getCallingConv()); 1061204792Srdivacky 1062204792Srdivacky return CI; 1063204792Srdivacky} 1064204792Srdivacky 1065344779SdimValue *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, 1066344779Sdim const AttributeList &Attrs) { 1067344779Sdim SmallString<20> NameBuffer; 1068344779Sdim appendTypeSuffix(Op, Name, NameBuffer); 1069344779Sdim 1070344779Sdim return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); 1071344779Sdim} 1072344779Sdim 1073344779SdimValue *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI, 1074344779Sdim LibFunc DoubleFn, LibFunc FloatFn, 1075344779Sdim LibFunc LongDoubleFn, IRBuilder<> &B, 1076344779Sdim const AttributeList &Attrs) { 1077344779Sdim // Get the name of the function according to TLI. 1078360784Sdim StringRef Name = getFloatFnName(TLI, Op->getType(), 1079360784Sdim DoubleFn, FloatFn, LongDoubleFn); 1080344779Sdim 1081344779Sdim return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs); 1082344779Sdim} 1083344779Sdim 1084360784Sdimstatic Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2, 1085360784Sdim StringRef Name, IRBuilder<> &B, 1086360784Sdim const AttributeList &Attrs) { 1087344779Sdim assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); 1088344779Sdim 1089360784Sdim Module *M = B.GetInsertBlock()->getModule(); 1090360784Sdim FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(), 1091360784Sdim Op1->getType(), Op2->getType()); 1092360784Sdim CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name); 1093276479Sdim 1094360784Sdim // The incoming attribute set may have come from a speculatable intrinsic, but 1095360784Sdim // is being replaced with a library call which is not allowed to be 1096360784Sdim // speculatable. 1097360784Sdim CI->setAttributes(Attrs.removeAttribute(B.getContext(), 1098360784Sdim AttributeList::FunctionIndex, 1099360784Sdim Attribute::Speculatable)); 1100353358Sdim if (const Function *F = 1101353358Sdim dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 1102276479Sdim CI->setCallingConv(F->getCallingConv()); 1103276479Sdim 1104276479Sdim return CI; 1105276479Sdim} 1106276479Sdim 1107360784SdimValue *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name, 1108360784Sdim IRBuilder<> &B, const AttributeList &Attrs) { 1109360784Sdim assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall"); 1110360784Sdim 1111360784Sdim SmallString<20> NameBuffer; 1112360784Sdim appendTypeSuffix(Op1, Name, NameBuffer); 1113360784Sdim 1114360784Sdim return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs); 1115360784Sdim} 1116360784Sdim 1117360784SdimValue *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, 1118360784Sdim const TargetLibraryInfo *TLI, 1119360784Sdim LibFunc DoubleFn, LibFunc FloatFn, 1120360784Sdim LibFunc LongDoubleFn, IRBuilder<> &B, 1121360784Sdim const AttributeList &Attrs) { 1122360784Sdim // Get the name of the function according to TLI. 1123360784Sdim StringRef Name = getFloatFnName(TLI, Op1->getType(), 1124360784Sdim DoubleFn, FloatFn, LongDoubleFn); 1125360784Sdim 1126360784Sdim return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs); 1127360784Sdim} 1128360784Sdim 1129309124SdimValue *llvm::emitPutChar(Value *Char, IRBuilder<> &B, 1130239462Sdim const TargetLibraryInfo *TLI) { 1131321369Sdim if (!TLI->has(LibFunc_putchar)) 1132276479Sdim return nullptr; 1133239462Sdim 1134309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1135341825Sdim StringRef PutCharName = TLI->getName(LibFunc_putchar); 1136353358Sdim FunctionCallee PutChar = 1137353358Sdim M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty()); 1138341825Sdim inferLibFuncAttributes(M, PutCharName, *TLI); 1139204792Srdivacky CallInst *CI = B.CreateCall(PutChar, 1140204792Srdivacky B.CreateIntCast(Char, 1141204792Srdivacky B.getInt32Ty(), 1142204792Srdivacky /*isSigned*/true, 1143204792Srdivacky "chari"), 1144341825Sdim PutCharName); 1145204792Srdivacky 1146353358Sdim if (const Function *F = 1147353358Sdim dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts())) 1148204792Srdivacky CI->setCallingConv(F->getCallingConv()); 1149204792Srdivacky return CI; 1150204792Srdivacky} 1151204792Srdivacky 1152309124SdimValue *llvm::emitPutS(Value *Str, IRBuilder<> &B, 1153239462Sdim const TargetLibraryInfo *TLI) { 1154321369Sdim if (!TLI->has(LibFunc_puts)) 1155276479Sdim return nullptr; 1156239462Sdim 1157309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1158341825Sdim StringRef PutsName = TLI->getName(LibFunc_puts); 1159353358Sdim FunctionCallee PutS = 1160341825Sdim M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy()); 1161341825Sdim inferLibFuncAttributes(M, PutsName, *TLI); 1162341825Sdim CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName); 1163353358Sdim if (const Function *F = 1164353358Sdim dyn_cast<Function>(PutS.getCallee()->stripPointerCasts())) 1165204792Srdivacky CI->setCallingConv(F->getCallingConv()); 1166239462Sdim return CI; 1167204792Srdivacky} 1168204792Srdivacky 1169309124SdimValue *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B, 1170288943Sdim const TargetLibraryInfo *TLI) { 1171321369Sdim if (!TLI->has(LibFunc_fputc)) 1172276479Sdim return nullptr; 1173239462Sdim 1174309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1175341825Sdim StringRef FPutcName = TLI->getName(LibFunc_fputc); 1176353358Sdim FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), 1177353358Sdim B.getInt32Ty(), File->getType()); 1178204792Srdivacky if (File->getType()->isPointerTy()) 1179341825Sdim inferLibFuncAttributes(M, FPutcName, *TLI); 1180204792Srdivacky Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, 1181204792Srdivacky "chari"); 1182341825Sdim CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName); 1183204792Srdivacky 1184353358Sdim if (const Function *Fn = 1185353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1186204792Srdivacky CI->setCallingConv(Fn->getCallingConv()); 1187239462Sdim return CI; 1188204792Srdivacky} 1189204792Srdivacky 1190341825SdimValue *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B, 1191341825Sdim const TargetLibraryInfo *TLI) { 1192341825Sdim if (!TLI->has(LibFunc_fputc_unlocked)) 1193341825Sdim return nullptr; 1194341825Sdim 1195341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1196341825Sdim StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked); 1197353358Sdim FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(), 1198353358Sdim B.getInt32Ty(), File->getType()); 1199341825Sdim if (File->getType()->isPointerTy()) 1200341825Sdim inferLibFuncAttributes(M, FPutcUnlockedName, *TLI); 1201341825Sdim Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari"); 1202341825Sdim CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName); 1203341825Sdim 1204353358Sdim if (const Function *Fn = 1205353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1206341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1207341825Sdim return CI; 1208341825Sdim} 1209341825Sdim 1210309124SdimValue *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B, 1211288943Sdim const TargetLibraryInfo *TLI) { 1212321369Sdim if (!TLI->has(LibFunc_fputs)) 1213276479Sdim return nullptr; 1214239462Sdim 1215309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1216321369Sdim StringRef FPutsName = TLI->getName(LibFunc_fputs); 1217353358Sdim FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), 1218353358Sdim B.getInt8PtrTy(), File->getType()); 1219204792Srdivacky if (File->getType()->isPointerTy()) 1220341825Sdim inferLibFuncAttributes(M, FPutsName, *TLI); 1221341825Sdim CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName); 1222204792Srdivacky 1223353358Sdim if (const Function *Fn = 1224353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1225204792Srdivacky CI->setCallingConv(Fn->getCallingConv()); 1226239462Sdim return CI; 1227204792Srdivacky} 1228204792Srdivacky 1229341825SdimValue *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B, 1230341825Sdim const TargetLibraryInfo *TLI) { 1231341825Sdim if (!TLI->has(LibFunc_fputs_unlocked)) 1232341825Sdim return nullptr; 1233341825Sdim 1234341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1235341825Sdim StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked); 1236353358Sdim FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(), 1237353358Sdim B.getInt8PtrTy(), File->getType()); 1238341825Sdim if (File->getType()->isPointerTy()) 1239341825Sdim inferLibFuncAttributes(M, FPutsUnlockedName, *TLI); 1240341825Sdim CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName); 1241341825Sdim 1242353358Sdim if (const Function *Fn = 1243353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1244341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1245341825Sdim return CI; 1246341825Sdim} 1247341825Sdim 1248309124SdimValue *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B, 1249288943Sdim const DataLayout &DL, const TargetLibraryInfo *TLI) { 1250321369Sdim if (!TLI->has(LibFunc_fwrite)) 1251276479Sdim return nullptr; 1252239462Sdim 1253309124Sdim Module *M = B.GetInsertBlock()->getModule(); 1254204792Srdivacky LLVMContext &Context = B.GetInsertBlock()->getContext(); 1255321369Sdim StringRef FWriteName = TLI->getName(LibFunc_fwrite); 1256353358Sdim FunctionCallee F = M->getOrInsertFunction( 1257309124Sdim FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(), 1258321369Sdim DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); 1259321369Sdim 1260204792Srdivacky if (File->getType()->isPointerTy()) 1261341825Sdim inferLibFuncAttributes(M, FWriteName, *TLI); 1262288943Sdim CallInst *CI = 1263309124Sdim B.CreateCall(F, {castToCStr(Ptr, B), Size, 1264288943Sdim ConstantInt::get(DL.getIntPtrType(Context), 1), File}); 1265204792Srdivacky 1266353358Sdim if (const Function *Fn = 1267353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1268204792Srdivacky CI->setCallingConv(Fn->getCallingConv()); 1269239462Sdim return CI; 1270204792Srdivacky} 1271341825Sdim 1272341825SdimValue *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL, 1273341825Sdim const TargetLibraryInfo *TLI) { 1274341825Sdim if (!TLI->has(LibFunc_malloc)) 1275341825Sdim return nullptr; 1276341825Sdim 1277341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1278341825Sdim StringRef MallocName = TLI->getName(LibFunc_malloc); 1279341825Sdim LLVMContext &Context = B.GetInsertBlock()->getContext(); 1280353358Sdim FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(), 1281353358Sdim DL.getIntPtrType(Context)); 1282341825Sdim inferLibFuncAttributes(M, MallocName, *TLI); 1283341825Sdim CallInst *CI = B.CreateCall(Malloc, Num, MallocName); 1284341825Sdim 1285353358Sdim if (const Function *F = 1286353358Sdim dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts())) 1287341825Sdim CI->setCallingConv(F->getCallingConv()); 1288341825Sdim 1289341825Sdim return CI; 1290341825Sdim} 1291341825Sdim 1292341825SdimValue *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs, 1293341825Sdim IRBuilder<> &B, const TargetLibraryInfo &TLI) { 1294341825Sdim if (!TLI.has(LibFunc_calloc)) 1295341825Sdim return nullptr; 1296341825Sdim 1297341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1298341825Sdim StringRef CallocName = TLI.getName(LibFunc_calloc); 1299341825Sdim const DataLayout &DL = M->getDataLayout(); 1300341825Sdim IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext())); 1301353358Sdim FunctionCallee Calloc = M->getOrInsertFunction( 1302353358Sdim CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType); 1303341825Sdim inferLibFuncAttributes(M, CallocName, TLI); 1304341825Sdim CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName); 1305341825Sdim 1306353358Sdim if (const auto *F = 1307353358Sdim dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts())) 1308341825Sdim CI->setCallingConv(F->getCallingConv()); 1309341825Sdim 1310341825Sdim return CI; 1311341825Sdim} 1312341825Sdim 1313341825SdimValue *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, 1314341825Sdim IRBuilder<> &B, const DataLayout &DL, 1315341825Sdim const TargetLibraryInfo *TLI) { 1316341825Sdim if (!TLI->has(LibFunc_fwrite_unlocked)) 1317341825Sdim return nullptr; 1318341825Sdim 1319341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1320341825Sdim LLVMContext &Context = B.GetInsertBlock()->getContext(); 1321341825Sdim StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked); 1322353358Sdim FunctionCallee F = M->getOrInsertFunction( 1323341825Sdim FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), 1324341825Sdim DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); 1325341825Sdim 1326341825Sdim if (File->getType()->isPointerTy()) 1327341825Sdim inferLibFuncAttributes(M, FWriteUnlockedName, *TLI); 1328341825Sdim CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); 1329341825Sdim 1330353358Sdim if (const Function *Fn = 1331353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1332341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1333341825Sdim return CI; 1334341825Sdim} 1335341825Sdim 1336341825SdimValue *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B, 1337341825Sdim const TargetLibraryInfo *TLI) { 1338341825Sdim if (!TLI->has(LibFunc_fgetc_unlocked)) 1339341825Sdim return nullptr; 1340341825Sdim 1341341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1342341825Sdim StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked); 1343353358Sdim FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), 1344353358Sdim File->getType()); 1345341825Sdim if (File->getType()->isPointerTy()) 1346341825Sdim inferLibFuncAttributes(M, FGetCUnlockedName, *TLI); 1347341825Sdim CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName); 1348341825Sdim 1349353358Sdim if (const Function *Fn = 1350353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1351341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1352341825Sdim return CI; 1353341825Sdim} 1354341825Sdim 1355341825SdimValue *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File, 1356341825Sdim IRBuilder<> &B, const TargetLibraryInfo *TLI) { 1357341825Sdim if (!TLI->has(LibFunc_fgets_unlocked)) 1358341825Sdim return nullptr; 1359341825Sdim 1360341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1361341825Sdim StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked); 1362353358Sdim FunctionCallee F = 1363341825Sdim M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(), 1364341825Sdim B.getInt8PtrTy(), B.getInt32Ty(), File->getType()); 1365341825Sdim inferLibFuncAttributes(M, FGetSUnlockedName, *TLI); 1366341825Sdim CallInst *CI = 1367341825Sdim B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName); 1368341825Sdim 1369353358Sdim if (const Function *Fn = 1370353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1371341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1372341825Sdim return CI; 1373341825Sdim} 1374341825Sdim 1375341825SdimValue *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File, 1376341825Sdim IRBuilder<> &B, const DataLayout &DL, 1377341825Sdim const TargetLibraryInfo *TLI) { 1378341825Sdim if (!TLI->has(LibFunc_fread_unlocked)) 1379341825Sdim return nullptr; 1380341825Sdim 1381341825Sdim Module *M = B.GetInsertBlock()->getModule(); 1382341825Sdim LLVMContext &Context = B.GetInsertBlock()->getContext(); 1383341825Sdim StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked); 1384353358Sdim FunctionCallee F = M->getOrInsertFunction( 1385341825Sdim FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(), 1386341825Sdim DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType()); 1387341825Sdim 1388341825Sdim if (File->getType()->isPointerTy()) 1389341825Sdim inferLibFuncAttributes(M, FReadUnlockedName, *TLI); 1390341825Sdim CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File}); 1391341825Sdim 1392353358Sdim if (const Function *Fn = 1393353358Sdim dyn_cast<Function>(F.getCallee()->stripPointerCasts())) 1394341825Sdim CI->setCallingConv(Fn->getCallingConv()); 1395341825Sdim return CI; 1396341825Sdim} 1397