2247 lines · cpp
1//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements some functions that will create standard C libcalls.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Transforms/Utils/BuildLibCalls.h"14#include "llvm/ADT/SmallString.h"15#include "llvm/ADT/Statistic.h"16#include "llvm/Analysis/MemoryBuiltins.h"17#include "llvm/Analysis/TargetLibraryInfo.h"18#include "llvm/IR/Argument.h"19#include "llvm/IR/CallingConv.h"20#include "llvm/IR/Constants.h"21#include "llvm/IR/DataLayout.h"22#include "llvm/IR/DerivedTypes.h"23#include "llvm/IR/Function.h"24#include "llvm/IR/IRBuilder.h"25#include "llvm/IR/Module.h"26#include "llvm/IR/Type.h"27#include "llvm/Support/TypeSize.h"28#include <optional>29 30using namespace llvm;31 32#define DEBUG_TYPE "build-libcalls"33 34//- Infer Attributes ---------------------------------------------------------//35 36STATISTIC(NumReadNone, "Number of functions inferred as readnone");37STATISTIC(NumInaccessibleMemOnly,38 "Number of functions inferred as inaccessiblememonly");39STATISTIC(NumReadOnly, "Number of functions inferred as readonly");40STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");41STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");42STATISTIC(NumWriteErrnoMemOnly,43 "Number of functions inferred as memory(errnomem: write)");44STATISTIC(NumInaccessibleMemOrArgMemOnly,45 "Number of functions inferred as inaccessiblemem_or_argmemonly");46STATISTIC(47 NumWriteArgumentMemOrErrnoMemOnly,48 "Number of functions inferred as memory(argmem: write, errnomem: write)");49STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");50STATISTIC(NumNoCallback, "Number of functions inferred as nocallback");51STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");52STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");53STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");54STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");55STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");56STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");57STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");58STATISTIC(NumCold, "Number of functions inferred as cold");59STATISTIC(NumNoReturn, "Number of functions inferred as no return");60 61static bool setDoesNotAccessMemory(Function &F) {62 if (F.doesNotAccessMemory())63 return false;64 F.setDoesNotAccessMemory();65 ++NumReadNone;66 return true;67}68 69static bool setIsCold(Function &F) {70 if (F.hasFnAttribute(Attribute::Cold))71 return false;72 F.addFnAttr(Attribute::Cold);73 ++NumCold;74 return true;75}76 77static bool setNoReturn(Function &F) {78 if (F.hasFnAttribute(Attribute::NoReturn))79 return false;80 F.addFnAttr(Attribute::NoReturn);81 ++NumNoReturn;82 return true;83}84 85static bool setMemoryEffects(Function &F, MemoryEffects ME) {86 MemoryEffects OrigME = F.getMemoryEffects();87 MemoryEffects NewME = OrigME & ME;88 if (OrigME == NewME)89 return false;90 F.setMemoryEffects(NewME);91 return true;92}93 94static bool setOnlyAccessesInaccessibleMemory(Function &F) {95 if (!setMemoryEffects(F, MemoryEffects::inaccessibleMemOnly()))96 return false;97 ++NumInaccessibleMemOnly;98 return true;99}100 101static bool setOnlyReadsMemory(Function &F) {102 if (!setMemoryEffects(F, MemoryEffects::readOnly()))103 return false;104 ++NumReadOnly;105 return true;106}107 108static bool setOnlyWritesMemory(Function &F) {109 if (!setMemoryEffects(F, MemoryEffects::writeOnly()))110 return false;111 ++NumWriteOnly;112 return true;113}114 115static bool setOnlyAccessesArgMemory(Function &F) {116 if (!setMemoryEffects(F, MemoryEffects::argMemOnly()))117 return false;118 ++NumArgMemOnly;119 return true;120}121 122static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {123 if (!setMemoryEffects(F, MemoryEffects::inaccessibleOrArgMemOnly()))124 return false;125 ++NumInaccessibleMemOrArgMemOnly;126 return true;127}128 129static bool setOnlyWritesErrnoMemory(Function &F) {130 if (!setMemoryEffects(F, MemoryEffects::errnoMemOnly(ModRefInfo::Mod)))131 return false;132 ++NumWriteErrnoMemOnly;133 return true;134}135 136static bool setOnlyWritesArgMemOrErrnoMem(Function &F) {137 if (!setMemoryEffects(F, MemoryEffects::argumentOrErrnoMemOnly(138 ModRefInfo::Mod, ModRefInfo::Mod)))139 return false;140 ++NumWriteArgumentMemOrErrnoMemOnly;141 return true;142}143 144static bool setDoesNotThrow(Function &F) {145 if (F.doesNotThrow())146 return false;147 F.setDoesNotThrow();148 ++NumNoUnwind;149 return true;150}151 152static bool setDoesNotCallback(Function &F) {153 if (F.hasFnAttribute(Attribute::NoCallback))154 return false;155 F.addFnAttr(Attribute::NoCallback);156 ++NumNoCallback;157 return true;158}159 160static bool setRetDoesNotAlias(Function &F) {161 if (F.hasRetAttribute(Attribute::NoAlias))162 return false;163 F.addRetAttr(Attribute::NoAlias);164 ++NumNoAlias;165 return true;166}167 168static bool setDoesNotCapture(Function &F, unsigned ArgNo) {169 if (F.hasParamAttribute(ArgNo, Attribute::Captures))170 return false;171 F.addParamAttr(ArgNo, Attribute::getWithCaptureInfo(F.getContext(),172 CaptureInfo::none()));173 ++NumNoCapture;174 return true;175}176 177static bool setDoesNotAlias(Function &F, unsigned ArgNo) {178 if (F.hasParamAttribute(ArgNo, Attribute::NoAlias))179 return false;180 F.addParamAttr(ArgNo, Attribute::NoAlias);181 ++NumNoAlias;182 return true;183}184 185static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {186 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))187 return false;188 F.addParamAttr(ArgNo, Attribute::ReadOnly);189 ++NumReadOnlyArg;190 return true;191}192 193static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {194 if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))195 return false;196 F.addParamAttr(ArgNo, Attribute::WriteOnly);197 ++NumWriteOnlyArg;198 return true;199}200 201static bool setRetNoUndef(Function &F) {202 if (!F.getReturnType()->isVoidTy() &&203 !F.hasRetAttribute(Attribute::NoUndef)) {204 F.addRetAttr(Attribute::NoUndef);205 ++NumNoUndef;206 return true;207 }208 return false;209}210 211static bool setArgsNoUndef(Function &F) {212 bool Changed = false;213 for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {214 if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {215 F.addParamAttr(ArgNo, Attribute::NoUndef);216 ++NumNoUndef;217 Changed = true;218 }219 }220 return Changed;221}222 223static bool setArgNoUndef(Function &F, unsigned ArgNo) {224 if (F.hasParamAttribute(ArgNo, Attribute::NoUndef))225 return false;226 F.addParamAttr(ArgNo, Attribute::NoUndef);227 ++NumNoUndef;228 return true;229}230 231static bool setRetAndArgsNoUndef(Function &F) {232 bool UndefAdded = false;233 UndefAdded |= setRetNoUndef(F);234 UndefAdded |= setArgsNoUndef(F);235 return UndefAdded;236}237 238static bool setReturnedArg(Function &F, unsigned ArgNo) {239 if (F.hasParamAttribute(ArgNo, Attribute::Returned))240 return false;241 F.addParamAttr(ArgNo, Attribute::Returned);242 ++NumReturnedArg;243 return true;244}245 246static bool setNonLazyBind(Function &F) {247 if (F.hasFnAttribute(Attribute::NonLazyBind))248 return false;249 F.addFnAttr(Attribute::NonLazyBind);250 return true;251}252 253static bool setDoesNotFreeMemory(Function &F) {254 if (F.hasFnAttribute(Attribute::NoFree))255 return false;256 F.addFnAttr(Attribute::NoFree);257 return true;258}259 260static bool setWillReturn(Function &F) {261 if (F.hasFnAttribute(Attribute::WillReturn))262 return false;263 F.addFnAttr(Attribute::WillReturn);264 ++NumWillReturn;265 return true;266}267 268static bool setAlignedAllocParam(Function &F, unsigned ArgNo) {269 if (F.hasParamAttribute(ArgNo, Attribute::AllocAlign))270 return false;271 F.addParamAttr(ArgNo, Attribute::AllocAlign);272 return true;273}274 275static bool setAllocatedPointerParam(Function &F, unsigned ArgNo) {276 if (F.hasParamAttribute(ArgNo, Attribute::AllocatedPointer))277 return false;278 F.addParamAttr(ArgNo, Attribute::AllocatedPointer);279 return true;280}281 282static bool setAllocSize(Function &F, unsigned ElemSizeArg,283 std::optional<unsigned> NumElemsArg) {284 if (F.hasFnAttribute(Attribute::AllocSize))285 return false;286 F.addFnAttr(Attribute::getWithAllocSizeArgs(F.getContext(), ElemSizeArg,287 NumElemsArg));288 return true;289}290 291static bool setAllocFamily(Function &F, StringRef Family) {292 if (F.hasFnAttribute("alloc-family"))293 return false;294 F.addFnAttr("alloc-family", Family);295 return true;296}297 298static bool setAllocKind(Function &F, AllocFnKind K) {299 if (F.hasFnAttribute(Attribute::AllocKind))300 return false;301 F.addFnAttr(302 Attribute::get(F.getContext(), Attribute::AllocKind, uint64_t(K)));303 return true;304}305 306bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,307 const TargetLibraryInfo &TLI) {308 Function *F = M->getFunction(Name);309 if (!F)310 return false;311 return inferNonMandatoryLibFuncAttrs(*F, TLI);312}313 314bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,315 const TargetLibraryInfo &TLI) {316 LibFunc TheLibFunc;317 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))318 return false;319 320 bool Changed = false;321 322 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())323 Changed |= setNonLazyBind(F);324 325 switch (TheLibFunc) {326 case LibFunc_nan:327 case LibFunc_nanf:328 case LibFunc_nanl:329 case LibFunc_strlen:330 case LibFunc_strnlen:331 case LibFunc_wcslen:332 Changed |= setOnlyReadsMemory(F);333 Changed |= setDoesNotThrow(F);334 Changed |= setDoesNotCallback(F);335 Changed |= setOnlyAccessesArgMemory(F);336 Changed |= setWillReturn(F);337 Changed |= setDoesNotCapture(F, 0);338 break;339 case LibFunc_strchr:340 case LibFunc_strrchr:341 Changed |= setOnlyAccessesArgMemory(F);342 Changed |= setOnlyReadsMemory(F);343 Changed |= setDoesNotThrow(F);344 Changed |= setDoesNotCallback(F);345 Changed |= setWillReturn(F);346 break;347 case LibFunc_strtol:348 case LibFunc_strtod:349 case LibFunc_strtof:350 case LibFunc_strtoul:351 case LibFunc_strtoll:352 case LibFunc_strtold:353 case LibFunc_strtoull:354 Changed |= setDoesNotThrow(F);355 Changed |= setDoesNotCallback(F);356 Changed |= setWillReturn(F);357 Changed |= setDoesNotCapture(F, 1);358 Changed |= setOnlyReadsMemory(F, 0);359 break;360 case LibFunc_strcat:361 case LibFunc_strncat:362 Changed |= setOnlyAccessesArgMemory(F);363 Changed |= setDoesNotThrow(F);364 Changed |= setDoesNotCallback(F);365 Changed |= setWillReturn(F);366 Changed |= setReturnedArg(F, 0);367 Changed |= setDoesNotCapture(F, 1);368 Changed |= setOnlyReadsMemory(F, 1);369 Changed |= setDoesNotAlias(F, 0);370 Changed |= setDoesNotAlias(F, 1);371 break;372 case LibFunc_strcpy:373 case LibFunc_strncpy:374 Changed |= setReturnedArg(F, 0);375 [[fallthrough]];376 case LibFunc_stpcpy:377 case LibFunc_stpncpy:378 Changed |= setOnlyAccessesArgMemory(F);379 Changed |= setDoesNotThrow(F);380 Changed |= setDoesNotCallback(F);381 Changed |= setWillReturn(F);382 Changed |= setDoesNotCapture(F, 1);383 Changed |= setOnlyWritesMemory(F, 0);384 Changed |= setOnlyReadsMemory(F, 1);385 Changed |= setDoesNotAlias(F, 0);386 Changed |= setDoesNotAlias(F, 1);387 break;388 case LibFunc_strxfrm:389 Changed |= setDoesNotThrow(F);390 Changed |= setDoesNotCallback(F);391 Changed |= setWillReturn(F);392 Changed |= setDoesNotCapture(F, 0);393 Changed |= setDoesNotCapture(F, 1);394 Changed |= setOnlyReadsMemory(F, 1);395 break;396 case LibFunc_strcmp: // 0,1397 case LibFunc_strspn: // 0,1398 case LibFunc_strncmp: // 0,1399 case LibFunc_strcspn: // 0,1400 Changed |= setDoesNotThrow(F);401 Changed |= setDoesNotCallback(F);402 Changed |= setOnlyAccessesArgMemory(F);403 Changed |= setWillReturn(F);404 Changed |= setOnlyReadsMemory(F);405 Changed |= setDoesNotCapture(F, 0);406 Changed |= setDoesNotCapture(F, 1);407 break;408 case LibFunc_strcoll:409 case LibFunc_strcasecmp: // 0,1410 case LibFunc_strncasecmp: //411 // Those functions may depend on the locale, which may be accessed through412 // global memory.413 Changed |= setOnlyReadsMemory(F);414 Changed |= setDoesNotThrow(F);415 Changed |= setDoesNotCallback(F);416 Changed |= setWillReturn(F);417 Changed |= setDoesNotCapture(F, 0);418 Changed |= setDoesNotCapture(F, 1);419 break;420 case LibFunc_strstr:421 case LibFunc_strpbrk:422 Changed |= setOnlyAccessesArgMemory(F);423 Changed |= setOnlyReadsMemory(F);424 Changed |= setDoesNotThrow(F);425 Changed |= setDoesNotCallback(F);426 Changed |= setWillReturn(F);427 Changed |= setDoesNotCapture(F, 1);428 break;429 case LibFunc_strtok:430 case LibFunc_strtok_r:431 Changed |= setDoesNotThrow(F);432 Changed |= setDoesNotCallback(F);433 Changed |= setWillReturn(F);434 Changed |= setDoesNotCapture(F, 1);435 Changed |= setOnlyReadsMemory(F, 1);436 break;437 case LibFunc_scanf:438 Changed |= setRetAndArgsNoUndef(F);439 Changed |= setDoesNotThrow(F);440 Changed |= setDoesNotCapture(F, 0);441 Changed |= setOnlyReadsMemory(F, 0);442 break;443 case LibFunc_setbuf:444 case LibFunc_setvbuf:445 Changed |= setRetAndArgsNoUndef(F);446 Changed |= setDoesNotThrow(F);447 Changed |= setDoesNotCapture(F, 0);448 break;449 case LibFunc_strndup:450 Changed |= setArgNoUndef(F, 1);451 [[fallthrough]];452 case LibFunc_strdup:453 Changed |= setAllocFamily(F, "malloc");454 Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);455 Changed |= setDoesNotThrow(F);456 Changed |= setRetDoesNotAlias(F);457 Changed |= setWillReturn(F);458 Changed |= setDoesNotCapture(F, 0);459 Changed |= setOnlyReadsMemory(F, 0);460 break;461 case LibFunc_stat:462 case LibFunc_statvfs:463 Changed |= setRetAndArgsNoUndef(F);464 Changed |= setDoesNotThrow(F);465 Changed |= setDoesNotCapture(F, 0);466 Changed |= setDoesNotCapture(F, 1);467 Changed |= setOnlyReadsMemory(F, 0);468 break;469 case LibFunc_sscanf:470 Changed |= setRetAndArgsNoUndef(F);471 Changed |= setDoesNotThrow(F);472 Changed |= setDoesNotCapture(F, 0);473 Changed |= setDoesNotCapture(F, 1);474 Changed |= setOnlyReadsMemory(F, 0);475 Changed |= setOnlyReadsMemory(F, 1);476 break;477 case LibFunc_sprintf:478 Changed |= setRetAndArgsNoUndef(F);479 Changed |= setDoesNotThrow(F);480 Changed |= setDoesNotCapture(F, 0);481 Changed |= setDoesNotAlias(F, 0);482 Changed |= setOnlyWritesMemory(F, 0);483 Changed |= setDoesNotCapture(F, 1);484 Changed |= setOnlyReadsMemory(F, 1);485 break;486 case LibFunc_snprintf:487 Changed |= setRetAndArgsNoUndef(F);488 Changed |= setDoesNotThrow(F);489 Changed |= setDoesNotCapture(F, 0);490 Changed |= setDoesNotAlias(F, 0);491 Changed |= setOnlyWritesMemory(F, 0);492 Changed |= setDoesNotCapture(F, 2);493 Changed |= setOnlyReadsMemory(F, 2);494 break;495 case LibFunc_setitimer:496 Changed |= setRetAndArgsNoUndef(F);497 Changed |= setDoesNotThrow(F);498 Changed |= setWillReturn(F);499 Changed |= setDoesNotCapture(F, 1);500 Changed |= setDoesNotCapture(F, 2);501 Changed |= setOnlyReadsMemory(F, 1);502 break;503 case LibFunc_system:504 // May throw; "system" is a valid pthread cancellation point.505 Changed |= setRetAndArgsNoUndef(F);506 Changed |= setDoesNotCapture(F, 0);507 Changed |= setOnlyReadsMemory(F, 0);508 break;509 case LibFunc_aligned_alloc:510 Changed |= setAlignedAllocParam(F, 0);511 Changed |= setAllocSize(F, 1, std::nullopt);512 Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized | AllocFnKind::Aligned);513 [[fallthrough]];514 case LibFunc_valloc:515 case LibFunc_malloc:516 case LibFunc_vec_malloc:517 Changed |= setAllocSize(F, 0, std::nullopt);518 [[fallthrough]];519 case LibFunc_pvalloc:520 Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_malloc ? "vec_malloc"521 : "malloc");522 Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized);523 Changed |= setOnlyAccessesInaccessibleMemory(F);524 Changed |= setRetAndArgsNoUndef(F);525 Changed |= setDoesNotThrow(F);526 Changed |= setRetDoesNotAlias(F);527 Changed |= setWillReturn(F);528 break;529 case LibFunc_memcmp:530 Changed |= setOnlyAccessesArgMemory(F);531 Changed |= setOnlyReadsMemory(F);532 Changed |= setDoesNotThrow(F);533 Changed |= setDoesNotCallback(F);534 Changed |= setWillReturn(F);535 Changed |= setDoesNotCapture(F, 0);536 Changed |= setDoesNotCapture(F, 1);537 break;538 case LibFunc_memchr:539 case LibFunc_memrchr:540 Changed |= setDoesNotThrow(F);541 Changed |= setDoesNotCallback(F);542 Changed |= setOnlyAccessesArgMemory(F);543 Changed |= setOnlyReadsMemory(F);544 Changed |= setWillReturn(F);545 break;546 case LibFunc_modf:547 case LibFunc_modff:548 case LibFunc_modfl:549 Changed |= setDoesNotThrow(F);550 Changed |= setDoesNotCallback(F);551 Changed |= setWillReturn(F);552 Changed |= setOnlyAccessesArgMemory(F);553 Changed |= setOnlyWritesMemory(F);554 Changed |= setDoesNotCapture(F, 1);555 break;556 case LibFunc_memcpy:557 Changed |= setDoesNotThrow(F);558 Changed |= setDoesNotCallback(F);559 Changed |= setOnlyAccessesArgMemory(F);560 Changed |= setWillReturn(F);561 Changed |= setDoesNotAlias(F, 0);562 Changed |= setReturnedArg(F, 0);563 Changed |= setOnlyWritesMemory(F, 0);564 Changed |= setDoesNotAlias(F, 1);565 Changed |= setDoesNotCapture(F, 1);566 Changed |= setOnlyReadsMemory(F, 1);567 break;568 case LibFunc_memmove:569 Changed |= setDoesNotThrow(F);570 Changed |= setDoesNotCallback(F);571 Changed |= setOnlyAccessesArgMemory(F);572 Changed |= setWillReturn(F);573 Changed |= setReturnedArg(F, 0);574 Changed |= setOnlyWritesMemory(F, 0);575 Changed |= setDoesNotCapture(F, 1);576 Changed |= setOnlyReadsMemory(F, 1);577 break;578 case LibFunc_mempcpy:579 case LibFunc_memccpy:580 Changed |= setWillReturn(F);581 [[fallthrough]];582 case LibFunc_memcpy_chk:583 Changed |= setDoesNotThrow(F);584 Changed |= setDoesNotCallback(F);585 Changed |= setOnlyAccessesArgMemory(F);586 Changed |= setDoesNotAlias(F, 0);587 Changed |= setOnlyWritesMemory(F, 0);588 Changed |= setDoesNotAlias(F, 1);589 Changed |= setDoesNotCapture(F, 1);590 Changed |= setOnlyReadsMemory(F, 1);591 break;592 case LibFunc_memalign:593 Changed |= setAllocFamily(F, "malloc");594 Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Aligned |595 AllocFnKind::Uninitialized);596 Changed |= setAllocSize(F, 1, std::nullopt);597 Changed |= setAlignedAllocParam(F, 0);598 Changed |= setOnlyAccessesInaccessibleMemory(F);599 Changed |= setRetNoUndef(F);600 Changed |= setDoesNotThrow(F);601 Changed |= setRetDoesNotAlias(F);602 Changed |= setWillReturn(F);603 break;604 case LibFunc_mkdir:605 Changed |= setRetAndArgsNoUndef(F);606 Changed |= setDoesNotThrow(F);607 Changed |= setDoesNotCapture(F, 0);608 Changed |= setOnlyReadsMemory(F, 0);609 break;610 case LibFunc_mktime:611 Changed |= setRetAndArgsNoUndef(F);612 Changed |= setDoesNotThrow(F);613 Changed |= setWillReturn(F);614 Changed |= setDoesNotCapture(F, 0);615 break;616 case LibFunc_realloc:617 case LibFunc_reallocf:618 case LibFunc_vec_realloc:619 Changed |= setAllocFamily(620 F, TheLibFunc == LibFunc_vec_realloc ? "vec_malloc" : "malloc");621 Changed |= setAllocKind(F, AllocFnKind::Realloc);622 Changed |= setAllocatedPointerParam(F, 0);623 Changed |= setAllocSize(F, 1, std::nullopt);624 Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);625 Changed |= setRetNoUndef(F);626 Changed |= setDoesNotThrow(F);627 Changed |= setRetDoesNotAlias(F);628 Changed |= setWillReturn(F);629 Changed |= setDoesNotCapture(F, 0);630 Changed |= setArgNoUndef(F, 1);631 break;632 case LibFunc_reallocarray:633 Changed |= setAllocFamily(F, "malloc");634 Changed |= setAllocKind(F, AllocFnKind::Realloc);635 Changed |= setAllocatedPointerParam(F, 0);636 Changed |= setAllocSize(F, 1, 2);637 Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);638 Changed |= setRetNoUndef(F);639 Changed |= setDoesNotThrow(F);640 Changed |= setRetDoesNotAlias(F);641 Changed |= setWillReturn(F);642 Changed |= setDoesNotCapture(F, 0);643 Changed |= setArgNoUndef(F, 1);644 Changed |= setArgNoUndef(F, 2);645 break;646 case LibFunc_read:647 // May throw; "read" is a valid pthread cancellation point.648 Changed |= setRetAndArgsNoUndef(F);649 Changed |= setDoesNotCapture(F, 1);650 break;651 case LibFunc_rewind:652 Changed |= setRetAndArgsNoUndef(F);653 Changed |= setDoesNotThrow(F);654 Changed |= setDoesNotCapture(F, 0);655 break;656 case LibFunc_rmdir:657 case LibFunc_remove:658 case LibFunc_realpath:659 Changed |= setRetAndArgsNoUndef(F);660 Changed |= setDoesNotThrow(F);661 Changed |= setDoesNotCapture(F, 0);662 Changed |= setOnlyReadsMemory(F, 0);663 break;664 case LibFunc_rename:665 Changed |= setRetAndArgsNoUndef(F);666 Changed |= setDoesNotThrow(F);667 Changed |= setDoesNotCapture(F, 0);668 Changed |= setDoesNotCapture(F, 1);669 Changed |= setOnlyReadsMemory(F, 0);670 Changed |= setOnlyReadsMemory(F, 1);671 break;672 case LibFunc_readlink:673 Changed |= setRetAndArgsNoUndef(F);674 Changed |= setDoesNotThrow(F);675 Changed |= setDoesNotCapture(F, 0);676 Changed |= setDoesNotCapture(F, 1);677 Changed |= setOnlyReadsMemory(F, 0);678 break;679 case LibFunc_write:680 // May throw; "write" is a valid pthread cancellation point.681 Changed |= setRetAndArgsNoUndef(F);682 Changed |= setDoesNotCapture(F, 1);683 Changed |= setOnlyReadsMemory(F, 1);684 break;685 case LibFunc_bcopy:686 Changed |= setDoesNotThrow(F);687 Changed |= setDoesNotCallback(F);688 Changed |= setOnlyAccessesArgMemory(F);689 Changed |= setWillReturn(F);690 Changed |= setDoesNotCapture(F, 0);691 Changed |= setOnlyReadsMemory(F, 0);692 Changed |= setOnlyWritesMemory(F, 1);693 Changed |= setDoesNotCapture(F, 1);694 break;695 case LibFunc_bcmp:696 Changed |= setDoesNotThrow(F);697 Changed |= setDoesNotCallback(F);698 Changed |= setOnlyAccessesArgMemory(F);699 Changed |= setOnlyReadsMemory(F);700 Changed |= setWillReturn(F);701 Changed |= setDoesNotCapture(F, 0);702 Changed |= setDoesNotCapture(F, 1);703 break;704 case LibFunc_bzero:705 Changed |= setDoesNotThrow(F);706 Changed |= setDoesNotCallback(F);707 Changed |= setOnlyAccessesArgMemory(F);708 Changed |= setWillReturn(F);709 Changed |= setDoesNotCapture(F, 0);710 Changed |= setOnlyWritesMemory(F, 0);711 break;712 case LibFunc_calloc:713 case LibFunc_vec_calloc:714 Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_calloc ? "vec_malloc"715 : "malloc");716 Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Zeroed);717 Changed |= setAllocSize(F, 0, 1);718 Changed |= setOnlyAccessesInaccessibleMemory(F);719 Changed |= setRetAndArgsNoUndef(F);720 Changed |= setDoesNotThrow(F);721 Changed |= setRetDoesNotAlias(F);722 Changed |= setWillReturn(F);723 break;724 case LibFunc_chmod:725 case LibFunc_chown:726 Changed |= setRetAndArgsNoUndef(F);727 Changed |= setDoesNotThrow(F);728 Changed |= setDoesNotCapture(F, 0);729 Changed |= setOnlyReadsMemory(F, 0);730 break;731 case LibFunc_ctermid:732 case LibFunc_clearerr:733 case LibFunc_closedir:734 Changed |= setRetAndArgsNoUndef(F);735 Changed |= setDoesNotThrow(F);736 Changed |= setDoesNotCapture(F, 0);737 break;738 case LibFunc_atoi:739 case LibFunc_atol:740 case LibFunc_atof:741 case LibFunc_atoll:742 Changed |= setDoesNotThrow(F);743 Changed |= setDoesNotCallback(F);744 Changed |= setOnlyReadsMemory(F);745 Changed |= setWillReturn(F);746 Changed |= setDoesNotCapture(F, 0);747 break;748 case LibFunc_access:749 Changed |= setRetAndArgsNoUndef(F);750 Changed |= setDoesNotThrow(F);751 Changed |= setDoesNotCapture(F, 0);752 Changed |= setOnlyReadsMemory(F, 0);753 break;754 case LibFunc_fopen:755 Changed |= setRetAndArgsNoUndef(F);756 Changed |= setDoesNotThrow(F);757 Changed |= setRetDoesNotAlias(F);758 Changed |= setDoesNotCapture(F, 0);759 Changed |= setDoesNotCapture(F, 1);760 Changed |= setOnlyReadsMemory(F, 0);761 Changed |= setOnlyReadsMemory(F, 1);762 break;763 case LibFunc_fdopen:764 Changed |= setRetAndArgsNoUndef(F);765 Changed |= setDoesNotThrow(F);766 Changed |= setRetDoesNotAlias(F);767 Changed |= setDoesNotCapture(F, 1);768 Changed |= setOnlyReadsMemory(F, 1);769 break;770 case LibFunc_feof:771 Changed |= setRetAndArgsNoUndef(F);772 Changed |= setDoesNotThrow(F);773 Changed |= setDoesNotCapture(F, 0);774 break;775 case LibFunc_free:776 case LibFunc_vec_free:777 Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_free ? "vec_malloc"778 : "malloc");779 Changed |= setAllocKind(F, AllocFnKind::Free);780 Changed |= setAllocatedPointerParam(F, 0);781 Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);782 Changed |= setArgsNoUndef(F);783 Changed |= setDoesNotThrow(F);784 Changed |= setWillReturn(F);785 Changed |= setDoesNotCapture(F, 0);786 break;787 case LibFunc_fseek:788 case LibFunc_ftell:789 case LibFunc_fgetc:790 case LibFunc_fgetc_unlocked:791 case LibFunc_fseeko:792 case LibFunc_ftello:793 case LibFunc_fileno:794 case LibFunc_fflush:795 case LibFunc_fclose:796 case LibFunc_fsetpos:797 case LibFunc_flockfile:798 case LibFunc_funlockfile:799 case LibFunc_ftrylockfile:800 Changed |= setRetAndArgsNoUndef(F);801 Changed |= setDoesNotThrow(F);802 Changed |= setDoesNotCapture(F, 0);803 break;804 case LibFunc_ferror:805 Changed |= setRetAndArgsNoUndef(F);806 Changed |= setDoesNotThrow(F);807 Changed |= setDoesNotCapture(F, 0);808 Changed |= setOnlyReadsMemory(F);809 break;810 case LibFunc_fputc:811 case LibFunc_fputc_unlocked:812 case LibFunc_fstat:813 Changed |= setRetAndArgsNoUndef(F);814 Changed |= setDoesNotThrow(F);815 Changed |= setDoesNotCapture(F, 1);816 break;817 case LibFunc_frexp:818 case LibFunc_frexpf:819 case LibFunc_frexpl:820 Changed |= setDoesNotThrow(F);821 Changed |= setDoesNotCallback(F);822 Changed |= setWillReturn(F);823 Changed |= setOnlyAccessesArgMemory(F);824 Changed |= setOnlyWritesMemory(F);825 Changed |= setDoesNotCapture(F, 1);826 break;827 case LibFunc_fstatvfs:828 Changed |= setRetAndArgsNoUndef(F);829 Changed |= setDoesNotThrow(F);830 Changed |= setDoesNotCapture(F, 1);831 break;832 case LibFunc_fgets:833 case LibFunc_fgets_unlocked:834 Changed |= setRetAndArgsNoUndef(F);835 Changed |= setDoesNotThrow(F);836 Changed |= setDoesNotCapture(F, 2);837 Changed |= setOnlyWritesMemory(F, 0);838 break;839 case LibFunc_fread:840 case LibFunc_fread_unlocked:841 Changed |= setRetAndArgsNoUndef(F);842 Changed |= setDoesNotThrow(F);843 Changed |= setDoesNotCapture(F, 0);844 Changed |= setDoesNotCapture(F, 3);845 Changed |= setOnlyWritesMemory(F, 0);846 break;847 case LibFunc_fwrite:848 case LibFunc_fwrite_unlocked:849 Changed |= setRetAndArgsNoUndef(F);850 Changed |= setDoesNotThrow(F);851 Changed |= setDoesNotCapture(F, 0);852 Changed |= setDoesNotCapture(F, 3);853 Changed |= setOnlyReadsMemory(F, 0);854 break;855 case LibFunc_fputs:856 case LibFunc_fputs_unlocked:857 Changed |= setRetAndArgsNoUndef(F);858 Changed |= setDoesNotThrow(F);859 Changed |= setDoesNotCapture(F, 0);860 Changed |= setDoesNotCapture(F, 1);861 Changed |= setOnlyReadsMemory(F, 0);862 break;863 case LibFunc_fscanf:864 case LibFunc_fprintf:865 Changed |= setRetAndArgsNoUndef(F);866 Changed |= setDoesNotThrow(F);867 Changed |= setDoesNotCapture(F, 0);868 Changed |= setDoesNotCapture(F, 1);869 Changed |= setOnlyReadsMemory(F, 1);870 break;871 case LibFunc_fgetpos:872 Changed |= setRetAndArgsNoUndef(F);873 Changed |= setDoesNotThrow(F);874 Changed |= setDoesNotCapture(F, 0);875 Changed |= setDoesNotCapture(F, 1);876 break;877 case LibFunc_getc:878 Changed |= setRetAndArgsNoUndef(F);879 Changed |= setDoesNotThrow(F);880 Changed |= setDoesNotCapture(F, 0);881 break;882 case LibFunc_getlogin_r:883 Changed |= setRetAndArgsNoUndef(F);884 Changed |= setDoesNotThrow(F);885 Changed |= setDoesNotCapture(F, 0);886 break;887 case LibFunc_getc_unlocked:888 Changed |= setRetAndArgsNoUndef(F);889 Changed |= setDoesNotThrow(F);890 Changed |= setDoesNotCapture(F, 0);891 break;892 case LibFunc_getenv:893 Changed |= setRetAndArgsNoUndef(F);894 Changed |= setDoesNotThrow(F);895 Changed |= setOnlyReadsMemory(F);896 Changed |= setDoesNotCapture(F, 0);897 break;898 case LibFunc_gets:899 case LibFunc_getchar:900 case LibFunc_getchar_unlocked:901 Changed |= setRetAndArgsNoUndef(F);902 Changed |= setDoesNotThrow(F);903 break;904 case LibFunc_getitimer:905 Changed |= setRetAndArgsNoUndef(F);906 Changed |= setDoesNotThrow(F);907 Changed |= setDoesNotCapture(F, 1);908 break;909 case LibFunc_getpwnam:910 Changed |= setRetAndArgsNoUndef(F);911 Changed |= setDoesNotThrow(F);912 Changed |= setDoesNotCapture(F, 0);913 Changed |= setOnlyReadsMemory(F, 0);914 break;915 case LibFunc_ungetc:916 Changed |= setRetAndArgsNoUndef(F);917 Changed |= setDoesNotThrow(F);918 Changed |= setDoesNotCapture(F, 1);919 break;920 case LibFunc_uname:921 Changed |= setRetAndArgsNoUndef(F);922 Changed |= setDoesNotThrow(F);923 Changed |= setDoesNotCapture(F, 0);924 break;925 case LibFunc_unlink:926 Changed |= setRetAndArgsNoUndef(F);927 Changed |= setDoesNotThrow(F);928 Changed |= setDoesNotCapture(F, 0);929 Changed |= setOnlyReadsMemory(F, 0);930 break;931 case LibFunc_unsetenv:932 Changed |= setRetAndArgsNoUndef(F);933 Changed |= setDoesNotThrow(F);934 Changed |= setDoesNotCapture(F, 0);935 Changed |= setOnlyReadsMemory(F, 0);936 break;937 case LibFunc_utime:938 case LibFunc_utimes:939 Changed |= setRetAndArgsNoUndef(F);940 Changed |= setDoesNotThrow(F);941 Changed |= setDoesNotCapture(F, 0);942 Changed |= setDoesNotCapture(F, 1);943 Changed |= setOnlyReadsMemory(F, 0);944 Changed |= setOnlyReadsMemory(F, 1);945 break;946 case LibFunc_putc:947 case LibFunc_putc_unlocked:948 Changed |= setRetAndArgsNoUndef(F);949 Changed |= setDoesNotThrow(F);950 Changed |= setDoesNotCapture(F, 1);951 break;952 case LibFunc_puts:953 case LibFunc_printf:954 case LibFunc_perror:955 Changed |= setRetAndArgsNoUndef(F);956 Changed |= setDoesNotThrow(F);957 Changed |= setDoesNotCapture(F, 0);958 Changed |= setOnlyReadsMemory(F, 0);959 break;960 case LibFunc_pread:961 // May throw; "pread" is a valid pthread cancellation point.962 Changed |= setRetAndArgsNoUndef(F);963 Changed |= setDoesNotCapture(F, 1);964 break;965 case LibFunc_pwrite:966 // May throw; "pwrite" is a valid pthread cancellation point.967 Changed |= setRetAndArgsNoUndef(F);968 Changed |= setDoesNotCapture(F, 1);969 Changed |= setOnlyReadsMemory(F, 1);970 break;971 case LibFunc_putchar:972 case LibFunc_putchar_unlocked:973 Changed |= setRetAndArgsNoUndef(F);974 Changed |= setDoesNotThrow(F);975 break;976 case LibFunc_popen:977 Changed |= setRetAndArgsNoUndef(F);978 Changed |= setDoesNotThrow(F);979 Changed |= setRetDoesNotAlias(F);980 Changed |= setDoesNotCapture(F, 0);981 Changed |= setDoesNotCapture(F, 1);982 Changed |= setOnlyReadsMemory(F, 0);983 Changed |= setOnlyReadsMemory(F, 1);984 break;985 case LibFunc_pclose:986 Changed |= setRetAndArgsNoUndef(F);987 Changed |= setDoesNotThrow(F);988 Changed |= setDoesNotCapture(F, 0);989 break;990 case LibFunc_vscanf:991 Changed |= setRetAndArgsNoUndef(F);992 Changed |= setDoesNotThrow(F);993 Changed |= setDoesNotCapture(F, 0);994 Changed |= setOnlyReadsMemory(F, 0);995 break;996 case LibFunc_vsscanf:997 Changed |= setRetAndArgsNoUndef(F);998 Changed |= setDoesNotThrow(F);999 Changed |= setDoesNotCapture(F, 0);1000 Changed |= setDoesNotCapture(F, 1);1001 Changed |= setOnlyReadsMemory(F, 0);1002 Changed |= setOnlyReadsMemory(F, 1);1003 break;1004 case LibFunc_vfscanf:1005 Changed |= setRetAndArgsNoUndef(F);1006 Changed |= setDoesNotThrow(F);1007 Changed |= setDoesNotCapture(F, 0);1008 Changed |= setDoesNotCapture(F, 1);1009 Changed |= setOnlyReadsMemory(F, 1);1010 break;1011 case LibFunc_vprintf:1012 Changed |= setRetAndArgsNoUndef(F);1013 Changed |= setDoesNotThrow(F);1014 Changed |= setDoesNotCapture(F, 0);1015 Changed |= setOnlyReadsMemory(F, 0);1016 break;1017 case LibFunc_vfprintf:1018 case LibFunc_vsprintf:1019 Changed |= setRetAndArgsNoUndef(F);1020 Changed |= setDoesNotThrow(F);1021 Changed |= setDoesNotCapture(F, 0);1022 Changed |= setDoesNotCapture(F, 1);1023 Changed |= setOnlyReadsMemory(F, 1);1024 break;1025 case LibFunc_vsnprintf:1026 Changed |= setRetAndArgsNoUndef(F);1027 Changed |= setDoesNotThrow(F);1028 Changed |= setDoesNotCapture(F, 0);1029 Changed |= setDoesNotCapture(F, 2);1030 Changed |= setOnlyReadsMemory(F, 2);1031 break;1032 case LibFunc_open:1033 // May throw; "open" is a valid pthread cancellation point.1034 Changed |= setRetAndArgsNoUndef(F);1035 Changed |= setDoesNotCapture(F, 0);1036 Changed |= setOnlyReadsMemory(F, 0);1037 break;1038 case LibFunc_opendir:1039 Changed |= setRetAndArgsNoUndef(F);1040 Changed |= setDoesNotThrow(F);1041 Changed |= setRetDoesNotAlias(F);1042 Changed |= setDoesNotCapture(F, 0);1043 Changed |= setOnlyReadsMemory(F, 0);1044 break;1045 case LibFunc_tmpfile:1046 Changed |= setRetAndArgsNoUndef(F);1047 Changed |= setDoesNotThrow(F);1048 Changed |= setRetDoesNotAlias(F);1049 break;1050 case LibFunc_times:1051 Changed |= setRetAndArgsNoUndef(F);1052 Changed |= setDoesNotThrow(F);1053 Changed |= setDoesNotCapture(F, 0);1054 break;1055 case LibFunc_htonl:1056 case LibFunc_htons:1057 case LibFunc_ntohl:1058 case LibFunc_ntohs:1059 Changed |= setDoesNotThrow(F);1060 Changed |= setDoesNotCallback(F);1061 Changed |= setDoesNotAccessMemory(F);1062 break;1063 case LibFunc_lstat:1064 Changed |= setRetAndArgsNoUndef(F);1065 Changed |= setDoesNotThrow(F);1066 Changed |= setDoesNotCapture(F, 0);1067 Changed |= setDoesNotCapture(F, 1);1068 Changed |= setOnlyReadsMemory(F, 0);1069 break;1070 case LibFunc_lchown:1071 Changed |= setRetAndArgsNoUndef(F);1072 Changed |= setDoesNotThrow(F);1073 Changed |= setDoesNotCapture(F, 0);1074 Changed |= setOnlyReadsMemory(F, 0);1075 break;1076 case LibFunc_qsort:1077 // May throw/callback; places call through function pointer.1078 // Cannot give undef pointer/size1079 Changed |= setRetAndArgsNoUndef(F);1080 Changed |= setDoesNotCapture(F, 3);1081 break;1082 case LibFunc_dunder_strndup:1083 Changed |= setArgNoUndef(F, 1);1084 [[fallthrough]];1085 case LibFunc_dunder_strdup:1086 Changed |= setDoesNotThrow(F);1087 Changed |= setRetDoesNotAlias(F);1088 Changed |= setWillReturn(F);1089 Changed |= setDoesNotCapture(F, 0);1090 Changed |= setOnlyReadsMemory(F, 0);1091 break;1092 case LibFunc_dunder_strtok_r:1093 Changed |= setDoesNotThrow(F);1094 Changed |= setDoesNotCallback(F);1095 Changed |= setDoesNotCapture(F, 1);1096 Changed |= setOnlyReadsMemory(F, 1);1097 break;1098 case LibFunc_under_IO_getc:1099 Changed |= setRetAndArgsNoUndef(F);1100 Changed |= setDoesNotThrow(F);1101 Changed |= setDoesNotCapture(F, 0);1102 break;1103 case LibFunc_under_IO_putc:1104 Changed |= setRetAndArgsNoUndef(F);1105 Changed |= setDoesNotThrow(F);1106 Changed |= setDoesNotCapture(F, 1);1107 break;1108 case LibFunc_dunder_isoc99_scanf:1109 Changed |= setRetAndArgsNoUndef(F);1110 Changed |= setDoesNotThrow(F);1111 Changed |= setDoesNotCapture(F, 0);1112 Changed |= setOnlyReadsMemory(F, 0);1113 break;1114 case LibFunc_stat64:1115 case LibFunc_lstat64:1116 case LibFunc_statvfs64:1117 Changed |= setRetAndArgsNoUndef(F);1118 Changed |= setDoesNotThrow(F);1119 Changed |= setDoesNotCapture(F, 0);1120 Changed |= setDoesNotCapture(F, 1);1121 Changed |= setOnlyReadsMemory(F, 0);1122 break;1123 case LibFunc_dunder_isoc99_sscanf:1124 Changed |= setRetAndArgsNoUndef(F);1125 Changed |= setDoesNotThrow(F);1126 Changed |= setDoesNotCapture(F, 0);1127 Changed |= setDoesNotCapture(F, 1);1128 Changed |= setOnlyReadsMemory(F, 0);1129 Changed |= setOnlyReadsMemory(F, 1);1130 break;1131 case LibFunc_fopen64:1132 Changed |= setRetAndArgsNoUndef(F);1133 Changed |= setDoesNotThrow(F);1134 Changed |= setRetDoesNotAlias(F);1135 Changed |= setDoesNotCapture(F, 0);1136 Changed |= setDoesNotCapture(F, 1);1137 Changed |= setOnlyReadsMemory(F, 0);1138 Changed |= setOnlyReadsMemory(F, 1);1139 break;1140 case LibFunc_fseeko64:1141 case LibFunc_ftello64:1142 Changed |= setRetAndArgsNoUndef(F);1143 Changed |= setDoesNotThrow(F);1144 Changed |= setDoesNotCapture(F, 0);1145 break;1146 case LibFunc_tmpfile64:1147 Changed |= setRetAndArgsNoUndef(F);1148 Changed |= setDoesNotThrow(F);1149 Changed |= setRetDoesNotAlias(F);1150 break;1151 case LibFunc_fstat64:1152 case LibFunc_fstatvfs64:1153 Changed |= setRetAndArgsNoUndef(F);1154 Changed |= setDoesNotThrow(F);1155 Changed |= setDoesNotCapture(F, 1);1156 break;1157 case LibFunc_open64:1158 // May throw; "open" is a valid pthread cancellation point.1159 Changed |= setRetAndArgsNoUndef(F);1160 Changed |= setDoesNotCapture(F, 0);1161 Changed |= setOnlyReadsMemory(F, 0);1162 break;1163 case LibFunc_gettimeofday:1164 // Currently some platforms have the restrict keyword on the arguments to1165 // gettimeofday. To be conservative, do not add noalias to gettimeofday's1166 // arguments.1167 Changed |= setRetAndArgsNoUndef(F);1168 Changed |= setDoesNotThrow(F);1169 Changed |= setDoesNotCapture(F, 0);1170 Changed |= setDoesNotCapture(F, 1);1171 break;1172 case LibFunc_memset_pattern4:1173 case LibFunc_memset_pattern8:1174 case LibFunc_memset_pattern16:1175 Changed |= setDoesNotCapture(F, 0);1176 Changed |= setDoesNotCapture(F, 1);1177 Changed |= setOnlyReadsMemory(F, 1);1178 [[fallthrough]];1179 case LibFunc_memset:1180 Changed |= setWillReturn(F);1181 [[fallthrough]];1182 case LibFunc_memset_chk:1183 Changed |= setOnlyAccessesArgMemory(F);1184 Changed |= setOnlyWritesMemory(F, 0);1185 Changed |= setDoesNotThrow(F);1186 Changed |= setDoesNotCallback(F);1187 break;1188 case LibFunc_abort:1189 Changed |= setIsCold(F);1190 Changed |= setNoReturn(F);1191 Changed |= setDoesNotThrow(F);1192 break;1193 case LibFunc_terminate:1194 // May callback; terminate_handler may be called1195 Changed |= setIsCold(F);1196 Changed |= setNoReturn(F);1197 break;1198 case LibFunc_cxa_throw:1199 Changed |= setIsCold(F);1200 Changed |= setNoReturn(F);1201 // Don't add `nofree` on `__cxa_throw`1202 return Changed;1203 // int __nvvm_reflect(const char *)1204 case LibFunc_nvvm_reflect:1205 Changed |= setRetAndArgsNoUndef(F);1206 Changed |= setDoesNotAccessMemory(F);1207 Changed |= setDoesNotThrow(F);1208 break;1209 case LibFunc_acos:1210 case LibFunc_acosf:1211 case LibFunc_acosh:1212 case LibFunc_acoshf:1213 case LibFunc_acoshl:1214 case LibFunc_acosl:1215 case LibFunc_asin:1216 case LibFunc_asinf:1217 case LibFunc_asinh:1218 case LibFunc_asinhf:1219 case LibFunc_asinhl:1220 case LibFunc_asinl:1221 case LibFunc_atan:1222 case LibFunc_atan2:1223 case LibFunc_atan2f:1224 case LibFunc_atan2l:1225 case LibFunc_atanf:1226 case LibFunc_atanh:1227 case LibFunc_atanhf:1228 case LibFunc_atanhl:1229 case LibFunc_atanl:1230 case LibFunc_ceil:1231 case LibFunc_ceilf:1232 case LibFunc_ceill:1233 case LibFunc_cos:1234 case LibFunc_cosh:1235 case LibFunc_coshf:1236 case LibFunc_coshl:1237 case LibFunc_cosf:1238 case LibFunc_cosl:1239 case LibFunc_cospi:1240 case LibFunc_cospif:1241 case LibFunc_erf:1242 case LibFunc_erff:1243 case LibFunc_erfl:1244 case LibFunc_tgamma:1245 case LibFunc_tgammaf:1246 case LibFunc_tgammal:1247 case LibFunc_exp:1248 case LibFunc_expf:1249 case LibFunc_expl:1250 case LibFunc_exp2:1251 case LibFunc_exp2f:1252 case LibFunc_exp2l:1253 case LibFunc_expm1:1254 case LibFunc_expm1f:1255 case LibFunc_expm1l:1256 case LibFunc_fdim:1257 case LibFunc_fdiml:1258 case LibFunc_fdimf:1259 case LibFunc_fmod:1260 case LibFunc_fmodf:1261 case LibFunc_fmodl:1262 case LibFunc_hypot:1263 case LibFunc_hypotf:1264 case LibFunc_hypotl:1265 case LibFunc_ldexp:1266 case LibFunc_ldexpf:1267 case LibFunc_ldexpl:1268 case LibFunc_log:1269 case LibFunc_log10:1270 case LibFunc_log10f:1271 case LibFunc_log10l:1272 case LibFunc_log1p:1273 case LibFunc_log1pf:1274 case LibFunc_log1pl:1275 case LibFunc_log2:1276 case LibFunc_log2f:1277 case LibFunc_log2l:1278 case LibFunc_logb:1279 case LibFunc_logbf:1280 case LibFunc_logbl:1281 case LibFunc_ilogb:1282 case LibFunc_ilogbf:1283 case LibFunc_ilogbl:1284 case LibFunc_logf:1285 case LibFunc_logl:1286 case LibFunc_nextafter:1287 case LibFunc_nextafterf:1288 case LibFunc_nextafterl:1289 case LibFunc_nexttoward:1290 case LibFunc_nexttowardf:1291 case LibFunc_nexttowardl:1292 case LibFunc_pow:1293 case LibFunc_powf:1294 case LibFunc_powl:1295 case LibFunc_remainder:1296 case LibFunc_remainderf:1297 case LibFunc_remainderl:1298 case LibFunc_rint:1299 case LibFunc_rintf:1300 case LibFunc_rintl:1301 case LibFunc_round:1302 case LibFunc_roundf:1303 case LibFunc_roundl:1304 case LibFunc_scalbln:1305 case LibFunc_scalblnf:1306 case LibFunc_scalblnl:1307 case LibFunc_scalbn:1308 case LibFunc_scalbnf:1309 case LibFunc_scalbnl:1310 case LibFunc_sin:1311 case LibFunc_sincospif_stret:1312 case LibFunc_sinf:1313 case LibFunc_sinh:1314 case LibFunc_sinhf:1315 case LibFunc_sinhl:1316 case LibFunc_sinl:1317 case LibFunc_sinpi:1318 case LibFunc_sinpif:1319 case LibFunc_sqrt:1320 case LibFunc_sqrtf:1321 case LibFunc_sqrtl:1322 case LibFunc_tan:1323 case LibFunc_tanf:1324 case LibFunc_tanh:1325 case LibFunc_tanhf:1326 case LibFunc_tanhl:1327 case LibFunc_tanl:1328 Changed |= setDoesNotThrow(F);1329 Changed |= setDoesNotCallback(F);1330 Changed |= setDoesNotFreeMemory(F);1331 Changed |= setWillReturn(F);1332 Changed |= setOnlyWritesErrnoMemory(F);1333 break;1334 case LibFunc_abs:1335 case LibFunc_cbrt:1336 case LibFunc_cbrtf:1337 case LibFunc_cbrtl:1338 case LibFunc_copysign:1339 case LibFunc_copysignf:1340 case LibFunc_copysignl:1341 case LibFunc_fabs:1342 case LibFunc_fabsf:1343 case LibFunc_fabsl:1344 case LibFunc_ffs:1345 case LibFunc_ffsl:1346 case LibFunc_ffsll:1347 case LibFunc_floor:1348 case LibFunc_floorf:1349 case LibFunc_floorl:1350 case LibFunc_fls:1351 case LibFunc_flsl:1352 case LibFunc_flsll:1353 case LibFunc_fmax:1354 case LibFunc_fmaxf:1355 case LibFunc_fmaxl:1356 case LibFunc_fmin:1357 case LibFunc_fminf:1358 case LibFunc_fminl:1359 case LibFunc_labs:1360 case LibFunc_llabs:1361 case LibFunc_nearbyint:1362 case LibFunc_nearbyintf:1363 case LibFunc_nearbyintl:1364 case LibFunc_toascii:1365 case LibFunc_trunc:1366 case LibFunc_truncf:1367 case LibFunc_truncl:1368 Changed |= setDoesNotAccessMemory(F);1369 [[fallthrough]];1370 case LibFunc_isascii:1371 case LibFunc_isdigit:1372 Changed |= setDoesNotThrow(F);1373 Changed |= setDoesNotCallback(F);1374 Changed |= setDoesNotFreeMemory(F);1375 Changed |= setWillReturn(F);1376 break;1377 case LibFunc_sincos:1378 case LibFunc_sincosf:1379 case LibFunc_sincosl:1380 Changed |= setDoesNotCapture(F, 1);1381 Changed |= setOnlyWritesMemory(F, 1);1382 [[fallthrough]];1383 case LibFunc_remquo:1384 case LibFunc_remquof:1385 case LibFunc_remquol:1386 Changed |= setDoesNotThrow(F);1387 Changed |= setDoesNotCallback(F);1388 Changed |= setDoesNotFreeMemory(F);1389 Changed |= setOnlyWritesMemory(F, 2);1390 Changed |= setDoesNotCapture(F, 2);1391 Changed |= setWillReturn(F);1392 Changed |= setOnlyWritesArgMemOrErrnoMem(F);1393 break;1394 default:1395 // FIXME: It'd be really nice to cover all the library functions we're1396 // aware of here.1397 break;1398 }1399 // We have to do this step after AllocKind has been inferred on functions so1400 // we can reliably identify free-like and realloc-like functions.1401 if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F))1402 Changed |= setDoesNotFreeMemory(F);1403 return Changed;1404}1405 1406static void setArgExtAttr(Function &F, unsigned ArgNo,1407 const TargetLibraryInfo &TLI, bool Signed = true) {1408 Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed);1409 if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr))1410 F.addParamAttr(ArgNo, ExtAttr);1411}1412 1413static void setRetExtAttr(Function &F,1414 const TargetLibraryInfo &TLI, bool Signed = true) {1415 Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed);1416 if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr))1417 F.addRetAttr(ExtAttr);1418}1419 1420// Modeled after X86TargetLowering::markLibCallAttributes.1421void llvm::markRegisterParameterAttributes(Function *F) {1422 if (!F->arg_size() || F->isVarArg())1423 return;1424 1425 const CallingConv::ID CC = F->getCallingConv();1426 if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)1427 return;1428 1429 const Module *M = F->getParent();1430 unsigned N = M->getNumberRegisterParameters();1431 if (!N)1432 return;1433 1434 const DataLayout &DL = M->getDataLayout();1435 1436 for (Argument &A : F->args()) {1437 Type *T = A.getType();1438 if (!T->isIntOrPtrTy())1439 continue;1440 1441 const TypeSize &TS = DL.getTypeAllocSize(T);1442 if (TS > 8)1443 continue;1444 1445 assert(TS <= 4 && "Need to account for parameters larger than word size");1446 const unsigned NumRegs = TS > 4 ? 2 : 1;1447 if (N < NumRegs)1448 return;1449 1450 N -= NumRegs;1451 F->addParamAttr(A.getArgNo(), Attribute::InReg);1452 }1453}1454 1455FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,1456 LibFunc TheLibFunc, FunctionType *T,1457 AttributeList AttributeList) {1458 assert(TLI.has(TheLibFunc) &&1459 "Creating call to non-existing library function.");1460 StringRef Name = TLI.getName(TheLibFunc);1461 FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList);1462 1463 // Make sure any mandatory argument attributes are added.1464 1465 // Any outgoing i32 argument should be handled with setArgExtAttr() which1466 // will add an extension attribute if the target ABI requires it. Adding1467 // argument extensions is typically done by the front end but when an1468 // optimizer is building a library call on its own it has to take care of1469 // this. Each such generated function must be handled here with sign or1470 // zero extensions as needed. F is retreived with cast<> because we demand1471 // of the caller to have called isLibFuncEmittable() first.1472 Function *F = cast<Function>(C.getCallee());1473 assert(F->getFunctionType() == T && "Function type does not match.");1474 switch (TheLibFunc) {1475 case LibFunc_fputc:1476 case LibFunc_putchar:1477 setArgExtAttr(*F, 0, TLI);1478 break;1479 case LibFunc_ldexp:1480 case LibFunc_ldexpf:1481 case LibFunc_ldexpl:1482 case LibFunc_memchr:1483 case LibFunc_memrchr:1484 case LibFunc_strchr:1485 setArgExtAttr(*F, 1, TLI);1486 break;1487 case LibFunc_memccpy:1488 setArgExtAttr(*F, 2, TLI);1489 break;1490 1491 // These are functions that are known to not need any argument extension1492 // on any target: A size_t argument (which may be an i32 on some targets)1493 // should not trigger the assert below.1494 case LibFunc_bcmp:1495 setRetExtAttr(*F, TLI);1496 break;1497 case LibFunc_calloc:1498 case LibFunc_fwrite:1499 case LibFunc_malloc:1500 case LibFunc_memcmp:1501 case LibFunc_memcpy_chk:1502 case LibFunc_mempcpy:1503 case LibFunc_memset_pattern16:1504 case LibFunc_snprintf:1505 case LibFunc_stpncpy:1506 case LibFunc_strlcat:1507 case LibFunc_strlcpy:1508 case LibFunc_strncat:1509 case LibFunc_strncmp:1510 case LibFunc_strncpy:1511 case LibFunc_vsnprintf:1512 break;1513 1514 default:1515#ifndef NDEBUG1516 for (unsigned i = 0; i < T->getNumParams(); i++)1517 assert(!isa<IntegerType>(T->getParamType(i)) &&1518 "Unhandled integer argument.");1519#endif1520 break;1521 }1522 1523 markRegisterParameterAttributes(F);1524 1525 return C;1526}1527 1528FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,1529 LibFunc TheLibFunc, FunctionType *T) {1530 return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList());1531}1532 1533bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,1534 LibFunc TheLibFunc) {1535 StringRef FuncName = TLI->getName(TheLibFunc);1536 if (!TLI->has(TheLibFunc))1537 return false;1538 1539 // Check if the Module already has a GlobalValue with the same name, in1540 // which case it must be a Function with the expected type.1541 if (GlobalValue *GV = M->getNamedValue(FuncName)) {1542 if (auto *F = dyn_cast<Function>(GV))1543 return TLI->isValidProtoForLibFunc(*F->getFunctionType(), TheLibFunc, *M);1544 return false;1545 }1546 1547 return true;1548}1549 1550bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,1551 StringRef Name) {1552 LibFunc TheLibFunc;1553 return TLI->getLibFunc(Name, TheLibFunc) &&1554 isLibFuncEmittable(M, TLI, TheLibFunc);1555}1556 1557bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,1558 LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {1559 switch (Ty->getTypeID()) {1560 case Type::HalfTyID:1561 return false;1562 case Type::FloatTyID:1563 return isLibFuncEmittable(M, TLI, FloatFn);1564 case Type::DoubleTyID:1565 return isLibFuncEmittable(M, TLI, DoubleFn);1566 default:1567 return isLibFuncEmittable(M, TLI, LongDoubleFn);1568 }1569}1570 1571StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI,1572 Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,1573 LibFunc LongDoubleFn, LibFunc &TheLibFunc) {1574 assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&1575 "Cannot get name for unavailable function!");1576 1577 switch (Ty->getTypeID()) {1578 case Type::HalfTyID:1579 llvm_unreachable("No name for HalfTy!");1580 case Type::FloatTyID:1581 TheLibFunc = FloatFn;1582 return TLI->getName(FloatFn);1583 case Type::DoubleTyID:1584 TheLibFunc = DoubleFn;1585 return TLI->getName(DoubleFn);1586 default:1587 TheLibFunc = LongDoubleFn;1588 return TLI->getName(LongDoubleFn);1589 }1590}1591 1592//- Emit LibCalls ------------------------------------------------------------//1593 1594static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {1595 return B.getIntNTy(TLI->getIntSize());1596}1597 1598static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {1599 const Module *M = B.GetInsertBlock()->getModule();1600 return B.getIntNTy(TLI->getSizeTSize(*M));1601}1602 1603static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,1604 ArrayRef<Type *> ParamTypes,1605 ArrayRef<Value *> Operands, IRBuilderBase &B,1606 const TargetLibraryInfo *TLI,1607 bool IsVaArgs = false) {1608 Module *M = B.GetInsertBlock()->getModule();1609 if (!isLibFuncEmittable(M, TLI, TheLibFunc))1610 return nullptr;1611 1612 StringRef FuncName = TLI->getName(TheLibFunc);1613 FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);1614 FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType);1615 inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI);1616 CallInst *CI = B.CreateCall(Callee, Operands, FuncName);1617 if (const Function *F =1618 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1619 CI->setCallingConv(F->getCallingConv());1620 return CI;1621}1622 1623Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,1624 const TargetLibraryInfo *TLI) {1625 Type *CharPtrTy = B.getPtrTy();1626 Type *SizeTTy = getSizeTTy(B, TLI);1627 return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI);1628}1629 1630Value *llvm::emitWcsLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,1631 const TargetLibraryInfo *TLI) {1632 assert(Ptr && Ptr->getType()->isPointerTy() &&1633 "Argument to wcslen intrinsic must be a pointer.");1634 Type *PtrTy = B.getPtrTy();1635 Type *SizeTTy = getSizeTTy(B, TLI);1636 return emitLibCall(LibFunc_wcslen, SizeTTy, PtrTy, Ptr, B, TLI);1637}1638 1639Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B,1640 const TargetLibraryInfo *TLI) {1641 Type *CharPtrTy = B.getPtrTy();1642 return emitLibCall(LibFunc_strdup, CharPtrTy, CharPtrTy, Ptr, B, TLI);1643}1644 1645Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B,1646 const TargetLibraryInfo *TLI) {1647 Type *CharPtrTy = B.getPtrTy();1648 Type *IntTy = getIntTy(B, TLI);1649 return emitLibCall(LibFunc_strchr, CharPtrTy, {CharPtrTy, IntTy},1650 {Ptr, ConstantInt::get(IntTy, C)}, B, TLI);1651}1652 1653Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1654 const DataLayout &DL, const TargetLibraryInfo *TLI) {1655 Type *CharPtrTy = B.getPtrTy();1656 Type *IntTy = getIntTy(B, TLI);1657 Type *SizeTTy = getSizeTTy(B, TLI);1658 return emitLibCall(1659 LibFunc_strncmp, IntTy,1660 {CharPtrTy, CharPtrTy, SizeTTy},1661 {Ptr1, Ptr2, Len}, B, TLI);1662}1663 1664Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,1665 const TargetLibraryInfo *TLI) {1666 Type *CharPtrTy = Dst->getType();1667 return emitLibCall(LibFunc_strcpy, CharPtrTy, {CharPtrTy, CharPtrTy},1668 {Dst, Src}, B, TLI);1669}1670 1671Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,1672 const TargetLibraryInfo *TLI) {1673 Type *CharPtrTy = B.getPtrTy();1674 return emitLibCall(LibFunc_stpcpy, CharPtrTy, {CharPtrTy, CharPtrTy},1675 {Dst, Src}, B, TLI);1676}1677 1678Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1679 const TargetLibraryInfo *TLI) {1680 Type *CharPtrTy = B.getPtrTy();1681 Type *SizeTTy = getSizeTTy(B, TLI);1682 return emitLibCall(LibFunc_strncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},1683 {Dst, Src, Len}, B, TLI);1684}1685 1686Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1687 const TargetLibraryInfo *TLI) {1688 Type *CharPtrTy = B.getPtrTy();1689 Type *SizeTTy = getSizeTTy(B, TLI);1690 return emitLibCall(LibFunc_stpncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},1691 {Dst, Src, Len}, B, TLI);1692}1693 1694Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,1695 IRBuilderBase &B, const DataLayout &DL,1696 const TargetLibraryInfo *TLI) {1697 Module *M = B.GetInsertBlock()->getModule();1698 if (!isLibFuncEmittable(M, TLI, LibFunc_memcpy_chk))1699 return nullptr;1700 1701 AttributeList AS;1702 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,1703 Attribute::NoUnwind);1704 Type *VoidPtrTy = B.getPtrTy();1705 Type *SizeTTy = getSizeTTy(B, TLI);1706 FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk,1707 AttributeList::get(M->getContext(), AS), VoidPtrTy,1708 VoidPtrTy, VoidPtrTy, SizeTTy, SizeTTy);1709 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});1710 if (const Function *F =1711 dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))1712 CI->setCallingConv(F->getCallingConv());1713 return CI;1714}1715 1716Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1717 const DataLayout &DL, const TargetLibraryInfo *TLI) {1718 Type *VoidPtrTy = B.getPtrTy();1719 Type *SizeTTy = getSizeTTy(B, TLI);1720 return emitLibCall(LibFunc_mempcpy, VoidPtrTy,1721 {VoidPtrTy, VoidPtrTy, SizeTTy},1722 {Dst, Src, Len}, B, TLI);1723}1724 1725Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,1726 const DataLayout &DL, const TargetLibraryInfo *TLI) {1727 Type *VoidPtrTy = B.getPtrTy();1728 Type *IntTy = getIntTy(B, TLI);1729 Type *SizeTTy = getSizeTTy(B, TLI);1730 return emitLibCall(LibFunc_memchr, VoidPtrTy,1731 {VoidPtrTy, IntTy, SizeTTy},1732 {Ptr, Val, Len}, B, TLI);1733}1734 1735Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,1736 const DataLayout &DL, const TargetLibraryInfo *TLI) {1737 Type *VoidPtrTy = B.getPtrTy();1738 Type *IntTy = getIntTy(B, TLI);1739 Type *SizeTTy = getSizeTTy(B, TLI);1740 return emitLibCall(LibFunc_memrchr, VoidPtrTy,1741 {VoidPtrTy, IntTy, SizeTTy},1742 {Ptr, Val, Len}, B, TLI);1743}1744 1745Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1746 const DataLayout &DL, const TargetLibraryInfo *TLI) {1747 Type *VoidPtrTy = B.getPtrTy();1748 Type *IntTy = getIntTy(B, TLI);1749 Type *SizeTTy = getSizeTTy(B, TLI);1750 return emitLibCall(LibFunc_memcmp, IntTy,1751 {VoidPtrTy, VoidPtrTy, SizeTTy},1752 {Ptr1, Ptr2, Len}, B, TLI);1753}1754 1755Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1756 const DataLayout &DL, const TargetLibraryInfo *TLI) {1757 Type *VoidPtrTy = B.getPtrTy();1758 Type *IntTy = getIntTy(B, TLI);1759 Type *SizeTTy = getSizeTTy(B, TLI);1760 return emitLibCall(LibFunc_bcmp, IntTy,1761 {VoidPtrTy, VoidPtrTy, SizeTTy},1762 {Ptr1, Ptr2, Len}, B, TLI);1763}1764 1765Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,1766 IRBuilderBase &B, const TargetLibraryInfo *TLI) {1767 Type *VoidPtrTy = B.getPtrTy();1768 Type *IntTy = getIntTy(B, TLI);1769 Type *SizeTTy = getSizeTTy(B, TLI);1770 return emitLibCall(LibFunc_memccpy, VoidPtrTy,1771 {VoidPtrTy, VoidPtrTy, IntTy, SizeTTy},1772 {Ptr1, Ptr2, Val, Len}, B, TLI);1773}1774 1775Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,1776 ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,1777 const TargetLibraryInfo *TLI) {1778 Type *CharPtrTy = B.getPtrTy();1779 Type *IntTy = getIntTy(B, TLI);1780 Type *SizeTTy = getSizeTTy(B, TLI);1781 SmallVector<Value *, 8> Args{Dest, Size, Fmt};1782 llvm::append_range(Args, VariadicArgs);1783 return emitLibCall(LibFunc_snprintf, IntTy,1784 {CharPtrTy, SizeTTy, CharPtrTy},1785 Args, B, TLI, /*IsVaArgs=*/true);1786}1787 1788Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,1789 ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,1790 const TargetLibraryInfo *TLI) {1791 Type *CharPtrTy = B.getPtrTy();1792 Type *IntTy = getIntTy(B, TLI);1793 SmallVector<Value *, 8> Args{Dest, Fmt};1794 llvm::append_range(Args, VariadicArgs);1795 return emitLibCall(LibFunc_sprintf, IntTy,1796 {CharPtrTy, CharPtrTy}, Args, B, TLI,1797 /*IsVaArgs=*/true);1798}1799 1800Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,1801 const TargetLibraryInfo *TLI) {1802 Type *CharPtrTy = B.getPtrTy();1803 return emitLibCall(LibFunc_strcat, CharPtrTy,1804 {CharPtrTy, CharPtrTy},1805 {Dest, Src}, B, TLI);1806}1807 1808Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1809 const TargetLibraryInfo *TLI) {1810 Type *CharPtrTy = B.getPtrTy();1811 Type *SizeTTy = getSizeTTy(B, TLI);1812 return emitLibCall(LibFunc_strlcpy, SizeTTy,1813 {CharPtrTy, CharPtrTy, SizeTTy},1814 {Dest, Src, Size}, B, TLI);1815}1816 1817Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1818 const TargetLibraryInfo *TLI) {1819 Type *CharPtrTy = B.getPtrTy();1820 Type *SizeTTy = getSizeTTy(B, TLI);1821 return emitLibCall(LibFunc_strlcat, SizeTTy,1822 {CharPtrTy, CharPtrTy, SizeTTy},1823 {Dest, Src, Size}, B, TLI);1824}1825 1826Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1827 const TargetLibraryInfo *TLI) {1828 Type *CharPtrTy = B.getPtrTy();1829 Type *SizeTTy = getSizeTTy(B, TLI);1830 return emitLibCall(LibFunc_strncat, CharPtrTy,1831 {CharPtrTy, CharPtrTy, SizeTTy},1832 {Dest, Src, Size}, B, TLI);1833}1834 1835Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,1836 IRBuilderBase &B, const TargetLibraryInfo *TLI) {1837 Type *CharPtrTy = B.getPtrTy();1838 Type *IntTy = getIntTy(B, TLI);1839 Type *SizeTTy = getSizeTTy(B, TLI);1840 return emitLibCall(1841 LibFunc_vsnprintf, IntTy,1842 {CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()},1843 {Dest, Size, Fmt, VAList}, B, TLI);1844}1845 1846Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,1847 IRBuilderBase &B, const TargetLibraryInfo *TLI) {1848 Type *CharPtrTy = B.getPtrTy();1849 Type *IntTy = getIntTy(B, TLI);1850 return emitLibCall(LibFunc_vsprintf, IntTy,1851 {CharPtrTy, CharPtrTy, VAList->getType()},1852 {Dest, Fmt, VAList}, B, TLI);1853}1854 1855/// Append a suffix to the function name according to the type of 'Op'.1856static void appendTypeSuffix(Value *Op, StringRef &Name,1857 SmallString<20> &NameBuffer) {1858 if (!Op->getType()->isDoubleTy()) {1859 NameBuffer += Name;1860 1861 if (Op->getType()->isFloatTy())1862 NameBuffer += 'f';1863 else1864 NameBuffer += 'l';1865 1866 Name = NameBuffer;1867 }1868}1869 1870static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc,1871 StringRef Name, IRBuilderBase &B,1872 const AttributeList &Attrs,1873 const TargetLibraryInfo *TLI) {1874 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");1875 1876 Module *M = B.GetInsertBlock()->getModule();1877 FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(),1878 Op->getType());1879 CallInst *CI = B.CreateCall(Callee, Op, Name);1880 1881 // The incoming attribute set may have come from a speculatable intrinsic, but1882 // is being replaced with a library call which is not allowed to be1883 // speculatable.1884 CI->setAttributes(1885 Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));1886 if (const Function *F =1887 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1888 CI->setCallingConv(F->getCallingConv());1889 1890 return CI;1891}1892 1893Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,1894 StringRef Name, IRBuilderBase &B,1895 const AttributeList &Attrs) {1896 SmallString<20> NameBuffer;1897 appendTypeSuffix(Op, Name, NameBuffer);1898 1899 LibFunc TheLibFunc;1900 TLI->getLibFunc(Name, TheLibFunc);1901 1902 return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);1903}1904 1905Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,1906 LibFunc DoubleFn, LibFunc FloatFn,1907 LibFunc LongDoubleFn, IRBuilderBase &B,1908 const AttributeList &Attrs) {1909 // Get the name of the function according to TLI.1910 Module *M = B.GetInsertBlock()->getModule();1911 LibFunc TheLibFunc;1912 StringRef Name = getFloatFn(M, TLI, Op->getType(), DoubleFn, FloatFn,1913 LongDoubleFn, TheLibFunc);1914 1915 return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);1916}1917 1918static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,1919 LibFunc TheLibFunc,1920 StringRef Name, IRBuilderBase &B,1921 const AttributeList &Attrs,1922 const TargetLibraryInfo *TLI) {1923 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");1924 1925 Module *M = B.GetInsertBlock()->getModule();1926 FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(),1927 Op1->getType(), Op2->getType());1928 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);1929 CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);1930 1931 // The incoming attribute set may have come from a speculatable intrinsic, but1932 // is being replaced with a library call which is not allowed to be1933 // speculatable.1934 CI->setAttributes(1935 Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));1936 if (const Function *F =1937 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1938 CI->setCallingConv(F->getCallingConv());1939 1940 return CI;1941}1942 1943Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,1944 const TargetLibraryInfo *TLI,1945 StringRef Name, IRBuilderBase &B,1946 const AttributeList &Attrs) {1947 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");1948 1949 SmallString<20> NameBuffer;1950 appendTypeSuffix(Op1, Name, NameBuffer);1951 1952 LibFunc TheLibFunc;1953 TLI->getLibFunc(Name, TheLibFunc);1954 1955 return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);1956}1957 1958Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,1959 const TargetLibraryInfo *TLI,1960 LibFunc DoubleFn, LibFunc FloatFn,1961 LibFunc LongDoubleFn, IRBuilderBase &B,1962 const AttributeList &Attrs) {1963 // Get the name of the function according to TLI.1964 Module *M = B.GetInsertBlock()->getModule();1965 LibFunc TheLibFunc;1966 StringRef Name = getFloatFn(M, TLI, Op1->getType(), DoubleFn, FloatFn,1967 LongDoubleFn, TheLibFunc);1968 1969 return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);1970}1971 1972// Emit a call to putchar(int) with Char as the argument. Char must have1973// the same precision as int, which need not be 32 bits.1974Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,1975 const TargetLibraryInfo *TLI) {1976 Module *M = B.GetInsertBlock()->getModule();1977 if (!isLibFuncEmittable(M, TLI, LibFunc_putchar))1978 return nullptr;1979 1980 Type *IntTy = getIntTy(B, TLI);1981 StringRef PutCharName = TLI->getName(LibFunc_putchar);1982 FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar,1983 IntTy, IntTy);1984 inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI);1985 CallInst *CI = B.CreateCall(PutChar, Char, PutCharName);1986 1987 if (const Function *F =1988 dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))1989 CI->setCallingConv(F->getCallingConv());1990 return CI;1991}1992 1993Value *llvm::emitPutS(Value *Str, IRBuilderBase &B,1994 const TargetLibraryInfo *TLI) {1995 Module *M = B.GetInsertBlock()->getModule();1996 if (!isLibFuncEmittable(M, TLI, LibFunc_puts))1997 return nullptr;1998 1999 Type *IntTy = getIntTy(B, TLI);2000 StringRef PutsName = TLI->getName(LibFunc_puts);2001 FunctionCallee PutS =2002 getOrInsertLibFunc(M, *TLI, LibFunc_puts, IntTy, B.getPtrTy());2003 inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI);2004 CallInst *CI = B.CreateCall(PutS, Str, PutsName);2005 if (const Function *F =2006 dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))2007 CI->setCallingConv(F->getCallingConv());2008 return CI;2009}2010 2011Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B,2012 const TargetLibraryInfo *TLI) {2013 Module *M = B.GetInsertBlock()->getModule();2014 if (!isLibFuncEmittable(M, TLI, LibFunc_fputc))2015 return nullptr;2016 2017 Type *IntTy = getIntTy(B, TLI);2018 StringRef FPutcName = TLI->getName(LibFunc_fputc);2019 FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, IntTy,2020 IntTy, File->getType());2021 if (File->getType()->isPointerTy())2022 inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI);2023 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);2024 2025 if (const Function *Fn =2026 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))2027 CI->setCallingConv(Fn->getCallingConv());2028 return CI;2029}2030 2031Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B,2032 const TargetLibraryInfo *TLI) {2033 Module *M = B.GetInsertBlock()->getModule();2034 if (!isLibFuncEmittable(M, TLI, LibFunc_fputs))2035 return nullptr;2036 2037 Type *IntTy = getIntTy(B, TLI);2038 StringRef FPutsName = TLI->getName(LibFunc_fputs);2039 FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, IntTy,2040 B.getPtrTy(), File->getType());2041 if (File->getType()->isPointerTy())2042 inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI);2043 CallInst *CI = B.CreateCall(F, {Str, File}, FPutsName);2044 2045 if (const Function *Fn =2046 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))2047 CI->setCallingConv(Fn->getCallingConv());2048 return CI;2049}2050 2051Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,2052 const DataLayout &DL, const TargetLibraryInfo *TLI) {2053 Module *M = B.GetInsertBlock()->getModule();2054 if (!isLibFuncEmittable(M, TLI, LibFunc_fwrite))2055 return nullptr;2056 2057 Type *SizeTTy = getSizeTTy(B, TLI);2058 StringRef FWriteName = TLI->getName(LibFunc_fwrite);2059 FunctionCallee F =2060 getOrInsertLibFunc(M, *TLI, LibFunc_fwrite, SizeTTy, B.getPtrTy(),2061 SizeTTy, SizeTTy, File->getType());2062 2063 if (File->getType()->isPointerTy())2064 inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI);2065 CallInst *CI =2066 B.CreateCall(F, {Ptr, Size,2067 ConstantInt::get(SizeTTy, 1), File});2068 2069 if (const Function *Fn =2070 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))2071 CI->setCallingConv(Fn->getCallingConv());2072 return CI;2073}2074 2075Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,2076 const TargetLibraryInfo *TLI) {2077 Module *M = B.GetInsertBlock()->getModule();2078 if (!isLibFuncEmittable(M, TLI, LibFunc_malloc))2079 return nullptr;2080 2081 StringRef MallocName = TLI->getName(LibFunc_malloc);2082 Type *SizeTTy = getSizeTTy(B, TLI);2083 FunctionCallee Malloc =2084 getOrInsertLibFunc(M, *TLI, LibFunc_malloc, B.getPtrTy(), SizeTTy);2085 inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI);2086 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);2087 2088 if (const Function *F =2089 dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))2090 CI->setCallingConv(F->getCallingConv());2091 2092 return CI;2093}2094 2095Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,2096 const TargetLibraryInfo &TLI, unsigned AddrSpace) {2097 Module *M = B.GetInsertBlock()->getModule();2098 if (!isLibFuncEmittable(M, &TLI, LibFunc_calloc))2099 return nullptr;2100 2101 StringRef CallocName = TLI.getName(LibFunc_calloc);2102 Type *SizeTTy = getSizeTTy(B, &TLI);2103 FunctionCallee Calloc = getOrInsertLibFunc(2104 M, TLI, LibFunc_calloc, B.getPtrTy(AddrSpace), SizeTTy, SizeTTy);2105 inferNonMandatoryLibFuncAttrs(M, CallocName, TLI);2106 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);2107 2108 if (const auto *F =2109 dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))2110 CI->setCallingConv(F->getCallingConv());2111 2112 return CI;2113}2114 2115Value *llvm::emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B,2116 const TargetLibraryInfo *TLI,2117 LibFunc SizeFeedbackNewFunc,2118 uint8_t HotCold) {2119 Module *M = B.GetInsertBlock()->getModule();2120 if (!isLibFuncEmittable(M, TLI, SizeFeedbackNewFunc))2121 return nullptr;2122 2123 StringRef Name = TLI->getName(SizeFeedbackNewFunc);2124 2125 // __sized_ptr_t struct return type { void*, size_t }2126 StructType *SizedPtrT =2127 StructType::get(M->getContext(), {B.getPtrTy(), Num->getType()});2128 FunctionCallee Func =2129 M->getOrInsertFunction(Name, SizedPtrT, Num->getType(), B.getInt8Ty());2130 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2131 CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, "sized_ptr");2132 2133 if (const Function *F = dyn_cast<Function>(Func.getCallee()))2134 CI->setCallingConv(F->getCallingConv());2135 2136 return CI;2137}2138 2139Value *llvm::emitHotColdSizeReturningNewAligned(Value *Num, Value *Align,2140 IRBuilderBase &B,2141 const TargetLibraryInfo *TLI,2142 LibFunc SizeFeedbackNewFunc,2143 uint8_t HotCold) {2144 Module *M = B.GetInsertBlock()->getModule();2145 if (!isLibFuncEmittable(M, TLI, SizeFeedbackNewFunc))2146 return nullptr;2147 2148 StringRef Name = TLI->getName(SizeFeedbackNewFunc);2149 2150 // __sized_ptr_t struct return type { void*, size_t }2151 StructType *SizedPtrT =2152 StructType::get(M->getContext(), {B.getPtrTy(), Num->getType()});2153 FunctionCallee Func = M->getOrInsertFunction(Name, SizedPtrT, Num->getType(),2154 Align->getType(), B.getInt8Ty());2155 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2156 CallInst *CI =2157 B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, "sized_ptr");2158 2159 if (const Function *F = dyn_cast<Function>(Func.getCallee()))2160 CI->setCallingConv(F->getCallingConv());2161 2162 return CI;2163}2164 2165Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B,2166 const TargetLibraryInfo *TLI, LibFunc NewFunc,2167 uint8_t HotCold) {2168 Module *M = B.GetInsertBlock()->getModule();2169 if (!isLibFuncEmittable(M, TLI, NewFunc))2170 return nullptr;2171 2172 StringRef Name = TLI->getName(NewFunc);2173 FunctionCallee Func =2174 M->getOrInsertFunction(Name, B.getPtrTy(), Num->getType(), B.getInt8Ty());2175 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2176 CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, Name);2177 2178 if (const Function *F =2179 dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2180 CI->setCallingConv(F->getCallingConv());2181 2182 return CI;2183}2184 2185Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,2186 const TargetLibraryInfo *TLI,2187 LibFunc NewFunc, uint8_t HotCold) {2188 Module *M = B.GetInsertBlock()->getModule();2189 if (!isLibFuncEmittable(M, TLI, NewFunc))2190 return nullptr;2191 2192 StringRef Name = TLI->getName(NewFunc);2193 FunctionCallee Func = M->getOrInsertFunction(2194 Name, B.getPtrTy(), Num->getType(), NoThrow->getType(), B.getInt8Ty());2195 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2196 CallInst *CI = B.CreateCall(Func, {Num, NoThrow, B.getInt8(HotCold)}, Name);2197 2198 if (const Function *F =2199 dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2200 CI->setCallingConv(F->getCallingConv());2201 2202 return CI;2203}2204 2205Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,2206 const TargetLibraryInfo *TLI,2207 LibFunc NewFunc, uint8_t HotCold) {2208 Module *M = B.GetInsertBlock()->getModule();2209 if (!isLibFuncEmittable(M, TLI, NewFunc))2210 return nullptr;2211 2212 StringRef Name = TLI->getName(NewFunc);2213 FunctionCallee Func = M->getOrInsertFunction(2214 Name, B.getPtrTy(), Num->getType(), Align->getType(), B.getInt8Ty());2215 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2216 CallInst *CI = B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, Name);2217 2218 if (const Function *F =2219 dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2220 CI->setCallingConv(F->getCallingConv());2221 2222 return CI;2223}2224 2225Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,2226 Value *NoThrow, IRBuilderBase &B,2227 const TargetLibraryInfo *TLI,2228 LibFunc NewFunc, uint8_t HotCold) {2229 Module *M = B.GetInsertBlock()->getModule();2230 if (!isLibFuncEmittable(M, TLI, NewFunc))2231 return nullptr;2232 2233 StringRef Name = TLI->getName(NewFunc);2234 FunctionCallee Func = M->getOrInsertFunction(2235 Name, B.getPtrTy(), Num->getType(), Align->getType(), NoThrow->getType(),2236 B.getInt8Ty());2237 inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2238 CallInst *CI =2239 B.CreateCall(Func, {Num, Align, NoThrow, B.getInt8(HotCold)}, Name);2240 2241 if (const Function *F =2242 dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2243 CI->setCallingConv(F->getCallingConv());2244 2245 return CI;2246}2247