mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-14 17:06:38 +00:00
[LibCall] Infer nocallback for libcalls (#135173)
This patch adds `nocallback` attributes for string/math libcalls. It allows FuncAttributor to infer `norecurse` more precisely and encourages more aggressive global optimization.
This commit is contained in:
parent
339f58de16
commit
76e07d8ba5
@ -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);
|
||||
@ -509,6 +528,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 +536,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 +545,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 +553,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 +565,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 +579,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);
|
||||
@ -657,6 +682,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
break;
|
||||
case LibFunc_bcopy:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setOnlyAccessesArgMemory(F);
|
||||
Changed |= setWillReturn(F);
|
||||
Changed |= setDoesNotCapture(F, 0);
|
||||
@ -666,6 +692,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 +701,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);
|
||||
@ -710,6 +738,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);
|
||||
@ -787,6 +816,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
case LibFunc_frexpf:
|
||||
case LibFunc_frexpl:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setWillReturn(F);
|
||||
Changed |= setOnlyAccessesArgMemory(F);
|
||||
Changed |= setOnlyWritesMemory(F);
|
||||
@ -1025,6 +1055,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
case LibFunc_ntohl:
|
||||
case LibFunc_ntohs:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setDoesNotAccessMemory(F);
|
||||
break;
|
||||
case LibFunc_lstat:
|
||||
@ -1041,7 +1072,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
Changed |= setOnlyReadsMemory(F, 0);
|
||||
break;
|
||||
case LibFunc_qsort:
|
||||
// May throw; places call through function pointer.
|
||||
// May throw/callback; places call through function pointer.
|
||||
// Cannot give undef pointer/size
|
||||
Changed |= setRetAndArgsNoUndef(F);
|
||||
Changed |= setDoesNotCapture(F, 3);
|
||||
@ -1058,6 +1089,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
break;
|
||||
case LibFunc_dunder_strtok_r:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setDoesNotCapture(F, 1);
|
||||
Changed |= setOnlyReadsMemory(F, 1);
|
||||
break;
|
||||
@ -1149,6 +1181,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
Changed |= setOnlyAccessesArgMemory(F);
|
||||
Changed |= setOnlyWritesMemory(F, 0);
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
break;
|
||||
case LibFunc_abort:
|
||||
Changed |= setIsCold(F);
|
||||
@ -1156,6 +1189,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
Changed |= setDoesNotThrow(F);
|
||||
break;
|
||||
case LibFunc_terminate:
|
||||
// May callback; terminate_handler may be called
|
||||
Changed |= setIsCold(F);
|
||||
Changed |= setNoReturn(F);
|
||||
break;
|
||||
@ -1284,6 +1318,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
case LibFunc_tanhl:
|
||||
case LibFunc_tanl:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setDoesNotFreeMemory(F);
|
||||
Changed |= setWillReturn(F);
|
||||
Changed |= setOnlyWritesErrnoMemory(F);
|
||||
@ -1327,6 +1362,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
case LibFunc_isascii:
|
||||
case LibFunc_isdigit:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setDoesNotFreeMemory(F);
|
||||
Changed |= setWillReturn(F);
|
||||
break;
|
||||
@ -1340,6 +1376,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
|
||||
case LibFunc_remquof:
|
||||
case LibFunc_remquol:
|
||||
Changed |= setDoesNotThrow(F);
|
||||
Changed |= setDoesNotCallback(F);
|
||||
Changed |= setDoesNotFreeMemory(F);
|
||||
Changed |= setOnlyWritesMemory(F, 2);
|
||||
Changed |= setDoesNotCapture(F, 2);
|
||||
|
@ -1038,34 +1038,34 @@ declare i64 @strspn(ptr, ptr)
|
||||
; CHECK: declare ptr @strstr(ptr, ptr captures(none)) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]]
|
||||
declare ptr @strstr(ptr, ptr)
|
||||
|
||||
; CHECK: declare double @strtod(ptr readonly, ptr captures(none)) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare double @strtod(ptr readonly, ptr captures(none)) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
|
||||
declare double @strtod(ptr, ptr)
|
||||
|
||||
; CHECK: declare float @strtof(ptr readonly, ptr captures(none)) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare float @strtof(ptr readonly, ptr captures(none)) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare float @strtof(ptr, ptr)
|
||||
|
||||
; CHECK: declare ptr @strtok(ptr, ptr readonly captures(none)) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare ptr @strtok(ptr, ptr readonly captures(none)) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare ptr @strtok(ptr, ptr)
|
||||
|
||||
; CHECK: declare ptr @strtok_r(ptr, ptr readonly captures(none), ptr) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare ptr @strtok_r(ptr, ptr readonly captures(none), ptr) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare ptr @strtok_r(ptr, ptr, ptr)
|
||||
|
||||
; CHECK: declare i64 @strtol(ptr readonly, ptr captures(none), i32) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare i64 @strtol(ptr readonly, ptr captures(none), i32) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i64 @strtol(ptr, ptr, i32)
|
||||
|
||||
; CHECK: declare x86_fp80 @strtold(ptr readonly, ptr captures(none)) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare x86_fp80 @strtold(ptr readonly, ptr captures(none)) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare x86_fp80 @strtold(ptr, ptr)
|
||||
|
||||
; CHECK: declare i64 @strtoll(ptr readonly, ptr captures(none), i32) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare i64 @strtoll(ptr readonly, ptr captures(none), i32) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i64 @strtoll(ptr, ptr, i32)
|
||||
|
||||
; CHECK: declare i64 @strtoul(ptr readonly, ptr captures(none), i32) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare i64 @strtoul(ptr readonly, ptr captures(none), i32) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i64 @strtoul(ptr, ptr, i32)
|
||||
|
||||
; CHECK: declare i64 @strtoull(ptr readonly, ptr captures(none), i32) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare i64 @strtoull(ptr readonly, ptr captures(none), i32) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i64 @strtoull(ptr, ptr, i32)
|
||||
|
||||
; CHECK: declare i64 @strxfrm(ptr captures(none), ptr readonly captures(none), i64) [[NOFREE_NOUNWIND_WILLRETURN]]
|
||||
; CHECK: declare i64 @strxfrm(ptr captures(none), ptr readonly captures(none), i64) [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]]
|
||||
declare i64 @strxfrm(ptr, ptr, i64)
|
||||
|
||||
; CHECK: declare noundef i32 @system(ptr noundef readonly captures(none)) [[NOFREE]]
|
||||
@ -1182,21 +1182,22 @@ declare void @memset_pattern8(ptr, ptr, i64)
|
||||
declare void @memset_pattern16(ptr, ptr, i64)
|
||||
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn }
|
||||
; CHECK-DAG: attributes [[MEMNONE_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
|
||||
; CHECK-DAG: attributes [[ARGMEMORERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: write, errnomem: write) }
|
||||
; CHECK-DAG: attributes [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(errnomem: write) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]] = { mustprogress nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK-DAG: attributes [[NOCALLBACK_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn }
|
||||
; CHECK-DAG: attributes [[MEMNONE_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
|
||||
; CHECK-DAG: attributes [[ARGMEMORERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write, errnomem: write) }
|
||||
; CHECK-DAG: attributes [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(errnomem: write) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN_WRITEONLY]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized,aligned") allocsize(1) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCZEROED_ALLOCSIZE01_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,zeroed") allocsize(0,1) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(read) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(read) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nofree nounwind willreturn memory(argmem: read) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: read) }
|
||||
; CHECK-DAG: attributes [[NOFREE]] = { nofree }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { nofree nounwind memory(argmem: readwrite) }
|
||||
; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { nocallback nofree nounwind memory(argmem: readwrite) }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE1_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_REALLOC_ALLOCSIZE12_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("realloc") allocsize(1,2) memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
|
||||
|
@ -5,4 +5,4 @@
|
||||
; CHECK: declare double @acos(double) [[NOFREE_NOUNWIND_WILLRETURN_READNONE:#[0-9]+]]
|
||||
declare double @acos(double) readonly
|
||||
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_READNONE]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
|
||||
; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN_READNONE]] = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
|
||||
|
@ -13,7 +13,7 @@ loop:
|
||||
}
|
||||
|
||||
; CHECK: declare i64 @strlen(ptr captures(none)) #0
|
||||
; CHECK: attributes #0 = { mustprogress nofree nounwind willreturn memory(argmem: read) }
|
||||
; CHECK: attributes #0 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: read) }
|
||||
declare i64 @strlen(ptr)
|
||||
|
||||
|
||||
|
@ -1625,6 +1625,5 @@ define noalias ptr @_ZN8CMSPULog9beginImplEja(ptr nocapture writeonly %0) local_
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK: attributes #[[ATTR4:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
;.
|
||||
|
@ -116,7 +116,7 @@ for.body:
|
||||
!21 = !{!22, !20, i64 0}
|
||||
!22 = !{!"B", !20, i64 0}
|
||||
;.
|
||||
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
;.
|
||||
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
|
||||
; CHECK: [[META1]] = !{!"double", [[META2:![0-9]+]], i64 0}
|
||||
|
@ -292,5 +292,5 @@ for.end: ; preds = %for.end.loopexit, %
|
||||
}
|
||||
;.
|
||||
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind ssp }
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
;.
|
||||
|
@ -126,5 +126,5 @@ for.end: ; preds = %for.end.loopexit, %
|
||||
;.
|
||||
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind ssp }
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
;.
|
||||
|
@ -130,5 +130,5 @@ for.end: ; preds = %for.end.loopexit, %
|
||||
;.
|
||||
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind ssp }
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
;.
|
||||
|
@ -220,7 +220,7 @@ define void @memset_pattern_i64_x_fromnonconstptr(ptr %a, i64 %x, ptr %p) nounwi
|
||||
;.
|
||||
; CHECK: attributes #[[ATTR0]] = { nounwind }
|
||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
|
||||
;.
|
||||
; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
|
||||
; CHECK: [[META1]] = !{!"double", [[META2:![0-9]+]], i64 0}
|
||||
|
Loading…
x
Reference in New Issue
Block a user