[llvm] [LibCall] Infer nocallback for libcalls (PR #135173)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 10 10:08:35 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
This patch adds `nocallback` attributes for most of libcalls (except for exit/terminate/qsort/signal/...). It allows FuncAttributor to infer `norecurse` more precisely and encourages more aggressive global optimization.
---
Patch is 53.30 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135173.diff
12 Files Affected:
- (modified) llvm/lib/Transforms/Utils/BuildLibCalls.cpp (+122-1)
- (modified) llvm/test/CodeGen/X86/no-plt-libcalls.ll (+1-1)
- (modified) llvm/test/Transforms/InferFunctionAttrs/annotate.ll (+34-33)
- (modified) llvm/test/Transforms/InferFunctionAttrs/readonly_and_writeonly.ll (+1-1)
- (modified) llvm/test/Transforms/InstCombine/printf-2.ll (+1-1)
- (modified) llvm/test/Transforms/LICM/strlen.ll (+1-1)
- (modified) llvm/test/Transforms/LoopIdiom/basic.ll (+1-2)
- (modified) llvm/test/Transforms/LoopIdiom/memset-pattern-tbaa.ll (+1-1)
- (modified) llvm/test/Transforms/LoopIdiom/struct_pattern.ll (+1-1)
- (modified) llvm/test/Transforms/LoopIdiom/unroll-custom-dl.ll (+1-1)
- (modified) llvm/test/Transforms/LoopIdiom/unroll.ll (+1-1)
- (modified) llvm/test/Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll (+1-1)
``````````diff
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index 24eefc91117b4..88704d689c3b1 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -47,6 +47,7 @@ STATISTIC(
NumWriteArgumentMemOrErrnoMemOnly,
"Number of functions inferred as memory(argmem: write, errnomem: write)");
STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
+STATISTIC(NumNoCallback, "Number of functions inferred as nocallback");
STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
@@ -148,6 +149,14 @@ static bool setDoesNotThrow(Function &F) {
return true;
}
+static bool setDoesNotCallback(Function &F) {
+ if (F.hasFnAttribute(Attribute::NoCallback))
+ return false;
+ F.addFnAttr(Attribute::NoCallback);
+ ++NumNoCallback;
+ return true;
+}
+
static bool setRetDoesNotAlias(Function &F) {
if (F.hasRetAttribute(Attribute::NoAlias))
return false;
@@ -322,6 +331,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_wcslen:
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -331,6 +341,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
break;
case LibFunc_strtol:
@@ -341,6 +352,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_strtold:
case LibFunc_strtoull:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
@@ -349,6 +361,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_strncat:
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setReturnedArg(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -364,6 +377,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_stpncpy:
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyWritesMemory(F, 0);
@@ -373,6 +387,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_strxfrm:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -383,6 +398,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_strncmp: // 0,1
case LibFunc_strcspn: // 0,1
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setOnlyReadsMemory(F);
@@ -396,6 +412,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
// global memory.
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -405,12 +422,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
break;
case LibFunc_strtok:
case LibFunc_strtok_r:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
@@ -418,6 +437,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_scanf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
break;
@@ -425,6 +445,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_setvbuf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_strndup:
@@ -434,6 +455,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setAllocFamily(F, "malloc");
Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -443,6 +465,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_statvfs:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
@@ -450,6 +473,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_sscanf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
@@ -458,6 +482,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_sprintf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotAlias(F, 0);
Changed |= setOnlyWritesMemory(F, 0);
@@ -467,6 +492,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_snprintf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotAlias(F, 0);
Changed |= setOnlyWritesMemory(F, 0);
@@ -476,6 +502,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_setitimer:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setDoesNotCapture(F, 2);
@@ -483,6 +510,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_system:
// May throw; "system" is a valid pthread cancellation point.
+ Changed |= setDoesNotCallback(F);
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
@@ -502,6 +530,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemory(F);
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
break;
@@ -509,6 +538,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -516,6 +546,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_memchr:
case LibFunc_memrchr:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setWillReturn(F);
@@ -524,6 +555,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_modff:
case LibFunc_modfl:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyWritesMemory(F);
@@ -531,6 +563,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_memcpy:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotAlias(F, 0);
@@ -542,6 +575,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_memmove:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setReturnedArg(F, 0);
@@ -555,6 +589,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
[[fallthrough]];
case LibFunc_memcpy_chk:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setDoesNotAlias(F, 0);
Changed |= setOnlyWritesMemory(F, 0);
@@ -571,18 +606,21 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemory(F);
Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
break;
case LibFunc_mkdir:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
break;
case LibFunc_mktime:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
break;
@@ -597,6 +635,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -610,6 +649,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
Changed |= setRetNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -618,12 +658,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_read:
// May throw; "read" is a valid pthread cancellation point.
+ Changed |= setDoesNotCallback(F);
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
break;
case LibFunc_rewind:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_rmdir:
@@ -631,12 +673,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_realpath:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
break;
case LibFunc_rename:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
@@ -645,18 +689,21 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_readlink:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
break;
case LibFunc_write:
// May throw; "write" is a valid pthread cancellation point.
+ Changed |= setDoesNotCallback(F);
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
break;
case LibFunc_bcopy:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -666,6 +713,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_bcmp:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setWillReturn(F);
@@ -674,6 +722,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
break;
case LibFunc_bzero:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -688,6 +737,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemory(F);
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setWillReturn(F);
break;
@@ -695,6 +745,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_chown:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
break;
@@ -703,6 +754,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_closedir:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_atoi:
@@ -710,6 +762,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_atof:
case LibFunc_atoll:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
@@ -717,12 +770,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_access:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F, 0);
break;
case LibFunc_fopen:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
@@ -732,6 +787,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fdopen:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setRetDoesNotAlias(F);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
@@ -739,6 +795,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_feof:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_free:
@@ -750,6 +807,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
Changed |= setArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setDoesNotCapture(F, 0);
break;
@@ -768,11 +826,13 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_ftrylockfile:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_ferror:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setOnlyReadsMemory(F);
break;
@@ -781,12 +841,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fstat:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 1);
break;
case LibFunc_frexp:
case LibFunc_frexpf:
case LibFunc_frexpl:
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setWillReturn(F);
Changed |= setOnlyAccessesArgMemory(F);
Changed |= setOnlyWritesMemory(F);
@@ -795,12 +857,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fstatvfs:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 1);
break;
case LibFunc_fgets:
case LibFunc_fgets_unlocked:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 2);
Changed |= setOnlyWritesMemory(F, 0);
break;
@@ -808,6 +872,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fread_unlocked:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 3);
Changed |= setOnlyWritesMemory(F, 0);
@@ -816,6 +881,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fwrite_unlocked:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 3);
Changed |= setOnlyReadsMemory(F, 0);
@@ -824,6 +890,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fputs_unlocked:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 0);
@@ -832,6 +899,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fprintf:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyReadsMemory(F, 1);
@@ -839,27 +907,32 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_fgetpos:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
Changed |= setDoesNotCapture(F, 1);
break;
case LibFunc_getc:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_getlogin_r:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_getc_unlocked:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setDoesNotCapture(F, 0);
break;
case LibFunc_getenv:
Changed |= setRetAndArgsNoUndef(F);
Changed |= setDoesNotThrow(F);
+ Changed |= setDoesNotCallback(F);
Changed |= setOnlyReadsMemory(F);
Changed |= setDoesNotCapture(F, 0);
break;
@@ -868,37 +941,44 @@ bool llvm::inferNonMandatoryLibFuncAttr...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/135173
More information about the llvm-commits
mailing list